Führen Sie hybride Workloads mit PennyLane eingebetteten Simulatoren aus - Amazon Braket

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Führen Sie hybride Workloads mit PennyLane eingebetteten Simulatoren aus

Schauen wir uns an, wie Sie eingebettete Simulatoren von PennyLane Amazon Braket Hybrid Jobs aus verwenden können, um Hybrid-Workloads auszuführen. Der auf Pennylane GPU basierende eingebettete Simulator verwendet die cuQuantum Nvidia-Bibliothek lightning.gpu, um Schaltungssimulationen zu beschleunigen. Der eingebettete GPU Simulator ist in allen Braket-Jobcontainern vorkonfiguriert, die Benutzer sofort verwenden können. Auf dieser Seite zeigen wir Ihnen, wie Sie lightning.gpu damit Ihre Hybrid-Workloads beschleunigen können.

lightning.gpuFür QAOA Workloads verwenden

Sehen Sie sich die Beispiele für den Algorithmus zur quantennahen Optimierung (QAOA) aus diesem Notizbuch an. Um einen eingebetteten Simulator auszuwählen, geben Sie als device Argument eine Zeichenfolge der folgenden Form an:"local:<provider>/<simulator_name>". Zum Beispiel würden Sie "local:pennylane/lightning.gpu" für festlegenlightning.gpu. Die Gerätezeichenfolge, die Sie dem Hybrid-Job beim Start geben, wird als Umgebungsvariable an den Job übergeben"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)

Lassen Sie uns auf dieser Seite die beiden eingebetteten PennyLane Zustandsvektorsimulatoren lightning.qubit (welcher CPU basiert) und lightning.gpu (welcher GPU basiert) vergleichen. Sie müssen den Simulatoren einige benutzerdefinierte Gate-Zerlegungen zur Verfügung stellen, um verschiedene Gradienten berechnen zu können.

Jetzt sind Sie bereit, das Skript zum Starten des Hybrid-Jobs vorzubereiten. Sie führen den QAOA Algorithmus mit zwei Instanztypen aus: m5.2xlarge undp3.2xlarge. Der m5.2xlarge Instanztyp ist mit einem Standard-Entwickler-Laptop vergleichbar. Dabei p3.2xlarge handelt es sich um eine beschleunigte Recheninstanz GPU mit einem einzigen NVIDIA Volta und 16 GB Arbeitsspeicher.

Das wird hyperparameters für all Ihre Hybrid-Jobs gleich sein. Um verschiedene Instanzen und Simulatoren auszuprobieren, müssen Sie lediglich zwei Zeilen wie folgt ändern.

# Specify device that the hybrid job will primarily be targeting device = "local:pennylane/lightning.qubit" # Run on a CPU based instance with about as much power as a laptop instance_config = InstanceConfig(instanceType='ml.m5.2xlarge')

oder:

# Specify device that the hybrid job will primarily be targeting device = "local:pennylane/lightning.gpu" # Run on an inexpensive GPU based instance instance_config = InstanceConfig(instanceType='ml.p3.2xlarge')
Anmerkung

Wenn Sie das instance_config als mithilfe einer GPU basierten Instanz angeben, aber device den eingebetteten CPU basierten Simulator (lightning.qubit) wählen, GPU wird der nicht verwendet. Stellen Sie sicher, dass Sie den GPU eingebetteten Simulator verwenden, wenn Sie auf denGPU!

Zunächst können Sie zwei Hybrid-Jobs erstellen und Max-Cut mit einem Graphen mit 18 QAOA Eckpunkten lösen. Das entspricht einer 18-Qubit-Schaltung, die relativ klein ist und schnell auf Ihrem Laptop oder der Instanz ausgeführt werden kann. m5.2xlarge

num_nodes = 18 num_edges = 24 seed = 1967 graph = nx.gnm_random_graph(num_nodes, num_edges, seed=seed) # And similarly for the p3 job m5_job = AwsQuantumJob.create( device=device, source_module="qaoa_source", job_name="qaoa-m5-" + str(int(time.time())), image_uri=image_uri, # Relative to the source_module entry_point="qaoa_source.qaoa_algorithm_script", copy_checkpoints_from_job=None, instance_config=instance_config, # general parameters hyperparameters=hyperparameters, input_data={"input-graph": input_file_path}, wait_until_complete=True, )

Die durchschnittliche Iterationszeit für die m5.2xlarge Instance beträgt etwa 25 Sekunden, während sie für die p3.2xlarge Instance etwa 12 Sekunden beträgt. Für diesen 18-Qubit-Workflow bietet uns die GPU Instanz eine 2-fache Beschleunigung. Wenn Sie sich die Preisseite für Amazon Braket Hybrid Jobs ansehen, können Sie sehen, dass die Kosten pro Minute für eine m5.2xlarge Instance 0,00768 USD betragen, während sie für die p3.2xlarge Instance 0,06375 USD betragen. Das Ausführen von insgesamt 5 Iterationen, wie Sie es hier getan haben, würde 0,016$ mit der CPU Instance oder 0,06375$ mit der Instance kosten — beides ziemlich günstig! GPU

Lassen Sie uns nun das Problem noch schwieriger machen und versuchen, ein Max-Cut-Problem auf einem Graphen mit 24 Eckpunkten zu lösen, was 24 Qubits ergibt. Führen Sie die Hybrid-Jobs erneut auf denselben beiden Instanzen aus und vergleichen Sie die Kosten.

Anmerkung

Sie werden feststellen, dass die Ausführung dieses Hybrid-Jobs auf der CPU Instance etwa fünf Stunden dauern kann!

num_nodes = 24 num_edges = 36 seed = 1967 graph = nx.gnm_random_graph(num_nodes, num_edges, seed=seed) # And similarly for the p3 job m5_big_job = AwsQuantumJob.create( device=device, source_module="qaoa_source", job_name="qaoa-m5-big-" + str(int(time.time())), image_uri=image_uri, # Relative to the source_module entry_point="qaoa_source.qaoa_algorithm_script", copy_checkpoints_from_job=None, instance_config=instance_config, # general parameters hyperparameters=hyperparameters, input_data={"input-graph": input_file_path}, wait_until_complete=True, )

Die durchschnittliche Iterationszeit für die m5.2xlarge Instanz beträgt ungefähr eine Stunde, während sie für die p3.2xlarge Instanz ungefähr zwei Minuten beträgt. Bei diesem größeren Problem ist die GPU Instanz um eine Größenordnung schneller! Um von dieser Beschleunigung zu profitieren, mussten Sie lediglich zwei Codezeilen ändern und dabei den Instanztyp und den verwendeten lokalen Simulator austauschen. Eine Ausführung von insgesamt 5 Iterationen, wie es hier der Fall war, würde mit der Instanz etwa 2,27072$ oder mit der CPU Instanz etwa 0,775625$ kosten. GPU Die CPU Nutzung ist nicht nur teurer, sondern nimmt auch mehr Zeit in Anspruch. Wenn Sie diesen Workflow mit einer GPU Instanz beschleunigen AWS, auf der PennyLane der eingebettete Simulator verwendet wird NVIDIA CuQuantum, können Sie Workflows mit mittleren Qubitzahlen (zwischen 20 und 30) zu geringeren Gesamtkosten und in kürzerer Zeit ausführen. Das bedeutet, dass Sie mit Quantencomputing auch bei Problemen experimentieren können, die zu groß sind, um sie schnell auf Ihrem Laptop oder einer Instanz ähnlicher Größe auszuführen.

Maschinelles Quantenlernen und Datenparallelität

Wenn es sich bei Ihrem Workload-Typ um maschinelles Quantenlernen (QML) handelt, das auf Datensätzen trainiert, können Sie Ihren Workload mithilfe von Datenparallelität weiter beschleunigen. InQML, das Modell enthält einen oder mehrere Quantenschaltkreise. Das Modell kann auch klassische neuronale Netze enthalten oder nicht. Beim Training des Modells mit dem Datensatz werden die Parameter im Modell aktualisiert, um die Verlustfunktion zu minimieren. Eine Verlustfunktion wird normalerweise für einen einzelnen Datenpunkt und der Gesamtverlust für den durchschnittlichen Verlust über den gesamten Datensatz definiert. In werden die Verluste normalerweise seriell berechnetQML, bevor bei Gradientenberechnungen der Mittelwert zum Gesamtverlust berechnet wird. Dieses Verfahren ist zeitaufwändig, insbesondere bei Hunderten von Datenpunkten.

Da der Verlust von einem Datenpunkt nicht von anderen Datenpunkten abhängt, können die Verluste parallel ausgewertet werden! Verluste und Gradienten, die mit verschiedenen Datenpunkten verbunden sind, können gleichzeitig ausgewertet werden. Dies wird als Datenparallelität bezeichnet. Mit SageMaker der verteilten Datenparallelbibliothek erleichtert Ihnen Amazon Braket Hybrid Jobs die Nutzung von Datenparallelität, um Ihr Training zu beschleunigen.

Stellen Sie sich den folgenden QML Workload für Datenparallelität vor, bei dem der Sonar-Datensatz aus dem bekannten UCI Repository als Beispiel für die binäre Klassifizierung verwendet wird. Der Sonar-Datensatz enthält 208 Datenpunkte mit jeweils 60 Merkmalen, die anhand von Sonarsignalen erfasst wurden, die von Materialien abprallen. Jeder Datenpunkt ist entweder mit „M“ für Minen oder mit „R“ für Gesteine gekennzeichnet. Unser QML Modell besteht aus einer Eingangsschicht, einem Quantenschaltkreis als versteckte Schicht und einer Ausgangsschicht. Die Eingabe- und Ausgabeschichten sind klassische neuronale Netze, die in implementiert sind PyTorch. Der Quantenschaltkreis ist mithilfe PennyLane des qml.qnn-Moduls in die PyTorch neuronalen Netze integriert. Weitere Informationen zur Arbeitslast finden Sie in unseren Beispiel-Notizbüchern. Wie im obigen QAOA Beispiel können Sie das Potenzial von nutzen, GPU indem Sie eingebettete GPU Simulatoren wie PennyLane diese verwenden, lightning.gpu um die Leistung gegenüber eingebetteten CPU Simulatoren zu verbessern.

Um einen Hybrid-Job zu erstellen, können Sie das Algorithmus-Skript, das Gerät AwsQuantumJob.create und andere Konfigurationen über seine Schlüsselwortargumente aufrufen und angeben.

instance_config = InstanceConfig(instanceType='ml.p3.2xlarge') 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, ... )

Um Datenparallelität zu verwenden, müssen Sie einige Codezeilen im Algorithmus-Skript für die SageMaker verteilte Bibliothek ändern, um das Training korrekt zu parallelisieren. Zunächst importieren Sie das smdistributed Paket, das den Großteil der Arbeit für die Verteilung Ihrer Workloads auf mehrere und mehrere Instanzen übernimmt. GPUs Dieses Paket ist im Braket und in den Containern vorkonfiguriert. PyTorch TensorFlow Das dist Modul teilt unserem Algorithmus-Skript die Gesamtzahl der GPUs Trainingseinheiten (world_size) rank sowie das Ende local_rank eines GPU Kerns mit. rankist der absolute Index von a GPU für alle Instanzen, während local_rank es der Index von a GPU innerhalb einer Instanz ist. Wenn es beispielsweise vier Instanzen gibt, von denen jeweils acht für das Training GPUs zugewiesen sind, rank liegen die Bereiche zwischen 0 und 31 und die local_rank Bereiche zwischen 0 und 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)

Als Nächstes definieren Sie a DistributedSampler entsprechend dem world_size und rank und übergeben es dann an den Datenlader. Dieser Sampler vermeidet den GPUs Zugriff auf dasselbe Segment eines Datensatzes.

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, )

Als Nächstes verwenden Sie die DistributedDataParallel Klasse, um Datenparallelität zu aktivieren.

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"])

Die oben genannten Änderungen sind erforderlich, um Datenparallelität zu verwenden. In QML möchten Sie häufig Ergebnisse speichern und den Trainingsfortschritt ausdrucken. Wenn beide den GPU Befehl zum Speichern und Drucken ausführen, wird das Protokoll mit den sich wiederholenden Informationen überflutet, und die Ergebnisse überschreiben sich gegenseitig. Um dies zu vermeiden, können Sie nur den GPU Wert 0 speichern und drucken. rank

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 unterstützt ml.p3.16xlarge Instance-Typen für die SageMaker Distributed Data Parallel Library. Sie konfigurieren den Instance-Typ über das InstanceConfig Argument in Hybrid Jobs. Damit die SageMaker Distributed Data Parallel Library weiß, dass Datenparallelität aktiviert ist, müssen Sie zwei zusätzliche Hyperparameter hinzufügen: "sagemaker_distributed_dataparallel_enabled" Einstellung auf "true" und "sagemaker_instance_type" Einstellung auf den Instanztyp, den Sie verwenden. Diese beiden Hyperparameter werden pro Paket verwendet. smdistributed Ihr Algorithmus-Skript muss sie nicht explizit verwenden. In Amazon Braket SDK bietet es ein praktisches Schlüsselwortargumentdistribution. distribution="data_parallel"Bei der hybriden Auftragserstellung fügt Amazon Braket die beiden Hyperparameter SDK automatisch für Sie ein. Wenn Sie Amazon Braket verwendenAPI, müssen Sie diese beiden Hyperparameter einbeziehen.

Wenn die Instanz und der Datenparallelismus konfiguriert sind, können Sie jetzt Ihren Hybrid-Job einreichen. In einer ml.p3.16xlarge Instanz gibt es 8. GPUs Wenn Sie festlegeninstanceCount=1, wird die Arbeitslast auf die 8 GPUs in der Instanz verteilt. Wenn Sie instanceCount mehr als eine festlegen, wird die Arbeitslast auf alle GPUs verfügbaren Instanzen verteilt. Wenn Sie mehrere Instanzen verwenden, fällt für jede Instanz eine Gebühr an, die davon abhängt, wie lange Sie sie verwenden. Wenn Sie beispielsweise vier Instances verwenden, beträgt die abrechnungsfähige Zeit das Vierfache der Laufzeit pro Instance, da Ihre Workloads von vier Instances gleichzeitig ausgeführt werden.

instance_config = InstanceConfig(instanceType='ml.p3.16xlarge', 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", ... )
Anmerkung

In der obigen Hybrid-Job-Erstellung train_dp.py ist das modifizierte Algorithmus-Skript für die Verwendung von Datenparallelität enthalten. Beachten Sie, dass Datenparallelität nur dann korrekt funktioniert, wenn Sie Ihr Algorithmus-Skript gemäß dem obigen Abschnitt ändern. Wenn die Option Datenparallelität ohne ein korrekt modifiziertes Algorithmus-Skript aktiviert ist, kann es sein, dass der Hybrid-Job Fehler auslöst oder GPU dass beide wiederholt denselben Datenabschnitt verarbeiten, was ineffizient ist.

Lassen Sie uns die Laufzeit und die Kosten anhand eines Beispiels vergleichen, bei dem ein Modell mit einem 26-Qubit-Quantenschaltkreis trainiert wird, um das oben erwähnte Problem der binären Klassifikation zu lösen. Die in diesem ml.p3.16xlarge Beispiel verwendete Instanz kostet 0,4692$ pro Minute. Ohne Datenparallelität benötigt der Simulator etwa 45 Minuten, um das Modell für eine Epoche (d. h. über 208 Datenpunkte) zu trainieren, und es kostet etwa 20$. Bei Datenparallelität über 1 Instanz und 4 Instanzen dauert es nur 6 Minuten bzw. 1,5 Minuten, was ungefähr 2,8$ für beide entspricht. Durch die Verwendung von Datenparallelität über 4 Instanzen hinweg verbessern Sie nicht nur die Laufzeit um das 30-fache, sondern reduzieren auch die Kosten um eine Größenordnung!