Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Exécutez des charges de travail hybrides avec des simulateurs PennyLane intégrés
Voyons comment utiliser des simulateurs intégrés à partir PennyLane d'Amazon Braket Hybrid Jobs pour exécuter des charges de travail hybrides. Le simulateur GPU-based intégré de Pennylane utilise la bibliothèque Nvidia CuQuantum lightning.gpu Le simulateur GPU intégré est préconfiguré dans tous les conteneurs de tâches Braket que les utilisateurs peuvent utiliser prêts à l'lightning.gpu pour accélérer vos charges de travail hybrides.
Utilisation de lightning.gpu pour les charges de travail QAOA
Examinez les exemples d'algorithme d'optimisation approximative quantique (QAOA) tirés de ce bloc-notes. deviceargument est une chaîne de la forme :"local:<provider>/<simulator_name>". Par exemple, vous pouvez définir "local:pennylane/lightning.gpu" pourlightning.gpu. La chaîne de périphérique que vous donnez à la tâche hybride lors de son lancement est transmise à la tâche en tant que variable d'environnement"AMZN_BRAKET_DEVICE_ARN".
device_string = os.environ["AMZN_BRAKET_DEVICE_ARN"] prefix, device_name = device_string.split("/") device = qml.device(simulator_name, wires=n_wires)
Dans cette page, comparez les deux simulateurs de vecteurs PennyLane d'état intégrés lightning.qubit (qui est CPU-based) et lightning.gpu (qui est GPU-based). Fournissez aux simulateurs des décompositions de portes personnalisées pour calculer différents gradients.
Vous êtes maintenant prêt à préparer le script de lancement de tâches hybrides. Exécutez l'algorithme QAOA à l'aide de deux types d'instances : ml.m5.2xlarge et. ml.g4dn.xlarge Le type d'ml.m5.2xlargeinstance est comparable à un ordinateur portable de développeur standard. ml.g4dn.xlargeIl s'agit d'une instance informatique accélérée dotée d'un seul GPU NVIDIA T4 avec 16 Go de mémoire.
Pour exécuter le GPU, nous devons d'abord spécifier une image compatible et l'instance correcte (qui est par défaut une ml.m5.2xlarge instance).
from braket.aws import AwsSession from braket.jobs.image_uris import Framework, retrieve_image image_uri = retrieve_image(Framework.PL_PYTORCH, AwsSession().region) instance_config = InstanceConfig(instanceType="ml.g4dn.xlarge")
Nous devons ensuite les saisir dans le décorateur de tâches hybride, ainsi que les paramètres de périphérique mis à jour dans les arguments système et de tâche hybride.
@hybrid_job( device="local:pennylane/lightning.gpu", input_data=input_file_path, image_uri=image_uri, instance_config=instance_config) def run_qaoa_hybrid_job_gpu(p=1, steps=10): params = np.random.rand(2, p) braket_task_tracker = Tracker() graph = nx.read_adjlist(input_file_path, nodetype=int) wires = list(graph.nodes) cost_h, _mixer_h = qaoa.maxcut(graph) device_string = os.environ["AMZN_BRAKET_DEVICE_ARN"] prefix, device_name = device_string.split("/") dev= qml.device(simulator_name, wires=len(wires)) ...
Note
Si vous le spécifiez instance_config comme utilisant une GPU-based instance, mais que device vous choisissez comme CPU-based simulateur intégré (lightning.qubit), le GPU ne sera pas utilisé. Assurez-vous d'utiliser le GPU-based simulateur intégré si vous souhaitez cibler le GPU !
Le temps d'itération moyen pour l'm5.2xlargeinstance est d'environ 73 secondes, alors que pour l'ml.g4dn.xlargeinstance, il est d'environ 0,6 seconde. Pour ce flux de travail de 21 qubits, l'instance GPU nous accélère de 100 fois. Si vous consultez la page de tarification d'Amazon Braket Hybrid Jobsm5.2xlarge instance est de 0,00768 USD, alors que pour l'instance, il est de 0,01227 ml.g4dn.xlarge USD. Dans ce cas, il est plus rapide et moins coûteux de l'exécuter sur l'instance GPU.
Apprentissage automatique quantique et parallélisme des données
Si votre type de charge de travail est un apprentissage automatique quantique (QML) qui s'entraîne sur des ensembles de données, vous pouvez encore accélérer votre charge de travail en utilisant le parallélisme des données. Dans QML, le modèle contient un ou plusieurs circuits quantiques. Le modèle peut également contenir ou non des réseaux neuronaux classiques. Lors de l'entraînement du modèle à l'aide de l'ensemble de données, les paramètres du modèle sont mis à jour pour minimiser la fonction de perte. Une fonction de perte est généralement définie pour un seul point de données, et la perte totale est définie pour la perte moyenne sur l'ensemble de l'ensemble de données. Dans QML, les pertes sont généralement calculées en série avant d'être moyennées par rapport à la perte totale pour les calculs de gradient. Cette procédure prend du temps, surtout lorsqu'il existe des centaines de points de données.
Comme la perte d'un point de données ne dépend pas des autres points de données, les pertes peuvent être évaluées en parallèle ! Les pertes et les gradients associés à différents points de données peuvent être évalués simultanément. C'est ce que l'on appelle le parallélisme des données. Grâce à SageMaker sa bibliothèque de données parallèles distribuées, Amazon Braket Hybrid Jobs vous permet d'utiliser plus facilement le parallélisme des données pour accélérer votre entraînement.
Considérez la charge de travail QML suivante pour le parallélisme des données, qui utilise l'ensemble de données lightning.gpu aux simulateurs intégrés. CPU-based
Pour créer une tâche hybride, vous pouvez appeler AwsQuantumJob.create et spécifier le script de l'algorithme, le périphérique et d'autres configurations à l'aide de ses arguments de mot-clé.
instance_config = InstanceConfig(instanceType='ml.g4dn.xlarge') hyperparameters={"nwires": "10", "ndata": "32", ... } job = AwsQuantumJob.create( device="local:pennylane/lightning.gpu", source_module="qml_source", entry_point="qml_source.train_single", hyperparameters=hyperparameters, instance_config=instance_config, ... )
Pour utiliser le parallélisme des données, vous devez modifier quelques lignes de code dans le script de l'algorithme de la bibliothèque SageMaker distribuée afin de paralléliser correctement l'apprentissage. Tout d'abord, vous importez le smdistributed package qui fait le plus gros du travail pour répartir vos charges de travail sur plusieurs GPU et plusieurs instances. Ce package est préconfiguré dans le Braket et PyTorch les conteneurs. TensorFlow Le dist module indique à notre script d'algorithme le nombre total de GPU pour l'entraînement (world_size) ainsi que la fin rank local_rank d'un cœur de GPU. rankest l'indice absolu d'un GPU pour toutes les instances, tandis local_rank que l'indice d'un GPU au sein d'une instance. Par exemple, s'il existe quatre instances avec chacune huit GPU alloués à l'entraînement, les rank plages vont de 0 à 31 et les local_rank plages de 0 à 7.
import smdistributed.dataparallel.torch.distributed as dist dp_info = { "world_size": dist.get_world_size(), "rank": dist.get_rank(), "local_rank": dist.get_local_rank(), } batch_size //= dp_info["world_size"] // 8 batch_size = max(batch_size, 1)
Ensuite, vous définissez un DistributedSampler en fonction de world_size rank et puis vous le transmettez au chargeur de données. Cet échantillonneur évite aux GPU d'accéder à la même tranche d'un ensemble de données.
train_sampler = torch.utils.data.distributed.DistributedSampler( train_dataset, num_replicas=dp_info["world_size"], rank=dp_info["rank"] ) train_loader = torch.utils.data.DataLoader( train_dataset, batch_size=batch_size, shuffle=False, num_workers=0, pin_memory=True, sampler=train_sampler, )
Ensuite, vous utilisez la DistributedDataParallel classe pour activer le parallélisme des données.
from smdistributed.dataparallel.torch.parallel.distributed import DistributedDataParallel as DDP model = DressedQNN(qc_dev).to(device) model = DDP(model) torch.cuda.set_device(dp_info["local_rank"]) model.cuda(dp_info["local_rank"])
Les modifications ci-dessus sont nécessaires pour utiliser le parallélisme des données. Dans QML, vous souhaitez souvent enregistrer les résultats et imprimer la progression de l'entraînement. Si chaque GPU exécute la commande de sauvegarde et d'impression, le journal sera inondé d'informations répétées et les résultats s'écraseront les uns les autres. Pour éviter cela, vous ne pouvez enregistrer et imprimer qu'à partir du GPU qui a rank 0.
if dp_info["rank"]==0: print('elapsed time: ', elapsed) torch.save(model.state_dict(), f"{output_dir}/test_local.pt") save_job_result({"last loss": loss_before})
Amazon Braket Hybrid Jobs prend en charge les types d'ml.g4dn.12xlargeinstances pour la bibliothèque parallèle de données SageMaker distribuées. Vous configurez le type d'instance via l'InstanceConfigargument dans Hybrid Jobs. Pour que la bibliothèque de données parallèles SageMaker distribuées sache que le parallélisme des données est activé, vous devez ajouter deux hyperparamètres supplémentaires, le "sagemaker_distributed_dataparallel_enabled" paramétrage "true" et le "sagemaker_instance_type" paramétrage du type d'instance que vous utilisez. Ces deux hyperparamètres sont utilisés par smdistributed package. Le script de votre algorithme n'a pas besoin de les utiliser explicitement. Dans le SDK Amazon Braket, il fournit un argument de mot clé pratique. distribution distribution="data_parallel"Dans le cadre de la création de tâches hybride, le SDK Amazon Braket insère automatiquement les deux hyperparamètres pour vous. Si vous utilisez l'API Amazon Braket, vous devez inclure ces deux hyperparamètres.
Une fois le parallélisme des instances et des données configuré, vous pouvez désormais soumettre votre tâche hybride. Il y a 4 GPU dans une ml.g4dn.12xlarge instance. Lorsque vous définissezinstanceCount=1, la charge de travail est répartie sur les 8 GPU de l'instance. Lorsque vous en définissez instanceCount plusieurs, la charge de travail est répartie sur les GPU disponibles dans toutes les instances. Lorsque vous utilisez plusieurs instances, chaque instance est facturée en fonction de la durée d'utilisation. Par exemple, lorsque vous utilisez quatre instances, la durée facturable est quatre fois supérieure à la durée d'exécution par instance, car quatre instances exécutent vos charges de travail en même temps.
instance_config = InstanceConfig(instanceType='ml.g4dn.12xlarge', instanceCount=1, ) hyperparameters={"nwires": "10", "ndata": "32", ..., } job = AwsQuantumJob.create( device="local:pennylane/lightning.gpu", source_module="qml_source", entry_point="qml_source.train_dp", hyperparameters=hyperparameters, instance_config=instance_config, distribution="data_parallel", ... )
Note
Dans la création d'emplois hybride ci-dessus, train_dp.py se trouve le script d'algorithme modifié pour utiliser le parallélisme des données. N'oubliez pas que le parallélisme des données ne fonctionne correctement que lorsque vous modifiez le script de votre algorithme conformément à la section ci-dessus. Si l'option de parallélisme des données est activée sans qu'un script d'algorithme soit correctement modifié, la tâche hybride peut générer des erreurs ou chaque GPU peut traiter à plusieurs reprises la même tranche de données, ce qui est inefficace.
Si elle est utilisée correctement, l'utilisation de plusieurs instances peut entraîner une réduction de plusieurs ordres de grandeur en termes de temps et de coûts. Consultez l'exemple de bloc-notes pour plus de détails