

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

# Amazon Braket Hybrid Jobs 작업
<a name="braket-jobs"></a>

Amazon Braket Hybrid Jobs는 클래식 AWS 리소스와 양자 처리 장치(QPUs)가 모두 필요한 하이브리드 양자 클래식 알고리즘을 실행할 수 있는 방법을 제공합니다. 하이브리드 작업은 요청된 고전적 리소스를 구동하고 알고리즘을 실행하며 완료 후 인스턴스를 해제하도록 설계되었으므로 *사용한 만큼*만 비용을 지불하면 됩니다.

하이브리드 작업은 고전 컴퓨팅 리소스와 양자 컴퓨팅 리소스를 모두 사용하는 장기 실행 반복 알고리즘에 적합합니다. 하이브리드 작업에서는 실행할 알고리즘을 제출하고 나면, Braket이 확장 가능하고 컨테이너화된 환경에서 해당 알고리즘을 실행합니다. 알고리즘이 완료되면 결과를 검색할 수 있습니다.

또한 하이브리드 작업에서 생성된 양자 작업은 대상 QPU 디바이스에 대한 대기열에서 더 높은 우선순위로 지정되는 이점을 누릴 수 있습니다. 이러한 우선순위 지정 덕분에 대기열에 있는 다른 작업들보다 양자 계산이 먼저 처리되고 실행됩니다. 이는 하나의 양자 작업의 결과가 이전 양자 작업의 결과에 따라 달라지는 반복 하이브리드 알고리즘에 특히 유용합니다. 이러한 알고리즘의 예로는 [양자 근사 최적화 알고리즘(Quantum Approximate Optimization Algorithm, QAOA)](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_quantum_algorithms/QAOA/QAOA_braket.ipynb), [변분 양자 고유해석기](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_quantum_algorithms/VQE_Chemistry/VQE_chemistry_braket.ipynb) 또는 [양자 기계 학습](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/1_Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs/Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs.ipynb)이 있습니다. 또한 알고리즘 진행 상황을 거의 실시간으로 모니터링하여 비용, 예산 또는 훈련 손실이나 기대값과 같은 사용자 지정 지표를 추적할 수 있습니다.

다음을 사용하여 Braket에서 하이브리드 작업에 액세스할 수 있습니다.
+ [Amazon Braket Python SDK](https://github.com/aws/amazon-braket-sdk-python)
+ [Amazon Braket 콘솔](https://console.aws.amazon.com/braket/home)
+ Amazon Braket API

**Topics**
+ [Amazon Braket Hybrid Jobs를 사용해야 하는 시점](#braket-jobs-use)
+ [Amazon Braket Hybrid Jobs를 사용한 하이브리드 작업 실행](#braket-jobs-works)
+ [하이브리드 작업의 주요 개념](braket-jobs-concepts.md)
+ [사전 조건](braket-jobs-prerequisites.md)
+ [하이브리드 작업 생성](braket-jobs-first.md)
+ [하이브리드 작업 취소](braket-jobs-cancel.md)
+ [하이브리드 작업 사용자 지정](braket-jobs-customize.md)
+ [Amazon Braket에서 PennyLane 사용](hybrid.md)
+ [Amazon Braket에서 CUDA-Q 사용](braket-using-cuda-q.md)

## Amazon Braket Hybrid Jobs를 사용해야 하는 시점
<a name="braket-jobs-use"></a>

 Amazon Braket Hybrid Jobs를 사용하면 변분 양자 고유해석기(Variational Quantum Eigensolver, VQE) 및 양자 근사 최적화 알고리즘(Quantum Approximate Optimization Algorithm, QAOA)과 같은 하이브리드 양자-고전 알고리즘을 실행하여 고전 컴퓨팅 리소스를 양자 컴퓨팅 디바이스와 결합해 오늘날 양자 시스템의 성능을 최적화할 수 있습니다. Amazon Braket Hybrid Jobs는 다음과 같은 세 가지 주요 이점을 제공합니다.

1.  **성능**: Amazon Braket Hybrid Jobs는 자체 환경에서 하이브리드 알고리즘을 실행하는 것보다 더 나은 성능을 제공합니다. 작업이 실행되는 동안 선택한 대상 QPU에 우선적으로 액세스할 수 있습니다. 따라서 해당 양자 작업의 작업이 디바이스에 대기 중인 다른 작업보다 먼저 실행됩니다. 따라서 하이브리드 알고리즘의 런타임이 단축되고 예측 가능성은 더 높아집니다. Amazon Braket Hybrid Jobs는 파라메트릭 컴파일도 지원합니다. 자유 파라미터를 사용하여 회로를 제출할 수 있으며 Braket은 동일한 회로에 대한 후속 파라미터 업데이트를 위해 다시 컴파일할 필요 없이 회로를 한 번 컴파일하므로 런타임이 훨씬 빨라집니다.

1.  **편의성**: Amazon Braket Hybrid Jobs는 컴퓨팅 환경 설정 및 관리를 간소화하고 하이브리드 알고리즘이 실행되는 동안 환경을 계속 가동 상태로 유지합니다. 알고리즘 스크립트를 제공하고 실행할 양자 디바이스(양자 처리 장치 또는 시뮬레이터)를 선택하면 됩니다. Amazon Braket은 대상 디바이스가 사용 가능 상태가 될 때까지 대기하고 고전 리소스를 구동하며 사전 빌드된 컨테이너 환경에서 워크로드를 실행하고 결과를 Amazon Simple Storage Service(Amazon S3)에 반환한 다음 컴퓨팅 리소스를 해제합니다.

1.  **지표**: Amazon Braket Hybrid Jobs는 실행 중인 알고리즘에 대한 즉각적인 인사이트를 제공하고 사용자 지정 가능한 알고리즘 지표를 거의 실시간으로 Amazon CloudWatch 및 Amazon Braket 콘솔에 전달하여 알고리즘의 진행 상황을 추적할 수 있게 합니다.

## Amazon Braket Hybrid Jobs를 사용한 하이브리드 작업 실행
<a name="braket-jobs-works"></a>

Amazon Braket Hybrid Jobs로 하이브리드 작업을 실행하려면 먼저 알고리즘을 정의해야 합니다. [Amazon Braket Python SDK](https://github.com/aws/amazon-braket-sdk-python) 또는 [PennyLane](https://pennylane.ai)을 사용하여 *알고리즘 스크립트*와 기타 종속성 파일(선택 사항)을 작성하여 정의할 수 있습니다. 다른 (오픈 소스 또는 독점) 라이브러리를 사용하려면 이러한 라이브러리가 포함된 Docker를 사용하여 자체 사용자 지정 컨테이너 이미지를 정의할 수 있습니다. 자세한 내용은 [자체 컨테이너 사용(BYOC)](braket-jobs-byoc.md)을 참조하세요.

어느 경우든, 다음으로 Amazon Braket API를 사용하여 하이브리드 작업을 생성합니다. 여기서 알고리즘 스크립트 또는 컨테이너를 제공하고 하이브리드 작업이 사용할 대상 양자 디바이스를 선택한 다음 다양한 옵션 설정 중에서 선택합니다. 이러한 옵션 설정에 제공된 기본값은 대부분의 사용 사례에 적합합니다. 하이브리드 작업을 실행할 대상 디바이스로 QPU, 온디맨드 시뮬레이터(예: SV1, DM1 또는 TN1) 또는 고전적인 하이브리드 작업 인스턴스 자체 중에서 선택할 수 있습니다. 온디맨드 시뮬레이터 또는 QPU를 사용하면 하이브리드 작업 컨테이너가 원격 디바이스에 대한 API 직접 호출을 수행합니다. 임베디드 시뮬레이터를 사용하면, 시뮬레이터가 알고리즘 스크립트와 동일한 컨테이너에 임베디드됩니다. PennyLane의 [라이트닝 시뮬레이터](https://github.com/PennyLaneAI/pennylane-lightning)에는 사용자를 위해 사전 빌드된 기본 하이브리드 작업 컨테이너가 임베디드되어 있습니다. 임베디드 PennyLane 시뮬레이터 또는 사용자 지정 시뮬레이터를 사용하여 코드를 실행하는 경우 인스턴스 유형과 사용하려는 인스턴스 수를 지정할 수 있습니다. 각 선택과 관련된 비용은 [Amazon Braket 요금 페이지](https://aws.amazon.com/braket/pricing/)를 참조하세요.

![\[하이브리드, QPU, 온디맨드 및 임베디드 작업에 대한 Amazon Braket 구성 요소, API, 작업 인스턴스 및 시뮬레이터와의 사용자 상호 작용을 보여주는 흐름도입니다. 결과는 Amazon Simple Storage Service 버킷에 저장되고 Amazon Braket 콘솔에서 Amazon CloudWatch를 사용하여 분석됩니다.\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/images/braket-hybrid-job-run.png)


대상 디바이스가 온디맨드 또는 임베디드 시뮬레이터인 경우 Amazon Braket은 하이브리드 작업을 즉시 실행하기 시작합니다. 하이브리드 작업 인스턴스를 구동하고(API 직접 호출 시 인스턴스 유형을 사용자 지정할 수 있음) 알고리즘을 실행하며 Amazon S3에 결과를 쓰고 리소스를 해제합니다. 이러한 리소스 해제 방식 덕분에 사용한 만큼만 비용을 지불하면 됩니다.

QPU당 동시 하이브리드 작업의 총 수는 제한됩니다. 현재 QPU에서는 한 번에 하나의 하이브리드 작업만 실행할 수 있습니다. 대기열은 허용된 제한을 초과하지 않도록 실행이 허용되는 하이브리드 작업의 수를 제어하는 데 사용됩니다. 대상 디바이스가 QPU인 경우 하이브리드 작업은 먼저 선택한 QPU의 *작업 대기열*에 들어갑니다. Amazon Braket은 필요한 하이브리드 작업 인스턴스를 구동하고 디바이스에서 하이브리드 작업을 실행합니다. 알고리즘 실행 기간 동안에는 하이브리드 작업이 우선적으로 처리됩니다. 즉, 하이브리드 작업의 양자 작업이 디바이스에 대기 중인 다른 Braket 양자 작업보다 먼저 실행됩니다. 단, 하이브리드 작업의 양자 작업은 몇 분 간격으로 QPU에 제출되어야 합니다. 하이브리드 작업이 완료되면 리소스가 해제되므로, 사용한 만큼만 비용을 지불하면 됩니다.

**참고**  
디바이스는 리전별이며 하이브리드 작업은 기본 디바이스 AWS 리전 와 동일한에서 실행됩니다.

시뮬레이터 및 QPU 대상 시나리오 모두에서 알고리즘의 일부로 해밀토니안의 에너지와 같은 사용자 지정 알고리즘 지표를 정의할 수 있는 옵션이 있습니다. 이러한 지표는 Amazon CloudWatch에 자동으로 보고되며 거기서 Amazon Braket 콘솔에 거의 실시간으로 표시됩니다.

**참고**  
GPU 기반 인스턴스를 사용하려면 Braket의 임베디드 시뮬레이터와 함께 사용할 수 있는 GPU 기반 시뮬레이터 중 하나를 사용해야 합니다(예: `lightning.gpu`). CPU 기반 임베디드 시뮬레이터(예: `lightning.qubit`또는 `braket:default-simulator`) 중 하나를 선택하면 GPU가 사용되지 않으므로 불필요한 비용이 발생할 수 있습니다.

# 하이브리드 작업의 주요 개념
<a name="braket-jobs-concepts"></a>

이 섹션에서는 Amazon Braket Python SDK에서 제공하는 `AwsQuantumJob.create` 함수의 주요 개념과 컨테이너 파일 구조에 대한 매핑을 설명합니다.

전체 알고리즘 스크립트를 구성하는 파일 외에도, 하이브리드 작업에는 추가 입력과 출력이 있을 수 있습니다. 하이브리드 작업이 시작되면 Amazon Braket은 하이브리드 작업 생성의 일부로 제공된 입력을 알고리즘 스크립트를 실행하는 컨테이너에 복사합니다. 하이브리드 작업이 완료되면 알고리즘 중에 정의된 모든 출력이 지정된 Amazon S3 위치로 복사됩니다.

**참고**  
 *알고리즘 지표*는 실시간으로 보고되며 이 출력 절차를 따르지 않습니다.

또한 Amazon Braket은 컨테이너 입력 및 출력과의 상호 작용을 간소화하는 여러 환경 변수 및 헬퍼 함수를 제공합니다. 자세한 내용은 *Amazon Braket SDK*의 [braket.jobs 패키지](https://amazon-braket-sdk-python.readthedocs.io/en/latest/_apidoc/braket.jobs.html)를 참조하세요.

**Topics**
+ [입력](#braket-jobs-inputs)
+ [출력](#braket-jobs-outputs)
+ [환경 변수](#braket-jobs-environmental-variables)
+ [헬퍼 함수](#braket-jobs-helper-functions)

## 입력
<a name="braket-jobs-inputs"></a>

 **입력 데이터**: 입력 데이터는 딕셔너리로 설정된 입력 데이터 파일을 `input_data` 인수와 함께 지정하여 하이브리드 알고리즘에 제공할 수 있습니다. 사용자는 SDK의 `AwsQuantumJob.create` 함수 내에서 `input_data` 인수를 정의합니다. 그러면 환경 변수 `"AMZN_BRAKET_INPUT_DIR"`에서 지정한 위치의 컨테이너 파일 시스템에 입력 데이터가 복사됩니다. 하이브리드 알고리즘에서 입력 데이터가 사용되는 방법에 대한 몇 가지 예제는 [Amazon Braket Hybrid Jobs와 PennyLane을 활용한 QAOA](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/2_Using_PennyLane_with_Braket_Hybrid_Jobs/Using_PennyLane_with_Braket_Hybrid_Jobs.ipynb) 및 [Amazon Braket Hybrid Jobs에서의 양자 기계 학습](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/1_Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs/Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs.ipynb) Jupyter notebooks를 참조하세요.

**참고**  
입력 데이터가 크면(>1GB) 하이브리드 작업이 제출되기까지 대기 시간이 길어집니다. 이는 로컬 입력 데이터가 먼저 S3 버킷에 업로드된 다음 S3 경로가 하이브리드 작업 요청에 추가되고, 마지막으로 하이브리드 작업 요청이 Braket 서비스에 제출되기 때문입니다.

 **하이퍼파라미터**: `hyperparameters`를 전달하면 환경 변수 `"AMZN_BRAKET_HP_FILE"`에서 사용할 수 있습니다.

**참고**  
하이퍼파라미터 및 입력 데이터를 생성한 다음 이 정보를 하이브리드 작업 스크립트에 전달하는 방법에 대한 자세한 내용은 [하이퍼파라미터 사용](braket-jobs-hyperparameters.md) 섹션 및 이 github [페이지](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/1_Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs/qcbm/qcbm.py)를 참조하세요.

 **체크포인트**: 새 하이브리드 작업에서 사용할 체크포인트를 갖는 `job-arn`을 지정하려면 `copy_checkpoints_from_job` 명령을 사용합니다. 이 명령은 체크포인트 데이터를 새 하이브리드 작업의 `checkpoint_configs3Uri`으로 복사하여 작업이 실행되는 동안 환경 변수 `AMZN_BRAKET_CHECKPOINT_DIR`이 지정한 경로에서 사용할 수 있게 합니다. 기본값은 `None`입니다. 즉, 다른 하이브리드 작업의 체크포인트 데이터는 새 하이브리드 작업에 사용되지 않습니다.

## 출력
<a name="braket-jobs-outputs"></a>

 **양자 작업**: 양자 작업 결과는 S3 위치 `s3://amazon-braket-<region>-<accountID>/jobs/<job-name>/tasks`에 저장됩니다.

 **작업 결과**: 알고리즘 스크립트가 환경 변수 `"AMZN_BRAKET_JOB_RESULTS_DIR"`에 의해 지정된 디렉터리에 저장하는 모든 내용은 `output_data_config`에 지정된 S3 위치로 복사됩니다. 값이 지정되지 않은 경우 기본값은 `s3://amazon-braket-<region>-<accountID>/jobs/<job-name>/<timestamp>/data`입니다. 알고리즘 스크립트에서 직접적으로 호출할 때 결과를 딕셔너리 형태로 편리하게 저장하는 데 사용할 수 있는 SDK 헬퍼 함수 **`save_job_result`**를 제공합니다.

 **체크포인트**: 체크포인트를 사용하려면 환경 변수 `"AMZN_BRAKET_CHECKPOINT_DIR"`에 의해 지정된 디렉터리에 체해당 크포인트를 저장할 수 있습니다. SDK 헬퍼 함수 `save_job_checkpoint`를 대신 사용할 수도 있습니다.

 **알고리즘 지표**: 하이브리드 작업이 실행되는 동안 Amazon CloudWatch로 내보내지고 Amazon Braket 콘솔에 실시간으로 표시되는 알고리즘 스크립트의 일부로 알고리즘 지표를 정의할 수 있습니다. 알고리즘 지표를 사용하는 방법의 예제는 [Amazon Braket Hybrid Jobs를 사용하여 QAOA 알고리즘 실행](braket-jobs-run-qaoa-algorithm.md)을 참조하세요.

작업 출력 저장에 대한 자세한 내용은 하이브리드 작업 설명서의 [결과 저장](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs-first.html#braket-jobs-save-results)을 참조하세요.

## 환경 변수
<a name="braket-jobs-environmental-variables"></a>

Amazon Braket은 컨테이너 입력 및 출력과의 상호 작용을 간소화하는 여러 환경 변수를 제공합니다. 아래 코드는 Braket이 사용하는 환경 변수를 나열합니다.
+ `AMZN_BRAKET_INPUT_DIR` - 입력 데이터 디렉터리 opt/braket/input/data
+ `AMZN_BRAKET_JOB_RESULTS_DIR` - 작업 결과를 쓸 출력 디렉터리 opt/braket/model
+ `AMZN_BRAKET_JOB_NAME` - 작업의 이름
+ `AMZN_BRAKET_CHECKPOINT_DIR` - 체크포인트 디렉터리
+ `AMZN_BRAKET_HP_FILE` - 하이퍼파라미터가 포함된 파일
+ `AMZN_BRAKET_DEVICE_ARN` - 디바이스 ARN(AWS 리소스 이름).
+ `AMZN_BRAKET_OUT_S3_BUCKET` - `CreateJob` 요청의 `OutputDataConfig`에 지정된 출력 Amazon S3 버킷
+ `AMZN_BRAKET_SCRIPT_ENTRY_POINT` - `CreateJob` 요청의 `ScriptModeConfig`에 지정된 진입점
+ `AMZN_BRAKET_SCRIPT_COMPRESSION_TYPE` - `CreateJob` 요청의 `ScriptModeConfig`에 지정된 압축 유형
+ `AMZN_BRAKET_SCRIPT_S3_URI` - `CreateJob` 요청의 `ScriptModeConfig`에 지정된 사용자 스크립트의 Amazon S3 위치
+ `AMZN_BRAKET_TASK_RESULTS_S3_URI` - SDK가 기본적으로 작업에 대한 양자 작업 결과를 저장하는 Amazon S3 위치
+ `AMZN_BRAKET_JOB_RESULTS_S3_PATH` - `CreateJob` 요청의 `OutputDataConfig`에 지정된 대로 작업 결과가 저장될 Amazon S3 위치
+ `AMZN_BRAKET_JOB_TOKEN` - 작업 컨테이너에 생성된 양자 작업에 대해 `CreateQuantumTask`의 `jobToken` 파라미터에 전달되어야 하는 문자열

## 헬퍼 함수
<a name="braket-jobs-helper-functions"></a>

Amazon Braket은 컨테이너 입력 및 출력과의 상호 작용을 간소화하는 여러 헬퍼 함수를 제공합니다. 이러한 헬퍼 함수는 하이브리드 작업을 실행하는 데 사용되는 알고리즘 스크립트 내에서 직접적으로 호출됩니다. 다음 예제에서는 이러한 함수를 사용하는 방법을 보여줍니다.

```
from braket.jobs import get_checkpoint_dir, get_hyperparameters, get_input_data_dir, get_job_device_arn, get_job_name, get_results_dir, save_job_result, save_job_checkpoint, load_job_checkpoint

get_checkpoint_dir() # Get the checkpoint directory
get_hyperparameters() # Get the hyperparameters as strings
get_input_data_dir() # Get the input data directory
get_job_device_arn() # Get the device specified by the hybrid job
get_job_name() # Get the name of the hybrid job.
get_results_dir() # Get the path to a results directory
save_job_result(result_data='data') # Save hybrid job results
save_job_checkpoint(checkpoint_data={'key': 'value'}) # Save a checkpoint
load_job_checkpoint() # Load a previously saved checkpoint
```

# 사전 조건
<a name="braket-jobs-prerequisites"></a>

첫 번째 하이브리드 작업을 실행하기 전에, 이 작업을 진행할 수 있는 충분한 권한이 있는지 확인해야 합니다. 올바른 권한이 있는지 확인하려면 Braket 콘솔 왼쪽의 메뉴에서 **권한**을 선택합니다. **Amazon Braket에 대한 권한 관리 ** 페이지는 기존 역할 중 하나에 하이브리드 작업을 실행하기 충분한 권한이 있는지 확인하는 데 도움을 주거나, 해당 역할이 아직 없는 경우 하이브리드 작업을 실행하는 데 사용할 수 있는 기본 역할 생성 과정을 안내합니다.

![\[서비스 연결 역할 및 하이브리드 작업 실행 역할의 기존 역할을 확인하는 옵션을 보여주는 Amazon Braket 서비스의 권한 및 설정 페이지입니다.\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/images/braket-jobs-first-permissions.png)


하이브리드 작업을 실행할 수 있는 충분한 권한을 가진 역할이 있는지 확인하려면 **기존 역할 확인** 버튼을 선택합니다. 이렇게 하면 역할을 찾았다는 메시지가 표시됩니다. 역할의 이름과 역할 ARN을 보려면 **역할 표시** 버튼을 선택합니다.

![\[찾은 서비스 연결 역할과 하이브리드 작업을 실행할 수 있는 충분한 권한이 있는 기존 역할을 보여주는 Amazon Braket 권한 및 설정 화면입니다.\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/images/braket-jobs-first-permissions-verify-yes.png)


하이브리드 작업을 실행할 수 있는 충분한 권한이 있는 역할이 없는 경우 해당 역할을 찾을 수 없다는 메시지가 표시됩니다. 충분한 권한이 있는 역할을 얻으려면 **기본 역할 생성** 버튼을 선택합니다.

![\[서비스 연결 역할을 찾았지만 하이브리드 작업 실행 역할은 찾을 수 없음을 보여주는 Amazon Braket 권한 및 설정 페이지입니다.\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/images/braket-jobs-first-permissions-verify-no.png)


역할이 성공적으로 생성되면 이를 확인하는 메시지가 표시됩니다.

![\[찾은 서비스 연결 역할과 성공적으로 생성된 하이브리드 작업 실행 역할을 보여주는 Amazon Braket 권한 및 설정 페이지입니다.\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/images/braket-jobs-first-permissions-verify-created.png)


이 문의를 수행할 권한이 없는 경우 액세스가 거부됩니다. 이 경우 내부 AWS 관리자에게 문의하세요.

![\[명시적 거부가 설정된 AmazonBraketJobsExecutionRole에 대해 사용자가 iam:ListAttachedRolePolicies를 수행할 권한이 없음을 나타내는 AccessDenied 오류 메시지입니다.\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/images/braket-jobs-first-permissions-access-denied.png)


# 하이브리드 작업 생성
<a name="braket-jobs-first"></a>

 이 섹션에서는 Python 스크립트를 사용하여 하이브리드 작업을 생성하는 방법을 보여줍니다. 또는 선호하는 통합 개발 환경(IDE)이나 Braket 노트북 같은 로컬 Python 코드에서 하이브리드 작업을 생성하려면 [로컬 코드를 하이브리드 작업으로 실행](braket-hybrid-job-decorator.md)을 참조하세요.

**Topics**
+ [생성 및 실행](#braket-jobs-first-create)
+ [결과 모니터링](#braket-jobs-first-monitor-results)
+ [결과 저장](#braket-jobs-save-results)
+ [체크포인트 사용](#braket-jobs-checkpoints)
+ [로컬 코드를 하이브리드 작업으로 실행](braket-hybrid-job-decorator.md)
+ [하이브리드 작업에 API 사용](braket-jobs-api.md)
+ [로컬 모드로 하이브리드 작업 생성 및 디버깅](braket-jobs-local-mode.md)

## 생성 및 실행
<a name="braket-jobs-first-create"></a>

하이브리드 작업을 실행할 권한이 있는 역할이 있으면 바로 진행할 수 있습니다. 첫 번째 Braket 하이브리드 작업의 핵심은 *알고리즘 스크립트*입니다. 실행하려는 알고리즘을 정의하고 알고리즘의 일부인 고전 논리 및 양자 작업을 포함합니다. 알고리즘 스크립트 외에도 다른 종속성 파일을 제공할 수 있습니다. 알고리즘 스크립트와 해당 종속성을 합쳐서 *소스 모듈*이라고 합니다. *진입점*은 하이브리드 작업이 시작될 때 소스 모듈에서 실행할 첫 번째 파일 또는 함수를 정의합니다.

![\[콘솔 또는 노트북을 사용하여 양자 작업을 생성하고, 양자 디바이스에서 알고리즘 스크립트를 실행하고, 결과를 분석하는 워크플로를 보여주는 다이어그램입니다.\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/images/braket-jobs-first-workflow.jpg)


먼저 5개의 벨 상태를 생성하고 해당 측정 결과를 출력하는 알고리즘 스크립트의 다음 기본 예제를 살펴보세요.

```
import os

from braket.aws import AwsDevice
from braket.circuits import Circuit


def start_here():

    print("Test job started!")

    # Use the device declared in the job script
    device = AwsDevice(os.environ["AMZN_BRAKET_DEVICE_ARN"])

    bell = Circuit().h(0).cnot(0, 1)
    for count in range(5):
        task = device.run(bell, shots=100)
        print(task.result().measurement_counts)

    print("Test job completed!")
```

이 파일을 Braket 노트북 또는 로컬 환경의 현재 작업 디렉터리에 *algorithm\$1script.py*라는 이름으로 저장합니다. algorithm\$1script.py 파일은 `start_here()`를 계획된 진입점으로 사용합니다.

그런 다음 algorithm\$1script.py 파일과 동일한 디렉터리에 Python 파일 또는 Python 노트북을 생성합니다. 이 스크립트는 하이브리드 작업을 시작하고 상태나 관심 대상 주요 결과 출력과 같은 모든 비동기 처리를 해결합니다. 최소한 이 스크립트는 하이브리드 작업 스크립트와 기본 디바이스를 지정해야 합니다.

**참고**  
노트북과 동일한 디렉터리에 Braket 노트북을 생성하거나 *algorithm\$1script.py* 파일과 같은 파일을 업로드하는 방법에 대한 자세한 내용은 [Amazon Braket Python SDK를 사용하여 첫 번째 회로 실행](braket-get-started-run-circuit.md)을 참조하세요.

이 기본적인 첫 번째 사례의 경우 시뮬레이터를 대상으로 합니다. 대상 양자 디바이스 유형, 시뮬레이터 또는 실제 QPU에 관계없이 다음 스크립트에서 `device`로 지정하는 디바이스는 하이브리드 작업을 예약하는 데 사용되며 알고리즘 스크립트에서 환경 변수 `AMZN_BRAKET_DEVICE_ARN`으로 사용할 수 있습니다.

**참고**  
하이브리드 작업 AWS 리전 의에서 사용할 수 있는 디바이스만 사용할 수 있습니다. Amazon Braket SDK는 이 AWS 리전을 자동으로 선택합니다. 예를 들어 us-east-1의 하이브리드 작업은 IonQ, SV1, DM1 및 TN1 디바이스를 사용할 수 있지만 Rigetti 디바이스는 사용할 수 없습니다.

시뮬레이터 대신 양자 컴퓨터를 선택하면, Braket은 하이브리드 작업을 예약하여 모든 양자 작업을 우선적으로 실행하도록 합니다.

```
from braket.aws import AwsQuantumJob
from braket.devices import Devices

job = AwsQuantumJob.create(
    Devices.Amazon.SV1,
    source_module="algorithm_script.py",
    entry_point="algorithm_script:start_here",
    wait_until_complete=True
)
```

파라미터 `wait_until_complete=True`는 작업이 실행 중인 실제 작업의 출력을 인쇄하도록 자세한 정보 표시 모드를 설정합니다. 다음 예제와 유사한 출력이 표시됩니다.

```
Initializing Braket Job: arn:aws:braket:us-west-2:111122223333:job/braket-job-default-123456789012
Job queue position: 1
Job queue position: 1
Job queue position: 1
..............
.
.
.
Beginning Setup
Checking for Additional Requirements
Additional Requirements Check Finished
Running Code As Process
Test job started!
Counter({'00': 58, '11': 42})
Counter({'00': 55, '11': 45})
Counter({'11': 51, '00': 49})
Counter({'00': 56, '11': 44})
Counter({'11': 56, '00': 44})
Test job completed!
Code Run Finished
2025-09-24 23:13:40,962 sagemaker-training-toolkit INFO     Reporting training SUCCESS
```

**참고**  
위치(로컬 디렉터리 또는 파일의 경로, 또는 tar.gz 파일의 S3 URI)를 전달하여 [AwsQuantumJob.create](https://amazon-braket-sdk-python.readthedocs.io/en/latest/_apidoc/braket.aws.aws_quantum_job.html#braket.aws.aws_quantum_job.AwsQuantumJob.create) 메서드와 함께 사용자 지정 모듈을 사용할 수도 있습니다. 작업 예제는 [Amazon Braket 예제 Github 리포지토리](https://github.com/amazon-braket/amazon-braket-examples/tree/main)의 하이브리드 작업 폴더에서 [Parallelize\$1training\$1for\$1QML.ipynb](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/5_Parallelize_training_for_QML/Parallelize_training_for_QML.ipynb) 파일을 참조하세요.

## 결과 모니터링
<a name="braket-jobs-first-monitor-results"></a>

또는, Amazon CloudWatch의 로그 출력에 액세스할 수 있습니다. 이렇게 하려면 작업 세부 정보 페이지의 왼쪽 메뉴에 있는 **로그 그룹** 탭으로 이동하여 로그 그룹 `aws/braket/jobs`를 선택한 다음, 작업 이름이 포함된 로그 스트림을 선택합니다. 위 예제에서는 `braket-job-default-1631915042705/algo-1-1631915190`입니다.

![\[Amazon Braket SDK Python 테스트에 대한 파일 경로 및 타임스탬프가 있는 로그 이벤트 목록을 보여주는 CloudWatch 로그 그룹입니다.\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/images/braket-jobs-first-cw-log.png)


**하이브리드 작업** 페이지를 선택한 다음 **설정**을 선택하여 콘솔에서 하이브리드 작업의 상태를 볼 수도 있습니다.

![\[요약, 이벤트 시간, 소스 코드 및 인스턴스 구성, 중지 조건을 보여주는 Amazon Braket Hybrid Jobs 세부 정보입니다.\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/images/braket-jobs-first-console-status.png)


하이브리드 작업은 실행되는 동안 Amazon S3에서 일부 아티팩트를 생성합니다. 기본 S3 버킷 이름은 `amazon-braket-<region>-<accountid>`이고 콘텐츠는 `jobs/<jobname>/<timestamp>` 디렉터리에 있습니다. Braket Python SDK를 사용하여 하이브리드 작업을 생성할 때 다른 `code_location`을 지정하여 이러한 아티팩트가 저장되는 S3 위치를 구성할 수 있습니다.

**참고**  
이 S3 버킷은 작업 스크립트 AWS 리전 와 동일한에 있어야 합니다.

`jobs/<jobname>/<timestamp>` 디렉터리에는 `model.tar.gz` 파일에 담긴 진입점 스크립트의 출력이 있는 하위 폴더가 포함되어 있습니다. 또한 `source.tar.gz` 파일에 알고리즘 스크립트 아티팩트가 포함된 `script`라고 하는 디렉터리도 있습니다. 실제 양자 작업의 결과는 `jobs/<jobname>/tasks`라는 디렉터리에 있습니다.

## 결과 저장
<a name="braket-jobs-save-results"></a>

하이브리드 작업 스크립트의 하이브리드 작업 객체와 Amazon S3의 출력 폴더(model.tar.gz라는 이름의 tar-zipped 파일)에서 사용할 수 있도록 알고리즘 스크립트에서 생성된 결과를 저장할 수 있습니다.

출력은 JavaScript Object Notation(JSON) 형식을 사용하여 파일에 저장해야 합니다. 넘파이 배열의 경우처럼 데이터가 텍스트로 쉽게 직렬화될 수 없는 경우, 피클링된 데이터 형식을 사용하여 직렬화하는 옵션을 전달할 수 있습니다. 자세한 내용은 [braket.jobs.data\$1persistence 모듈](https://amazon-braket-sdk-python.readthedocs.io/en/latest/_apidoc/braket.jobs.data_persistence.html#braket.jobs.data_persistence.save_job_result)을 참조하세요.

하이브리드 작업의 결과를 저장하려면 \$1ADD로 주석이 달린 다음 줄을 algorithm\$1script.py 파일에 추가합니다.

```
import os

from braket.aws import AwsDevice
from braket.circuits import Circuit
from braket.jobs import save_job_result  # ADD


def start_here():

    print("Test job started!")

    device = AwsDevice(os.environ['AMZN_BRAKET_DEVICE_ARN'])

    results = []  # ADD

    bell = Circuit().h(0).cnot(0, 1)
    for count in range(5):
        task = device.run(bell, shots=100)
        print(task.result().measurement_counts)
        results.append(task.result().measurement_counts)  # ADD

        save_job_result({"measurement_counts": results})  # ADD

    print("Test job completed!")
```

그런 다음 \$1ADD로 주석이 달린 줄 **`print(job.result())`**를 추가하여 작업 스크립트의 작업 결과를 표시할 수 있습니다.

```
import time
from braket.aws import AwsQuantumJob

job = AwsQuantumJob.create(
    source_module="algorithm_script.py",
    entry_point="algorithm_script:start_here",
    device="arn:aws:braket:::device/quantum-simulator/amazon/sv1",
)

print(job.arn)
while job.state() not in AwsQuantumJob.TERMINAL_STATES:
    print(job.state())
    time.sleep(10)

print(job.state())
print(job.result())   # ADD
```

이 예제에서는 자세한 정보 출력을 억제하기 위해 `wait_until_complete=True`를 제거했습니다. 디버깅을 위해 다시 추가할 수 있습니다. 이 하이브리드 작업을 실행하면 식별자와 `job-arn`을 출력한 다음 하이브리드 작업이 `COMPLETED` 상태가 될 때까지 10초마다 하이브리드 작업의 상태를 출력한 후에 벨 회로의 결과가 보여줍니다. 다음 예제를 참조하세요.

```
arn:aws:braket:us-west-2:111122223333:job/braket-job-default-123456789012
INITIALIZED
RUNNING
RUNNING
RUNNING
RUNNING
RUNNING
RUNNING
RUNNING
RUNNING
RUNNING
RUNNING
...
RUNNING
RUNNING
COMPLETED
{'measurement_counts': [{'11': 53, '00': 47},..., {'00': 51, '11': 49}]}
```

## 체크포인트 사용
<a name="braket-jobs-checkpoints"></a>

체크포인트를 사용하여 하이브리드 작업의 중간 반복을 저장할 수 있습니다. 이전 섹션의 알고리즘 스크립트 예제에서 체크포인트 파일을 생성하려면 \$1ADD로 주석이 달린 다음 줄을 추가하면 됩니다.

```
from braket.aws import AwsDevice
from braket.circuits import Circuit
from braket.jobs import save_job_checkpoint  # ADD
import os


def start_here():

    print("Test job starts!")

    device = AwsDevice(os.environ["AMZN_BRAKET_DEVICE_ARN"])

    # ADD the following code
    job_name = os.environ["AMZN_BRAKET_JOB_NAME"]
    save_job_checkpoint(checkpoint_data={"data": f"data for checkpoint from {job_name}"}, checkpoint_file_suffix="checkpoint-1")  # End of ADD

    bell = Circuit().h(0).cnot(0, 1)
    for count in range(5):
        task = device.run(bell, shots=100)
        print(task.result().measurement_counts)

    print("Test hybrid job completed!")
```

하이브리드 작업을 실행하면 기본 `/opt/jobs/checkpoints` 경로의 체크포인트 디렉터리 내 하이브리드 작업 아티팩트에 *<jobname>-checkpoint-1.json* 파일이 생성됩니다. 이 기본 경로를 변경하지 않는 한 하이브리드 작업 스크립트는 변경되지 않습니다.

이전 하이브리드 작업에서 생성된 체크포인트에서 하이브리드 작업을 로드하려는 경우 알고리즘 스크립트는 `from braket.jobs import load_job_checkpoint`를 사용합니다. 알고리즘 스크립트에 로드할 논리는 다음과 같습니다.

```
from braket.jobs import load_job_checkpoint

checkpoint_1 = load_job_checkpoint(
    "previous_job_name",
    checkpoint_file_suffix="checkpoint-1",
)
```

이 체크포인트를 로드한 후 `checkpoint-1`에 로드된 콘텐츠를 기반으로 논리를 계속 진행할 수 있습니다.

**참고**  
*checkpoint\$1file\$1suffix*는 체크포인트 생성 시 이전에 지정한 접미사와 일치해야 합니다.

오케스트레이션 스크립트는 \$1ADD로 주석이 달린 줄로 이전 하이브리드 작업의 `job-arn`을 지정해야 합니다.

```
from braket.aws import AwsQuantumJob

job = AwsQuantumJob.create(
    source_module="source_dir",
    entry_point="source_dir.algorithm_script:start_here",
    device="arn:aws:braket:::device/quantum-simulator/amazon/sv1",
    copy_checkpoints_from_job="<previous-job-ARN>", #ADD
    )
```

# 로컬 코드를 하이브리드 작업으로 실행
<a name="braket-hybrid-job-decorator"></a>

Amazon Braket Hybrid Jobs는 Amazon EC2 컴퓨팅 리소스와 Amazon Braket Quantum Processing Unit(QPU) 액세스를 결합하여 하이브리드 양자-고전 알고리즘의 완전관리형 오케스트레이션을 제공합니다. 하이브리드 작업에서 생성된 양자 작업은 개별 양자 작업보다 대기열에서 우선순위를 가지므로, 양자 작업 대기열의 변동으로 인해 알고리즘이 중단되지 않습니다. 각 QPU는 별도의 하이브리드 작업 대기열을 유지하여 한 번에 하나의 하이브리드 작업만 실행되도록 보장합니다.

**Topics**
+ [로컬 Python 코드에서 하이브리드 작업 생성](#create-hybrid-job-from-local-python-code)
+ [추가 Python 패키지 및 소스 코드 설치](#install-python-packages-and-code)
+ [하이브리드 작업 인스턴스에 데이터 저장 및 로드](#save-load-data-into-instance)
+ [하이브리드 작업 데코레이터 모범 사례](#best-practices)

## 로컬 Python 코드에서 하이브리드 작업 생성
<a name="create-hybrid-job-from-local-python-code"></a>

로컬 Python 코드를 Amazon Braket Hybrid Jobs로 실행할 수 있습니다. 다음 코드 예제와 같이 `@hybrid_job` 데코레이터로 코드에 주석을 달아 이 작업을 수행할 수 있습니다. 사용자 지정 환경의 경우 Amazon Elastic Container Registry(ECR)의 [사용자 지정 컨테이너를 사용](braket-jobs-byoc.md)하도록 선택할 수 있습니다.

**참고**  
Python 3.12만 기본적으로 지원됩니다.

 `@hybrid_job` 데코레이터를 사용하여 함수에 주석을 달 수 있습니다. Braket은 데코레이터 내부의 코드를 Braket 하이브리드 작업 [알고리즘 스크립트](braket-jobs-first.md)로 변환합니다. 그런 다음 하이브리드 작업은 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-jobs-hyperparameters.md)로 자동으로 캡처합니다.

**참고**  
하이퍼파라미터는 Braket 콘솔에 문자열로 표시되며, 문자열은 2,500자로 제한됩니다.

**지표 및 로깅** 

`run_hybrid_job()` 함수 내에서 반복 알고리즘의 지표는 `log_metrics`를 사용하여 기록됩니다. 지표는 하이브리드 작업 탭 아래의 Braket 콘솔 페이지에 자동으로 플롯됩니다. [Braket 비용 추적기](braket-pricing.md)를 사용하면 하이브리드 작업 실행 중에 지표를 사용하여 거의 실시간으로 양자 작업 비용을 추적할 수 있습니다. 위 예제에서는 [결과 유형](braket-result-types.md)의 첫 번째 확률을 기록하는 지표 이름 “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
```

**로컬 모드** 

[로컬 작업](braket-jobs-local-mode.md)은 데코레이터에 인수 `local=True`를 추가하여 생성됩니다. 그러면 랩톱과 같은 로컬 컴퓨팅 환경의 컨테이너화된 환경에서 하이브리드 작업이 실행됩니다. 로컬 작업에는 양자 작업에 대한 우선순위 대기열이 **없습니다**. 다중 노드 또는 MPI와 같은 고급 사례의 경우 로컬 작업이 필요한 Braket 환경 변수에 액세스할 수 있습니다. 다음 코드는 디바이스를 SV1 시뮬레이터로 사용하여 로컬 하이브리드 작업을 생성합니다.

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

다른 모든 하이브리드 작업 옵션도 지원됩니다. 옵션 목록은 [braket.jobs.quantum\$1job\$1creation 모듈](https://amazon-braket-sdk-python.readthedocs.io/en/stable/_apidoc/braket.jobs.quantum_job_creation.html)을 참조하세요.

## 추가 Python 패키지 및 소스 코드 설치
<a name="install-python-packages-and-code"></a>

원하는 Python 패키지를 사용하도록 런타임 환경을 사용자 지정할 수 있습니다. `requirements.txt` 파일, 패키지 이름 목록을 사용하거나 [자체 컨테이너를 사용할 수 있습니다(BYOC)](braket-jobs-byoc.md). 예를 들어 `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 ...
```

## 하이브리드 작업 인스턴스에 데이터 저장 및 로드
<a name="save-load-data-into-instance"></a>

**입력 훈련 데이터 지정**

하이브리드 작업을 생성할 때 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)`을 사용하여 체크포인트에서를 로드합니다.

## 하이브리드 작업 데코레이터 모범 사례
<a name="best-practices"></a>

**비동기성 수용**

데코레이터 주석으로 생성된 하이브리드 작업은 비동기적입니다. 즉, 고전 리소스와 양자 리소스를 사용할 수 있게 되면 실행됩니다. Braket Management Console 또는 Amazon CloudWatch를 사용하여 알고리즘의 진행 상황을 모니터링합니다. 실행할 알고리즘을 제출하면 Braket은 확장 가능한 컨테이너화된 환경에서 해당 알고리즘을 실행하고 알고리즘이 완료되면 결과가 검색됩니다.

**반복 변분 알고리즘 실행**

하이브리드 작업은 반복적인 양자-고전 알고리즘을 실행할 수 있는 도구를 제공합니다. 순수하게 양자 문제인 경우 [양자 작업](braket-submit-tasks.md) 또는 [양자 작업 배치](braket-batching-tasks.md)를 사용합니다. 특정 QPU에 대한 우선 액세스는 중간에 고전적 처리를 수행하면서 QPU에 대한 여러 번의 반복 직접 호출을 필요로 하는 장기 실행 변분 알고리즘에 가장 유용합니다.

**로컬 모드를 사용한 디버깅**

QPU에서 하이브리드 작업을 실행하기 전에 먼저 시뮬레이터 SV1에서를 실행하여 예상대로 실행되는지 확인하는 것이 좋습니다. 소규모 테스트의 경우 빠른 반복 및 디버깅을 위해 로컬 모드로 실행할 수 있습니다.

**[BYOC(Bring Your Own Container)](braket-jobs-byoc.md)를 통한 재현성 향상**

컨테이너화된 환경 내에서 소프트웨어와 해당 종속성을 캡슐화하여 재현 가능한 실험을 생성합니다. 컨테이너에 모든 코드, 종속성 및 설정을 패키징하면 잠재적인 충돌 및 버전 관리 문제를 방지할 수 있습니다.

**다중 인스턴스 분산 시뮬레이터**

많은 수의 회로를 실행하려면 기본 제공 MPI 지원을 사용하여 단일 하이브리드 작업 내의 여러 인스턴스에서 로컬 시뮬레이터를 실행하는 것이 좋습니다. 자세한 내용은 [임베디드 시뮬레이터](pennylane-embedded-simulators.md)를 참조하세요.

**파라메트릭 회로 사용**

하이브리드 작업에서 제출하는 파라메트릭 회로는 [파라메트릭 컴파일](braket-jobs-parametric-compilation.md)을 사용하여 특정 QPU에서 자동으로 컴파일되어 알고리즘의 런타임을 개선합니다.

**주기적인 체크포인트**

장기 실행 하이브리드 작업의 경우 알고리즘의 중간 상태를 주기적으로 저장하는 것이 좋습니다.

**추가 예제, 사용 사례 및 모범 사례는 [Amazon Braket 예제 GitHub](https://github.com/amazon-braket/amazon-braket-examples)를 참조하세요.**

# 하이브리드 작업에 API 사용
<a name="braket-jobs-api"></a>

API를 사용하여 Amazon Braket Hybrid Jobs에 직접 액세스하고 상호 작용할 수 있습니다. 그러나 API를 직접 사용할 때는 기본값 및 편의 메서드를 사용할 수 없습니다.

**참고**  
[Amazon Braket Python SDK](https://github.com/aws/amazon-braket-sdk-python)를 사용하여 Amazon Braket Hybrid Jobs와 상호 작용하는 것이 좋습니다. 이 SDK는하이브리드 작업을 성공적으로 실행하는 데 도움이 되는 편의 기본값과 보호 기능을 제공합니다.

이 주제에서는 API 사용의 기본 사항을 다룹니다. API를 사용하기로 선택한 경우 이 접근 방식은 더 복잡할 수 있으며 하이브리드 작업이 실행되도록 하기 위해 여러 번의 반복에 대비해야 함을 염두에 두세요.

API를 사용하려면 계정에 `AmazonBraketFullAccess` 관리형 정책이 적용된 역할이 있어야 합니다.

**참고**  
`AmazonBraketFullAccess` 관리형 정책이 적용된 역할을 얻는 방법에 대한 자세한 내용은 [Amazon Braket 활성화](braket-enable-overview.md) 페이지를 참조하세요.

또한 **실행 역할**이 필요합니다. 이 역할은 서비스에 전달됩니다. **Amazon Braket 콘솔**을 사용하여 역할을 생성할 수 있습니다. **권한 및 설정** 페이지의 **실행 역할** 탭을 사용하여 하이브리드 작업에 대한 기본 역할을 생성합니다.

`CreateJob` API에서는 하이브리드 작업에 필요한 모든 파라미터를 지정해야 합니다. Python을 사용하려면 알고리즘 스크립트 파일을 input.tar.gz 파일과 같은 tar 번들로 압축하고 다음 스크립트를 실행합니다. 하이브리드 작업이 시작되는 경로, 파일 및 메서드를 지정하는 계정 정보 및 진입점과 일치하도록 꺾쇠 대괄호(`<>`) 안의 코드 부분을 업데이트합니다.

```
from braket.aws import AwsDevice, AwsSession
import boto3
from datetime import datetime

s3_client = boto3.client("s3")
client = boto3.client("braket")

project_name = "job-test"
job_name = project_name + "-" + datetime.strftime(datetime.now(), "%Y%m%d%H%M%S")
bucket = "amazon-braket-<your_bucket>"
s3_prefix = job_name

job_script = "input.tar.gz"
job_object = f"{s3_prefix}/script/{job_script}"
s3_client.upload_file(job_script, bucket, job_object)

input_data = "inputdata.csv"
input_object = f"{s3_prefix}/input/{input_data}"
s3_client.upload_file(input_data, bucket, input_object)

job = client.create_job(
    jobName=job_name,
    roleArn="arn:aws:iam::<your_account>:role/service-role/AmazonBraketJobsExecutionRole",  # https://docs.aws.amazon.com/braket/latest/developerguide/braket-manage-access.html#about-amazonbraketjobsexecution
    algorithmSpecification={
        "scriptModeConfig": {
            "entryPoint": "<your_execution_module>:<your_execution_method>",
            "containerImage": {"uri": "292282985366.dkr.ecr.us-west-1.amazonaws.com/amazon-braket-base-jobs:1.0-cpu-py37-ubuntu18.04"},   # Change to the specific region you are using
            "s3Uri": f"s3://{bucket}/{job_object}",
            "compressionType": "GZIP"
        }
    },
    inputDataConfig=[
        {
            "channelName": "hellothere",
            "compressionType": "NONE",
            "dataSource": {
                "s3DataSource": {
                    "s3Uri": f"s3://{bucket}/{s3_prefix}/input",
                    "s3DataType": "S3_PREFIX"
                }
            }
        }
    ],
    outputDataConfig={
        "s3Path": f"s3://{bucket}/{s3_prefix}/output"
    },
    instanceConfig={
        "instanceType": "ml.m5.large",
        "instanceCount": 1,
        "volumeSizeInGb": 1
    },
    checkpointConfig={
        "s3Uri":  f"s3://{bucket}/{s3_prefix}/checkpoints",
        "localPath": "/opt/omega/checkpoints"
    },
    deviceConfig={
        "priorityAccess": {
            "devices": [
                "arn:aws:braket:us-west-1::device/qpu/rigetti/Ankaa-3"
            ]
        }
    },
    hyperParameters={
        "hyperparameter key you wish to pass": "<hyperparameter value you wish to pass>",
    },
    stoppingCondition={
        "maxRuntimeInSeconds": 1200,
        "maximumTaskLimit": 10
    },
)
```

하이브리드 작업을 생성한 후에는 `GetJob` API 또는 콘솔을 통해 하이브리드 작업 세부 정보에 액세스할 수 있습니다. 이전 예제와 같이 `createJob` 코드를 실행한 Python 세션에서 하이브리드 작업 세부 정보를 가져오려면 다음 Python 명령을 사용합니다.

```
getJob = client.get_job(jobArn=job["jobArn"])
```

하이브리드 작업을 취소하려면 작업('JobArn')의 Amazon Resource Name을 사용하여 `CancelJob` API를 직접적으로 호출합니다.

```
cancelJob = client.cancel_job(jobArn=job["jobArn"])
```

`checkpointConfig` 파라미터를 사용하여 체크포인트를 `createJob` API의 일부로 지정할 수 있습니다.

```
    checkpointConfig = {
        "localPath" : "/opt/omega/checkpoints",
        "s3Uri": f"s3://{bucket}/{s3_prefix}/checkpoints"
    },
```

**참고**  
`checkpointConfig`의 localPath는 다음의 예약된 경로 `/opt/ml`, `/opt/braket`, `/tmp` 또는 `/usr/local/nvidia` 중 어느 것으로도 시작할 수 없습니다.

# 로컬 모드로 하이브리드 작업 생성 및 디버깅
<a name="braket-jobs-local-mode"></a>

새 하이브리드 알고리즘을 빌드할 때 로컬 모드를 사용하면 알고리즘 스크립트를 디버깅하고 테스트할 수 있습니다. 로컬 모드는 Amazon Braket Hybrid Jobs에서 사용하려는 코드를 실행할 수 있게 해주지만, 하이브리드 작업 실행을 위한 인프라 관리를 Braket에 의존하지 않아도 되는 기능입니다. 대신, Amazon Braket Notebook 인스턴스 또는 랩톱이나 데스크톱 컴퓨터와 같은 기본 클라이언트에서 로컬로 하이브리드 작업을 실행합니다.

로컬 모드에서는 여전히 양자 작업을 실제 디바이스로 전송할 수 있지만, 로컬 모드에서 실제 QPU를 대상으로 실행할 때 성능상의 이점을 얻을 수 없습니다.

로컬 모드를 사용하려면 프로그램 내 어디에서 발생하든, `LocalQuantumJob`을 `AwsQuantumJob`으로 수정합니다. 예를 들어 [첫 번째 하이브리드 작업 생성](braket-jobs-first.md)의 예제를 실행하려면 다음과 같이 코드에서 하이브리드 작업 스크립트를 편집합니다.

```
from braket.jobs.local import LocalQuantumJob

job = LocalQuantumJob.create(
    device="arn:aws:braket:::device/quantum-simulator/amazon/sv1",
    source_module="algorithm_script.py",
    entry_point="algorithm_script:start_here",
)
```

**참고**  
이 기능을 사용하려면 Amazon Braket 노트북에 이미 사전 설치되어 있는 Docker를 로컬 환경에 설치해야 합니다. Docker 설치 지침은 [Get Docker](https://docs.docker.com/get-started/get-docker/) 페이지에서 확인할 수 있습니다. 또한 모든 파라미터가 로컬 모드에서 지원되는 것은 아닙니다.

# 하이브리드 작업 취소
<a name="braket-jobs-cancel"></a>

비종료 상태에서 하이브리드 작업을 취소해야 할 수 있습니다. 콘솔에서 또는 코드를 사용하여 이 작업을 수행할 수 있습니다.

콘솔에서 하이브리드 작업을 취소하려면 **하이브리드 작업** 페이지에서 취소할 하이브리드 작업을 선택한 다음 **작업** 드롭다운 메뉴에서 **하이브리드 작업 취소**를 선택합니다.

![\[이름, 상태, 디바이스 정보 및 타임스탬프를 보여주는 4개의 작업이 있는 Amazon Braket Hybrid Jobs 테이블입니다. 작업 드롭다운에는 새 하이브리드 작업을 보거나, 취소하거나, 태그를 관리하는 옵션이 포함되어 있습니다.\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/images/braket-hybrid-cancel-job.png)


취소를 확인하려면 메시지가 표시될 때 입력 필드에 *cancel*를 입력한 다음 **확인**을 선택합니다.

![\[특정 작업을 취소하는 대화 상자로, 취소 프로세스에 대한 경고와 “cancel”를 입력하여 확인하는 텍스트 입력 필드가 있습니다.\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/images/braket-hybrid-cancel-job-confirm.png)


Braket Python SDK의 코드를 사용하여 하이브리드 작업을 취소하려면 `job_arn`을 사용하여 하이브리드 작업을 식별한 다음, 다음 코드에서와 같이 `cancel` 명령을 직접적으로 호출합니다.

```
job = AwsQuantumJob(arn=job_arn)
job.cancel()
```

이 `cancel` 명령은 고전 하이브리드 작업 컨테이너를 즉시 종료하며 아직 비종료 상태인 모든 관련 양자 작업을 취소하기 위한 작업을 실행합니다.

# 하이브리드 작업 사용자 지정
<a name="braket-jobs-customize"></a>

Amazon Braket은 하이브리드 작업 실행 방식을 사용자 지정하여 특정 요구 사항에 맞게 환경을 조정할 수 있는 여러 가지 방법을 제공합니다. 이 섹션에서는 알고리즘 스크립트 환경 정의부터 자체 컨테이너 사용(BYOC)에 이르기까지 하이브리드 작업을 사용자 지정하는 옵션을 살펴봅니다. 하이퍼파라미터를 사용하여 워크플로를 최적화하고 작업 인스턴스를 구성하며 파라메트릭 컴파일을 활용하여 성능을 개선하는 방법을 알아봅니다. 이러한 사용자 지정 기법은 Amazon Braket에서 하이브리드 양자 계산의 잠재력을 극대화하는 데 도움이 됩니다.

**Topics**
+ [알고리즘 스크립트의 환경 정의](braket-jobs-script-environment.md)
+ [하이퍼파라미터 사용](braket-jobs-hyperparameters.md)
+ [하이브리드 작업 인스턴스 구성](braket-jobs-configure-job-instance-for-script.md)
+ [파라메트릭 컴파일을 사용하여 하이브리드 작업 가속화](braket-jobs-parametric-compilation.md)

# 알고리즘 스크립트의 환경 정의
<a name="braket-jobs-script-environment"></a>

Amazon Braket은 알고리즘 스크립트의 컨테이너에서 정의한 환경을 지원합니다.
+ 기본 컨테이너(`image_uri`가 지정되지 않은 경우의 기본값)
+ CUDA-Q가 포함된 컨테이너
+ Tensorflow 및 PennyLane이 포함된 컨테이너
+ PyTorch, PennyLane 및 CUDA-Q가 포함된 컨테이너

다음 표에는 컨테이너와 컨테이너에 포함된 라이브러리에 대한 세부 정보가 나와 있습니다.


**Amazon Braket 컨테이너**  

| Type | 기본 | CUDA-Q | TensorFlow | PyTorch | 
| --- | --- | --- | --- | --- | 
|   **이미지 URI**   |  292282985366.dkr.ecr.us-west-2.amazonaws.com/amazon-braket-base-jobs:latest  |  292282985366.dkr.ecr.us-west-2.amazonaws.com/amazon-braket-cudaq-jobs:latest  |  292282985366.dkr.ecr.us-east-1.amazonaws.com/amazon-braket-tensorflow-jobs:latest  |  292282985366.dkr.ecr.us-west-2.amazonaws.com/amazon-braket-pytorch-jobs:latest  | 
|   **상속된 라이브러리**   |  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/braket-jobs-script-environment.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/braket-jobs-script-environment.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/braket-jobs-script-environment.html)  | 
|   **추가 라이브러리**   |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/braket-jobs-script-environment.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/braket-jobs-script-environment.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/braket-jobs-script-environment.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/braket/latest/developerguide/braket-jobs-script-environment.html)  | 

[aws/amazon-braket-containers](https://github.com/aws/amazon-braket-containers)에서 오픈 소스 컨테이너 정의를 보고 액세스할 수 있습니다. 사용 사례에 가장 적합한 컨테이너를 선택합니다. Braket에서 사용 가능한 AWS 리전(us-east-1, us-west-1, us-west-2, eu-north-1, eu-west-2)을 사용할 수 있지만 컨테이너 리전은 하이브리드 작업의 리전과 일치해야 합니다. 하이브리드 작업을 생성할 때 하이브리드 작업 스크립트의 `create(…​)` 직접 호출에 다음 세 인수 중 하나를 추가하여 컨테이너 이미지를 지정합니다. Amazon Braket 컨테이너는 인터넷 연결이 가능하므로 런타임(시작 또는 런타임 시 비용 발생) 시 선택한 컨테이너에 추가 종속성을 설치할 수 있습니다. 다음 예제는 us-west-2 리전에 대한 것입니다.
+  **기본 이미지:** image\$1uri="292282985366.dkr.ecr.us-west-2.amazonaws.com/amazon-braket-base-jobs:latest"
+  **CUDA-Q 이미지:** image\$1uri="292282985366.dkr.ecr.us-west-2.amazonaws.com/amazon-braket-cudaq-jobs:latest"
+  **Tensorflow 이미지:** image\$1uri="292282985366.dkr.ecr.us-west-2.amazonaws.com/amazon-braket-tensorflow-jobs:latest"
+  **PyTorch 이미지:** image\$1uri="292282985366.dkr.ecr.us-west-2.amazonaws.com/amazon-braket-pytorch-jobs:latest"

Amazon Braket SDK의 `retrieve_image()` 함수를 사용하여 `image-uris`를 검색할 수도 있습니다. 다음 예제에서는 us-west-2에서 검색하는 방법을 보여줍니다 AWS 리전.

```
from braket.jobs.image_uris import retrieve_image, Framework

image_uri_base = retrieve_image(Framework.BASE, "us-west-2")
image_uri_cudaq = retrieve_image(Framework.CUDAQ, "us-west-2")
image_uri_tf = retrieve_image(Framework.PL_TENSORFLOW, "us-west-2")
image_uri_pytorch = retrieve_image(Framework.PL_PYTORCH, "us-west-2")
```

# 자체 컨테이너 사용(Bring Your Own Container, BYOC)
<a name="braket-jobs-byoc"></a>

Amazon Braket Hybrid Jobs는 다양한 환경에서 코드를 실행하기 위해 사전 빌드된 세 개의 컨테이너를 제공합니다. 이러한 컨테이너 중 하나가 사용 사례를 지원하는 경우 하이브리드 작업을 생성할 때 알고리즘 스크립트만 제공하면 됩니다. 사소한 누락 종속성은 `pip`을 사용하여 알고리즘 스크립트 또는 `requirements.txt` 파일에서 추가할 수 있습니다.

이러한 컨테이너 중 사용 사례를 지원하는 컨테이너가 없거나 컨테이너를 확장하려는 경우 Braket Hybrid Jobs는 자체 사용자 지정 Docker 컨테이너 이미지로 하이브리드 작업을 실행하거나 자체 컨테이너를 사용(BYOC)할 수 있도록 지원합니다. 사용 사례에 적합한 기능인지 확인하세요.

**Topics**
+ [자체 컨테이너 사용이 올바른 결정인 시기는 언제인가요?](#bring-own-container-decision)
+ [자체 컨테이너 사용 방법](bring-own-container-recipe.md)
+ [자체 컨테이너에서 Braket 하이브리드 작업 실행](running-hybrid-jobs-in-own-container.md)

## 자체 컨테이너 사용이 올바른 결정인 시기는 언제인가요?
<a name="bring-own-container-decision"></a>

Braket Hybrid Jobs에서 자체 컨테이너를 사용(BYOC)하면 자체 소프트웨어를 패키지 환경에 설치하여 유연하게 사용할 수 있습니다. 특정 요구 사항에 따라, 전체 BYOC Docker 빌드 - Amazon ECR 업로드 - 사용자 지정 이미지 URI 주기를 거치지 않고도 동일한 유연성을 달성할 수 있는 방법이 있을 수 있습니다.

**참고**  
공개적으로 사용할 수 있는 소수의 추가 Python 패키지(일반적으로 10개 미만)를 추가하려는 경우 BYOC가 적합하지 않을 수 있습니다. 예를 들어 PyPi를 사용하는 경우입니다.

이 경우 사전 빌드된 Braket 이미지 중 하나를 사용한 다음, 작업 제출 시 소스 디렉터리에 `requirements.txt` 파일을 포함할 수 있습니다. 파일은 자동으로 읽히며 `pip`는 지정된 버전이 포함된 패키지를 정상적으로 설치합니다. 많은 수의 패키지를 설치하는 경우 해당 작업의 런타임이 크게 증가할 수 있습니다. 사용하려는 사전 빌드된 컨테이너의 Python 버전과 CUDA 버전(해당하는 경우)을 확인하여 소프트웨어가 작동하는지 테스트합니다.

작업 스크립트에 비Python 언어(예: C\$1\$1 또는 Rust)를 사용하거나 Braket 사전 빌드 컨테이너를 통해 제공되지 않는 Python 버전을 사용하려는 경우 BYOC가 필요합니다. 이는 다음과 같은 경우에도 좋은 선택입니다.
+ 라이선스 키와 함께 소프트웨어를 사용 중이며 소프트웨어를 실행하려면 라이선스 서버에 대해 해당 키를 인증해야 합니다. BYOC를 사용하면 Docker 이미지에 라이선스 키를 임베드하고 이를 인증하는 코드를 포함할 수 있습니다.
+ 공개적으로 사용할 수 없는 소프트웨어를 사용하고 있습니다. 예를 들어, 소프트웨어가 특정 SSH 키가 있어야 액세스할 수 있는 비공개 GitLab 또는 GitHub 리포지토리에 호스팅되는 경우입니다.
+ Braket 제공 컨테이너에 패키징되지 않은 대규모 소프트웨어 제품군을 설치해야 합니다. BYOC를 사용하면 소프트웨어 설치로 인해 하이브리드 작업 컨테이너의 시작 시간이 길어지는 문제를 해결할 수 있습니다.

또한 BYOC를 사용하면 소프트웨어로 Docker 컨테이너를 빌드하여 사용자에게 제공함으로써 고객이 사용자 지정 SDK 또는 알고리즘을 사용하도록 할 수 있습니다. Amazon ECR에서 적절한 권한을 설정하여 이 작업을 수행할 수 있습니다.

**참고**  
해당하는 모든 소프트웨어 라이선스를 준수해야 합니다.

# 자체 컨테이너 사용 방법
<a name="bring-own-container-recipe"></a>

이 섹션에서는 Braket Hybrid Jobs에 bring your own container (BYOC)를 적용하는 데 필요한 사항, 즉 스크립트, 파일 및 이를 결합하여 사용자 지정 Docker 이미지를 시작하고 실행하는 단계에 대한 단계별 가이드를 제공합니다. 두 가지 일반적인 사례에 대한 방법:

1. Docker 이미지에 추가 소프트웨어를 설치하고 해당 작업에 Python 알고리즘 스크립트만 사용합니다.

1. 하이브리드 작업 또는 x86 이외의 CPU 아키텍처와 함께 비Python 언어로 작성된 알고리즘 스크립트를 사용합니다.

*컨테이너 항목 스크립트* 정의는 두 번째 사례에서 더 복잡합니다.

Braket은 하이브리드 작업을 실행할 때 요청된 수와 유형의 Amazon EC2 인스턴스를 시작한 다음, 이미지 URI 입력으로 지정된 Docker 이미지를 실행하여 해당 인스턴스에서 작업을 생성합니다. BYOC 기능을 사용할 때는 읽기 액세스 권한이 있는 [비공개 Amazon ECR 리포지토리](https://docs.aws.amazon.com/AmazonECR/latest/userguide/Repositories.html)에 호스팅된 이미지 URI를 지정합니다. Braket Hybrid Jobs는 해당 사용자 지정 이미지를 사용하여 작업을 실행합니다.

하이브리드 작업과 함께 사용할 수 있는 Docker 이미지를 빌드하는 데 필요한 특정 구성 요소입니다. `Dockerfiles` 작성 및 빌드에 익숙하지 않은 경우 [Dockerfile 설명서](https://docs.docker.com/reference/dockerfile/) 및 [Amazon ECR CLI 설명서](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html)를 참조하세요.

**Topics**
+ [Dockerfile의 기본 이미지](#base-image-dockerfile)
+ [(선택 사항) 수정된 컨테이너 진입점 스크립트](#modified-container-entry-point)
+ [`Dockerfile`을 사용하여 필요한 소프트웨어 및 컨테이너 스크립트 설치](#install-docketfile)

## Dockerfile의 기본 이미지
<a name="base-image-dockerfile"></a>

Python을 사용 중이고 Braket 제공 컨테이너에 제공된 것 외에도 추가로 소프트웨어를 설치하려는 경우, 기본 이미지에 대한 옵션은 [GitHub 리포지토리](https://github.com/amazon-braket/amazon-braket-containers)와 Amazon ECR에 호스팅된 Braket 컨테이너 이미지 중 하나입니다. 이미지를 가져와 이를 기반으로 빌드하려면 [Amazon ECR에 인증](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html#cli-authenticate-registry)해야 합니다. 예를 들어 BYOC Docker 파일의 첫 번째 줄은 다음과 같을 수 있습니다. `FROM [IMAGE_URI_HERE]` 

다음으로, Dockerfile의 나머지 부분을 채워 컨테이너에 추가하려는 소프트웨어를 설치하고 설정합니다. 사전 빌드된 Braket 이미지에는 이미 적절한 컨테이너 진입점 스크립트가 포함되어 있으므로 이를 포함하는 것에 대해 걱정할 필요가 없습니다.

C\$1\$1, Rust 또는 Julia와 같은 비Python 언어를 사용하거나 ARM과 같은 비x86 CPU 아키텍처용 이미지를 빌드하려는 경우 기본 공개 이미지를 기반으로 빌드해야 할 수 있습니다. 이러한 이미지는 [Amazon Elastic Container Registry Public Gallery](https://gallery.ecr.aws/)에서 찾을 수 있습니다. CPU 아키텍처에 적합한 아키텍처와 필요시 사용하려는 GPU를 선택해야 합니다.

## (선택 사항) 수정된 컨테이너 진입점 스크립트
<a name="modified-container-entry-point"></a>

**참고**  
사전 빌드된 Braket 이미지에 추가 소프트웨어만 추가하는 경우 이 섹션을 건너뛸 수 있습니다.

하이브리드 작업의 일부로 비Python 코드를 실행하려면 컨테이너 진입점을 정의하는 Python 스크립트를 수정합니다. 예를 들면, [`braket_container.py` Amazon Braket Github의 python 스크립트](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py)입니다. 이는 Braket이 사전 빌드한 이미지가 알고리즘 스크립트를 실행하고 적절한 환경 변수를 설정하는 데 사용하는 스크립트입니다. 컨테이너 진입점 스크립트 자체는 Python으로 작성**되어야** 하지만, 비Python 스크립트를 실행할 수 있습니다. 사전 빌드된 예제에서 볼 수 있듯이, Python 알고리즘 스크립트는 [Python 하위 프로세스](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L274) 또는 [완전히 새로운 프로세스](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L257)로 실행됩니다. 이 논리를 수정하면 진입점 스크립트가 비Python 알고리즘 스크립트를 실행하도록 할 수 있습니다. 예를 들어, 파일 확장자 끝에 따라 Rust 프로세스를 실행하도록 [https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L139](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L139) 함수를 수정할 수 있습니다.

완전히 새로운 `braket_container.py`를 작성하도록 선택할 수도 있습니다. 입력 데이터, 소스 아카이브 및 기타 필요한 파일을 Amazon S3에서 컨테이너로 복사하고 적절한 환경 변수를 정의해야 합니다.

## `Dockerfile`을 사용하여 필요한 소프트웨어 및 컨테이너 스크립트 설치
<a name="install-docketfile"></a>

**참고**  
사전 빌드된 Braket 이미지를 Docker 기본 이미지로 사용하는 경우 컨테이너 스크립트가 이미 있습니다.

이전 단계에서 수정된 컨테이너 스크립트를 생성한 경우 컨테이너에 이를 복사**하고** 환경 변수 `SAGEMAKER_PROGRAM`을 `braket_container.py`로 정의하거나 새 컨테이너 진입점 스크립트에 지정한 이름으로 정의해야 합니다.

다음은 GPU 가속 작업 인스턴스에서 Julia를 사용할 수 있게 하는 `Dockerfile`의 예제입니다.

```
FROM nvidia/cuda:12.2.0-devel-ubuntu22.04

    
 ARG DEBIAN_FRONTEND=noninteractive
 ARG JULIA_RELEASE=1.8
 ARG JULIA_VERSION=1.8.3


 ARG PYTHON=python3.11 
 ARG PYTHON_PIP=python3-pip
 ARG PIP=pip


 ARG JULIA_URL = https://julialang-s3.julialang.org/bin/linux/x64/${JULIA_RELEASE}/
 ARG TAR_NAME = julia-${JULIA_VERSION}-linux-x86_64.tar.gz


 ARG PYTHON_PKGS = # list your Python packages and versions here


 RUN curl -s -L ${JULIA_URL}/${TAR_NAME} | tar -C /usr/local -x -z --strip-components=1 -f -


 RUN apt-get update \

    && apt-get install -y --no-install-recommends \

    build-essential \

    tzdata \

    openssh-client \

    openssh-server \

    ca-certificates \

    curl \

    git \

    libtemplate-perl \

    libssl1.1 \

    openssl \

    unzip \ 

    wget \

    zlib1g-dev \

    ${PYTHON_PIP} \

    ${PYTHON}-dev \




 RUN ${PIP} install --no-cache --upgrade ${PYTHON_PKGS}


 RUN ${PIP} install --no-cache --upgrade sagemaker-training==4.1.3


 # Add EFA and SMDDP to LD library path
 ENV LD_LIBRARY_PATH="/opt/conda/lib/python${PYTHON_SHORT_VERSION}/site-packages/smdistributed/dataparallel/lib:$LD_LIBRARY_PATH"
 ENV LD_LIBRARY_PATH=/opt/amazon/efa/lib/:$LD_LIBRARY_PATH


 # Julia specific installation instructions
 COPY Project.toml /usr/local/share/julia/environments/v${JULIA_RELEASE}/
 RUN JULIA_DEPOT_PATH=/usr/local/share/julia \

    julia -e 'using Pkg; Pkg.instantiate(); Pkg.API.precompile()'
 # generate the device runtime library for all known and supported devices
 RUN JULIA_DEPOT_PATH=/usr/local/share/julia \

    julia -e 'using CUDA; CUDA.precompile_runtime()'


 # Open source compliance scripts
 RUN HOME_DIR=/root \

 && curl -o ${HOME_DIR}/oss_compliance.zip https://aws-dlinfra-utilities.s3.amazonaws.com/oss_compliance.zip \

 && unzip ${HOME_DIR}/oss_compliance.zip -d ${HOME_DIR}/ \

 && cp ${HOME_DIR}/oss_compliance/test/testOSSCompliance /usr/local/bin/testOSSCompliance \

 && chmod +x /usr/local/bin/testOSSCompliance \

 && chmod +x ${HOME_DIR}/oss_compliance/generate_oss_compliance.sh \

 && ${HOME_DIR}/oss_compliance/generate_oss_compliance.sh ${HOME_DIR} ${PYTHON} \

 && rm -rf ${HOME_DIR}/oss_compliance*


 # Copying the container entry point script
 COPY braket_container.py /opt/ml/code/braket_container.py
 ENV SAGEMAKER_PROGRAM braket_container.py
```

이 예제에서는 모든 관련 오픈 소스 라이선스를 준수하기 AWS 위해에서 제공하는 스크립트를 다운로드하고 실행합니다. 예를 들어, MIT license에 의해 관리되는 모든 설치된 코드를 적절하게 속성화합니다.

비공개 코드(예: 비공개 GitHub 또는 GitLab 리포지토리에 호스팅된 코드)를 포함해야 하는 경우, 해당 코드에 액세스하기 위해 SSH 키를 Docker 이미지에 임베드하지 **마세요**. 대신, 빌드할 때 Docker Compose를 사용하여 Docker가 빌드된 호스트 시스템에서 SSH에 액세스할 수 있도록 허용합니다. 자세한 내용은 [비공개 GitHub 리포지토리에 액세스하기 위해 Docker에서 SSH 키를 안전하게 사용하는 방법](https://www.fastruby.io/blog/docker/docker-ssh-keys.html) 가이드를 참조하세요.

**Docker 이미지 빌드 및 업로드**

`Dockerfile`이 올바르게 정의되었으므로, 이제 다음 단계에 따라 [비공개 Amazon ECR 리포지토리를 생성](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-create.html)할 준비가 되었습니다(아직 없는 경우). 컨테이너 이미지를 빌드하고 태그를 지정하여 리포지토리에 업로드할 수도 있습니다.

이미지를 빌드, 태그 지정 및 푸시할 준비가 되었습니다. `docker build`에 대한 옵션의 자세한 설명과 몇 가지 예제는 [Docker 빌드 설명서](https://docs.docker.com/reference/cli/docker/buildx/build/)를 참조하세요.

위에 정의된 샘플 파일의 경우 다음을 실행할 수 있습니다.

```
aws ecr get-login-password --region ${your_region} | docker login --username AWS --password-stdin ${aws_account_id}.dkr.ecr.${your_region}.amazonaws.com
 docker build -t braket-julia .
 docker tag braket-julia:latest ${aws_account_id}.dkr.ecr.${your_region}.amazonaws.com/braket-julia:latest
 docker push ${aws_account_id}.dkr.ecr.${your_region}.amazonaws.com/braket-julia:latest
```

**적절한 Amazon ECR 권한 할당**

Braket Hybrid Jobs Docker 이미지는 비공개 Amazon ECR 리포지토리에 호스팅되어야 합니다. 기본적으로 비공개 Amazon ECR 리포지토리는 Braket Hybrid Jobs IAM role 또는 공동 작업자나 학생 등 해당 이미지를 사용하려는 다른 사용자에게 읽기 액세스 권한을 제공하지 **않습니다**. 적절한 권한을 부여하려면 [리포지토리 정책을 설정](https://docs.aws.amazon.com/AmazonECR/latest/userguide/set-repository-policy.html)해야 합니다. 일반적으로, 이미지에 액세스하려는 특정 사용자와 IAM 역할에만 권한을 부여하고, image URI를 가진 사람 누구나 이미지를 가져오는 것을 허용하지 마세요.

# 자체 컨테이너에서 Braket 하이브리드 작업 실행
<a name="running-hybrid-jobs-in-own-container"></a>

자체 컨테이너로 하이브리드 작업을 생성하려면 지정된 인수 `image_uri`로 `AwsQuantumJob.create()`를 직접적으로 호출합니다. QPU, 온디맨드 시뮬레이터를 사용하거나 Braket Hybrid Jobs에서 사용할 수 있는 고전 프로세서에서 로컬로 코드를 실행할 수 있습니다. 실제 QPU에서 실행하기 전에 SV1, DM1 또는 TN1과 같은 시뮬레이터에서 코드를 테스트하는 것이 좋습니다.

고전 프로세서에서 코드를 실행하려면 `InstanceConfig`를 업데이트하여 사용하는 `instanceType` 및 `instanceCount`를 지정합니다. `instance_count` > 1을 지정하는 경우 코드가 여러 호스트에서 실행될 수 있는지 확인해야 합니다. 선택할 수 있는 인스턴스 수의 상한은 5입니다. 예제:

```
job = AwsQuantumJob.create(
    source_module="source_dir",
    entry_point="source_dir.algorithm_script:start_here",
    image_uri="111122223333.dkr.ecr.us-west-2.amazonaws.com/my-byoc-container:latest",
    instance_config=InstanceConfig(instanceType="ml.g4dn.xlarge", instanceCount=3),
    device="local:braket/braket.local.qubit",
    # ...)
```

**참고**  
디바이스 ARN을 사용하여 하이브리드 작업 메타데이터로 사용한 시뮬레이터를 추적합니다. 허용되는 값은 형식 `device = "local:<provider>/<simulator_name>"`을 따라야 합니다. `<provider>` 및 `<simulator_name>`은 문자, 숫자, `_`, `-`, `.`으로만 구성되어야 합니다. 문자열은 256자로 제한됩니다.  
BYOC를 사용할 계획이고 Braket SDK를 사용하여 양자 작업을 생성하지 않는 경우 환경 변수 `AMZN_BRAKET_JOB_TOKEN`의 값을 `CreateQuantumTask` 요청의 `jobToken` 파라미터에 전달해야 합니다. 그렇지 않으면 양자 작업에 우선순위가 부여되지 않으며 일반 독립 실행형 양자 작업으로 청구됩니다.

# 하이퍼파라미터 사용
<a name="braket-jobs-hyperparameters"></a>

하이브리드 작업을 생성할 때 학습률 또는 단계 크기와 같이 알고리즘에 필요한 하이퍼파라미터를 정의할 수 있습니다. 하이퍼파라미터 값은 일반적으로 알고리즘의 다양한 측면을 제어하는 데 사용되며 알고리즘의 성능을 최적화하기 위해 조정되는 경우가 많습니다. Braket 하이브리드 작업에서 하이퍼파라미터를 사용하려면 이름과 값을 딕셔너리로 명시적으로 지정해야 합니다. 최적의 값 집합을 검색할 때 테스트할 하이퍼파라미터 값을 지정합니다. 하이퍼파라미터를 사용하기 위한 첫 번째 단계는 하이퍼파라미터를 딕셔너리로 설정하고 정의하는 것이며, 이는 다음 코드에서 확인할 수 있습니다.

```
from braket.devices import Devices

device_arn = Devices.Amazon.SV1

hyperparameters = {"shots": 1_000}
```

그런 다음 위에 제공된 코드 조각에 정의된 하이퍼파라미터를 전달하여 원하는 알고리즘에 사용합니다. 다음 코드 예제를 실행하려면 하이퍼파라미터 파일과 동일한 경로에 “src”라는 디렉터리를 생성합니다. "src" 디렉터리 내에 [0\$1Getting\$1started\$1papermill.ipynb](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/7_Running_notebooks_as_hybrid_jobs/src/0_Getting_started_papermill.ipynb), [notebook\$1runner.py](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/7_Running_notebooks_as_hybrid_jobs/src/notebook_runner.py) 및 [requirements.txt](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/7_Running_notebooks_as_hybrid_jobs/src/requirements.txt) 코드 파일을 추가합니다.

```
import time
from braket.aws import AwsQuantumJob

job = AwsQuantumJob.create(
    device=device_arn,
    source_module="src",
    entry_point="src.notebook_runner:run_notebook",
    input_data="src/0_Getting_started_papermill.ipynb",
    hyperparameters=hyperparameters,
    job_name=f"papermill-job-demo-{int(time.time())}",
)

# Print job to record the ARN
print(job)
```

하이브리드 작업 스크립트 *내에서* 하이퍼파라미터에 액세스하려면 [notebook\$1runner.py](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/7_Running_notebooks_as_hybrid_jobs/src/notebook_runner.py) python 파일의 `load_jobs_hyperparams()` 함수를 참조하세요. 하이브리드 작업 스크립트 *외부*에서 하이퍼파라미터에 액세스하려면 다음 코드를 실행합니다.

```
from braket.aws import AwsQuantumJob

# Get the job using the ARN
job_arn = "arn:aws:braket:us-east-1:111122223333:job/5eabb790-d3ff-47cc-98ed-b4025e9e296f"  # Replace with your job ARN
job = AwsQuantumJob(arn=job_arn)

# Access the hyperparameters
job_metadata = job.metadata()
hyperparameters = job_metadata.get("hyperParameters", {})
print(hyperparameters)
```

하이퍼파라미터 사용 방법에 대한 자세한 내용은 [Amazon Braket Hybrid Jobs와 PennyLane을 활용한 QAOA](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/2_Using_PennyLane_with_Braket_Hybrid_Jobs/Using_PennyLane_with_Braket_Hybrid_Jobs.ipynb) 및 [Amazon Braket Hybrid Jobs에서의 양자 기계 학습](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/1_Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs/Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs.ipynb) 자습서를 참조하세요.

# 하이브리드 작업 인스턴스 구성
<a name="braket-jobs-configure-job-instance-for-script"></a>

알고리즘에 따라 요구 사항이 다를 수 있습니다. 기본적으로 Amazon Braket은 `ml.m5.large` 인스턴스에서 알고리즘 스크립트를 실행합니다. 그러나 다음 가져오기 및 구성 인수를 사용하여 하이브리드 작업을 생성할 때 이 인스턴스 유형을 사용자 지정할 수 있습니다.

```
from braket.jobs.config import InstanceConfig

job = AwsQuantumJob.create(
    ...
    instance_config=InstanceConfig(instanceType="ml.g4dn.xlarge"), # Use NVIDIA T4 instance with 4 GPUs.
    ...
    ),
```

임베디드 시뮬레이션을 실행 중이고 디바이스 구성에서 로컬 디바이스를 지정한 경우, `instanceCount`를 지정하고 둘 이상으로 설정하여 `InstanceConfig`에서 둘 이상의 인스턴스를 추가로 요청할 수 있습니다. 상한은 5입니다. 예를 들어 다음과 같이 인스턴스 3개를 선택할 수 있습니다.

```
from braket.jobs.config import InstanceConfig
job = AwsQuantumJob.create(
    ...
    instance_config=InstanceConfig(instanceType="ml.g4dn.xlarge", instanceCount=3), # Use 3 NVIDIA T4 instances
    ...
    ),
```

여러 인스턴스를 사용하는 경우 데이터 병렬 기능을 사용하여 하이브리드 작업을 배포하는 것이 좋습니다. 이 [QML을 위한 병렬화 훈련](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/5_Parallelize_training_for_QML/Parallelize_training_for_QML.ipynb) 예제를 확인하는 방법에 대한 자세한 내용은 다음 예제 노트북을 참조하세요.

다음 세 개의 표에는 표준, 고성능 및 GPU 가속 인스턴스에 사용할 수 있는 인스턴스 유형과 사양이 나와 있습니다.

**참고**  
하이브리드 작업에 대한 기본 고전 컴퓨팅 인스턴스 할당량을 보려면 [Amazon Braket 할당량](braket-quotas.md) 페이지를 참조하세요.


| 표준 인스턴스 | vCPU | 메모리(GiB) | 
| --- | --- | --- | 
|  ml.m5.large(기본값)  |  4  |  16  | 
|  ml.m5.xlarge  |  4  |  16  | 
|  ml.m5.2xlarge  |  8  |  32  | 
|  ml.m5.4xlarge  |  16  |  64  | 
|  ml.m5.12xlarge  |  48  |  192  | 
|  ml.m5.24xlarge  |  96  |  384  | 


| 고성능 인스턴스 | vCPU | 메모리(GiB) | 
| --- | --- | --- | 
|  ml.c5.xlarge  |  4  |  8  | 
|  ml.c5.2xlarge  |  8  |  16  | 
|  ml.c5.4xlarge  |  16  |  32  | 
|  ml.c5.9xlarge  |  36  |  72  | 
|  ml.c5.18xlarge  |  72  |  144  | 
|  ml.c5n.xlarge  |  4  |  10.5  | 
|  ml.c5n.2xlarge  |  8  |  21  | 
|  ml.c5n.4xlarge  |  16  |  32  | 
|  ml.c5n.9xlarge  |  36  |  72  | 
|  ml.c5n.18xlarge  |  72  |  192  | 


| GPU 가속 인스턴스 | GPU | vCPU | 메모리(GiB) | GPU 메모리(GiB) | 
| --- | --- | --- | --- | --- | 
|  ml.p4d.24xlarge  |  8  |  96  |  1152  |  320  | 
|  ml.g4dn.xlarge  |  1  |  4  |  16  |  16  | 
|  ml.g4dn.2xlarge  |  1  |  8  |  32  |  16  | 
|  ml.g4dn.4xlarge  |  1  |  16  |  64  |  16  | 
|  ml.g4dn.8xlarge  |  1  |  32  |  128  |  16  | 
|  ml.g4dn.12xlarge  |  4  |  48  |  192  |  64  | 
|  ml.g4dn.16xlarge  |  1  |  64  |  256  |  16  | 

각 인스턴스는 30GB의 기본 데이터 스토리지(SSD) 구성을 사용합니다. 그러나 `instanceType`을 구성하는 것과 동일한 방식으로 스토리지를 조정할 수 있습니다. 다음 예제에서는 총 스토리지를 50GB로 늘리는 방법을 보여줍니다.

```
from braket.jobs.config import InstanceConfig

job = AwsQuantumJob.create(
    ...
    instance_config=InstanceConfig(
        instanceType="ml.g4dn.xlarge",
        volumeSizeInGb=50,
    ),
    ...
    ),
```

## `AwsSession`에서 기본 버킷 구성
<a name="braket-jobs-configure-default-bucket"></a>

자체 `AwsSession` 인스턴스를 활용하면 기본 Amazon S3 버킷의 사용자 지정 위치를 지정하는 등 향상된 유연성을 누릴 수 있습니다. 기본적으로 `AwsSession`에는 `"amazon-braket-{id}-{region}"`의 사전 구성된 Amazon S3 버킷 위치가 있습니다. 그러나 `AwsSession`을 생성할 때 기본 Amazon S3 버킷 위치를 재정의할 수 있는 옵션이 있습니다. 다음 코드 예제에서 볼 수 있듯이, 사용자는 `aws_session` 파라미터를 제공하여 선택적으로 `AwsSession` 객체를 `AwsQuantumJob.create()` 메서드로 전달할 수 있습니다.

```
aws_session = AwsSession(default_bucket="amazon-braket-s3-demo-bucket")

# Then you can use that AwsSession when creating a hybrid job
job = AwsQuantumJob.create(
    ...
    aws_session=aws_session
)
```

# 파라메트릭 컴파일을 사용하여 하이브리드 작업 가속화
<a name="braket-jobs-parametric-compilation"></a>

 Amazon Braket은 특정 QPU에서 파라메트릭 컴파일을 지원합니다. 따라서 하이브리드 알고리즘의 모든 반복에 대해 회로를 한 번만 컴파일하여 계산 비용이 많이 드는 컴파일 단계와 관련된 오버헤드를 줄일 수 있습니다. 각 단계에서 회로를 다시 컴파일할 필요가 없으므로 하이브리드 작업의 런타임이 크게 향상됩니다. 파라미터화된 회로를 Braket Hybrid Job으로 지원되는 QPU 중 하나에 제출하기만 하면 됩니다. 장기 실행 하이브리드 작업의 경우, Braket은 회로를 컴파일할 때 하드웨어 공급자의 업데이트된 보정 데이터를 자동으로 사용하여 최고 품질의 결과를 보장합니다.

파라메트릭 회로를 생성하려면 먼저 알고리즘 스크립트에 파라미터를 입력으로 제공해야 합니다. 이 예제에서는 작은 파라미터 회로를 사용하고 각 반복 사이의 모든 고전적 처리를 무시합니다. 일반적인 워크로드의 경우 여러 회로를 일괄적으로 제출하고 각 반복에서 파라미터를 업데이트하는 등의 고전적 처리를 수행합니다.

```
import os

from braket.aws import AwsDevice
from braket.circuits import Circuit, FreeParameter

def start_here():

    print("Test job started.")

    # Use the device declared in the job script
    device = AwsDevice(os.environ["AMZN_BRAKET_DEVICE_ARN"])

    circuit = Circuit().rx(0, FreeParameter("theta"))
    parameter_list = [0.1, 0.2, 0.3]
    
    for parameter in parameter_list:
        result = device.run(circuit, shots=1000, inputs={"theta": parameter})

    print("Test job completed.")
```

다음 작업 스크립트를 사용하여 하이브리드 작업으로 실행할 알고리즘 스크립트를 제출할 수 있습니다. 파라메트릭 컴파일을 지원하는 QPU에서 하이브리드 작업을 실행할 때 회로는 첫 번째 실행 시에만 컴파일됩니다. 다음 실행에서는 컴파일된 회로가 재사용되므로 추가 코드 줄 없이 하이브리드 작업의 런타임 성능이 향상됩니다.

```
from braket.aws import AwsQuantumJob

job = AwsQuantumJob.create(
    device=device_arn,
    source_module="algorithm_script.py",
)
```

**참고**  
파라메트릭 컴파일은 펄스 레벨 프로그램을 제외한 Rigetti Computing의 모든 초전도 게이트 기반 QPU에서 지원됩니다.

# Amazon Braket에서 PennyLane 사용
<a name="hybrid"></a>

하이브리드 알고리즘은 고전 명령과 양자 명령을 모두 포함하는 알고리즘입니다. 고전 명령은 고전 하드웨어(EC2 인스턴스 또는 랩톱)에서 실행되고 양자 명령은 시뮬레이터 또는 양자 컴퓨터에서 실행됩니다. 하이브리드 작업 기능을 사용하여 하이브리드 알고리즘을 실행하는 것이 좋습니다. 자세한 내용은 [Amazon Braket Jobs를 사용해야 하는 시점](braket-jobs.md#braket-jobs-use)을 참조하세요.

Amazon Braket을 사용하면 **Amazon Braket PennyLane 플러그인**의 지원 또는 **Amazon Braket Python SDK** 및 예제 노트북 리포지토리를 통해 하이브리드 양자 알고리즘을 설정하고 실행할 수 있습니다. SDK를 기반으로 하는 Amazon Braket 예제 노트북을 사용하면 PennyLane 플러그인 없이 특정 하이브리드 알고리즘을 설정하고 실행할 수 있습니다. 그러나 PennyLane은 더 풍부한 경험을 제공하므로 PennyLane을 사용하는 것이 좋습니다.

 **하이브리드 양자 알고리즘 정보** 

하이브리드 양자 알고리즘은 오늘날 산업계에 중요합니다. 현대 양자 컴퓨팅 디바이스는 일반적으로 노이즈를 생성하고 이로 인해 오류가 발생하기 때문입니다. 계산에 양자 게이트를 추가할 때마다 노이즈가 추가될 가능성이 커지며, 따라서 장기 실행 알고리즘은 노이즈에 압도되어 잘못된 계산을 초래할 수 있습니다.

Shor's[(양자 위상 추정 예제)](https://github.com/amazon-braket/amazon-braket-examples/tree/main/examples/advanced_circuits_algorithms/Quantum_Phase_Estimation) 또는 Grover's[(Grover 예제)](https://github.com/aws/amazon-braket-examples/tree/main/examples/advanced_circuits_algorithms/Grover)와 같은 순수 양자 알고리즘에는 수천, 수백만 회의 연산이 필요합니다. 이러한 이유로, 일반적으로 *노이즈가 많은 중간 규모 양자* (NISQ) 디바이스라고 하는 기존 양자 디바이스에는 실용적이지 않을 수 있습니다.

하이브리드 양자 알고리즘에서 QPU는 고전 CPU의 공동 프로세서로 작동하여, 특히 고전적 알고리즘에서 특정 계산 속도를 높입니다. 회로 실행 시간이 현저히 단축되어 오늘날 디바이스의 성능에 도달할 수 있게 되었습니다.

**Topics**
+ [PennyLane을 지원하는 Amazon Braket](#pennylane-option)
+ [Amazon Braket 예제 노트북의 하이브리드 알고리즘](#braket-hybrid-workflow)
+ [PennyLane 시뮬레이터가 임베디드된 하이브리드 알고리즘](#hybrid-alorithms-pennylane)
+ [Amazon Braket 시뮬레이터를 사용한 PennyLane의 수반 기울기](#adjoint-gradient-pennylane)
+ [하이브리드 작업 및 PennyLane을 사용하여 QAOA 알고리즘 실행](braket-jobs-run-qaoa-algorithm.md)
+ [PennyLane 임베디드 시뮬레이터를 사용한 하이브리드 워크로드 실행](pennylane-embedded-simulators.md)

## PennyLane을 지원하는 Amazon Braket
<a name="pennylane-option"></a>

Amazon Braket은 *양자 미분 프로그래밍* 개념을 기반으로 빌드된 오픈 소스 소프트웨어 프레임워크인 [PennyLane](https://pennylane.ai)에 대한 지원을 제공합니다. 이 프레임워크를 사용하면 양자 화학, 양자 기계 학습, 최적화 분야의 계산 문제에 대한 해법을 찾기 위해 신경망을 훈련시키는 것과 동일한 방식으로 양자 회로를 훈련시킬 수 있습니다.

PennyLane 라이브러리는 PyTorch 및 TensorFlow를 비롯한 친숙한 기계 학습 도구에 대한 인터페이스를 제공하여 양자 회로 훈련을 빠르고 직관적으로 수행할 수 있게 합니다.
+  **PennyLane 라이브러리** -- PennyLane은 Amazon Braket 노트북에 사전 설치되어 있습니다. PennyLane에서 Amazon Braket 디바이스에 액세스하려면 노트북을 열고 다음 명령을 사용하여 PennyLane 라이브러리를 가져옵니다.

```
import pennylane as qml
```

자습서 노트북을 사용하면 빠르게 시작할 수 있습니다. 또는 원하는 IDE에서 Amazon Braket의 PennyLane을 사용할 수 있습니다.
+  **Amazon Braket PennyLane 플러그인** — 자체 IDE를 사용하려면 Amazon Braket PennyLane 플러그인을 수동으로 설치할 수 있습니다. 플러그인은 PennyLane을 [Amazon Braket Python SDK](https://github.com/aws/amazon-braket-sdk-python)와 연결하므로 Amazon Braket 디바이스의 PennyLane에서 회로를 실행할 수 있습니다. PennyLane 플러그인을 설치하려면 다음 명령을 사용합니다.

```
pip install amazon-braket-pennylane-plugin
```

다음 예제에서는 PennyLane에서 Amazon Braket 디바이스에 대한 액세스를 설정하는 방법을 보여줍니다.

```
# to use SV1
import pennylane as qml
sv1 = qml.device("braket.aws.qubit", device_arn="arn:aws:braket:::device/quantum-simulator/amazon/sv1", wires=2)

# to run a circuit:
@qml.qnode(sv1)
def circuit(x):
    qml.RZ(x, wires=0)
    qml.CNOT(wires=[0,1])
    qml.RY(x, wires=1)
    return qml.expval(qml.PauliZ(1))

result = circuit(0.543)


#To use the local sim:
local = qml.device("braket.local.qubit", wires=2)
```

PennyLane에 대한 자습서 예제와 자세한 내용은 [Amazon Braket 예제 리포지토리](https://github.com/aws/amazon-braket-examples/tree/main/examples/pennylane)를 참조하세요.

Amazon Braket PennyLane 플러그인을 사용하면 단 한 줄의 코드로 PennyLane에서 Amazon Braket QPU와 임베디드 시뮬레이터 디바이스 간에 전환할 수 있습니다. PennyLane과 함께 사용할 수 있는 2개의 Amazon Braket 양자 디바이스를 제공합니다.
+  QPU 및 시뮬레이터를 포함한 Amazon Braket 서비스의 양자 디바이스로 실행하기 위한 `braket.aws.qubit`
+  Amazon Braket SDK의 로컬 시뮬레이터로 실행하기 위한 `braket.local.qubit`

Amazon Braket PennyLane 플러그인은 오픈 소스입니다. [PennyLane Plugin GitHub 리포지토리](https://github.com/aws/amazon-braket-pennylane-plugin-python)에서 설치할 수 있습니다.

PennyLane에 대한 자세한 내용은 [PennyLane 웹 사이트](https://pennylane.ai)의 설명서를 참조하세요.

## Amazon Braket 예제 노트북의 하이브리드 알고리즘
<a name="braket-hybrid-workflow"></a>

Amazon Braket은 하이브리드 알고리즘 실행을 위해 PennyLane 플러그인에 의존하지 않는 다양한 예제 노트북을 제공합니다. 양자 근사 최적화 알고리즘(Quantum Approximate Optimization Algorithm, QAOA) 또는 변분 양자 고유해석기(Variational Quantum Eigensolver, VQE)와 같은 *변분법*을 설명하는 [Amazon Braket 하이브리드 예제 노트북](https://github.com/aws/amazon-braket-examples/tree/main/examples/hybrid_quantum_algorithms) 중 하나를 사용하여 시작할 수 있습니다.

Amazon Braket 예제 노트북은 [Amazon Braket Python SDK](https://github.com/aws/amazon-braket-sdk-python)를 사용합니다. SDK는 Amazon Braket을 통해 양자 컴퓨팅 하드웨어 디바이스와 상호 작용하는 프레임워크를 제공합니다. 하이브리드 워크플로의 양자 부분을 지원하도록 설계된 오픈 소스 라이브러리입니다.

[예제 노트북](https://github.com/aws/amazon-braket-examples)을 통해 Amazon Braket을 더 자세히 살펴볼 수 있습니다.

## PennyLane 시뮬레이터가 임베디드된 하이브리드 알고리즘
<a name="hybrid-alorithms-pennylane"></a>

Amazon Braket Hybrid Jobs는 이제 [PennyLane](https://github.com/PennyLaneAI/pennylane-lightning)의 고성능 CPU 및 GPU 기반 임베디드 시뮬레이터와 함께 제공됩니다. 이 임베디드 시뮬레이터 제품군은 하이브리드 작업 컨테이너 내에 직접 임베디드할 수 있으며 빠른 상태 벡터 `lightning.qubit` 시뮬레이터, NVIDIA의 [cuQuantum 라이브러리](https://developer.nvidia.com/cuquantum-sdk)를 사용하여 가속화된 `lightning.gpu` 시뮬레이터 등을 포함합니다. 이러한 임베디드 시뮬레이터는 [수반 미분법](https://docs.pennylane.ai/en/stable/introduction/interfaces.html#simulation-based-differentiation)과 같은 고급 방법을 활용할 수 있는 양자 기계 학습과 같은 변분 알고리즘에 적합합니다. 하나 이상의 CPU 또는 GPU 인스턴스에서 이러한 임베디드 시뮬레이터를 실행할 수 있습니다.

하이브리드 작업을 통해 이제 고전 공동 프로세서와 QPU를 조합하거나 SV1과 같은 Amazon Braket 온디맨드 시뮬레이터를 사용하거나 PennyLane의 임베디드 시뮬레이터를 직접 사용하여 변분 알고리즘 코드를 실행할 수 있습니다.

임베디드 시뮬레이터는 하이브리드 작업 컨테이너에 이미 제공되어 있으므로 `@hybrid_job` 데코레이터로 기본 Python 함수를 데코레이션해야 합니다. PennyLane `lightning.gpu` 시뮬레이터를 사용하려면 다음 코드 조각과 같이 `InstanceConfig`에서 GPU 인스턴스도 지정해야 합니다.

```
import pennylane as qml
from braket.jobs import hybrid_job
from braket.jobs.config import InstanceConfig


@hybrid_job(device="local:pennylane/lightning.gpu", instance_config=InstanceConfig(instanceType="ml.g4dn.xlarge"))
def function(wires):
    dev = qml.device("lightning.gpu", wires=wires)
    ...
```

하이브리드 작업에서 PennyLane 임베디드 시뮬레이터 사용을 시작하려면 [예제 노트북](https://github.com/aws/amazon-braket-examples/blob/main/examples/hybrid_jobs/4_Embedded_simulators_in_Braket_Hybrid_Jobs/Embedded_simulators_in_Braket_Hybrid_Jobs.ipynb)을 참조하세요.

## Amazon Braket 시뮬레이터를 사용한 PennyLane의 수반 기울기
<a name="adjoint-gradient-pennylane"></a>

Amazon Braket용 PennyLane 플러그인을 사용하면 로컬 상태 벡터 시뮬레이터 또는 SV1에서 실행할 때 수반 미분법을 사용하여 기울기를 계산할 수 있습니다.

 **참고:** 수반 미분법을 사용하려면 `diff_method='adjoint'`가 **아닌** `qnode`에 `diff_method='device'`를 지정해야 합니다. 다음 예제를 참조하세요.

```
device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1"
dev = qml.device("braket.aws.qubit", wires=wires, shots=0, device_arn=device_arn)
                
@qml.qnode(dev, diff_method="device")
def cost_function(params):
    circuit(params)
    return qml.expval(cost_h)

gradient = qml.grad(circuit)
initial_gradient = gradient(params0)
```

**참고**  
현재 PennyLane은 QAOA 해밀토니안에 대한 그룹화 인덱스를 계산하고 이를 사용하여 해밀토니안을 여러 기대값으로 분할합니다. PennyLane에서 QAOA를 실행할 때 SV1의 수반 미분 기능을 사용하려면 다음과 같이 그룹화 인덱스를 제거하여 비용 해밀토니안을 재구성해야 합니다. `cost_h, mixer_h = qml.qaoa.max_clique(g, constrained=False) cost_h = qml.Hamiltonian(cost_h.coeffs, cost_h.ops)` 

# 하이브리드 작업 및 PennyLane을 사용하여 QAOA 알고리즘 실행
<a name="braket-jobs-run-qaoa-algorithm"></a>

이 섹션에서는 학습한 내용을 바탕으로 파라메트릭 컴파일과 PennyLane을 함께 사용하여 실제 하이브리드 프로그램을 작성하게 됩니다. 알고리즘 스크립트를 사용하여 QAOA 문제를 해결합니다. 이 프로그램은 고전적 Max Cut 최적화 문제에 해당하는 비용 함수를 생성하고 파라미터화된 양자 회로를 지정하며 경사 하강법을 사용해 파라미터를 최적화하여 비용 함수가 최소화되도록 합니다. 이 예제에서는 단순화를 위해 알고리즘 스크립트에 문제 그래프를 생성하지만, 보다 일반적인 사용 사례에서는 입력 데이터 구성의 전용 채널을 통해 문제 사양을 제공하는 것이 가장 좋습니다. 플래그 `parametrize_differentiable`은 기본적으로 `True`로 설정되므로 지원되는 QPU에서 파라메트릭 컴파일을 통해 향상된 런타임 성능의 이점을 자동으로 얻을 수 있습니다.

```
import os
import json
import time

from braket.jobs import save_job_result
from braket.jobs.metrics import log_metric

import networkx as nx
import pennylane as qml
from pennylane import numpy as np
from matplotlib import pyplot as plt

def init_pl_device(device_arn, num_nodes, shots, max_parallel):
    return qml.device(
        "braket.aws.qubit",
        device_arn=device_arn,
        wires=num_nodes,
        shots=shots,
        # Set s3_destination_folder=None to output task results to a default folder
        s3_destination_folder=None,
        parallel=True,
        max_parallel=max_parallel,
        parametrize_differentiable=True, # This flag is True by default.
    )

def start_here():
    input_dir = os.environ["AMZN_BRAKET_INPUT_DIR"]
    output_dir = os.environ["AMZN_BRAKET_JOB_RESULTS_DIR"]
    job_name = os.environ["AMZN_BRAKET_JOB_NAME"]
    checkpoint_dir = os.environ["AMZN_BRAKET_CHECKPOINT_DIR"]
    hp_file = os.environ["AMZN_BRAKET_HP_FILE"]
    device_arn = os.environ["AMZN_BRAKET_DEVICE_ARN"]

    # Read the hyperparameters
    with open(hp_file, "r") as f:
        hyperparams = json.load(f)

    p = int(hyperparams["p"])
    seed = int(hyperparams["seed"])
    max_parallel = int(hyperparams["max_parallel"])
    num_iterations = int(hyperparams["num_iterations"])
    stepsize = float(hyperparams["stepsize"])
    shots = int(hyperparams["shots"])

    # Generate random graph
    num_nodes = 6
    num_edges = 8
    graph_seed = 1967
    g = nx.gnm_random_graph(num_nodes, num_edges, seed=graph_seed)

    # Output figure to file
    positions = nx.spring_layout(g, seed=seed)
    nx.draw(g, with_labels=True, pos=positions, node_size=600)
    plt.savefig(f"{output_dir}/graph.png")

    # Set up the QAOA problem
    cost_h, mixer_h = qml.qaoa.maxcut(g)

    def qaoa_layer(gamma, alpha):
        qml.qaoa.cost_layer(gamma, cost_h)
        qml.qaoa.mixer_layer(alpha, mixer_h)

    def circuit(params, **kwargs):
        for i in range(num_nodes):
            qml.Hadamard(wires=i)
        qml.layer(qaoa_layer, p, params[0], params[1])

    dev = init_pl_device(device_arn, num_nodes, shots, max_parallel)

    np.random.seed(seed)
    cost_function = qml.ExpvalCost(circuit, cost_h, dev, optimize=True)
    params = 0.01 * np.random.uniform(size=[2, p])

    optimizer = qml.GradientDescentOptimizer(stepsize=stepsize)
    print("Optimization start")

    for iteration in range(num_iterations):
        t0 = time.time()

        # Evaluates the cost, then does a gradient step to new params
        params, cost_before = optimizer.step_and_cost(cost_function, params)
        # Convert cost_before to a float so it's easier to handle
        cost_before = float(cost_before)

        t1 = time.time()

        if iteration == 0:
            print("Initial cost:", cost_before)
        else:
            print(f"Cost at step {iteration}:", cost_before)

        # Log the current loss as a metric
        log_metric(
            metric_name="Cost",
            value=cost_before,
            iteration_number=iteration,
        )

        print(f"Completed iteration {iteration + 1}")
        print(f"Time to complete iteration: {t1 - t0} seconds")

    final_cost = float(cost_function(params))
    log_metric(
        metric_name="Cost",
        value=final_cost,
        iteration_number=num_iterations,
    )

    # We're done with the hybrid job, so save the result.
    # This will be returned in job.result()
    save_job_result({"params": params.numpy().tolist(), "cost": final_cost})
```

**참고**  
파라메트릭 컴파일은 펄스 레벨 프로그램을 제외한 Rigetti Computing의 모든 초전도 게이트 기반 QPU에서 지원됩니다.

# PennyLane 임베디드 시뮬레이터를 사용한 하이브리드 워크로드 실행
<a name="pennylane-embedded-simulators"></a>

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

## QAOA 워크로드`lightning.gpu`에 사용
<a name="lightning-gpu-qaoa"></a>

이 [노트북](https://github.com/amazon-braket/amazon-braket-examples/tree/main/examples/hybrid_jobs/2_Using_PennyLane_with_Braket_Hybrid_Jobs)의 양자 근사 최적화 알고리즘(Quantum Approximate Optimization Algorithm, QAOA) 예제를 살펴보세요. 임베디드 시뮬레이터를 선택하려면 `device` 인수를 다음과 같은 형식의 문자열로 지정합니다. `"local:<provider>/<simulator_name>"` 예를 들어 `lightning.gpu`에 대해 `"local:pennylane/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)
```

이 페이지에서 2개의 임베디드 PennyLane 상태 벡터 시뮬레이터 `lightning.qubit`(CPU 기반)와 `lightning.gpu`(GPU 기반)를 비교합니다. 시뮬레이터에 사용자 지정 게이트 분해를 제공하여 다양한 기울기를 계산합니다.

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

GPU를 실행하려면 먼저 호환되는 이미지와 올바른 인스턴스(기본값은 `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")
```

그런 다음 시스템 및 하이브리드 작업 인수 모두에서 업데이트된 디바이스 파라미터와 함께 하이브리드 작업 데코레이터에 이를 입력해야 합니다.

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

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

`m5.2xlarge` 인스턴스의 평균 반복 시간은 약 73초이고 `ml.g4dn.xlarge` 인스턴스의 경우 약 0.6초입니다. 이 21비트 워크플로의 경우 GPU 인스턴스는 100배의 속도 향상을 제공합니다. Amazon Braket Hybrid Jobs [요금 페이지를](https://aws.amazon.com/braket/pricing/) 보면 `m5.2xlarge` 인스턴스의 분당 비용이 0.00768 USD인 반면 `ml.g4dn.xlarge` 인스턴스의 경우 0.01227 USD임을 알 수 있습니다. 이 인스턴스에서는 GPU 인스턴스에서 실행하는 것이 더 빠르고 저렴합니다.

## 양자 기계 학습 및 데이터 병렬 처리
<a name="quantumML-data-parallelism"></a>

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

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

바이너리 분류의 예로 잘 알려진 UCI 리포지토리의 [Sonar 데이터세트](https://archive.ics.uci.edu/dataset/151/connectionist+bench+sonar+mines+vs+rocks) 데이터세트를 사용하는 데이터 병렬 처리를 위한 다음 QML 워크로드를 고려해 보세요. Sonar 데이터세트에는 각각 60개의 특징을 가진 208개의 데이터 포인트가 있으며, 이는 물질에서 반사되는 Sonar 신호로부터 수집됩니다. 각 데이터 포인트는 mines의 "M", rocks의 "R"로 표시됩니다. QML 모델은 입력 계층, 은닉 계층으로서 양자 회로 및 출력 계층으로 구성됩니다. 입력 및 출력 계층은 PyTorch에서 구현된 고전 신경망입니다. 양자 회로는 PennyLane의 qml.qnn 모듈을 사용하여 PyTorch 신경망과 통합됩니다. 워크로드에 대한 자세한 내용은 [예제 노트북](https://github.com/aws/amazon-braket-examples)을 참조하세요. 위의 QAOA 예제와 마찬가지로, PennyLane의 `lightning.gpu`와 같은 임베디드 GPU 기반 시뮬레이터를 사용하면 GPU의 성능을 활용하여 임베디드 CPU 기반 시뮬레이터보다 성능을 개선할 수 있습니다.

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

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

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

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

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

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

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

올바르게 사용하면 여러 인스턴스를 사용하면 시간과 비용이 크게 감소할 수 있습니다. [ 자세한 내용은 예제 노트북을 참조](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/5_Parallelize_training_for_QML/Parallelize_training_for_QML.ipynb)하세요.

# Amazon Braket에서 CUDA-Q 사용
<a name="braket-using-cuda-q"></a>

NVIDIA's CUDA-Q는 CPU, GPU 및 QPU를 결합한 하이브리드 양자 알고리즘을 프로그래밍하기 위해 설계된 소프트웨어 라이브러리입니다. 이 라이브러리는 통합 프로그래밍 모델을 제공하여 개발자가 단일 프로그램 내에서 고전 명령과 양자 명령을 모두 표현할 수 있게 함으로써 워크플로를 간소화합니다. CUDA-Q는 기본 제공 CPU 및 GPU 시뮬레이터를 통해 양자 프로그램 시뮬레이션과 런타임을 가속화합니다. CUDA-Q는 네이티브 Braket 노트북 인스턴스(NBI)와 Amazon Braket Hybrid Jobs에서 사용할 수 있습니다.

**Topics**
+ [NBI에서의 CUDA-Q](#braket-cuda-q-nbis)
+ [하이브리드 작업에서의 CUDA-Q](#braket-cuda-q-hybrid-jobs)

## NBI에서의 CUDA-Q
<a name="braket-cuda-q-nbis"></a>

CUDA-Q는 기본적으로 Braket NBI 환경에 설치됩니다. Jupyter 시작 관리자 페이지로 이동하고 CUDA-Q 및 Braket 타일을 선택하여 CUDA-Q 예제 노트북을 열 수 있습니다. 그러면 기본 창에서 예제 노트북 `0_Getting_started_with_CUDA-Q.ipynb`이 열립니다. 자세한 CUDA-Q 예제는 `nvidia_cuda_q/` 디렉터리의 왼쪽 패널을 참조하세요.

NBI에 설치된 CUDA-Q 또는 다른 타사 패키지의 버전을 확인할 수도 있습니다. 예를 들어 노트북 코드 셀에서 다음 명령을 실행하여 환경에 설치된 CUDA-Q, Qiskit, PennyLane 및 Braket 패키지의 버전을 확인할 수 있습니다.

```
%pip freeze | grep -i -e cudaq -e qiskit -e pennylane -e braket
```

## 하이브리드 작업에서의 CUDA-Q
<a name="braket-cuda-q-hybrid-jobs"></a>

[Amazon Braket Hybrid Jobs](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs.html)에서 CUDA-Q를 사용하면 유연한 온디맨드 컴퓨팅 환경을 제공할 수 있습니다. 계산 인스턴스는 워크로드 기간 동안에만 실행되므로 사용한 만큼만 비용을 지불하면 됩니다. Amazon Braket Hybrid Jobs는 또한 확장 가능한 환경을 제공합니다. 사용자는 프로토타이핑 및 테스트를 위해 작은 인스턴스로 시작한 다음, 전체 실험을 위해 더 큰 워크로드를 처리할 수 있는 더 큰 인스턴스로 확장할 수 있습니다.

Amazon Braket Hybrid Jobs는 CUDA-Q의 잠재력을 극대화하는 데 필수적인 GPU를 지원합니다. GPU는 CPU 기반 시뮬레이터에 비해 양자 프로그램 시뮬레이션의 속도를 크게 높입니다. 특히 큐비트 수가 많은 회로 작업 시 더욱 그렇습니다. Amazon Braket Hybrid Jobs에서 CUDA-Q를 사용하면 병렬화가 간단해집니다. 하이브리드 작업은 여러 계산 노드에 걸쳐 회로 샘플링 및 관찰 가능 항목 평가의 분산을 단순화합니다. 이렇게 원활한 CUDA-Q 워크로드의 병렬화를 통해 사용자는 대규모 실험을 위한 인프라를 설정하는 대신 워크로드 개발에 더 집중할 수 있습니다.

시작하려면 Amazon Braket 예제 GitHub에서 [CUDA-Q 스타터 예제](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/nvidia_cuda_q/0_Getting_started_with_CUDA-Q.ipynb)를 참조하여 Braket에서 제공하는 CUDA-Q 하이브리드 작업 컨테이너를 사용하세요.

다음 코드 조각은 Amazon Braket Hybrid Jobs를 사용하여 CUDA-Q 프로그램을 실행하는 `hello-world` 예제입니다.

```
image_uri = retrieve_image(Framework.CUDAQ, AwsSession().region)

@hybrid_job(device='local:nvidia/qpp-cpu', image_uri=image_uri)
def hello_quantum():
    import cudaq

    # define the backend
    device=get_job_device_arn()
    cudaq.set_target(device.split('/')[-1])

    # define the Bell circuit
    kernel = cudaq.make_kernel()
    qubits = kernel.qalloc(2)
    kernel.h(qubits[0])
    kernel.cx(qubits[0], qubits[1])

    # sample the Bell circuit
    result = cudaq.sample(kernel, shots_count=1000)
    measurement_probabilities = dict(result.items())
    
    return measurement_probabilities
```

위 예제에서는 CPU 시뮬레이터에서 벨 회로를 시뮬레이션합니다. 이 예제는 렙톱 또는 Braket Jupyter Notebook에서 로컬로 실행됩니다. `local=True` 설정으로 인해 이 스크립트를 실행하면 로컬 환경에서 컨테이너가 시작되어 테스트 및 디버깅을 위한 CUDA-Q 프로그램을 실행합니다. 테스트를 완료한 후 `local=True` 플래그를 제거하고 AWS에서 작업을 실행할 수 있습니다. 자세한 내용은 [Amazon Braket Hybrid Jobs 작업](braket-jobs.md)을 참조하세요.

워크로드의 큐비트 수가 많거나 회로 수가 많거나 반복 횟수가 많은 경우, `instance_config` 설정을 지정하여 더 강력한 CPU 컴퓨팅 리소스를 사용할 수 있습니다. 다음 코드 조각은 `hybrid_job` 데코레이터에서 `instance_config` 설정을 구성하는 방법을 보여줍니다. 지원되는 인스턴스 유형에 대한 자세한 내용은 [하이브리드 작업 인스턴스 구성](braket-jobs-configure-job-instance-for-script.md)을 참조하세요. 인스턴스 유형 목록은 [Amazon EC2 인스턴스 유형](https://aws.amazon.com/ec2/instance-types/)을 참조하세요.

```
@hybrid_job(
    device="local:nvidia/qpp-cpu",
    image_uri=image_uri,
    instance_config=InstanceConfig(instanceType="ml.c5.2xlarge"),
)
def my_job_script():
    ...
```

더 까다로운 워크로드의 경우 CUDA-Q GPU 시뮬레이터에서 워크로드를 실행할 수 있습니다. GPU 시뮬레이터를 활성화하려면 백엔드 이름 `nvidia`를 사용합니다. `nvidia` 백엔드는 CUDA-Q GPU 시뮬레이터로 작동합니다. 다음으로, NVIDIA GPU를 지원하는 Amazon EC2 인스턴스 유형을 선택합니다. 다음 코드 조각은 GPU로 구성된 `hybrid_job` 데코레이터를 보여줍니다.

```
@hybrid_job(
    device="local:nvidia/nvidia",
    image_uri=image_uri,
    instance_config=InstanceConfig(instanceType="ml.g4dn.xlarge"),
)
def my_job_script():
    ...
```

Amazon Braket Hybrid Jobs 및 NBI는 CUDA-Q를 사용한 병렬 GPU 시뮬레이션을 지원합니다. 여러 관찰 가능 항목 또는 여러 회로의 평가를 병렬화하여 워크로드의 성능을 높일 수 있습니다. 여러 관찰 가능 항목을 병렬화하려면 알고리즘 스크립트를 다음과 같이 변경합니다.

`nvidia` 백엔드의 `mgpu` 옵션을 설정합니다. 이는 관찰 가능 항목을 병렬화하는 데 필요합니다. 병렬화는 GPU 간 통신에 MPI를 사용하므로, MPI는 실행 전에 초기화되고 실행 후에 종료되어야 합니다.

다음으로, `execution=cudaq.parallel.mpi`를 설정하여 실행 모드를 지정합니다. 다음 코드 조각은 이러한 변경 사항을 보여줍니다.

```
cudaq.set_target("nvidia", option="mqpu")
cudaq.mpi.initialize()
result = cudaq.observe(
    kernel, hamiltonian, shots_count=n_shots, execution=cudaq.parallel.mpi
)
cudaq.mpi.finalize()
```

다음 코드 조각에서와 같이 `hybrid_job` 데코레이터에서 여러 GPU를 호스팅하는 인스턴스 유형을 지정합니다.

```
@hybrid_job(
    device="local:nvidia/nvidia-mqpu",
    instance_config=InstanceConfig(instanceType="ml.g4dn.12xlarge", instanceCount=1),
    image_uri=image_uri,
)
def parallel_observables_gpu_job(sagemaker_mpi_enabled=True):
    ...
```

Amazon Braket 예제 GitHub의 [병렬 시뮬레이션 노트북](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/nvidia_cuda_q/5_Multiple_GPU_simulations.ipynb)은 GPU 백엔드에서 양자 프로그램 시뮬레이션을 실행하고 관찰 가능 항목 및 회로 배치에 대한 병렬 시뮬레이션을 수행하는 방법을 보여주는 종단 간 예제를 제공합니다.

### 양자 컴퓨터에서 워크로드 실행
<a name="braket-using-cuda-q-quantum"></a>

시뮬레이터 테스트를 완료한 후 QPU에서 실행 중인 실험으로 전환할 수 있습니다. 대상을 IQM, IonQ 또는 Rigetti 디바이스와 같은 Amazon Braket QPU로 바꾸기만 하면 됩니다. 다음 코드 조각은 대상을 IQM Garnet 디바이스로 설정하는 방법을 보여줍니다. 사용 가능한 QPU 목록은 [Amazon Braket 콘솔](https://console.aws.amazon.com/braket/home)을 참조하세요.

```
device_arn = "arn:aws:braket:eu-north-1::device/qpu/iqm/Garnet"
cudaq.set_target("braket", machine=device_arn)
```

하이브리드 작업에 대한 자세한 내용은 개발자 안내서의 [Amazon Braket Hybrid Jobs 작업](braket-jobs.md)을 참조하세요. CUDA-Q에 대한 자세한 내용은 [NVIDIA CUDA-Q 설명서](https://nvidia.github.io/cuda-quantum/latest/index.html)를 참조하세요.