의 임베디드 시뮬레이터로 하이브리드 워크로드를 가속화하십시오. PennyLane - Amazon Braket

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

의 임베디드 시뮬레이터로 하이브리드 워크로드를 가속화하십시오. PennyLane

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

양자 근사치 최적화 알고리즘 lightning.gpu 워크로드에 사용

이 노트북에 수록된 양자 근사 최적화 알고리즘 (QAOA) 예제를 고려해 보십시오. 임베디드 시뮬레이터를 선택하려면 device 인수를 다음과 같은 형식의 문자열로 지정합니다. "local:<provider>/<simulator_name>" 예를 들어, 를 다음과 같이 설정합니다 "local:pennylane/lightning.gpu"lightning.gpu. Hybrid Job을 시작할 때 제공하는 장치 문자열은 작업에 환경 변수로 "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 기반) 를 비교해 보겠습니다. 다양한 그래디언트를 계산하려면 시뮬레이터에 몇 가지 사용자 지정 게이트 분해를 제공해야 합니다.

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

모든 하이브리드 작업의 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 as를 지정하고 를 임베디드 CPU 기반 시뮬레이터 (lightning.qubit) device 로 선택하면 GPU는 사용되지 않습니다. GPU를 대상으로 하려면 반드시 내장된 GPU 기반 시뮬레이터를 사용하십시오!

먼저 두 개의 하이브리드 작업을 생성하고 꼭짓점이 18개인 그래프에서 QAOA를 사용하여 Max-Cut을 풀 수 있습니다. 이는 18큐비트 회로로 해석됩니다. 이 회로는 비교적 작아서 노트북이나 인스턴스에서 빠르게 실행할 수 있습니다. 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, )

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

이제 문제를 더 어렵게 만들고 24큐비트로 변환되는 24개의 꼭짓점 그래프에서 Max-Cut 문제를 풀어 보겠습니다. 동일한 두 인스턴스에서 하이브리드 작업을 다시 실행하고 비용을 비교하십시오.

참고

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 사용량은 더 비쌀 뿐만 아니라 실행하는 데 더 많은 시간이 걸립니다. CuQuantumNVIDIA가 지원하는 임베디드 시뮬레이터를 사용하여 사용 가능한 GPU 인스턴스로 이 워크플로를 가속화하면 총 비용을 줄이고 시간을 단축하면서 중간 큐비트 수 (20~30) PennyLane 의 워크플로를 실행할 수 있습니다. AWS즉, 노트북이나 비슷한 크기의 인스턴스에서 빠르게 실행하기에는 너무 큰 문제라도 양자 컴퓨팅을 실험해 볼 수 있습니다.

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

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

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

잘 알려진 UCI 리포지토리의 Sonar 데이터 세트를 이진 분류의 예로 사용하는 데이터 병렬 처리를 위한 다음 QML 워크로드를 고려해 보십시오. Sonar 데이터셋에는 208개의 데이터 포인트가 있으며, 각 데이터 포인트는 물질에서 반사되는 소나 신호에서 수집한 60개의 특징을 가지고 있습니다. 각 데이터 포인트는 광산의 경우 “M”, 암석의 경우 “R”로 표시됩니다. QML 모델은 입력 계층, 은닉 계층인 양자 회로, 출력 계층으로 구성되어 있습니다. 입력 및 출력 계층은 에서 PyTorch 구현되는 고전적인 신경망입니다. 양자 회로는 PennyLane 의 PyTorch qml.qnn 모듈을 사용하여 신경망과 통합됩니다. 워크로드에 대한 자세한 내용은 예제 노트북을 참조하십시오. 위의 QAOA 예제와 마찬가지로, 와 같은 임베디드 GPU 기반 시뮬레이터를 사용하여 GPU의 성능을 활용하여 임베디드 CPU 기반 시뮬레이터보다 성능을 개선할 수 있습니다. PennyLane lightning.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 분산 라이브러리의 알고리즘 스크립트에서 몇 줄의 코드를 수정하여 학습을 올바르게 병렬화해야 합니다. 먼저 여러 GPU와 여러 인스턴스에 워크로드를 분산하는 데 필요한 대부분의 번거로운 작업을 수행하는 smdistributed 패키지를 가져옵니다. 이 패키지는 브라켓과 컨테이너에 사전 구성되어 있습니다. PyTorch TensorFlow 이 dist 모듈은 훈련 (world_size) 에 사용할 총 GPU 수와 GPU local_rank 코어의 끝을 알고리즘 스크립트에 알려줍니다. rank rank는 모든 인스턴스에 대한 GPU의 절대 인덱스이고, local_rank 는 인스턴스 내 GPU의 절대 인덱스입니다. 예를 들어, 각각 8개의 GPU가 훈련용으로 할당된 인스턴스가 4개인 경우 rank 범위는 0에서 31이고 범위는 0에서 local_rank 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 rankDistributedSampler 에 따라 a를 정의한 다음 데이터 로더에 전달합니다. 이 샘플러를 사용하면 GPU가 동일한 데이터세트 조각에 액세스하는 것을 방지할 수 있습니다.

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가 저장 및 인쇄 명령을 실행하면 로그에 반복되는 정보가 넘쳐나고 결과가 서로 겹쳐쓰게 됩니다. 이를 방지하려면 0인 GPU에서만 저장하고 인쇄할 수 있습니다. 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 하이브리드 잡스는 SageMaker 분산 데이터 병렬 라이브러리의 ml.p3.16xlarge 인스턴스 유형을 지원합니다. 하이브리드 작업의 InstanceConfig 인수를 통해 인스턴스 유형을 구성합니다. SageMaker 분산 데이터 병렬 라이브러리가 데이터 병렬화가 활성화되었는지 확인하려면 사용 중인 인스턴스 유형으로 "sagemaker_distributed_dataparallel_enabled" 설정하고 설정하는 두 개의 추가 하이퍼파라미터를 추가해야 합니다. "true" "sagemaker_instance_type" 이 두 하이퍼파라미터는 패키지에서 사용됩니다. smdistributed 알고리즘 스크립트는 이를 명시적으로 사용할 필요가 없습니다. Amazon Braket SDK에서는 편리한 키워드 인수를 제공합니다. distribution 하이브리드 작업 distribution="data_parallel" 생성의 경우 Amazon Braket SDK는 두 개의 하이퍼파라미터를 자동으로 삽입합니다. Amazon Braket API를 사용하는 경우 이러한 두 하이퍼파라미터를 포함해야 합니다.

인스턴스 및 데이터 병렬화가 구성되었으므로 이제 하이브리드 작업을 제출할 수 있습니다. 인스턴스에는 8개의 GPU가 있습니다. ml.p3.16xlarge 설정하면 instanceCount=1 인스턴스의 8개 GPU에 워크로드가 분산됩니다. 둘 instanceCount 이상으로 설정하면 모든 인스턴스에서 사용 가능한 GPU에 워크로드가 분산됩니다. 여러 인스턴스를 사용하는 경우 사용 시간에 따라 각 인스턴스에 요금이 부과됩니다. 예를 들어 인스턴스 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달러입니다. 인스턴스 1개와 인스턴스 4개에 걸친 데이터 병렬화를 사용하면 각각 6분, 1.5분밖에 걸리지 않으며, 이는 두 인스턴스 모두 약 2.8 USD에 해당합니다. 4개 인스턴스에서 데이터 병렬화를 사용하면 실행 시간이 30배 향상될 뿐만 아니라 비용도 몇 배나 절감할 수 있습니다!