로컬 코드를 하이브리드 작업으로 실행
Amazon Braket Hybrid Jobs는 Amazon EC2 컴퓨팅 리소스와 Amazon Braket Quantum Processing Unit(QPU) 액세스를 결합하여 하이브리드 양자-고전 알고리즘의 완전관리형 오케스트레이션을 제공합니다. 하이브리드 작업에서 생성된 양자 작업은 개별 양자 작업보다 대기열에서 우선순위를 가지므로, 양자 작업 대기열의 변동으로 인해 알고리즘이 중단되지 않습니다. 각 QPU는 별도의 하이브리드 작업 대기열을 유지하여 한 번에 하나의 하이브리드 작업만 실행되도록 보장합니다.
이 섹션의 내용:
로컬 Python 코드에서 하이브리드 작업 생성
로컬 Python 코드를 Amazon Braket Hybrid Jobs로 실행할 수 있습니다. 다음 코드 예제와 같이 @hybrid_job 데코레이터로 코드에 주석을 달아 이 작업을 수행할 수 있습니다. 사용자 지정 환경의 경우 Amazon Elastic Container Registry(ECR)의 사용자 지정 컨테이너를 사용하도록 선택할 수 있습니다.
참고
기본적으로 Python 3.10만 지원됩니다.
@hybrid_job 데코레이터를 사용하여 함수에 주석을 달 수 있습니다. Braket은 데코레이터 내부의 코드를 Braket 하이브리드 작업 알고리즘 스크립트로 변환합니다. 그런 다음 하이브리드 작업은 Amazon EC2 인스턴스의 데코레이터 내에서 함수를 간적접으로 호출합니다. job.state() 또는 Braket 콘솔을 통해 작업 진행 상황을 모니터링할 수 있습니다. 다음 코드 예제는 State 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}
일반적인 Python 함수와 마찬가지로 함수를 간접적으로 호출하여 하이브리드 작업을 생성합니다. 그러나 데코레이터 함수는 함수의 결과가 아닌 하이브리드 작업 핸들을 반환합니다. 완료 후 결과를 검색하려면 job.result()를 사용합니다.
job = run_hybrid_job(num_tasks=1) result = job.result()
@hybrid_job 데코레이터의 디바이스 인수는 하이브리드 작업이 우선적으로 액세스할 수 있는 디바이스를 지정합니다. 이 경우 SV1 시뮬레이터입니다. QPU 우선순위를 얻으려면 함수 내에서 사용되는 디바이스 ARN이 데코레이터에 지정된 것과 일치하는지 확인해야 합니다. 편의를 위해 헬퍼 함수 get_job_device_arn()을 사용하여 @hybrid_job에 선언된 디바이스 ARN을 캡처할 수 있습니다.
참고
각 하이브리드 작업은 Amazon EC2에서 컨테이너화된 환경을 생성하기 때문에 시작 시간이 최소 1분입니다. 따라서 단일 회로 또는 여러 회로의 배치와 같이 매우 짧은 워크로드의 경우 양자 작업을 사용하기에 충분할 수 있습니다.
하이퍼파라미터
run_hybrid_job() 함수는 인수 num_tasks를 사용하여 생성된 양자 작업 수를 제어합니다. 하이브리드 작업은 이를 하이퍼파라미터로 자동으로 캡처합니다.
참고
하이퍼파라미터는 Braket 콘솔에 문자열로 표시되며, 문자열은 2,500자로 제한됩니다.
지표 및 로깅
run_hybrid_job() 함수 내에서 반복 알고리즘의 지표는 log_metrics를 사용하여 기록됩니다. 지표는 하이브리드 작업 탭 아래의 Braket 콘솔 페이지에 자동으로 플롯됩니다. Braket 비용 추적기를 사용하면 하이브리드 작업 실행 중에 지표를 사용하여 거의 실시간으로 양자 작업 비용을 추적할 수 있습니다. 위 예제에서는 결과 유형의 첫 번째 확률을 기록하는 지표 이름 “probability”를 사용합니다.
결과 검색
하이브리드 작업이 완료되면 job.result()를 사용하여 하이브리드 작업 결과를 검색합니다. 반환 문의 모든 객체는 Braket에 의해 자동으로 캡처됩니다. 함수에서 반환하는 객체는 각 요소가 직렬화 가능한 튜플이어야 합니다. 예를 들어, 다음 코드는 작동하는 예제와 실패하는 예제를 보여줍니다.
import numpy as np # Working example @hybrid_job(device=Devices.Amazon.SV1) def passing(): np_array = np.random.rand(5) return np_array # Serializable # # Failing example # @hybrid_job(device=Devices.Amazon.SV1) # def failing(): # return MyObject() # Not serializable
작업 이름
기본적으로 이 하이브리드 작업의 이름은 함수 이름에서 추론됩니다. 최대 50자까지 사용자 지정 이름을 지정할 수도 있습니다. 예를 들어, 다음 코드에서 작업 이름은 "my-job-name"입니다.
@hybrid_job(device=Devices.Amazon.SV1, job_name="my-job-name") def function(): pass
로컬 모드
로컬 작업은 데코레이터에 인수 local=True를 추가하여 생성됩니다. 그러면 랩톱과 같은 로컬 컴퓨팅 환경의 컨테이너화된 환경에서 하이브리드 작업이 실행됩니다. 로컬 작업에는 양자 작업에 대한 우선순위 대기열이 없습니다. 다중 노드 또는 MPI와 같은 고급 사례의 경우 로컬 작업이 필요한 Braket 환경 변수에 액세스할 수 있습니다. 다음 코드는 디바이스를 SV1 시뮬레이터로 사용하여 로컬 하이브리드 작업을 생성합니다.
@hybrid_job(device=Devices.Amazon.SV1, local=True) def run_hybrid_job(num_tasks=1): return ...
다른 모든 하이브리드 작업 옵션도 지원됩니다. 옵션 목록은 braket.jobs.quantum_job_creation 모듈
추가 Python 패키지 및 소스 코드 설치
원하는 Python 패키지를 사용하도록 런타임 환경을 사용자 지정할 수 있습니다. requirements.txt 파일, 패키지 이름 목록을 사용하거나 자체 컨테이너를 사용할 수 있습니다(BYOC). 예를 들어 requirements.txt 파일에는 설치할 다른 패키지가 포함될 수 있습니다.
qiskit pennylane >= 0.31 mitiq == 0.29
requirements.txt 파일을 사용하여 런타임 환경을 사용자 지정하려면 다음 코드 예제를 참조하세요.
@hybrid_job(device=Devices.Amazon.SV1, dependencies="requirements.txt") def run_hybrid_job(num_tasks=1): return ...
또는 다음과 같이 패키지 이름을 Python 목록으로 제공할 수 있습니다.
@hybrid_job(device=Devices.Amazon.SV1, dependencies=["qiskit", "pennylane>=0.31", "mitiq==0.29"]) def run_hybrid_job(num_tasks=1): return ...
추가 소스 코드는 다음 코드 예제와 같이 모듈 목록 또는 단일 모듈로 지정할 수 있습니다.
@hybrid_job(device=Devices.Amazon.SV1, include_modules=["my_module1", "my_module2"]) def run_hybrid_job(num_tasks=1): return ...
하이브리드 작업 인스턴스에 데이터 저장 및 로드
입력 훈련 데이터 지정
하이브리드 작업을 생성할 때 Amazon Simple Storage Service(Amazon S3) 버킷을 지정하여 입력 훈련 데이터세트를 제공할 수 있습니다. 로컬 경로를 지정할 수도 있으며, 그러면 Braket이 자동으로 데이터를 s3://<default_bucket_name>/jobs/<job_name>/<timestamp>/data/<channel_name>의 Amazon S3에 업로드합니다. 로컬 경로를 지정하는 경우 채널 이름은 기본적으로 “input”으로 설정됩니다. 다음 코드는 로컬 경로 data/file.npy의 넘파이 파일을 보여줍니다.
import numpy as np @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 ...
S3의 경우 get_input_data_dir() 헬퍼 함수를 사용해야 합니다.
import numpy as np from braket.jobs import get_input_data_dir s3_path = "s3://amazon-braket-us-east-1-123456789012/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")
채널 값 및 S3 URI 또는 로컬 경로의 딕셔너리를 제공하여 여러 입력 데이터 소스를 지정할 수 있습니다.
import numpy as np from braket.jobs import get_input_data_dir input_data = { "input": "data/file.npy", "input_2": "s3://amzn-s3-demo-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")
참고
입력 데이터가 크면(>1GB) 작업이 생성되기까지 대기 시간이 길어집니다. 이는 로컬 입력 데이터가 S3 버킷에 처음 업로드된 후 S3 경로가 작업 요청에 추가되기 때문입니다. 마지막으로, 작업 요청이 Braket 서비스에 제출됩니다.
S3에 결과 저장
데코레이션된 함수의 반환 문에 포함되지 않은 결과를 저장하려면 모든 파일 쓰기 작업에 올바른 디렉터리를 추가해야 합니다. 다음 예제에서는 넘파이 배열과 matplotlib 그림을 저장하는 방법을 보여줍니다.
import matplotlib.pyplot as plt import numpy as np @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 ...
모든 결과는 model.tar.gz라는 파일로 압축됩니다. Python 함수 job.result()를 사용하거나 Braket 관리 콘솔의 하이브리드 작업 페이지에서 결과 폴더로 이동하여 결과를 다운로드할 수 있습니다.
체크포인트에서 저장 및 재개
장기 실행 하이브리드 작업의 경우 알고리즘의 중간 상태를 주기적으로 저장하는 것이 좋습니다. 기본 제공 save_job_checkpoint() 헬퍼 함수를 사용하거나 파일을 AMZN_BRAKET_JOB_RESULTS_DIR 경로에 저장할 수 있습니다. 후자의 경우 헬퍼 함수 get_job_results_dir()과 함께 사용할 수 있습니다.
다음은 하이브리드 작업 데코레이터를 사용하여 체크포인트를 저장하고 로드하는 최소 작업 예제입니다.
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()
첫 번째 하이브리드 작업에서는 save_job_checkpoint()가 저장하려는 데이터가 포함된 딕셔너리와 함께 직접적으로 호출됩니다. 기본적으로 모든 값은 텍스트로 직렬화 가능해야 합니다. 넘파이 배열과 같은 더 복잡한 Python 객체를 체크포인트하려면 data_format = PersistedJobDataFormat.PICKLED_V4를 설정할 수 있습니다. 이 코드는 "checkpoints"라는 하위 폴더 아래의 하이브리드 작업 아티팩트에서 기본 이름 <jobname>.json으로 체크포인트 파일을 생성하고 덮어씁니다.
체크포인트에서 계속 진행하기 위해 새로운 하이브리드 작업을 생성하려면 copy_checkpoints_from_job=job_arn을 전달해야 합니다. 여기서 job_arn은 이전 작업의 하이브리드 작업 ARN입니다. 그런 다음 load_job_checkpoint(job_name)을 사용하여 체크포인트에서를 로드합니다.
하이브리드 작업 데코레이터 모범 사례
비동기성 수용
데코레이터 주석으로 생성된 하이브리드 작업은 비동기적입니다. 즉, 고전 리소스와 양자 리소스를 사용할 수 있게 되면 실행됩니다. Braket Management Console 또는 Amazon CloudWatch를 사용하여 알고리즘의 진행 상황을 모니터링합니다. 실행할 알고리즘을 제출하면 Braket은 확장 가능한 컨테이너화된 환경에서 해당 알고리즘을 실행하고 알고리즘이 완료되면 결과가 검색됩니다.
반복 변분 알고리즘 실행
하이브리드 작업은 반복적인 양자-고전 알고리즘을 실행할 수 있는 도구를 제공합니다. 순수하게 양자 문제인 경우 양자 작업 또는 양자 작업 배치를 사용합니다. 특정 QPU에 대한 우선 액세스는 중간에 고전적 처리를 수행하면서 QPU에 대한 여러 번의 반복 직접 호출을 필요로 하는 장기 실행 변분 알고리즘에 가장 유용합니다.
로컬 모드를 사용한 디버깅
QPU에서 하이브리드 작업을 실행하기 전에 먼저 시뮬레이터 SV1에서를 실행하여 예상대로 실행되는지 확인하는 것이 좋습니다. 소규모 테스트의 경우 빠른 반복 및 디버깅을 위해 로컬 모드로 실행할 수 있습니다.
BYOC(Bring Your Own Container)를 통한 재현성 향상
컨테이너화된 환경 내에서 소프트웨어와 해당 종속성을 캡슐화하여 재현 가능한 실험을 생성합니다. 컨테이너에 모든 코드, 종속성 및 설정을 패키징하면 잠재적인 충돌 및 버전 관리 문제를 방지할 수 있습니다.
다중 인스턴스 분산 시뮬레이터
많은 수의 회로를 실행하려면 기본 제공 MPI 지원을 사용하여 단일 하이브리드 작업 내의 여러 인스턴스에서 로컬 시뮬레이터를 실행하는 것이 좋습니다. 자세한 내용은 임베디드 시뮬레이터를 참조하세요.
파라메트릭 회로 사용
하이브리드 작업에서 제출하는 파라메트릭 회로는 파라메트릭 컴파일을 사용하여 특정 QPU에서 자동으로 컴파일되어 알고리즘의 런타임을 개선합니다.
주기적인 체크포인트
장기 실행 하이브리드 작업의 경우 알고리즘의 중간 상태를 주기적으로 저장하는 것이 좋습니다.
추가 예제, 사용 사례 및 모범 사례는 Amazon Braket 예제 GitHub