View a markdown version of this page

Esegui PennyLane carichi di lavoro ibridi con simulatori integrati - 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à.

Esegui PennyLane carichi di lavoro ibridi con simulatori integrati

Vediamo come puoi utilizzare i simulatori integrati di Amazon Braket Hybrid Jobs per eseguire carichi di lavoro ibridi. PennyLane Il simulatore GPU-based integrato di Pennylane utilizza la libreria Nvidia lightning.gpu CuQuantum per accelerare le simulazioni dei circuiti. Il simulatore GPU integrato è preconfigurato in tutti i job container Braket che gli utenti possono utilizzare immediatamente. In questa pagina, ti mostriamo come utilizzarlo per velocizzare i tuoi carichi lightning.gpu di lavoro ibridi.

Utilizzo di lightning.gpu per i carichi di lavoro QAOA

Considerate gli esempi di Quantum Approximate Optimization Algorithm (QAOA) tratti da questo notebook. https://github.com/amazon-braket/amazon-braket-examples/tree/main/examples/hybrid_jobs/2_Using_PennyLane_with_Braket_Hybrid_Jobs Per selezionare un simulatore incorporato, si specifica che l'deviceargomento sia una stringa nel formato:. "local:<provider>/<simulator_name>" Ad esempio, dovresti impostare "local:pennylane/lightning.gpu" perlightning.gpu. La stringa di dispositivo che fornisci all'Hybrid Job all'avvio viene passata al job 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, confronta i due simulatori vettoriali di PennyLane stato incorporati lightning.qubit (che è CPU-based) e lightning.gpu (che è GPU-based). Fornisci ai simulatori decomposizioni di gate personalizzate per calcolare vari gradienti.

Ora sei pronto per preparare lo script ibrido di avvio del lavoro. Esegui l'algoritmo QAOA utilizzando due tipi di istanza: e. ml.m5.2xlarge ml.g4dn.xlarge Il tipo di ml.m5.2xlarge istanza è paragonabile a un laptop per sviluppatori standard. ml.g4dn.xlargeÈ un'istanza di elaborazione accelerata che ha una singola GPU NVIDIA T4 con 16 GB di memoria.

Per eseguire la GPU, dobbiamo prima specificare un'immagine compatibile e l'istanza corretta (che per impostazione predefinita è un'istanza). ml.m5.2xlarge

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

Dobbiamo quindi inserirli nell'hybrid job decorator, insieme ai parametri del dispositivo aggiornati sia negli argomenti di sistema che in quelli del job ibrido.

@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)) ...
Nota

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

Il tempo medio di iterazione per l'm5.2xlargeistanza è di circa 73 secondi, mentre per l'ml.g4dn.xlargeistanza è di circa 0,6 secondi. Per questo flusso di lavoro a 21 qubit, l'istanza GPU ci offre una velocità di 100 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'istanza è di 0,01227 USD. ml.g4dn.xlarge In questo caso è più veloce ed economico eseguire sull'istanza GPU.

Apprendimento automatico quantistico e parallelismo dei dati

Se il tuo tipo di carico di lavoro è l'apprendimento automatico quantistico (QML) che si allena 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 allena il modello con il set di dati, i parametri del modello vengono aggiornati per ridurre al minimo la funzione di perdita. In genere 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 essere calcolate in media rispetto alla perdita totale per i calcoli del 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. Grazie SageMaker alla libreria parallela di dati distribuiti, Amazon Braket Hybrid Jobs semplifica l'utilizzo del 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 per la classificazione binaria. Il set di dati Sonar contiene 208 punti dati ciascuno con 60 caratteristiche 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 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 Guarda i nostri quaderni di esempio per maggiori dettagli sul carico di lavoro. Come nell'esempio QAOA riportato sopra, puoi sfruttare la potenza della GPU utilizzando simulatori integrati come quelli PennyLane per migliorare le prestazioni rispetto GPU-based ai simulatori integrati. lightning.gpu CPU-based

Per creare un job 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.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, ... )

Per utilizzare il parallelismo dei dati, è necessario modificare alcune righe di codice nello script dell'algoritmo affinché la libreria SageMaker distribuita parallelizzi correttamente l'addestramento. Innanzitutto, si importa il smdistributed pacchetto che fa la maggior parte del lavoro pesante per la distribuzione dei 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 qual è il numero totale di GPU per il training (world_size) rank e la fine local_rank di un core 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 ciascuna con otto GPU allocate per l'addestramento, gli rank intervalli 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)

Quindi, si definisce un DistributedSampler in base alla world_size rank e quindi lo si passa al 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 dell'allenamento. 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ò, è possibile 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.g4dn.12xlarge istanza per la libreria parallela di dati SageMaker 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, è necessario aggiungere due iperparametri aggiuntivi, "sagemaker_distributed_dataparallel_enabled" impostando "true" e "sagemaker_instance_type" impostando il tipo di istanza che si sta utilizzando. Questi due iperparametri vengono utilizzati dal pacchetto. smdistributed Lo script dell'algoritmo non deve utilizzarli esplicitamente. In Amazon Braket SDK, fornisce un comodo argomento relativo alle parole chiave. distribution distribution="data_parallel"Nella creazione ibrida di job, l'SDK Amazon Braket inserisce automaticamente i due iperparametri al posto tuo. Se utilizzi l'API Amazon Braket, devi includere questi due iperparametri.

Una volta configurato il parallelismo tra istanze e dati, puoi ora inviare il tuo job ibrido. Ci sono 4 GPU in un'istanza. ml.g4dn.12xlarge Una volta impostatoinstanceCount=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, a ciascuna istanza viene addebitato un costo in base al tempo di utilizzo. Ad esempio, quando utilizzi quattro istanze, il tempo fatturabile è quattro volte il tempo di esecuzione per istanza perché sono quattro le istanze che eseguono i carichi di lavoro contemporaneamente.

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

Nella precedente creazione ibrida di job, si train_dp.py trova lo script dell'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 processo ibrido potrebbe generare errori oppure ogni GPU potrebbe elaborare ripetutamente la stessa porzione di dati, il che è inefficiente.

Se usato correttamente, l'utilizzo di più istanze può portare a una riduzione di ordini di grandezza in termini di tempi e costi. Per maggiori dettagli, consulta il taccuino di esempio.