주 콘텐츠로 건너뛰기

양자 컴퓨팅 첫걸음

  • 난이도: 초급
  • QPU 사용 시간: 11s

여러분, 워크숍에 오신 것을 환영합니다! 이 입문 실습의 주요 목표는 1) Qiskit 설치 방법 안내 2) IBM Cloud 계정 생성 및 실제 양자 컴퓨터 사용을 위한 api_keycrn 준비 3) 첫 번째 양자 Circuit 만들기 4) 양자 상태 퀴즈 풀기 5) 실제 양자 컴퓨터에서 Circuit을 실행하고 결과를 시각화하는 것을 통해 여러분의 양자 여정을 준비시키는 것입니다.

1. 시작하기 전에: Qiskit

Qiskit이란

**Qiskit SDK**는 개발자와 연구자들이 유틸리티 규모 이상에서 양자 컴퓨터의 잠재력을 최대한 활용할 수 있도록 설계된 고성능 소프트웨어 스택입니다. 그 핵심에는 확장된 양자 Circuit, 연산자, 기본 요소(Primitives) 수준에서 양자 컴퓨터를 다룰 수 있는 오픈 소스 소프트웨어 개발 키트인 Qiskit SDK가 있습니다. Qiskit SDK를 사용하면 누구나 원하는 컴퓨팅 환경에서 실제 양자 컴퓨터의 최적 성능을 이끌어낼 수 있습니다.

Qiskit은 SDK 외에도 오류 경감을 관리하는 Primitives를 통해 클라우드에서 IBM 양자 컴퓨터의 최적화된 연산을 가능하게 하는 Qiskit Runtime Service와 같은 고성능 도구 및 서비스 모음도 포함하고 있습니다. Qiskit Transpiler 서비스는 일반적인 양자 Circuit 최적화 작업의 성능을 높이는 최첨단 휴리스틱 및 AI 기반 방법을 제공합니다.

Qiskit functions는 워크로드 최적화와 산업별 사용 사례에 Qiskit을 쉽게 활용할 수 있도록 IBM 및 서드파티 서비스로 구성된 카탈로그입니다. 양자 소프트웨어 개발자, 양자 실험가, 전산 과학자, 또는 이제 막 시작하는 분이든 Qiskit의 모듈식 유연한 프레임워크를 통해 자신에게 맞는 추상화 수준에서 작업할 수 있습니다.

Qiskit은 확장성과 커스터마이징을 고려해 설계되어 있어, 업계 최고 수준의 성능을 끌어내고 새로운 유형의 문제에 도전할 수 있습니다. 고성능 코드베이스 덕분에 Qiskit SDK는 이전보다 더 빠르게 작동하고, 메모리를 덜 사용하며, 더 나은 결과를 제공합니다. 또한 Qiskit은 질문에 기꺼이 답해줄 방대한 사용자 및 개발자 커뮤니티와 연결해 줍니다. 2019년에 처음 시작된 Qiskit 어드보케이트 프로그램은 전 세계 양자 컴퓨팅 전문가와 열정적인 참가자를 모집하는 글로벌 커뮤니티 중심 이니셔티브입니다. 수년에 걸쳐 어드보케이트들은 양자 커뮤니티에서 인정받는 리더로 성장해 왔습니다. 다음 양자 리더가 되고 싶나요? 주저하지 말고 지원해 보세요 - 여기

Qiskit 설치

먼저, 사용 중인 환경의 Python 버전이 python>=3.10인지 확인하세요. 이는 앞으로 사용할 최신 Qiskit 버전과의 호환성을 보장하기 위한 것입니다.

from platform import python_version

print(python_version())

그렇지 않은 경우, 원하는 도구를 사용하여 업그레이드할 수 있습니다. 방법을 잘 모르는 경우 다음과 같은 권장 옵션이 있습니다:

  • MacOS: Homebrew
  • Linux: sudo apt-get update

OS에 따른 Python 업그레이드 방법에 대한 자세한 가이드는 여기에서 확인할 수 있습니다: How to update Python

더 많은 정보는 QGSS(Qiskit Global Summer School) 2025 위키를 참고하세요: https://github.com/qiskit-community/qgss-2025/wiki/Jupyter-Notebook-Environment-(Local-and-Online)

아래 셀을 실행하여 설치를 확인할 수 있습니다. 올바르게 설치되었다면 qiskit 버전이 반환됩니다.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
%pip install 'qiskit[visualization]'
%pip install qiskit-ibm-runtime
%pip install qiskit-aer
import qiskit

print(f"Qiskit version: {qiskit.__version__}")

문제 해결

이전 셀에서 오류가 발생한 경우, 가상 환경에 Qiskit을 설치하는 방법을 선택할 수 있습니다(두 가지 방법을 제안합니다). 오류가 없다면 이 셀은 무시하고 다음으로 진행하세요.

Qiskit 설치를 위한 가상 환경 설정 방법 두 가지를 제안합니다.

  1. Qiskit 설치 가이드에 설명된 venv 사용.
  2. Coding with Qiskit 영상에 설명된 conda 사용.

2. IBM Cloud 계정 설정

실제 양자 컴퓨터를 사용하려면 클라우드의 주요 입장 티켓인 api key와 계정을 설정하여 리소스를 가져올 crn 토큰이 필요합니다.

아래 절차에 따라 계정을 설정하세요:

  1. IBM Quantum® Platform으로 이동합니다.
  2. 오른쪽 상단(위 그림 참조)으로 이동하여 API 토큰을 생성하고 안전한 위치에 복사합니다.
  3. 다음 셀에서 deleteThisAndPasteYourAPIKeyHere를 여러분의 API 키로 교체합니다.
  4. 왼쪽 하단(위 그림 참조)으로 이동하여 인스턴스를 생성합니다. 오픈 플랜을 선택해야 합니다.
  5. 인스턴스가 생성된 후 해당 CRN 코드를 복사합니다. 인스턴스가 보이려면 새로 고침이 필요할 수 있습니다.
  6. 아래 셀에서 deleteThisAndPasteYourCRNHere를 여러분의 CRN 코드로 교체합니다.

자세한 IBM Cloud® 계정 설정 방법은 이 가이드를 참조하세요.

⚠️ 참고: API 키를 안전한 비밀번호처럼 취급하세요. 안전한 환경과 신뢰할 수 없는 환경 모두에서 API 키 사용 방법에 대한 자세한 내용은 Cloud setup 가이드를 참조하세요.

또한 IBM 파트너 네트워크 대학교 구성원인 경우, 파트너 혜택을 받으려면 IBM ID에 기관 이메일 주소를 사용해 주세요.

from qiskit_ibm_runtime import QiskitRuntimeService

# Save your API key and crn and have access to the quantum computers
your_api_key = "deleteThisAndPasteYourAPIKeyHere"
your_crn = "deleteThisAndPasteYourCRNHere"

QiskitRuntimeService.save_account(
channel="ibm_cloud",
token=your_api_key,
instance=your_crn,
overwrite=True
)
# Check that the account has been saved properly
service = QiskitRuntimeService()
service.saved_accounts()
# See backends you can use
service.backends()

3. 나의 첫 번째 양자 Circuit

양자 Circuit

Qiskit의 기본 단위는 양자 Circuit입니다. 이는 양자 컴퓨터가 양자 정보 비트(Qubit이라고도 함)를 다루기 위해 사용하는 일련의 명령입니다. 이 Qubit들은 일반 노트북이나 스마트폰과는 다른 방식으로 문제에 접근할 수 있도록 하는 특별한 성질을 가지고 있습니다. Qiskit은 빠르게 발전하는 기술로서, 여전히 양자 Circuit을 직접 설계하고 실행 방법을 결정할 수 있지만(그렇게 할 충분한 이유도 있습니다), IBM Quantum은 이 과정을 간소화하는 도구도 제공합니다. 학습을 위해, 여기서는 매우 간단한 Circuit을 설계하고 시뮬레이터에서 실행해 볼 것입니다.

솔직히 말하면, 양자 정보와 계산의 기초를 설명하는 데만도 몇 시간이 걸릴 수 있기 때문에 여기서는 개요만 간략히 다룹니다. 실제로 IBM Quantum은 이미 이에 대한 강의 교재동영상 강의 시리즈를 제작했습니다. 복습이 필요하다면 참고해 보세요!

from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
from qiskit.visualization import plot_state_qsphere
from qiskit_aer import AerSimulator
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.visualization import array_to_latex
from qiskit.visualization import plot_distribution

import numpy as np
from numpy import sqrt

Qubit의 기본 연산과 측정

단일 Qubit 상태 표현

단일 Qubit부터 살펴보겠습니다. 0과 1 두 값만 가질 수 있는 고전 비트와 달리, 양자 비트(Qubit)는 0\vert0\rangle, 1\vert1\rangle 상태뿐만 아니라 두 상태의 선형 결합 상태에도 있을 수 있습니다. 이 특성은 중첩(superposition)이라고 하며, Qubit의 가장 일반적인 상태를 다음과 같이 표현할 수 있게 해줍니다:

ψ=1p0+eiϕp1\vert\psi\rangle = \sqrt{1-p}\vert0\rangle + e^{i \phi} \sqrt{p} \vert1\rangle

이 Qubit의 상태를 측정하면 확률 pp로 결과 11을, 확률 1p1-p로 결과 00을 얻게 됩니다. 보면 알 수 있듯이 총 확률이 11이므로, 측정 결과는 반드시 00 또는 11 중 하나입니다.

pp 외에도 위에서 또 다른 매개변수를 발견했을 것입니다. 변수 ϕ\phi는 두 상태 0\vert0\rangle1\vert1\rangle 사이의 상대적 양자 위상을 나타냅니다. 나중에 살펴보겠지만 이 상대적 위상은 매우 중요합니다. 지금은 양자 위상이 양자 상태 간의 간섭을 가능하게 하여, 특정 문제를 해결하는 양자 알고리즘을 작성할 수 있게 해준다는 점만 기억해 두세요.

양자 상태 시각화

이 실습 전반에 걸쳐 qsphere라고 알려진 도구를 사용해 양자 상태를 시각화합니다. 아래는 각각 0\vert0\rangle1\vert1\rangle 상태에 대한 qsphere 모습입니다. 구의 최상단은 0\vert0\rangle 상태를, 최하단은 1\vert1\rangle 상태를 나타냅니다.

#visualize |0>
sv=Statevector([1, 0])
plot_state_qsphere(sv)

양자 Circuit을 사용해서도 완전히 동일한 QSphere를 만들 수 있습니다. 여기서 사용하는 statevector는 0|0\rangle 상태에서 시작합니다. Qiskit에서는 Qubit이 0|0\rangle 상태로 초기화됩니다. 아래 Circuit을 실행해서 같은 QSphere를 얻을 수 있는지 확인해 보세요.

qc1 = QuantumCircuit(1)
sv=Statevector(qc1)
plot_state_qsphere(sv)

이제 1|1\rangle 상태를 시각화해 보겠습니다. 양자 위상 ϕ=0\phi = 0이고 확률 p=1/2p = 1/2(0과 1을 측정할 확률이 같음)인 중첩 상태가 qsphere에서 두 점으로 표시되는 것은 놀라운 일이 아닙니다. 하지만 두 점의 원 크기가 단순히 0\vert0\rangle이나 1\vert1\rangle만 있을 때보다 작다는 점에 주목하세요. 원의 크기는 각 상태를 측정할 확률에 비례하는데, 이제 절반으로 줄었기 때문입니다.

#visualize 1/sqrt(2)|0> + 1/sqrt(2)|1>

sv=Statevector([1/sqrt(2), 1/sqrt(2)])
plot_state_qsphere(sv)

양자 위상이 0이 아닌 중첩 상태의 경우, qsphere는 해당 위상을 각 점의 색상으로 시각화합니다. 예를 들어, ϕ=90\phi = 90^\circ(도)이고 확률 p=1/2p = 1/2인 상태는 아래 qsphere와 같이 표시됩니다.

sv=Statevector([1/sqrt(2), 1/sqrt(2)*1j])
plot_state_qsphere(sv)

Qubit 조작

Qubit은 양자 Gate를 적용하여 조작합니다. 다음 실습에서 사용할 다양한 Gate에 대한 개요를 살펴보겠습니다.

먼저, 일반적인 양자 상태에서 pp 값을 변경하는 방법에 대해 설명합니다. 이를 위해 두 가지 Gate를 사용합니다:

  1. XX-Gate: 이 Gate는 0\vert0\rangle1\vert1\rangle 두 상태 사이를 뒤집습니다. 이 연산은 고전 NOT Gate와 동일합니다. 따라서 XX-Gate는 비트 플립(bit flip) 또는 NOT Gate라고도 합니다. 수학적으로 XX Gate는 pp1p1-p로 변경하므로, 특히 0을 1로, 그리고 그 반대로 변환합니다.

  2. HH-Gate: 이 Gate는 0\vert0\rangle 상태에서 12(0+1)\frac{1}{\sqrt{2}}\left(\vert0\rangle + \vert1\rangle\right) 상태로 전환할 수 있게 해줍니다. 이 상태는 +\vert+\rangle로도 알려져 있습니다. 수학적으로 p=0,ϕ=0p=0, \phi=0에서 p=1/2,ϕ=0p=1/2, \phi=0으로의 전환을 의미합니다. Qubit의 최종 상태가 0\vert0\rangle1\vert1\rangle의 중첩이기 때문에, Hadamard Gate는 진정한 양자 연산을 나타냅니다.

두 Gate 모두 pp의 값을 변경하지만 ϕ\phi는 변경하지 않는다는 점에 주목하세요. 다행히도 아래 그림을 보면 이 Gate들의 작용을 시각적으로 쉽게 이해할 수 있습니다.

+\vert+\rangle 상태를 얻은 후에는 다른 Gate를 적용하여 양자 위상을 변경할 수 있습니다. 예를 들어, SS Gate는 ϕ\phi9090도의 위상을 추가하고, ZZ Gate는 ϕ\phi180180도의 위상을 추가합니다. 위상을 9090도 줄이려면 S-dagger라고 읽으며 일반적으로 sdg로 표기하는 SS^\dagger Gate를 적용할 수 있습니다. 마지막으로 ZZXX Gate의 순서를 적용하는 YY Gate도 있습니다.

XX, YY, ZZ, HH, SS, SS^\dagger Gate를 직접 실험하여 다양한 연산과 그것이 Qubit 상태에 미치는 영향을 익혀보세요. Circuit Composer를 방문하여 Circuit 위젯을 시작할 수 있습니다. Circuit Composer를 방문한 후 Qubit에 적용할 Gate를 선택하고 Qubit을 선택합니다(첫 번째 예제에서는 선택할 수 있는 유일한 Qubit인 Qubit 0을 선택하세요). 각 Gate에 따라 해당 상태가 어떻게 변하는지, 그리고 그 상태에 대한 설명을 살펴보세요. 또한 Qiskit에서 해당 양자 Circuit을 생성하는 코드도 제공됩니다.

양자 상태 설명, Pauli 연산자 및 기타 단일 Qubit Gate에 대해 더 알고 싶다면 John Watrous의 Basics of Quantum Information 강좌 중 Single System의 Quantum Information을 참고하세요.

연습: 단일 Qubit Gate를 사용한 양자 Circuit

qsphere에서 다양한 상태를 달성하기 위한 네 가지 소규모 연습입니다. Circuit Composer로 풀고 코드를 복사하여 각 셀에 붙여넣어 양자 Circuit을 만들거나, 다음 코드 줄의 조합을 프로그램에 직접 입력하여 다양한 Gate를 적용할 수 있습니다:

qc.x(0) # bit flip qc.y(0) # bit and phase flip qc.z(0) # phase flip qc.h(0) # superpostion qc.s(0) # quantum phase rotation by pi/2 (90 degrees) qc.sdg(0) # quantum phase rotation by -pi/2 (90 degrees)

'(0)'은 이 Gate를 첫 번째(이 경우 유일한) Qubit인 'q0'에 적용한다는 것을 나타냅니다.

각 다음 실습에서 qsphere에 주어진 상태를 달성해 보세요.

i) 비트 플립으로 시작해 보겠습니다. 목표는 0\vert0\rangle 상태에서 시작하여 1\vert1\rangle 상태에 도달하는 것입니다.


def create_circuit():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

# check solution
qc2 = create_circuit()
state = Statevector(qc2)

plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)

ii) 다음으로 중첩 상태를 만들어 보겠습니다. 목표는 +=12(0+1)|+\rangle = \frac{1}{\sqrt{2}}\left(|0\rangle + |1\rangle\right) 상태에 도달하는 것입니다.


def create_circuit2():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc3 = create_circuit2()
state = Statevector(qc3)
plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)

iii) 앞의 두 가지를 결합해 보겠습니다. 목표는 =12(01)|-\rangle = \frac{1}{\sqrt{2}}\left(|0\rangle - |1\rangle\right) 상태에 도달하는 것입니다.

위의 두 과제를 결합하여 해결책을 찾을 수 있을까요?

def create_circuit3():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc4 = create_circuit3()
state = Statevector(qc4)
plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)

iv) 마지막으로 복소수로 넘어가겠습니다. 목표는 =12(0i1)|\circlearrowleft\rangle = \frac{1}{\sqrt{2}}\left(|0\rangle - i|1\rangle\right) 상태에 도달하는 것입니다.

def create_circuit4():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc5 = create_circuit4()
state = Statevector(qc5)

plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)

4. Multi-Qubit Gate로 양자 퀴즈 풀기

수고하셨습니다! 단일 Qubit Gate를 이해했으니, 이제 여러 Qubit에 작용하는 Gate를 살펴보겠습니다. 여기서는 단일 Qubit Gate와 Multi-Qubit Gate를 조합하여 4가지 양자 상태 퀴즈를 풀어야 합니다. 두 Qubit에 대한 기본 Gate는 다음과 같습니다.

qc.cx(c,t) # controlled-X (= CNOT) gate with control qubit c and target qubit t qc.cz(c,t) # controlled-Z gate with control qubit c and target qubit t qc.swap(a,b) # SWAP gate that swaps the states of qubit a and qubit b

다양한 Multi-Qubit Gate와 그 관계에 대해 더 읽고 싶다면, John의 Basics of Quantum Information 강좌에서 다중 시스템의 Quantum Information을 방문해 보세요.

두 Qubit의 경우, 일반적인 상태는 a00+b01+c10+d11a|00\rangle + b |01\rangle + c |10\rangle + d|11\rangle 형태이며, aa, bb, cc, dd는 복소수로 그 절댓값의 제곱이 각 상태를 측정할 확률을 나타냅니다. 예를 들어, a2|a|^2는 두 Qubit 모두 '0'으로 끝날 확률입니다. 따라서 이제 qsphere에 최대 네 개의 점을 가질 수 있습니다.

두 Qubit의 대표적인 Gate인 controlled-NOT(CNOT 또는 CX) Gate부터 시작합니다. 모든 controlled 두 Qubit Gate와 마찬가지로, 하나의 Qubit은 "제어(control)", 다른 하나는 "대상(target)"으로 불립니다. 제어 Qubit이 0|0\rangle 상태이면 대상에 항등 II Gate를 적용하며, 즉 아무 연산도 수행되지 않습니다. 반면 제어 Qubit이 1|1\rangle 상태이면 대상 Qubit에 X-Gate가 적용됩니다. 따라서 두 Qubit 모두 고전적인 상태인 0|0\rangle 또는 1|1\rangle 중 하나일 때, CNOT Gate는 고전적 연산에 국한됩니다.

제어 Qubit에 Hadamard Gate를 먼저 적용하여 중첩 상태 +|+\rangle으로 만들면 상황이 극적으로 달라집니다. 이 비고전적 입력에 대한 CNOT Gate의 작용은 제어 Qubit과 대상 Qubit 사이에 고도로 얽힌 상태를 생성할 수 있습니다. 대상 Qubit이 초기에 0|0\rangle 상태에 있으면, 결과 상태는 Φ+|\Phi^+\rangle으로 표기되며, 이른바 Bell states 중 하나입니다.

i) Bell state Φ+=12(00+11)|\Phi^+\rangle = \frac{1}{\sqrt{2}}\left(|00\rangle + |11\rangle\right)을 구성하세요.

이 상태에서 "00"을 측정할 확률은 12\frac{1}{2}이고, "11"을 측정할 확률은 12\frac{1}{2}입니다. 따라서 두 Qubit의 측정 결과는 완벽하게 상관됩니다.


def create_circuit5():
qc = QuantumCircuit(2)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc6 = create_circuit5()
state = Statevector(qc6) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc6.draw(output='mpl') # we draw the circuit

다음으로, 완벽하게 반상관된 Qubit 상태를 만들어 보세요. 두 상태 사이의 상대적 위상을 나타내는 마이너스 부호에 주목하세요.

ii) Bell state Ψ=12(0110)\vert\Psi^-\rangle = \frac{1}{\sqrt{2}}\left(\vert01\rangle - \vert10\rangle\right)을 구성하세요.


def create_circuit6():
qc = QuantumCircuit(2)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc7 = create_circuit6()
state = Statevector(qc7) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc7.draw(output='mpl') # we draw the circuit

iii) 아래 함수에 기술된 양자 Circuit이 주어집니다. 첫 번째와 두 번째 Qubit의 상태를 교환하여 이 QSphere를 만드세요.

def create_circuit7():
qc = QuantumCircuit(2)
qc.rx(np.pi/3,0)
qc.x(1)
return qc

qc8 = create_circuit7()

#
#
# FILL YOUR CODE IN HERE
#
#

state = Statevector(qc8) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc8.draw(output='mpl') # we draw the circuit

iv) 처음부터 GHZ state(세 Qubit)를 생성하는 프로그램을 작성하세요, GHZ=12(000+111)\vert \text{GHZ}\rangle = \frac{1}{\sqrt{2}} \left(|000\rangle + |111 \rangle \right)


def create_circuit8():
#
#
# FILL YOUR CODE IN HERE
#
#
#
return qc

qc9 = create_circuit8()

pub4 = (qc9)

state = Statevector(qc9) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc9.draw(output='mpl') # we draw the circuit

5. Circuit를 실행하고 실제 양자 컴퓨터로 측정 결과 확인하기

Qubit의 상태 벡터를 조작하는 양자 Circuit을 구축하는 방법을 배웠습니다. 이제 가장 흥미로운 부분인 실행 및 결과 확인의 시간입니다! 여기서는 Qiskit을 사용하여 Circuit을 실행하는 현대적이고 효과적인 방법을 배웁니다.

Qiskit 패턴은 도메인별 문제를 분해하고 단계별로 필요한 기능을 맥락화하는 일반적인 프레임워크입니다. 이를 통해 IBM Quantum 연구자(및 기타 연구자)가 개발한 새로운 기능의 원활한 조합이 가능하며, 양자 컴퓨팅 작업이 강력한 이종(CPU/GPU/QPU) 컴퓨팅 인프라에 의해 수행되는 미래를 실현합니다.

Qiskit 패턴의 네 단계는 다음과 같습니다:

  1. Map 문제를 양자 Circuit과 연산자로 매핑
  2. Optimize 대상 하드웨어에 맞게 최적화
  3. Execute 대상 하드웨어에서 실행
  4. Post-process 결과 후처리

방금 Step 1: Mapping을 완료했습니다. 원하는 양자 상태를 생성하는 양자 Circuit을 구축했습니다. 이제 나머지 단계들을 진행하여 결과를 확인해 보겠습니다.

Optimize

여기서는 회로를 실행할 백엔드를 설정합니다 - 접근 가능한 QPU 그룹 중 least busy QPU를 선택하거나, 남은 QPU 시간이 충분하지 않은 경우 시뮬레이터를 선택할 수 있습니다. 백엔드를 선택하면, pass_manager가 회로를 선택한 백엔드의 기본 게이트 세트로 transpile하고 더 나은 결과를 얻을 수 있도록 최적화합니다. generate_preset_pass_manager를 사용하고 optimization_level을 설정하여 pass_manager를 쉽게 선언할 수 있으며, 숫자가 클수록 더 많은 최적화 단계를 나타냅니다.

다음 단계는 정말 흥미롭습니다 - Qiskit Runtime을 사용하여 양자 Circuit을 실행할 것입니다!

두 가지 Qiskit primitives를 사용할 것입니다:

  1. Sampler는 하나 이상의 양자 Circuit 실행에서 출력 레지스터를 샘플링합니다. 출력은 측정당 shot 수 기반의 counts입니다.
  2. Estimator는 양자 Circuit이 생성한 상태에 대해 하나 이상의 관측값(observable)의 기댓값을 계산합니다. 출력은 기댓값과 표준 오차로 구성됩니다.

여기서는 Sampler를 사용하여 Circuit을 실행합니다. 아래 코드 셀은 먼저 Backend와 해당 Backend의 pass manager를 정의하는 방법을 보여줍니다. 그런 다음 모든 Circuit에 measurement를 추가하고, Sampler에 전달할 양자 Circuit 배열(pub)을 생성합니다.


backend=service.least_busy()
#backend=AerSimulator()

pm = generate_preset_pass_manager(optimization_level=3, backend=backend)
sampler = Sampler(mode=backend)

pub = []
for qc in circ:
qc.measure_all()
pub.append(pm.run(qc))

Execute

Circuit을 실행해 봅시다. 클라우드에서 대기 큐가 많은 경우, 나중에 사용할 수 있도록 job_id를 출력하고 저장한 후 job_status를 확인하세요. 잡 상태가 Done으로 바뀐 것을 확인한 후 잡 결과를 가져오세요.

job = sampler.run(pub)
job_id = job.job_id()
print(job_id)
job.status()
job_retrived = service.job(job_id)
result = job.result()

Post-process

마지막 단계는 우리가 생성한 양자 상태를 이해하기 위해 시각화를 해석하는 것입니다. 여러 그래프를 그리기 전에, 모든 Circuit에서 counts를 가져옵니다. 그런 다음 Circuit을 분류하여 4개의 그래프를 그립니다.

result = job.result()
counts_all = [result[k].data.meas.get_counts() for k in range(9)]

The Single Qubit States

plot_distribution([counts_all[0], counts_all[1]], legend =['qc1', 'qc2'])

The Superpositioned One Qubit States

plot_distribution([counts_all[2], counts_all[3], counts_all[4]], legend =['qc3', 'qc4', 'qc5'])

Two Qubit States

plot_distribution([counts_all[5], counts_all[6], counts_all[7]],legend =['qc6', 'qc7', 'qc8'] )

Three Qubit States

plot_distribution(counts_all[8], legend=['qc9'])

Further challenge

실제 Backend 실험 결과에서 노이즈를 발견했나요? Qubit 노이즈 제거는 현재 활발히 연구되는 분야 중 하나입니다. Qiskit Runtime의 다양한 오류 완화 및 억제 옵션을 사용하여 실행 결과의 노이즈가 어떻게 변하는지 확인해 보세요! (참고) 이 옵션들은 더 많은 QPU 시간을 사용합니다.

Additional Info

import qiskit, qiskit_ibm_runtime

print("Qiskit version:", qiskit.version.get_version_info())
print("Qiskit Runtime version:", qiskit_ibm_runtime.__version__)
Qiskit version: 2.1.1
Qiskit Runtime version: 0.40.1

Created by: Sophy Shin

Reviewed by: Nate Earnest-Noble

© IBM Corp., 2025

This is licensed under the Apache License, Version 2.0. You may obtain a copy of this license in the LICENSE file in the root directory of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this must retain this copyright notice, and modified files need to carry a notice indicating that they have been altered from the originals.