AWS 기술 블로그

Amazon Braket 콘솔 소개 및 Amazon Braket에서 양자 회로를 실행하는 방법 -2

지난 블로그에서는 Amazon Braket 콘솔 소개 및 콘솔에서 특정 양자 하드웨어에 대한 정보를 확인하는 방법에 대해 소개하였습니다.

지난 블로그 보기

이번 글에서는 AWS가 제공하는 클라우드 기반 양자 컴퓨팅 서비스인 Amazon Braket을 활용해, 주피터 노트북 환경을 구축하고 로컬 시뮬레이터로 양자 회로를 직접 실행하는 과정을 단계별로 소개합니다. 참고로 이 블로그에서 실행한 원본 코드는 다음의 깃허브 링크에서 확인 가능합니다.

주피터 노트북 생성

양자 알고리즘 작성을 위해 Amazon Braket에서 제공하는 주피터 노트북을 생성해 보도록 하겠습니다. 그림1의 왼쪽 하단에서 ‘Notebooks’을 클릭하면, 현재 사용자가 보유하고 있는 주피터 노트북의 목록 및 개별 주피터 노트북의 상세 정보를 확인할 수 있습니다. 그림1의 오른쪽 상단에 있는 ‘Create notebook Instance’를 클릭합니다.

<그림 1. 사용자가 보유중인 주피터 노트북 정보>

그림 2와 같은 화면에서 주피터 노트북 생성을 위한 초기 화면을 만나게 됩니다. Step1에서는 주피터 노트북 이름을 임의로 설정합니다. 이 예에서는 ‘blog’라는 이름으로 설정하였습니다. 설정이 완료되면, 그림 하단의 ‘Next’를 클릭합니다.

<그림 2. Amazon Braket 노트북 인스턴스 생성을 위한 초기 세팅 화면>

그림3의 Step2에서는, 주피터 노트북을 구동하는 EC2 인스턴스를 선택하게 됩니다. 주피터 노트북 인스턴스를 선택할 때는 다음과 같은 기준을 고려해야 합니다. 우선 이미지에서 보이는 것처럼 Amazon Braket은 여러 인스턴스 유형을 제공합니다.

  • Standard (ml.t3.medium) – 기본 설정으로, 비용 효율적인 옵션입니다. 대부분의 기본적인 양자 컴퓨팅 작업에 적합합니다.
  • High performance (ml.c5.xlarge) – 더 많은 메모리와 처리 능력이 필요한 복잡한 양자 알고리즘을 실행할 때 적합합니다.
  • GPU accelerated (ml.p3.2xlarge) – GPU 가속이 필요한 시뮬레이션이나, CUDA-Q와 같은 GPU 기반 양자 컴퓨팅 프레임워크를 사용할 때 유용합니다.
  • Custom instance type – 특정 요구 사항에 맞게, 사용자가 필요한 인스턴스를 임의로 설정할 수 있습니다.

이 예제에서는 기본값인 Standard 타입의 인스턴스(ml.t3.medium)를 선택합니다. 개별 인스턴스에 대한 Spec은 다음의 링크에서 확인 가능합니다. 블록 스토리지인 Amazon EBS 볼륨 크기도 조정할 수 있으며, 기본값은 5GB입니다. 작업의 복잡성과 예산에 따라 적절한 인스턴스를 선택하는 것이 중요합니다. 비용 효율성을 위해서는 ml.t3.medium과 같은 작은 인스턴스로 시작하는 것이 좋습니다. 주피터 노트북 인스턴스의 비용 절감을 위해, 주피터 노트북을 사용하지 않을 때는 그림1의 우측 상단의 ‘Actions’을 클릭 하여 ’Stop’ 옵션을 선택하는 것이 좋습니다.

<그림 3. Amazon Braket 노트북 인스턴스 생성시 인스턴스 타입 선택 화면>

그림3의 좌측 상단에 있는 Step 3과 4의 경우 모두 선택 사항이므로, 특별한 요건이 없다면 설정 변경 없이 그대로 Step5로 진입할 수 있습니다. Step5에서 설정한 값을 최종적으로 확인하고, 이상이 없다면 그림 4 하단에 있는 ‘Launch’ 버튼을 클릭합니다.

<그림 4. Amazon Braket 노트북 인스턴스 생성을 위한 최종 화면>

노트북 인스턴스 생성이 완료된 후 그림1의 주피터 노트북 URL을 클릭하면, 그림5와 같이 주피터 노트북 화면을 만나게 됩니다. 그림의 왼쪽에서 이미 사전에 탑재된 몇 개의 샘플 알고리즘 및 코드를 확인할 수 있습니다.

<그림 5. Amazon Braket 주피터 노트북 접속 화면>

이 주피터 노트북 환경에서 그림 왼쪽 상단의 ‘Braket algorithms’ 및 ‘Braket examples’ 폴더의 내용은, 노트북 인스턴스 재시작 시(Stop -> Start) 덮어 쓰일 수 있습니다. 따라서 중요한 작업은 반드시 이 폴더 외부에 별도 저장해야 합니다.

양자 디바이스에 대한 단일 요청, 태스크(task)

Amazon Braket 주피터 노트북에서 양자 회로를 작성하기 위해서는 ‘태스크(task)’라는 개념을 이해하는 것이 중요합니다. 큐비트는 중첩 상태를 가지기 때문에, 양자 회로를 실행한 결과는 확률적으로 매번 달라질 수 있습니다. 따라서 보다 신뢰할 수 있는 결과를 얻기 위해 동일한 회로를 여러 번 반복 실행하고 측정하여, 이 결과들을 모아 확률 분포 형태로 출력하는 것이 일반적입니다.

<그림 6: Amazon Braket에서의 샷과 태스크의 개념 >

이때, 동일한 회로를 특정 양자 디바이스(시뮬레이터 또는 QPU)에서 여러 번 실행하는 각각의 과정을 ‘샷(shot)’이라고 하며, 여러 샷을 묶어서 한 번에 요청하는 단위를 ‘태스크(task)’라고 부릅니다. Amazon Braket에서는 사용자가 주피터 노트북 등에서 태스크를 생성할 때, 몇 번의 샷을 실행할지 직접 지정할 수 있습니다. 예를 들어, 1,000번의 샷으로 구성된 태스크를 제출하면, 선택한 양자 디바이스에서 동일한 회로가 1,000번 실행되고, 그 결과는 Amazon S3에 저장됩니다.

샷의 수가 많아질수록 결과의 신뢰도는 높아지게 됩니다. 이는 마치 동전을 여러 번 던질수록 앞면과 뒷면이 나올 확률이 50%에 가까워지는 원리와 비슷하다고 이해하시면 됩니다. 단, 그만큼 디바이스 사용 비용도 비례하여 증가합니다. 

Amazon Braket 주피터 노트북에서 양자 알고리즘 설계 실행

지금부터는 주피터 노트북 환경에서 실제로 ‘Bell state’(2개의 큐비트를 이용한 양자 얽힘 상태) 양자 회로를 작성하고 이를 양자 디바이스인 로컬 시뮬레이터(정확히는, 노이즈가 없는 환경을 시뮬레이션 하는 braket_sv 시뮬레이터)에 제출하여 결과를 확인하는 작업을 실제로 진행해 보겠습니다. 양자 세계에서 이 Bell state 회로는 우리가 알고 있는 가장 기초적인 프로그램인 “Hello World!”를 출력하는 일반 프로그램과 의미가 유사하다고 하겠습니다.

우선 다음 코드는 Amazon Braket 환경에서 양자 회로 실습을 준비하기 위한 기본적인 설정을 담고 있습니다. 먼저, 데이터 시각화를 위해 matplotlib의 pyplot 모듈을 plt라는 이름으로 불러옵니다. 그리고 %matplotlib inline이라는 명령어를 통해, 주피터 노트북에서 그래프가 셀 아래에 바로 표시될 수 있도록 설정합니다.

# general imports
import matplotlib.pyplot as plt

%matplotlib inline

# AWS imports: Import Braket SDK modules
from braket.circuits import Circuit
from braket.devices import LocalSimulator

이후, Amazon Braket SDK에서 양자 회로를 설계할 때 사용하는 Circuit 클래스를 불러오고, 실제 양자 하드웨어가 아닌, 내 컴퓨터에서 양자 회로의 동작을 시뮬레이션할 수 있도록 해주는 로컬 시뮬레이터도 함께 불러옵니다. 이렇게 준비된 환경에서는 직접 양자 회로를 만들고, 그 결과를 시각적으로 확인하면서 실습을 진행할 수 있습니다.

다음의 코드를 통해 Bell state 양자 회로를 정의합니다.

bell = Circuit().h(0).cnot(control=0, target=1)

<그림 7. 2개의 큐비트를 이용하는 Bell state 회로>

이 코드는 두 개의 큐비트를 이용해 ‘Bell state’라는 대표적인 양자 얽힘 상태를 만드는 양자 회로를 정의하는 명령입니다. 먼저 Circuit()을 통해 빈 양자 회로를 만들고, 첫 번째 큐비트(0번)에 Hadamard 게이트를 적용해 중첩 상태를 만듭니다. 그다음, 0번 큐비트를 제어로, 1번 큐비트를 대상으로 하는 CNOT(Controlled-NOT) 게이트를 적용해 두 큐비트가 얽힘 상태가 되도록 합니다. 이 회로의 출력 결과는 이론적으로 ‘00’이 50%, ‘11’이 50%가 발생하게 됩니다.

다음 코드는 앞서 만든 벨 상태 회로를 로컬 시뮬레이터에서 실행하고, 그 결과를 확인하는 과정을 보여줍니다.

# set up device
device = LocalSimulator()

# run circuit
result = device.run(bell, shots=1000).result()
# get measurement shots
counts = result.measurement_counts
# print counts
print(counts)

먼저, LocalSimulator()를 이용해 양자 회로를 실행할 양자 디바이스를 정의합니다. 이때 별도의 설정이 없으면, 기본적으로 최대 25 큐비트까지 노이즈가 없는 환경에 대한 시뮬레이션이 가능한 braket_sv가 선택이 됩니다. 만약 로컬 시뮬레이터로 노이즈 시뮬레이션 필요하다면, ‘device = LocalSimulator("braket_dm")’ 과 같이 정의하면 됩니다.

그 다음, device.run() 함수를 사용해 앞서 정의한 벨(bell) 회로를 1000번 반복해서 실행(shots=1000)하고, 그 결과를 result()로 받아옵니다. 대부분의 양자 시뮬레이터(또는 실제 양자 하드웨어)에서 ‘device.run(bell, shots=1000)’ 이 명령은 회로의 마지막에 측정 연산(게이트)이 포함되어 있다고 가정하고, 그 결과를 반환합니다. 실행이 끝나면 result.measurement_counts를 통해 각 측정 결과(예: '00', '11' 등)가 몇 번씩 나왔는지 집계된 횟수를 가져옵니다. 마지막으로, print(counts)를 통해 이 측정 결과 분포를 화면에 다음과 같이 출력합니다.

Counter({'11': 506, '00': 494})

이 과정을 통해 벨 상태의 얽힘 특성에 따라 '00'과 '11' 결과가 거의 비슷한 비율로 나타나는 것을 직접 확인할 수 있습니다. 두 가지 상태 모두가 정확하게 500번씩 발생하지 않는 이유는, 양자 회로에 대한 수행 결과는 확률적이기 때문입니다. 또한 만약 노이즈가 발생하는 실제 QPU에서 이 회로를 실행하였다면, ‘01’ 또는 ‘10’ 상태가 추가적으로 발생할 수 있는 것도 기억할 필요가 있습니다.

다음 코드는 앞서 얻은 측정 결과를 막대그래프로 시각화하는 과정입니다.

# plot using Counter

plt.bar(counts.keys(), counts.values())
plt.xlabel("bitstrings")
plt.ylabel("counts")

먼저, plt.bar() 함수를 이용해 측정 결과의 각 비트 문자열(예: '00', '11')을 x축에, 해당 결과가 나온 횟수를 y축에 표시하여 막대그래프를 그립니다. 이어서 plt.xlabel("bitstrings")로 x축에 'bitstrings'(비트 문자열)이라는 레이블을, plt.ylabel("counts")로 y축에 'counts'(측정 횟수)라는 레이블을 각각 추가합니다. 이렇게 하면 벨 상태에서 측정된 결과 분포를 한눈에 쉽게 확인할 수 있습니다.

<그림 8: 로컬 시뮬레이터에서 1000번의 Bell state 회로 측정 결과의 시각화>

Amazon Braket의 로컬 시뮬레이터는 실제 양자 하드웨어가 아닌, 여러분의 컴퓨터에서 양자 회로를 실행해 볼 수 있는 도구입니다. 이 시뮬레이터는 Amazon Braket SDK에서 제공되기 때문에 무료로 사용할 수 있습니다. 그러나 결과가 별도의 클라우드 저장소에 자동 저장되지 않고, Amazon Braket 콘솔의 'Quantum tasks' 목록에서도 확인할 수 없습니다. 하지만, 양자 컴퓨팅을 처음 배우는 분들이 양자 회로를 설계하고 실험해 보는 데 매우 유용한 기본 도구로 활용할 수 있습니다. 즉, 로컬 시뮬레이터는 양자 컴퓨팅 학습의 출발점이자 연습장 역할을 한다고 생각하시면 됩니다.

맺음말

Amazon Braket은 복잡해 보이는 양자 컴퓨팅을 누구나 쉽게 체험할 수 있도록 다양한 도구와 환경을 제공합니다. 특히 로컬 시뮬레이터는 별도의 비용 부담 없이, 실습 결과를 빠르게 확인하며 양자 회로 설계에 익숙해질 수 있는 좋은 출발점입니다. 이번 블로그에서 안내한 주피터 노트북 환경 구성과 실습 예제를 따라 하다 보면, 양자 알고리즘의 원리와 동작 방식을 직접 체험하며 이해할 수 있습니다. 앞으로도 Amazon Braket을 활용해 다양한 양자 알고리즘을 실험하고, 점차 실제 양자 하드웨어로 확장해 나가시길 바랍니다. 다음 블로그에서는 온디맨드 시뮬레이터와 실제 양자 하드웨어를 이용하는 방법에 대해서도 설명할 예정입니다.

Sangman Cho

Sangman Cho

조상만 Solutions Architect는 AWS 입사 이후, Automotive 및 Manufacturing 고객의 클라우드 기반의 디지털 전환 업무를 지원하였으며, 현재는 AWS 코리아 전체의 고성능 컴퓨팅(HPC)과 양자 컴퓨팅 등 계산 과학 영역의 디지털 전환 업무를 지원하고 있습니다.