PennyLane 임베디드 시뮬레이터를 사용하여 하이브리드 워크로드 실행 - Amazon Braket

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

PennyLane 임베디드 시뮬레이터를 사용하여 하이브리드 워크로드 실행

Amazon Braket Hybrid Jobs의 PennyLane에서 임베디드 시뮬레이터를 사용하여 하이브리드 워크로드를 실행하는 방법을 살펴보겠습니다. Pennylane의 GPU 기반 임베디드 시뮬레이터인는 Nvidia cuQuantum 라이브러리lightning.gpu사용하여 회로 시뮬레이션을 가속화합니다. 임베디드 GPU 시뮬레이터는 사용자가 즉시 사용할 수 있는 모든 Braket 작업 컨테이너에 미리 구성되어 있습니다. 이 페이지에서는를 사용하여 하이브리드 워크로드 lightning.gpu 속도를 높이는 방법을 보여줍니다.

QAOA 워크로드lightning.gpu에 사용

노트북의 Quantum Approximate Optimization Algorithm(QAOA) 예제를 고려해 보세요. 임베디드 시뮬레이터를 선택하려면 양식의 문자열로 device 인수를 지정합니다"local:<provider>/<simulator_name>". 예를 들어에 대해 "local:pennylane/lightning.gpu"를 설정합니다lightning.gpu. 시작 시 하이브리드 작업에 부여하는 디바이스 문자열은 환경 변수 로 작업에 전달됩니다"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)

이 페이지에서는 두 개의 임베디드 PennyLane 상태 벡터 시뮬레이터lightning.qubit(CPU 기반)와 lightning.gpu (GPU 기반)를 비교해 보겠습니다. 다양한 그라데이션을 계산하려면 시뮬레이터에 일부 사용자 지정 게이트 분해를 제공해야 합니다.

이제 하이브리드 작업 시작 스크립트를 준비할 준비가 되었습니다. m5.2xlarge 및 두 가지 인스턴스 유형을 사용하여 QAOA 알고리즘을 실행합니다p3.2xlarge. m5.2xlarge 인스턴스 유형은 표준 개발자 노트북과 비슷합니다. p3.2xlarge는 메모리가 16GB인 단일 NVIDIA Volta GPU가 있는 가속 컴퓨팅 인스턴스입니다.

모든 하이브리드 작업hyperparameters의는 동일합니다. 서로 다른 인스턴스와 시뮬레이터를 시도하기 위해 다음과 같이 두 줄을 변경하기만 하면 됩니다.

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

또는:

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

를 GPU 기반 인스턴스를 사용하는 instance_config 것으로 지정하지만 임베디드 CPU 기반 시뮬레이터(lightning.qubit)device로를 선택하면 GPU가 사용되지 않습니다. GPU를 대상으로 지정하려면 임베디드 GPU 기반 시뮬레이터를 사용해야 합니다.

먼저 두 개의 하이브리드 작업을 생성하고 18개의 버텍스가 있는 그래프에서 QAOA로 Max-Cut을 해결할 수 있습니다. 이는 비교적 작고 노트북 또는 m5.2xlarge 인스턴스에서 빠르게 실행할 수 있는 18비트 회로로 변환됩니다.

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

m5.2xlarge 인스턴스의 평균 반복 시간은 약 25초이고 p3.2xlarge 인스턴스의 경우 약 12초입니다. 이 18비트 워크플로의 경우 GPU 인스턴스는 2배의 속도를 제공합니다. Amazon Braket Hybrid Jobs 요금 페이지를 보면 m5.2xlarge 인스턴스의 분당 비용이 0.00768 USD인 반면 p3.2xlarge 인스턴스의 경우 0.06375 USD임을 알 수 있습니다. 여기서와 같이 총 5회 반복을 실행하려면 CPU 인스턴스를 사용하면 0.016 USD, GPU 인스턴스를 사용하면 0.06375 USD의 비용이 들며 둘 다 상당히 저렴합니다.

이제 문제를 더 어렵게 만들고 24-버텍스 그래프에서 Max-Cut 문제를 해결해 보겠습니다.이 그래프는 24쿼트로 변환됩니다. 동일한 두 인스턴스에서 하이브리드 작업을 다시 실행하고 비용을 비교합니다.

참고

CPU 인스턴스에서이 하이브리드 작업을 실행하는 데 약 5시간이 걸릴 수 있습니다.

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

m5.2xlarge 인스턴스의 평균 반복 시간은 약 1시간이지만 p3.2xlarge 인스턴스의 경우 약 2분입니다. 이 큰 문제의 경우 GPU 인스턴스가 훨씬 빠릅니다. 이 속도 향상의 이점을 활용하기 위해 해야 할 일은 인스턴스 유형과 사용된 로컬 시뮬레이터를 교체하여 두 줄의 코드를 변경하는 것이었습니다. 여기서 설명한 것처럼 총 5회 반복으로를 실행하려면 CPU 인스턴스를 사용하는 경우 약 2.27072 USD, GPU 인스턴스를 사용하는 경우 약 0.775625 USD의 비용이 발생합니다. CPU 사용량은 더 비싸고 실행하는 데 더 많은 시간이 걸립니다. NVIDIA CuQuantum에서 지원하는 PennyLane의 임베디드 시뮬레이터를 AWS사용하여에서 사용할 수 있는 GPU 인스턴스로이 워크플로를 가속화하면 중간 쿼비트 수(20~30)로 워크플로를 실행하여 총 비용을 절감하고 시간을 단축할 수 있습니다. 즉, 노트북이나 비슷한 크기의 인스턴스에서 빠르게 실행하기에는 너무 큰 문제라도 양자 컴퓨팅을 실험할 수 있습니다.

양자 기계 학습 및 데이터 병렬 처리

워크로드 유형이 데이터 세트를 훈련하는 양자 기계 학습(QML)인 경우 데이터 병렬 처리를 사용하여 워크로드를 더욱 가속화할 수 있습니다. QML에서 모델은 하나 이상의 양자 회로를 포함합니다. 모델에는 클래식 신경망이 포함될 수도 있고 포함되지 않을 수도 있습니다. 데이터 세트로 모델을 훈련할 때 모델의 파라미터가 업데이트되어 손실 함수를 최소화합니다. 손실 함수는 일반적으로 단일 데이터 포인트에 대해 정의되며 전체 데이터 세트에 대한 평균 손실의 총 손실입니다. QML에서 손실은 일반적으로 그라데이션 계산을 위한 총 손실로 평균화하기 전에 직렬로 계산됩니다. 이 절차는 특히 수백 개의 데이터 포인트가 있는 경우 시간이 많이 걸립니다.

한 데이터 포인트의 손실은 다른 데이터 포인트에 의존하지 않으므로 손실을 병렬로 평가할 수 있습니다. 서로 다른 데이터 포인트와 관련된 손실 및 그라데이션을 동시에 평가할 수 있습니다. 이를 데이터 병렬 처리라고 합니다. SageMaker의 분산 데이터 병렬 라이브러리를 사용하면 Amazon Braket Hybrid Jobs를 사용하면 데이터 병렬 처리를 활용하여 훈련을 더 쉽게 가속화할 수 있습니다.

잘 알려진 UCI 리포지토리의 Sonar 데이터 세트 데이터 세트를 바이너리 분류의 예로 사용하는 데이터 병렬화에 대해 다음 QML 워크로드를 고려하세요. Sonar 데이터 세트에는 각각 60개의 기능이 있는 208개의 데이터 포인트가 있으며, 이는 재료를 바운스하는 소나 신호에서 수집됩니다. 각 데이터 포인트에는 광산의 경우 "M" 또는 바위의 경우 "R" 레이블이 지정됩니다. QML 모델은 입력 계층, 숨겨진 계층으로서 양자 회로 및 출력 계층으로 구성됩니다. 입력 및 출력 계층은 PyTorch에 구현된 클래식 신경망입니다. 양자 회로는 PennyLane의 qml.qnn 모듈을 사용하여 PyTorch 신경망과 통합됩니다. 워크로드에 대한 자세한 내용은 예제 노트북을 참조하세요. 위의 QAOA 예제와 마찬가지로 PennyLane의와 같은 임베디드 GPU 기반 시뮬레이터lightning.gpu를 사용하여 임베디드 CPU 기반 시뮬레이터보다 성능을 개선하여 GPU의 성능을 활용할 수 있습니다.

하이브리드 작업을 생성하려면를 호출AwsQuantumJob.create하고 키워드 인수를 통해 알고리즘 스크립트, 디바이스 및 기타 구성을 지정할 수 있습니다.

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

데이터 병렬 처리를 사용하려면 훈련을 올바르게 병렬화하기 위해 SageMaker 분산 라이브러리의 알고리즘 스크립트에서 몇 줄의 코드를 수정해야 합니다. 먼저 워크로드를 여러 GPUs와 여러 인스턴스에 분산하기 위해 대부분의 작업을 수행하는 smdistributed 패키지를 가져옵니다. 이 패키지는 Braket PyTorch 및 TensorFlow 컨테이너에 미리 구성되어 있습니다. dist 모듈은 훈련을 위한 총 GPUs 수(world_size)와 GPU 코어local_rankrank 및를 알고리즘 스크립트에 알려줍니다. rank는 모든 인스턴스에서 GPU의 절대 인덱스이고 local_rank는 인스턴스 내 GPU의 인덱스입니다. 예를 들어 훈련에 할당된 GPUs가 각각 8개인 인스턴스가 4개인 경우 범위는 rank 0~31이고 local_rank 범위는 0~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)

그런 다음 world_size 및에 DistributedSampler 따라를 정의한 다음 데이터 rank 로더에 전달합니다. 이 샘플러는 GPUs 데이터 세트의 동일한 조각에 액세스하지 못하도록 합니다.

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

다음으로 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"])

위의 내용은 데이터 병렬 처리를 사용하는 데 필요한 변경 사항입니다. QML에서는 결과를 저장하고 훈련 진행 상황을 인쇄하는 경우가 많습니다. 각 GPU가 저장 및 인쇄 명령을 실행하면 로그에 반복되는 정보가 가득 차고 결과가 서로 덮어씁니다. 이를 방지하려면 rank 0이 있는 GPU에서만 저장하고 인쇄할 수 있습니다.

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는 SageMaker 분산 데이터 병렬 라이브러리의 ml.p3.16xlarge 인스턴스 유형을 지원합니다. 하이브리드 작업의 InstanceConfig 인수를 통해 인스턴스 유형을 구성합니다. SageMaker 분산 데이터 병렬 라이브러리에서 데이터 병렬 처리가 활성화되어 있음을 알 수 있으려면를 "true""sagemaker_distributed_dataparallel_enabled" 설정하고를 사용 중인 인스턴스 유형으로 "sagemaker_instance_type" 설정하는 두 개의 하이퍼파라미터를 추가해야 합니다. 이 두 하이퍼파라미터는 smdistributed 패키지에서 사용됩니다. 알고리즘 스크립트는 명시적으로 사용할 필요가 없습니다. Amazon Braket SDK에서는 편리한 키워드 인수를 제공합니다distribution. 하이브리드 작업 생성distribution="data_parallel"에서를 사용하면 Amazon Braket SDK가 자동으로 두 개의 하이퍼파라미터를 삽입합니다. Amazon Braket API를 사용하는 경우이 두 하이퍼파라미터를 포함해야 합니다.

인스턴스와 데이터 병렬 처리를 구성한 상태에서 이제 하이브리드 작업을 제출할 수 있습니다. ml.p3.16xlarge 인스턴스에는 8개의 GPUs. instanceCount=1를 설정하면 워크로드가 인스턴스의 8GPUs에 분산됩니다. 를 1보다 instanceCount 크게 설정하면 워크로드가 모든 인스턴스에서 사용 가능한 GPUs에 분산됩니다. 여러 인스턴스를 사용하는 경우 각 인스턴스에는 사용 시간에 따라 요금이 부과됩니다. 예를 들어 인스턴스 4개를 사용하는 경우 워크로드를 동시에 실행하는 인스턴스가 4개 있으므로 청구 가능 시간은 인스턴스당 실행 시간의 4배입니다.

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

위의 하이브리드 작업 생성에서 train_dp.py는 데이터 병렬 처리를 사용하기 위한 수정된 알고리즘 스크립트입니다. 데이터 병렬 처리는 위 섹션에 따라 알고리즘 스크립트를 수정할 때만 올바르게 작동합니다. 올바르게 수정된 알고리즘 스크립트 없이 데이터 병렬 처리 옵션이 활성화된 경우 하이브리드 작업에서 오류가 발생하거나 각 GPU가 동일한 데이터 조각을 반복적으로 처리할 수 있으며, 이는 비효율적입니다.

위에서 언급한 바이너리 분류 문제에 대해 26비트 양자 회로로 모델을 훈련하는 예제의 실행 시간과 비용을 비교해 보겠습니다. 이 예제에서 사용되는 ml.p3.16xlarge 인스턴스의 비용은 분당 0.4692 USD입니다. 데이터 병렬 처리가 없으면 시뮬레이터가 1에포크(즉, 208개 이상의 데이터 포인트)에 대해 모델을 훈련하는 데 약 45분이 걸리고 비용은 약 20 USD입니다. 1개의 인스턴스와 4개의 인스턴스에 대한 데이터 병렬 처리를 사용하면 각각 6분과 1.5분만 소요되며, 이는 둘 다 약 2.8 USD로 해석됩니다. 4개의 인스턴스에서 데이터 병렬 처리를 사용하면 실행 시간을 30배 개선할 뿐만 아니라 비용을 크게 줄일 수 있습니다.