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à.
Esegui carichi di lavoro ibridi con simulatori PennyLane integrati
Vediamo come utilizzare i simulatori integrati di Amazon Braket Hybrid Jobs per eseguire carichi di lavoro ibridi. PennyLane Il simulatore integrato GPU basato su Pennylane utilizza la libreria cuQuantum Nvidialightning.gpu
le simulazioni di circuiti. Il GPU simulatore integrato è preconfigurato in tutti i contenitori di lavorolightning.gpu
velocizzare i carichi di lavoro ibridi.
Utilizzo lightning.gpu
per carichi di lavoro QAOA
Considerate gli esempi di Quantum Approximate Optimization Algorithm (QAOA) tratti da questo taccuino.device
argomento 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
(CPUbasato) e lightning.gpu
(GPUbasato). 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. Eseguirete l'QAOAalgoritmo utilizzando due tipi di istanza: m5.2xlarge
ep3.2xlarge
. Il tipo di m5.2xlarge
istanza è paragonabile a un laptop per sviluppatori standard. p3.2xlarge
Si tratta di un'istanza di elaborazione accelerata che ha una singola NVIDIA Volta GPU con 16 GB di memoria.
hyperparameters
Per tutti i tuoi lavori ibridi sarà lo stesso. 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_config
as utilizzando un'istanza GPU basata, ma si sceglie come simulatore CPU basato su incorporato (lightning.qubit
), non GPU verrà utilizzato. device
Assicurati di utilizzare il simulatore GPU basato su embedded se desideri scegliere come target il! GPU
Innanzitutto, puoi creare due lavori ibridi e risolvere Max-Cut utilizzando un grafico con QAOA 18 vertici. Ciò si traduce in un circuito da 18 qubit, relativamente piccolo e facile 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.2xlarge
istanza è di circa 12 secondi. p3.2xlarge
Per questo flusso di lavoro da 18 qubit, l'GPUistanza ci offre una velocità di 2 volte superiore. Se guardi la pagina dei prezzim5.2xlarge
istanza è di 0,00768 USD, mentre per l'p3.2xlarge
istanza è di 0,06375 USD. L'esecuzione per 5 iterazioni totali, come hai fatto qui, costerebbe 0,016 USD utilizzando l'istanza o 0,06375 USD utilizzando l'CPUistanza, entrambe piuttosto economiche! GPU
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. 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'CPUistanza 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.2xlarge
istanza è di circa un'ora, mentre per l'p3.2xlarge
istanza è di circa due minuti. Per questo problema più ampio, l'GPUistanza è 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 o circa 0,775625 dollari utilizzando l'CPUistanza. GPU L'CPUutilizzo non è solo più costoso, ma richiede anche più tempo per l'esecuzione. L'accelerazione di questo flusso di lavoro con un'GPUistanza 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. NelQML, 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. NelQML, 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 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 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 QML carico di lavoro per il parallelismo dei dati, che utilizza il set di dati Sonarlightning.gpu
ai simulatori GPU basati su sistemi integrati. CPU
Per creare un processo ibrido, puoi chiamare AwsQuantumJob.create
e specificare lo script dell'algoritmo, il dispositivo e altre configurazioni tramite i relativi 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ù e più istanze. GPUs Questo pacchetto è preconfigurato nel Braket e nei contenitori. PyTorch TensorFlow Il dist
modulo indica al nostro script di algoritmo qual è il numero totale di elementi GPUs per il training (world_size
) rank
e la fine local_rank
di un GPU core. rank
è l'indice assoluto di a GPU in tutte le istanze, mentre local_rank
è l'indice di a GPU all'interno di un'istanza. Ad esempio, se ci sono quattro istanze, ognuna delle quali otto GPUs allocate per l'addestramento, i rank
valori vanno da 0 a 31 e gli local_rank
intervalli da 0 a 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 un DistributedSampler
in base a world_size
rank
e quindi lo si passa nel caricatore di dati. Questo campionatore evita di GPUs accedere 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 DistributedDataParallel
classe 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. InQML, spesso si desidera salvare i risultati e stampare i progressi della formazione. Se ciascuno GPU esegue il comando di salvataggio e stampa, il registro verrà riempito con le informazioni ripetute e i risultati si sovrascriveranno a vicenda. Per evitare ciò, è possibile salvare e stampare solo da file con 0GPU. 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'InstanceConfig
argomento 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 ha bisogno di utilizzarli in modo esplicito. In Amazon BraketSDK, fornisce un comodo argomento per le parole chiave. distribution
distribution="data_parallel"
Nella creazione di posti di lavoro ibridi, Amazon Braket inserisce SDK automaticamente i due iperparametri per te. Se utilizzi Amazon BraketAPI, devi includere questi due iperparametri.
Con il parallelismo di istanze e dati configurato, ora puoi inviare il tuo lavoro ibrido. Ce ne sono 8 GPUs in un'ml.p3.16xlarge
istanza. Quando si impostainstanceCount=1
, il carico di lavoro viene distribuito tra gli 8 componenti GPUs dell'istanza. Se ne imposti instanceCount
più di uno, il carico di lavoro viene distribuito tra quelli GPUs 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 ciascuno di essi 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.16xlarge
istanza 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 il costo è di 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!