주 콘텐츠로 건너뛰기

첫 번째 양자 프로그램 만들고 실행하기

소개

아래 영상에서 Olivia Lanes가 이 레슨의 내용을 안내해 드립니다. 또는 별도 창에서 이 레슨의 YouTube 영상을 열 수도 있습니다.

양자 컴퓨터를 오늘 바로 사용해 보세요에 오신 것을 환영합니다! 이 과정의 목표는 사전 지식 없이도 최대한 빠르게 실제 양자 컴퓨터에서 코드를 실행해 보는 것입니다. 시작해 봅시다.

이 첫 번째 레슨은 호기심 있는 초보자와 바쁜 리더 모두에게 적합한 부드러운 실습형 양자 컴퓨팅 입문입니다. 양자 Circuit에 대해 배우고, **얽힘(entanglement)**을 생성하는 간단한 양자 프로그램을 작성한 후, 실제 IBM® 양자 컴퓨터에서 실행해 볼 것입니다. 실제 양자 컴퓨터에서 실행하는 것을 건너뛰고 싶다면, 동일한 프로그램을 시뮬레이터에서 실행하는 옵션도 있습니다.

이 노트북은 새로운 Google Colab 런타임에서 처음부터 끝까지 실행하거나, 로컬에서 실행할 수 있습니다.

설정

Google Colab에서 이 노트북을 실행하려면 브라우저에서 노트북을 열고 셀을 실행할 수 있는 Google 계정이 필요합니다.

실제 IBM 양자 컴퓨터에서 실행하려면 (무료) IBM Quantum® Platform 계정도 필요합니다. Open Plan을 사용하여 28일 롤링 윈도우당 10분의 QPU(양자 처리 장치) 시간을 얻을 수 있는 인스턴스를 열 수 있는데, 실제로는 꽤 많은 시간입니다! 계정에 문제가 있으면 지원 페이지를 참조하세요.

IBM Quantum Platform의 지침에 따라 Qiskit을 설치한 후 이 노트북을 로컬에서 실행할 수도 있습니다.

설치 및 임포트

Colab에서는 모든 사람이 동일한 도구를 실행할 수 있도록 노트북 내에서 종속성을 설치합니다. 다음 셀은 시각화 모듈과 두 가지 애드온인 Aer(빠른 시뮬레이터)과 IBM Runtime 클라이언트(양자 컴퓨터 실행용)를 포함한 Qiskit을 설치합니다.

다음으로 여러 임포트가 있습니다. QuantumCircuit 클래스는 양자 비트(Qubit)를 정의하고 해당 Qubit에 대한 연산을 정의하는 곳입니다. 이것이 첫 번째 양자 용어입니다. Qubit은 비트가 고전적 컴퓨팅의 기본 구성 단위인 것처럼, 양자 컴퓨팅의 기본 구성 단위입니다. Circuit을 만들면서 Qubit의 특별한 속성에 대해 더 배울 것입니다. 다음으로 plot_histogram은 양자 Circuit의 결과를 시각화하는 데 사용됩니다. AerSimulator는 고전 컴퓨터에서 양자 Circuit을 시뮬레이션할 수 있게 해줍니다. 하지만 시뮬레이터는 실제 양자 컴퓨터와 동일한 규모로 양자 Circuit을 실행할 수 없습니다. 그래서 실제 양자 컴퓨터가 필요한 것입니다. 이는 테스트, 디버깅, 교육 목적으로 유용하거나, 10분의 무료 QPU 시간을 모두 사용한 경우에도 유용합니다. preset_passmanagers는 Circuit이 하드웨어에서 효율적으로 실행되도록 최적화하는 데 도움이 되며, Circuit이 더 복잡해질수록 매우 중요해집니다. SamplerQiskitRuntimeService는 실제로 양자 컴퓨터에서 Circuit을 실행하는 데 필요합니다. 이에 대해서는 나중에 더 자세히 설명합니다.

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit
!pip install 'qiskit[visualization]' qiskit-ibm-runtime qiskit-aer
# Core Qiskit imports
from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
from qiskit_aer import AerSimulator
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

# IBM Runtime specific imports
from qiskit_ibm_runtime import SamplerV2 as Sampler, QiskitRuntimeService

다음으로 빠른 환경 확인을 수행합니다. 버전을 확인하고 임포트를 확인합니다.

여기서 문제가 발생하면 대개 종속성 설치 문제입니다. 지금 수정하면 나중에 발생할 혼란스러운 오류를 방지할 수 있습니다.

import sys

import qiskit
import qiskit_aer
import qiskit_ibm_runtime

print("Python:", sys.version.split()[0])
print("qiskit:", qiskit.__version__)
print("qiskit-aer:", qiskit_aer.__version__)
print("qiskit-ibm-runtime:", qiskit_ibm_runtime.__version__)
Python: 3.12.2
qiskit: 2.2.3
qiskit-aer: 0.17.2
qiskit-ibm-runtime: 0.41.1

잠깐의 탐험: Composer 사용하기

코드를 작성하기 전에 Circuit을 시각적으로 보는 것이 도움이 됩니다. IBM Quantum Composer를 사용하면 와이어에 Gate를 드래그하여 Circuit을 만들 수 있습니다. 구문에 신경 쓰지 않고 Circuit이 무엇을 하는지 배우기에 좋은 방법입니다.

여기에서 Composer를 여세요.

로드되면 메뉴에서 안내 튜토리얼을 시작하세요: Help | Build your first circuit. 자신의 속도에 맞게 진행하세요. 진행하면서 각 Gate가 측정하려는 것을 어떻게 변경하는지 주목하세요.

튜토리얼은 "Hello World" Circuit을 만드는 과정을 단계별로 안내합니다. 이것은 Circuit 다이어그램으로 시각화되는데, Qubit은 수평선으로 표시되고, 해당 Qubit에 작용하는 Gate는 선 위의 상자나 다른 기호로 표시됩니다. 이 Circuit은 Qubit과 양자 컴퓨터의 몇 가지 핵심 특징을 소개합니다.

첫째, "H"라고 표시된 빨간 상자는 Hadamard Gate로, Qubit 0의 중첩(superposition) 상태를 생성합니다. 1 또는 0 상태만 가질 수 있는 비트와 달리, Qubit 상태는 두 가능성을 동시에 포함할 수 있으며, 각각에 특정 가중치(진폭이라고 함)가 붙습니다. 중첩은 한 번의 측정에서 두 결과를 모두 볼 수 있다는 의미가 아닙니다. 측정할 때 어느 결과든 발생할 수 있도록 상태가 설정되어 있다는 의미입니다.

둘째, 두 Qubit을 연결하는 원과 수직선은 CNOT Gate로, 두 Qubit 사이에 **얽힘(entanglement)**을 생성합니다. 얽힘은 Qubit 간의 특별한 연결입니다. Qubit이 얽혀 있으면, 측정 결과가 일반적인 독립적인 동전 던지기나 고전적인 상관관계에서 기대할 수 없는 방식으로 강하게 상관될 수 있습니다. 두 Qubit이 얽혀 있으면, 하나를 측정하면 즉시 다른 하나의 측정 결과를 알 수 있습니다.

튜토리얼에서 볼 수 있는 또 다른 핵심 개념은 shots입니다. **측정(measurement)**은 Qubit이 양자 상태로 동작하는 것을 멈추고 고전적인 읽기값을 제공하는 순간이기 때문에, 중첩 상태는 측정될 때 확률적으로 0 또는 1로 붕괴합니다. 따라서 그 중첩에 대해 알아보려면, 통계를 축적하기 위해 동일한 Circuit을 여러 번 실행하여 여러 번 측정해야 합니다. 이것들을 shots라고 합니다.

이해도 확인

아래 각 질문을 생각해보고, 클릭하여 답을 확인해 보세요.

단일 측정으로 중첩을 직접 볼 수 있을까요?

답변

아니요. 단일 측정은 항상 고전적인 값인 0 또는 1을 반환합니다. "혼합" 개념은 여러 번의 실행(shots라고도 함) 후에 보이는 통계에서만 나타납니다.

쉬운 말로, 얽힘은 무엇을 제공하나요?

답변

연결된 결과를 제공합니다. 하나의 Qubit을 측정하면 다른 Qubit에 대한 정보를 알 수 있습니다. 이 연결은 독립적인 무작위성보다 강하고, 순전히 고전적인 상관관계나 공유된 무작위성으로 설명할 수 있는 것보다도 강합니다.

Qubit이 중첩 상태에 있을 때, 단일 측정에서 무엇을 보게 되나요? 그리고 왜 많은 shots가 필요한가요?

답변

단일 측정에서는 0 또는 1 중 하나의 고전적인 결과만 볼 수 있습니다. "중첩"은 확률 분포로 나타나며, 이는 반복된 실행에서 통계를 수집해야만 추정할 수 있기 때문에 많은 shots가 필요합니다.

Composer에서 Hello World Circuit의 측정 히스토그램을 보세요. 무엇이 보이나요? 왜 이것이 얽힘의 특징인가요?

답변

00|00\rangle 상태에 있을 확률이 50%이고 11|11\rangle 상태에 있을 확률이 50%임을 보여줍니다. 이는 하나가 0으로 측정되면 다른 하나도 0이 되고, 하나가 1로 측정되면 다른 하나도 1이 된다는 것을 의미합니다. 이것은 얽힘으로 설명할 수 있는 두 Qubit 간의 상관관계입니다.

Qiskit을 사용하여 양자 프로그램 만들고 실행하기

자, 다시 코딩으로 돌아가겠습니다. Composer에서 했던 것과 동일한 얽힘 상태(Φ+\Phi^+ (파이-플러스) Bell 상태라고 함)를 생성할 것인데, 이번에는 코드를 직접 작성할 것입니다. Qubit 수와 Circuit의 복잡도가 증가할수록 Composer가 도움이 되지 않으므로 이 기술을 쌓아야 합니다.

Bell 상태 Circuit을 만들기 위해, HH (Hadamard) Gate를 사용하여 첫 번째 Qubit을 동일한 중첩 상태로 만들고, CXCX (제어-NOT) Gate를 적용하여 두 상태를 얽습니다. 이제 두 Qubit은 고전적으로는 동등한 것이 없는 방식으로 상관되어 있습니다.

# --- Build the Bell circuit (phi-plus) ---
bell = QuantumCircuit(2)
bell.h(0)
bell.cx(0, 1)
bell.measure_all() # creates a classical register named "meas"

bell.draw("mpl")

Output of the previous code cell

Circuit 실행을 위한 헬퍼 함수

이제 양자 Circuit을 실행하고 측정 결과를 가져오는 프로세스를 처리하는 헬퍼 함수를 정의해 봅시다. 이 함수는 Backend의 명령어 세트에 맞게 Circuit을 Transpile하고, Sampler 프리미티브를 통해 실행하고, 결과에서 측정 횟수를 추출하는 작업을 처리합니다.

def run_circuit_and_get_counts(circuit, backend, shots=1000):
"""
Runs a quantum circuit on a specified backend and returns the measurement counts.

Args:
circuit (QuantumCircuit): The quantum circuit to run.
backend: The Qiskit backend (real device or simulator).
shots (int): The number of shots to run the circuit.

Returns:
dict: A dictionary of measurement counts.
"""
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)

sampler = Sampler(mode=backend)

job = sampler.run([isa_circuit], shots=shots)
result = job.result()

return result[0].data.meas.get_counts()

QPU에서 실행하고 결과 시각화하기

마지막으로, 클라우드의 IBM QPU(양자 처리 장치)에서 1000 shots으로 Circuit을 실행하고 결과를 플롯합니다. IBM QPU는 노이즈를 감지할 수 있는 물리적 시스템이므로, Gate가 약간 불완전하고, 측정이 때때로 틀릴 수 있으며, 디바이스 캘리브레이션이 시간이 지남에 따라 변동합니다.

실제 양자 컴퓨터에서 실행하면 실용적인 고려사항도 생깁니다. 많은 사람들이 동일한 디바이스를 사용할 수 있기 때문에 작업이 대기열에 있을 수 있습니다. 또한 통계적 고려사항(shots가 많을수록 신호 대 잡음비가 높아짐)과 시간/비용 제약 사이의 균형을 맞추는 shot 수를 선택해야 합니다.

다음 셀의 코드 주석에 있는 지침을 따르세요. 셀을 실행한 후, 노이즈로 인해 0101 또는 1010이 일부 발생하더라도 00001111 비트 문자열에 대해 대략 동일한 횟수를 가진 히스토그램이 표시될 것입니다. 이 노트북의 다음 셀은 QPU에서 실행을 건너뛰고 싶은 경우 시뮬레이터에서 동일한 Circuit을 실행합니다.

# Syntax for first saving your token.  Delete these lines after saving your credentials.
QiskitRuntimeService.save_account(
channel="ibm_quantum_platform",
token="YOUR_TOKEN_HERE",
overwrite=True,
set_as_default=True,
)
service = QiskitRuntimeService(channel="ibm_quantum_platform")

# Load saved credentials
service = QiskitRuntimeService()

# Use the least busy backend, or uncomment the loading of a specific backend like "ibm_fez".
backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)
# backend = service.backend("ibm_fez")
print(backend.name)
ibm_pittsburgh
counts = run_circuit_and_get_counts(bell, backend, shots=1000)
plot_histogram(counts)

Output of the previous code cell

시뮬레이터에서 실행하고 결과 시각화하기

시뮬레이터는 양자 컴퓨팅의 "완벽한 세계" 버전입니다. 여기서 1000 shots으로 시뮬레이터에서 Circuit을 실행하고 결과를 플롯합니다. Bell 상태의 완벽한 상관관계의 특징인 0101 또는 1010은 나타나지 않고, 00001111 상태에 대해 대략 동일한 횟수가 표시될 것입니다.

backend = AerSimulator()
counts = run_circuit_and_get_counts(bell, backend, shots=1000)

plot_histogram(counts)

Output of the previous code cell

이해도 확인

Bell 상태를 생성하는 두 Gate는 무엇인가요?

답변

Qubit 0에 H Gate를 적용한 후, Qubit 0을 제어로 하고 Qubit 1을 타겟으로 하는 CX Gate를 적용합니다.

이상적인 시뮬레이터에서 히스토그램에 지배적으로 나타나야 하는 두 비트 문자열은 무엇인가요?

답변

00과 11이 지배적으로 나타나야 합니다.

완벽한 시뮬레이터에서도 항상 정확히 같은 수의 00 횟수와 11 횟수를 갖지 않는 이유는 무엇인가요?

답변

시뮬레이터가 "완벽"하여 완벽한 Bell 상태를 만들더라도, 여전히 본질적으로 무작위적인 과정을 시뮬레이션하기 때문에 통계적 변동이 발생합니다. 동전을 1000번 던지는 것과 같습니다. 동전이 앞면이나 뒷면으로 떨어질 확률이 정확히 50대 50이더라도, 항상 정확히 500번의 앞면과 500번의 뒷면을 얻는 것은 아닙니다.

시뮬레이터는 그렇지 않았는데, 실제 양자 컴퓨터에서 01 또는 10 결과가 나타날 수 있는 이유는 무엇인가요?

답변

실제 디바이스에는 노이즈가 있기 때문입니다. Gate와 측정이 완벽하지 않아, 이따금 오류가 발생할 수 있습니다.

노이즈 외에 시뮬레이터와 실제 양자 컴퓨터 간의 실용적인 차이점은 무엇인가요?

답변

양자 컴퓨터는 Circuit 실행에 영향을 미치는 대기 시간, 제한된 가용성 및 디바이스별 제약이 있을 수 있습니다.

결론

우리는 새로운 Colab 환경에서 Qiskit을 설정하는 것으로 시작했는데, 이것이 바로 많은 실제 노트북 워크플로가 시작되는 방식입니다. 이어서 Composer를 사용하여 양자 컴퓨팅을 탐험했습니다. 그런 다음 Φ+\Phi^+ Bell 상태를 생성하는 간단한 2-Qubit Circuit을 만들고, 반복 샘플링을 사용하여 Qubit 측정 히스토그램에서 상관관계로서의 얽힘을 시각화했습니다. 또한 실제 양자 컴퓨터가 어떻게 노이즈와 오류를 유발하는지도 살펴봤습니다.

학습 목표

Φ+\Phi^+ Bell 상태를 만드는 방법을 살펴봤으니, 코드를 수정하여 다른 세 가지 Bell 상태 중 하나를 만들어 보세요. 특히 Ψ\Psi^- 상태는 다음 레슨에서 사용될 것이므로, 만드는 방법을 알아두면 유리합니다.

This translation based on the English version of 2026년 5월 7일