Accelera i carichi di lavoro ibridi con i simulatori integrati di PennyLane - Amazon Braket

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Accelera i carichi di lavoro ibridi con i simulatori integrati di PennyLane

Diamo un'occhiata a come utilizzare i simulatori integrati di Amazon Braket Hybrid Jobs per eseguire carichi di lavoro ibridi. PennyLane Il simulatore integrato basato su GPU di Pennylane utilizza la libreria Nvidia CuQuantum per accelerare lightning.gpu le simulazioni dei circuiti. Il simulatore GPU integrato è preconfigurato in tutti i contenitori di lavoro Braket che gli utenti possono utilizzare immediatamente. In questa pagina, ti mostriamo come utilizzarlo per velocizzare i carichi lightning.gpu di lavoro ibridi.

Utilizzo lightning.gpu per carichi di lavoro dell'algoritmo di ottimizzazione quantistica approssimativa

Considerate gli esempi di Quantum Approximate Optimization Algorithm (QAOA) tratti da questo notebook. Per selezionare un simulatore incorporato, si specifica che l'deviceargomento sia una stringa del formato:. "local:<provider>/<simulator_name>" Ad esempio, imposteresti "local:pennylane/lightning.gpu" perlightning.gpu. La stringa del dispositivo fornita a Hybrid Job all'avvio viene passata al lavoro come variabile di ambiente"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)

In questa pagina, confrontiamo i due simulatori vettoriali di PennyLane stato incorporati lightning.qubit (basati su CPU) e lightning.gpu (basati su GPU). Dovrai fornire ai simulatori alcune scomposizioni di gate personalizzate per calcolare vari gradienti.

Ora sei pronto per preparare lo script ibrido di avvio del lavoro. Eseguirai l'algoritmo QAOA utilizzando due tipi di istanza: e. m5.2xlarge p3.2xlarge Il tipo di m5.2xlarge istanza è paragonabile a un laptop standard per sviluppatori. p3.2xlargeSi tratta di un'istanza di elaborazione accelerata con una singola GPU NVIDIA Volta con 16 GB di memoria.

Il risultato sarà lo stesso hyperparameters per tutti i tuoi lavori ibridi. Tutto quello che devi fare per provare diverse istanze e simulatori è cambiare due righe come segue.

# 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')

oppure:

# 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')
Nota

Se si specifica l'instance_configas utilizzando un'istanza basata su GPU, ma si sceglie come simulatore incorporato basato sulla CPU (lightning.qubit), la GPU non verrà utilizzata. device Assicurati di utilizzare il simulatore integrato basato su GPU se desideri utilizzare come target la GPU!

Innanzitutto, puoi creare due lavori ibridi e risolvere Max-Cut con QAOA su un grafico con 18 vertici. Ciò si traduce in un circuito da 18 qubit, relativamente piccolo e fattibile da eseguire rapidamente sul laptop o sull'istanza. 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, )

Il tempo di iterazione medio per l'istanza è di circa 25 secondi, mentre per l'm5.2xlargeistanza è di circa 12 secondi. p3.2xlarge Per questo flusso di lavoro da 18 qubit, l'istanza GPU ci offre una velocità di 2 volte superiore. Se guardi la pagina dei prezzi di Amazon Braket Hybrid Jobs, puoi vedere che il costo al minuto per un'm5.2xlargeistanza è di 0,00768 USD, mentre per l'p3.2xlargeistanza è di 0,06375 USD. L'esecuzione per un totale di 5 iterazioni, come hai fatto qui, costerebbe 0,016 dollari utilizzando l'istanza CPU o 0,06375 dollari usando l'istanza GPU, entrambe piuttosto economiche!

Ora rendiamo il problema più difficile e proviamo a risolvere un problema Max-Cut su un grafo a 24 vertici, che si tradurrà in 24 qubit. Esegui nuovamente i processi ibridi sulle stesse due istanze e confronta i costi.

Nota

Vedrai che il tempo necessario per eseguire questo processo ibrido sull'istanza della CPU potrebbe essere di circa cinque ore!

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

Il tempo medio di iterazione per l'm5.2xlargeistanza è di circa un'ora, mentre per l'p3.2xlargeistanza è di circa due minuti. Per questo problema più ampio, l'istanza GPU è un ordine di grandezza più veloce! Tutto quello che dovevi fare per trarre vantaggio da questa accelerazione era modificare due righe di codice, sostituendo il tipo di istanza e il simulatore locale utilizzato. L'esecuzione per un totale di 5 iterazioni, come è stato fatto qui, costerebbe circa 2,27072 dollari utilizzando l'istanza CPU o circa 0,775625 dollari utilizzando l'istanza GPU. L'utilizzo della CPU non è solo più costoso, ma richiede anche più tempo per l'esecuzione. L'accelerazione di questo flusso di lavoro con un'istanza GPU disponibile su AWS, utilizzando PennyLane il simulatore integrato supportato da NVIDIA CuQuantum, consente di eseguire flussi di lavoro con conteggi di qubit intermedi (tra 20 e 30) a un costo totale inferiore e in meno tempo. Ciò significa che puoi sperimentare con l'informatica quantistica anche per problemi troppo grandi per essere eseguiti rapidamente sul tuo laptop o su un'istanza di dimensioni simili.

Apprendimento automatico quantistico e parallelismo dei dati

Se il tuo tipo di carico di lavoro è l'apprendimento automatico quantistico (QML) che si addestra su set di dati, puoi accelerare ulteriormente il carico di lavoro utilizzando il parallelismo dei dati. In QML, il modello contiene uno o più circuiti quantistici. Il modello può contenere o meno anche reti neurali classiche. Quando si addestra il modello con il set di dati, i parametri del modello vengono aggiornati per ridurre al minimo la funzione di perdita. Di solito viene definita una funzione di perdita per un singolo punto dati e la perdita totale per la perdita media sull'intero set di dati. In QML, le perdite vengono generalmente calcolate in serie prima di calcolare la media della perdita totale per i calcoli a gradiente. Questa procedura richiede molto tempo, soprattutto quando ci sono centinaia di punti dati.

Poiché la perdita da un punto dati non dipende da altri punti dati, le perdite possono essere valutate in parallelo! Le perdite e i gradienti associati a diversi punti dati possono essere valutati contemporaneamente. Questo è noto come parallelismo dei dati. Con SageMaker la sua libreria parallela di dati distribuiti, Amazon Braket Hybrid Jobs ti consente di sfruttare più facilmente il parallelismo dei dati per accelerare la formazione.

Considera il seguente carico di lavoro QML per il parallelismo dei dati, che utilizza il set di dati Sonar del noto repository UCI come esempio di classificazione binaria. Il set di dati Sonar ha 208 punti dati ciascuno con 60 caratteristiche raccolte dai segnali sonar che rimbalzano sui materiali. Ogni punto dati è etichettato come «M» per le miniere o «R» per le rocce. Il nostro modello QML è costituito da un livello di input, un circuito quantistico come livello nascosto e un livello di output. I livelli di input e output sono reti neurali classiche implementate in. PyTorch Il circuito quantistico è integrato con le reti PyTorch neurali utilizzando il modulo qml.qnn. PennyLane Consulta i nostri taccuini di esempio per maggiori dettagli sul carico di lavoro. Come nell'esempio QAOA riportato sopra, puoi sfruttare la potenza della GPU utilizzando simulatori integrati basati su GPU come quelli per migliorare le prestazioni rispetto ai simulatori integrati basati su CPU. PennyLane lightning.gpu

Per creare un lavoro ibrido, puoi chiamare AwsQuantumJob.create e specificare lo script dell'algoritmo, il dispositivo e altre configurazioni tramite gli argomenti delle parole chiave.

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

Per utilizzare il parallelismo dei dati, è necessario modificare alcune righe di codice nello script dell'algoritmo per la libreria SageMaker distribuita per parallelizzare correttamente l'addestramento. Innanzitutto, importate il smdistributed pacchetto che svolge la maggior parte del lavoro necessario per distribuire i carichi di lavoro su più GPU e più istanze. Questo pacchetto è preconfigurato nel Braket e nei contenitori. PyTorch TensorFlow Il dist modulo indica al nostro script di algoritmo il numero totale di GPU per il training (world_size) rank e la quantità di core local_rank della GPU. rankè l'indice assoluto di una GPU in tutte le istanze, mentre local_rank è l'indice di una GPU all'interno di un'istanza. Ad esempio, se ci sono quattro istanze con ciascuna otto GPU allocate per l'addestramento, i rank valori vanno da 0 a 31 e vanno da 0 a 7. local_rank

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)

Successivamente, si definisce un DistributedSampler in base a world_size rank e quindi lo si passa nel caricatore di dati. Questo campionatore evita che le GPU accedano alla stessa porzione di un set di dati.

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

Successivamente, si utilizza la classe per abilitare il parallelismo dei dati. DistributedDataParallel

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

Quanto sopra sono le modifiche necessarie per utilizzare il parallelismo dei dati. In QML, spesso si desidera salvare i risultati e stampare i progressi della formazione. Se ogni GPU esegue il comando di salvataggio e stampa, il registro verrà invaso dalle informazioni ripetute e i risultati si sovrascriveranno a vicenda. Per evitare ciò, puoi salvare e stampare solo dalla GPU con 0. 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 supporta i tipi di ml.p3.16xlarge istanza per la libreria parallela di SageMaker dati distribuiti. Puoi configurare il tipo di istanza tramite l'InstanceConfigargomento in Hybrid Jobs. Affinché la libreria parallela di dati SageMaker distribuiti sappia che il parallelismo dei dati è abilitato, devi aggiungere due iperparametri aggiuntivi, "sagemaker_distributed_dataparallel_enabled" impostandoli "true" e "sagemaker_instance_type" impostandoli sul tipo di istanza che stai utilizzando. Questi due iperparametri vengono utilizzati per pacchetto. smdistributed Lo script dell'algoritmo non deve utilizzarli in modo esplicito. In Amazon Braket SDK, fornisce un comodo argomento per le parole chiave. distribution Per quanto distribution="data_parallel" riguarda la creazione di posti di lavoro ibridi, l'SDK Amazon Braket inserisce automaticamente i due iperparametri per te. Se utilizzi l'API Amazon Braket, devi includere questi due iperparametri.

Con il parallelismo di istanze e dati configurato, ora puoi inviare il tuo lavoro ibrido. Ci sono 8 GPU in un'istanza. ml.p3.16xlarge Quando si impostainstanceCount=1, il carico di lavoro viene distribuito tra le 8 GPU dell'istanza. Se ne imposti instanceCount più di una, il carico di lavoro viene distribuito tra le GPU disponibili in tutte le istanze. Quando si utilizzano più istanze, ogni istanza comporta un addebito in base al tempo di utilizzo. Ad esempio, quando utilizzi quattro istanze, il tempo fatturabile è quattro volte il tempo di esecuzione per istanza perché ci sono quattro istanze che eseguono i tuoi carichi di lavoro contemporaneamente.

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", ... )
Nota

Nella creazione di posti di lavoro ibridi di cui sopra, train_dp.py si tratta dello script algoritmico modificato per l'utilizzo del parallelismo dei dati. Tieni presente che il parallelismo dei dati funziona correttamente solo quando modifichi lo script dell'algoritmo in base alla sezione precedente. Se l'opzione di parallelismo dei dati è abilitata senza uno script di algoritmo modificato correttamente, il processo ibrido può generare errori o ogni GPU può elaborare ripetutamente la stessa porzione di dati, il che è inefficiente.

Confrontiamo il tempo di esecuzione e il costo in un esempio in cui si addestra un modello con un circuito quantistico a 26 qubit per il problema di classificazione binaria sopra menzionato. L'ml.p3.16xlargeistanza utilizzata in questo esempio costa 0,4692 USD al minuto. Senza il parallelismo dei dati, il simulatore impiega circa 45 minuti per addestrare il modello per un'epoca (ovvero oltre 208 punti dati) e costa circa 20 dollari. Con il parallelismo dei dati su 1 e 4 istanze, bastano rispettivamente solo 6 minuti e 1,5 minuti, il che si traduce in circa 2,8 dollari per entrambe. Utilizzando il parallelismo dei dati su 4 istanze, non solo migliorerai il tempo di esecuzione di 30 volte, ma riduci anche i costi di un ordine di grandezza!