Execute seu código local como um trabalho híbrido - Amazon Braket

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Execute seu código local como um trabalho híbrido

O Amazon Braket Hybrid Jobs fornece uma orquestração totalmente gerenciada de algoritmos clássicos quânticos híbridos, combinando recursos computacionais do Amazon EC2 com o acesso à Amazon Braket Quantum Processing Unit (QPU). As tarefas quânticas criadas em um trabalho híbrido têm prioridade na fila em relação às tarefas quânticas individuais, para que seus algoritmos não sejam interrompidos por flutuações na fila de tarefas quânticas. Cada QPU mantém uma fila de trabalhos híbridos separada, garantindo que somente um trabalho híbrido possa ser executado a qualquer momento.

Crie um trabalho híbrido a partir do código Python local

Você pode executar seu código Python local como um Amazon Braket Hybrid Job. Você pode fazer isso anotando seu código com um @hybrid_job decorador, conforme mostrado no exemplo de código a seguir. Para ambientes personalizados, você pode optar por usar um contêiner personalizado do Amazon Elastic Container Registry (ECR).

nota

Somente o Python 3.10 é compatível por padrão.

Você pode usar o @hybrid_job decorador para anotar uma função. O Braket transforma o código dentro do decorador em um script de algoritmo de trabalho híbrido do Braket. O trabalho híbrido então invoca a função dentro do decorador em uma instância do Amazon EC2. Você pode monitorar o progresso do trabalho com job.state() ou com o console Braket. O exemplo de código a seguir mostra como executar uma sequência de cinco estados noState Vector Simulator (SV1) device.

from braket.aws import AwsDevice from braket.circuits import Circuit, FreeParameter, Observable from braket.devices import Devices from braket.jobs.hybrid_job import hybrid_job from braket.jobs.metrics import log_metric device_arn = Devices.Amazon.SV1 @hybrid_job(device=device_arn) # choose priority device def run_hybrid_job(num_tasks=1): device = AwsDevice(device_arn) # declare AwsDevice within the hybrid job # create a parametric circuit circ = Circuit() circ.rx(0, FreeParameter("theta")) circ.cnot(0, 1) circ.expectation(observable=Observable.X(), target=0) theta = 0.0 # initial parameter for i in range(num_tasks): task = device.run(circ, shots=100, inputs={"theta": theta}) # input parameters exp_val = task.result().values[0] theta += exp_val # modify the parameter (possibly gradient descent) log_metric(metric_name="exp_val", value=exp_val, iteration_number=i) return {"final_theta": theta, "final_exp_val": exp_val}

Você cria o trabalho híbrido invocando a função como faria com as funções normais do Python. No entanto, a função decoradora retorna o identificador de trabalho híbrido em vez do resultado da função. Para recuperar os resultados após a conclusão, usejob.result().

job = run_hybrid_job(num_tasks=1) result = job.result()

O argumento do dispositivo no @hybrid_job decorador especifica o dispositivo ao qual a tarefa híbrida tem acesso prioritário - nesse caso, o SV1 simulador. Para obter prioridade de QPU, você deve garantir que o ARN do dispositivo usado na função corresponda ao especificado no decorador. Por conveniência, você pode usar a função auxiliar get_job_device_arn() para capturar o ARN do dispositivo declarado em. @hybrid_job

nota

Cada trabalho híbrido tem um tempo de inicialização de pelo menos um minuto, pois cria um ambiente em contêineres no Amazon EC2. Portanto, para cargas de trabalho muito curtas, como um único circuito ou um lote de circuitos, pode ser suficiente usar tarefas quânticas.

Hiperparâmetros

A run_hybrid_job() função usa o argumento num_tasks para controlar o número de tarefas quânticas criadas. A tarefa híbrida captura isso automaticamente como um hiperparâmetro.

nota

Os hiperparâmetros são exibidos no console do Braket como sequências de caracteres, limitadas a 2500 caracteres.

Métricas e registro

Dentro da run_hybrid_job() função, métricas de algoritmos iterativos são registradas comlog_metrics. As métricas são plotadas automaticamente na página do console do Braket, na guia de tarefas híbridas. Você pode usar métricas para rastrear os custos quânticos da tarefa quase em tempo real durante a execução do trabalho híbrido com o rastreador de custos Braket. O exemplo acima usa o nome da métrica “probabilidade” que registra a primeira probabilidade do tipo de resultado.

Recuperando resultados

Depois que a tarefa híbrida for concluída, você usará job.result() para recuperar os resultados da tarefa híbrida. Todos os objetos na declaração de retorno são automaticamente capturados pelo Braket. Observe que os objetos retornados pela função devem ser uma tupla com cada elemento sendo serializável. Por exemplo, o código a seguir mostra um exemplo de funcionamento e um de falha.

@hybrid_job(device=Devices.Amazon.SV1) def passing(): np_array = np.random.rand(5) return np_array # serializable @hybrid_job(device=Devices.Amazon.SV1) def failing(): return MyObject() # not serializable

Nome do trabalho

Por padrão, o nome desse trabalho híbrido é inferido do nome da função. Você também pode especificar um nome personalizado com até 50 caracteres. Por exemplo, no código a seguir, o nome do trabalho é "my-job-name”.

@hybrid_job(device=Devices.Amazon.SV1, job_name="my-job-name") def function(): pass

Modo local

Os trabalhos locais são criados adicionando o argumento local=True ao decorador. Isso executa a tarefa híbrida em um ambiente conteinerizado em seu ambiente de computação local, como seu laptop. Os trabalhos locais não têm fila prioritária para tarefas quânticas. Para casos avançados, como vários nós ou MPI, as tarefas locais podem ter acesso às variáveis de ambiente Braket necessárias. O código a seguir cria uma tarefa híbrida local com o dispositivo como simulador SV1.

@hybrid_job(device=Devices.Amazon.SV1, local=True) def run_hybrid_job(num_tasks = 1): return ...

Todas as outras opções de trabalho híbridas são suportadas. Para obter uma lista de opções, consulte o módulo braket.jobs.quantum_job_creation.

Instale pacotes e código-fonte adicionais do Python

Você pode personalizar seu ambiente de execução para usar seus pacotes Python preferidos. Você pode usar um requirements.txt arquivo, uma lista de nomes de pacotes ou trazer seu próprio contêiner (BYOC). Para personalizar um ambiente de tempo de execução usando um requirements.txt arquivo, consulte o exemplo de código a seguir.

@hybrid_job(device=Devices.Amazon.SV1, dependencies="requirements.txt") def run_hybrid_job(num_tasks = 1): return ...

Por exemplo, o requirements.txt arquivo pode incluir outros pacotes para instalação.

qiskit pennylane >= 0.31 mitiq == 0.29

Como alternativa, você pode fornecer os nomes dos pacotes como uma lista do Python da seguinte maneira.

@hybrid_job(device=Devices.Amazon.SV1, dependencies=["qiskit", "pennylane>=0.31", "mitiq==0.29"]) def run_hybrid_job(num_tasks = 1): return ...

O código-fonte adicional pode ser especificado como uma lista de módulos ou como um único módulo, como no exemplo de código a seguir.

@hybrid_job(device=Devices.Amazon.SV1, include_modules=["my_module1", "my_module2"]) def run_hybrid_job(num_tasks = 1): return ...

Salve e carregue dados em uma instância de trabalho híbrida

Especificando dados de treinamento de entrada

Ao criar um trabalho híbrido, você pode fornecer um conjunto de dados de treinamento de entrada especificando um bucket do Amazon Simple Storage Service (Amazon S3). Você também pode especificar um caminho local e, em seguida, o Braket carrega automaticamente os dados para o Amazon S3 em. s3://<default_bucket_name>/jobs/<job_name>/<timestamp>/data/<channel_name> Se você especificar um caminho local, o nome do canal será padronizado como “entrada”. O código a seguir mostra um arquivo numpy do caminho data/file.npy local.

@hybrid_job(device=Devices.Amazon.SV1, input_data="data/file.npy") def run_hybrid_job(num_tasks = 1): data = np.load("data/file.npy") return ...

Para o S3, você deve usar a função get_input_data_dir() auxiliar.

s3_path = "s3://amazon-braket-us-west-1-961591465522/job-data/file.npy" @hybrid_job(device=None, input_data=s3_path) def job_s3_input(): np.load(get_input_data_dir() + "/file.npy") @hybrid_job(device=None, input_data={"channel": s3_path}) def job_s3_input_channel(): np.load(get_input_data_dir("channel") + "/file.npy")

Você pode especificar várias fontes de dados de entrada fornecendo um dicionário de valores de canais e URIs do S3 ou caminhos locais.

input_data = { "input": "data/file.npy", "input_2": "s3://my-bucket/data.json" } @hybrid_job(device=None, input_data=input_data) def multiple_input_job(): np.load(get_input_data_dir("input") + "/file.npy") np.load(get_input_data_dir("input_2") + "/data.json")
nota

Quando os dados de entrada são grandes (>1 GB), há um longo tempo de espera até que a tarefa seja criada. Isso se deve aos dados de entrada locais quando eles são carregados pela primeira vez em um bucket do S3 e, em seguida, o caminho do S3 é adicionado à solicitação de trabalho. Finalmente, a solicitação de trabalho é enviada ao serviço Braket.

Salvando resultados no S3

Para salvar resultados não incluídos na instrução de retorno da função decorada, você deve acrescentar o diretório correto a todas as operações de gravação de arquivos. O exemplo a seguir mostra como salvar uma matriz numérica e uma figura matplotlib.

@hybrid_job(device=Devices.Amazon.SV1) def run_hybrid_job(num_tasks = 1): result = np.random.rand(5) # save a numpy array np.save("result.npy", result) # save a matplotlib figure plt.plot(result) plt.savefig("fig.png") return ...

Todos os resultados são compactados em um arquivo chamadomodel.tar.gz. Você pode baixar os resultados com a função job.result() Python ou navegando até a pasta de resultados na página de trabalhos híbridos no console de gerenciamento do Braket.

Salvando e retomando a partir dos pontos de verificação

Para trabalhos híbridos de longa duração, é recomendável salvar periodicamente o estado intermediário do algoritmo. Você pode usar a função save_job_checkpoint() auxiliar integrada ou salvar arquivos no AMZN_BRAKET_JOB_RESULTS_DIR caminho. O último está disponível com a função get_job_results_dir() auxiliar.

Veja a seguir um exemplo prático mínimo para salvar e carregar pontos de verificação com um decorador de tarefas híbrido:

from braket.jobs import save_job_checkpoint, load_job_checkpoint, hybrid_job @hybrid_job(device=None, wait_until_complete=True) def function(): save_job_checkpoint({"a": 1}) job = function() job_name = job.name job_arn = job.arn @hybrid_job(device=None, wait_until_complete=True, copy_checkpoints_from_job=job_arn) def continued_function(): load_job_checkpoint(job_name) continued_job = continued_function()

No primeiro trabalho híbrido, save_job_checkpoint() é chamado com um dicionário contendo os dados que queremos salvar. Por padrão, cada valor deve ser serializável como texto. Para verificar objetos Python mais complexos, como matrizes numpy, você pode definir. data_format = PersistedJobDataFormat.PICKLED_V4 Esse código cria e substitui um arquivo de ponto de verificação com nome padrão <jobname>.json em seus artefatos de trabalho híbridos em uma subpasta chamada “pontos de verificação”.

Para criar um novo trabalho híbrido para continuar a partir do posto de controle, precisamos informar copy_checkpoints_from_job=job_arn onde job_arn está o ARN do trabalho híbrido do trabalho anterior. Em seguida, usamos load_job_checkpoint(job_name) para carregar a partir do ponto de verificação.

Melhores práticas para decoradores de trabalho híbridos

Adote a assincronicidade

As tarefas híbridas criadas com a anotação do decorador são assíncronas — elas são executadas quando os recursos clássicos e quânticos estão disponíveis. Você monitora o progresso do algoritmo usando o Braket Management Console ou Amazon CloudWatch. Quando você envia seu algoritmo para execução, o Braket executa seu algoritmo em um ambiente escalável em contêineres e os resultados são recuperados quando o algoritmo é concluído.

Execute algoritmos variacionais iterativos

Os trabalhos híbridos oferecem as ferramentas para executar algoritmos clássicos quânticos iterativos. Para problemas puramente quânticos, use tarefas quânticas ou um lote de tarefas quânticas. O acesso prioritário a determinadas QPUs é mais benéfico para algoritmos variacionais de longa execução que exigem várias chamadas iterativas para as QPUs com processamento clássico intermediário.

Depurar usando o modo local

Antes de executar uma tarefa híbrida em uma QPU, é recomendável executá-la primeiro no simulador SV1 para confirmar se ela é executada conforme o esperado. Para testes de pequena escala, você pode executar com o modo local para iteração e depuração rápidas.

Melhore a reprodutibilidade com Bring your own container (BYOC)

Crie um experimento reproduzível encapsulando seu software e suas dependências em um ambiente em contêineres. Ao empacotar todo o seu código, dependências e configurações em um contêiner, você evita possíveis conflitos e problemas de versão.

Simuladores distribuídos de várias instâncias

Para executar um grande número de circuitos, considere usar o suporte MPI integrado para executar simuladores locais em várias instâncias em uma única tarefa híbrida. Para obter mais informações, consulte simuladores incorporados.

Use circuitos paramétricos

Os circuitos paramétricos que você envia de um trabalho híbrido são compilados automaticamente em determinadas QPUs usando compilação paramétrica para melhorar os tempos de execução de seus algoritmos.

Ponto de verificação periódico

Para trabalhos híbridos de longa duração, é recomendável salvar periodicamente o estado intermediário do algoritmo.

Para obter mais exemplos, casos de uso e melhores práticas, consulte exemplos do Amazon Braket. GitHub