Accelera i tuoi carichi di lavoro ibridi con simulatori integrati da 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 tuoi carichi di lavoro ibridi con simulatori integrati da PennyLane

Osserviamo come utilizzare i simulatori incorporati da PennyLane sulAmazon BraketProcessi ibridi per eseguire carichi di lavoro ibridi. Il simulatore basato su GPU di Pennylane,lightning.gpu, utilizza ilLibreria Nvidia CuQuantum cuper accelerare le simulazioni dei circuiti. Il simulatore GPU è preconfigurato in tutta Braketcontenitori di lavoroche gli utenti possono utilizzare come da impostazioni di fabbrica. In questa pagina viene illustrato come utilizzare.lightning.gpuper velocizzare i carichi di lavoro ibridi.

Utilizzo dilightning.gpuper i carichi di lavoro dell'algoritmo di ottimizzazione approssimativa

Si consideri gli esempi dell'algoritmo di ottimizzazione approssimativa quantistica (QAOA) da questoNotebook. Per selezionare un simulatore incorporato, è necessario specificare ildeviceargomento per essere una stringa della forma: "local:<provider>/<simulator_name>". Ad esempio, è necessario impostare"local:pennylane/lightning.gpu"perlightning.gpu. La stringa del dispositivo che assegni al Job Hybird al momento dell'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 PennyLane simulatori di vettore di statolightning.qubit(che è basato su CPU) elightning.gpu(che è basato su GPU). Dovrai fornire ai simulatori alcune scomposizioni di gate personalizzate per calcolare vari gradienti.

Ora è possibile preparare lo script di avvio del processo. Eseguirai l'algoritmo QAOA utilizzando due tipi di istanza:m5.2xlargeep3.2xlarge. Lam5.2xlargeil tipo di istanza è abbastanza paragonabile a un laptop per sviluppatori standard. Lap3.2xlargeè un'istanza di elaborazione accelerata con una singola GPU NVIDIA Volta con 16 GB di memoria.

Lahyperparametersper tutti i tuoi lavori sarà lo stesso. Tutto quello che devi fare per provare diverse istanze e simulatori è cambiare due righe:

# Specify device that the 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 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 ilinstance_configcome usare un'istanza basata su GPU, ma scegli ildeviceessere il simulatore basato sulla CPU (lightning.qubit), la GPUnon lo faròessere utilizzato. Assicurati di utilizzare il simulatore basato su GPU se desideri scegliere come target la GPU!

Innanzitutto, puoi creare due lavori 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 per funzionare rapidamente sul tuo laptop o sulm5.2xlargeistanza.

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 medio di iterazione per ilm5.2xlargel'istanza è di circa 25 secondi, mentre per ilp3.2xlargeistanza è di circa 12 secondi. Per questo flusso di lavoro a 18 qubit, l'istanza GPU ci offre una velocità 2x. Se si guarda alAmazon BraketIbridepagina dei prezzi, puoi vedere che il costo al minuto per unm5.2xlargeistanza è $0,00768, mentre per ilp3.2xlargeesempio è $0,06375. Eseguire per 5 iterazioni totali, come hai fatto qui, costerebbe $0,016 usando l'istanza CPU o $0,06375 usando l'istanza GPU - entrambi piuttosto economici!

Ora rendiamo il problema più difficile e proviamo a risolvere un problema Max-Cut su un grafico a 24 vertici, che si tradurrà in 24 qubit. Eseguire nuovamente i lavori sulle stesse due istanze e confrontare il costo.

Nota

Vedrai che il tempo necessario per eseguire questo job sull'istanza 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 ilm5.2xlargel'istanza è di circa un'ora, mentre per ilp3.2xlargeesempio sono circa due minuti. Per questo problema più grande, l'istanza GPU è di un ordine di grandezza più veloce! Tutto quello che dovevi fare per beneficiare di questa accelerazione era cambiare due righe di codice, sostituendo il tipo di istanza e il simulatore locale utilizzato. L'esecuzione per 5 iterazioni totali, come è stato fatto qui, costerebbe circa $2.27072 utilizzando l'istanza CPU o circa $0,775625 usando l'istanza GPU. L'utilizzo della CPU non è solo più costoso, ma richiede anche più tempo per l'esecuzione. Accelerare questo flusso di lavoro con un'istanza GPU disponibile suAWS, utilizzando PennyLanesimulatore 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, consentendo di sperimentare il calcolo quantistico anche per problemi troppo grandi per essere eseguiti rapidamente sul tuo laptop o su un'istanza di dimensioni simili.

Machine learning quantistico e parallelismo dei dati

Se il tipo di carico di lavoro è Quantum Machine Learning (QML) che si allena sui set di dati, è possibile 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. Durante l'addestramento del modello con il set di dati, i parametri nel modello vengono aggiornati per ridurre al minimo la funzione di perdita. Una funzione di perdita è solitamente definita per un singolo punto dati e la perdita totale per la perdita media sull'intero set di dati. In QML, le perdite sono generalmente calcolate in serie prima della media della perdita totale per i calcoli del gradiente. Questa procedura richiede molto tempo, soprattutto quando sono presenti centinaia di punti dati.

Poiché la perdita da un punto dati non dipende da altri punti dati, le perdite possono essere valutate in parallel! Le perdite e i gradienti associati a diversi punti dati possono essere valutati contemporaneamente. Questa funzione è nota come parallelismo dei dati. con SageMakerlibreria parallel di dati distribuiti,Amazon BraketI job ibridi ti consentono di sfruttare più facilmente il parallelismo dei dati per accelerare la tua formazione.

Si consideri il seguente carico di lavoro QML per il parallelismo dei dati che utilizza ilSet di dati del sonarset di dati dal noto repository UCI come esempio di classificazione binaria. Il set di dati Sonar ha 208 punti dati ciascuno con 60 caratteristiche che vengono raccolte dai segnali sonar che rimbalzano sui materiali. Ogni punto dati è etichettato come «M» per le mine o «R» per le rocce. Il nostro modello QML è costituito da un layer di input, un circuito quantistico come layer nascosto e un layer di output. I layer di input e output sono reti neurali classiche implementate in PyTorch. Il circuito quantistico è integrato con il PyTorch reti neurali usando PennyLanedel modulo qml.qnn. Guarda il nostroNotebook di esempioper maggiori dettagli sul carico di lavoro. Come nell'esempio QAOA sopra, puoi sfruttare la potenza della GPU utilizzando simulatori basati su GPU come PennyLane lightning.gpuper migliorare le prestazioni rispetto ai simulatori basati su CPU.

Per creare un lavoro, puoi chiamareAwsQuantumJob.createe 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 SageMaker libreria distribuita per parallelizzare correttamente la formazione. Per prima cosa, si importa ilsmdistributedpacchetto che fa la maggior parte del lavoro pesante per la distribuzione dei carichi di lavoro su più GPU e più istanze. Questo pacchetto è preconfigurato nella finestra di installazione diBraket PyTorch e TensorFlow container. Ladistmodule indica al nostro script algoritmo il numero totale di GPU per il training (world_size), e ilrankelocal_rankdi un core GPU.rankè l'indice assoluto di una GPU in tutte le istanze, mentrelocal_rankè l'indice di una GPU all'interno di un'istanza. Ad esempio, se vi sono quattro istanze con otto GPU assegnate per la formazione,rankcompreso tra 0 e 31 e illocal_rankvalore compreso tra 0 e 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)

Successivamente, si definisce unDistributedSamplersecondo ilworld_sizeeranke passarlo al caricatore dati. Questo campionatore evita che le GPU accedano alla stessa fetta 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 ilDistributedDataParallelclasse per abilitare il parallelismo dei dati.

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 verrebbe inondato di informazioni ripetute e i risultati si sovrascriverebbero a vicenda. Per evitare ciò, è possibile salvare e stampare solo dalla GPU che disponerank0.

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 BraketHybrid Jobsml.p3.16xlargetipi di istanza per la libreria SageMaker libreria parallel di dati distribuiti. È possibile configurare il tipo di istanza tramiteInstanceConfigargomento in Hybrid Jobs. Per il SageMaker libreria parallel di dati distribuiti per sapere che il parallelismo dei dati è abilitato, è necessario aggiungere due iperparametri aggiuntivi,"sagemaker_distributed_dataparallel_enabled"Impostazione di"true"e"sagemaker_instance_type"impostando il tipo di istanza che si sta utilizzando. Questi due iperparametri sono utilizzati dasmdistributedPacchetto. Il tuo script di algoritmo non ha bisogno di usarli in modo esplicito. Nello statoAmazon BraketSDK, fornisce un comodo argomento per le parole chiavedistribution. condistribution="data_parallel"nella creazione di posti di lavoroAmazon BraketSDK inserisce automaticamente i due iperparametri per te. PerAmazon Braket APIutenti, è necessario includere questi due iperparametri.

Con il parallelismo di istanze e dati configurato, ora puoi inviare il tuo lavoro. Ci sono 8 GPU in unml.p3.16xlargeistanza. Quando si impostainstanceCount=1, il carico di lavoro è distribuito tra le 8 GPU nell'istanza. Quando si impostainstanceCountmaggiore di uno, il carico di lavoro è 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 si utilizzano quattro istanze, il tempo fatturabile è quattro volte il tempo di esecuzione per istanza perché ci sono quattro istanze che eseguono i 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

Attenzione: Nella suddetta creazione di posti di lavoro,train_dp.pyè lo script algoritmo 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 lavoro potrebbe generare errori o ogni GPU potrebbe elaborare ripetutamente la stessa slice di dati, il che è inefficiente.

Confrontiamo il tempo di esecuzione e il costo in un esempio in cui quando si allena un modello con un circuito quantistico a 26 qubit per il problema di classificazione binaria sopra menzionato. Laml.p3.16xlargel'istanza utilizzata in questo esempio costa $0,4692 al minuto. Senza il parallelismo dei dati, il simulatore impiega circa 45 minuti per addestrare il modello per 1 epoca (cioè oltre 208 punti dati) e costa circa $20. Con il parallelismo dei dati su 1 istanza e 4 istanze, sono necessari rispettivamente solo 6 minuti e 1,5 minuti, il che si traduce in circa $2,8 per entrambe. Utilizzando il parallelismo dei dati su 4 istanze, non solo si migliora il tempo di esecuzione di 30 volte, ma si riducono anche i costi di un ordine di grandezza!