주 콘텐츠로 건너뛰기

REST API를 사용한 Sampler

이 항목의 단계에서는 REST API를 사용하여 워크로드를 실행하고 구성하는 방법을 설명하며, 원하는 프로그램에서 이를 호출하는 방법을 보여줍니다.

참고

이 문서는 Qiskit Runtime REST API를 시연하기 위해 Python requests 모듈을 사용합니다. 그러나 이 워크플로는 REST API를 지원하는 모든 언어나 프레임워크를 사용하여 실행할 수 있습니다. 자세한 내용은 API 참조 문서를 참조하세요.

1. 계정 초기화

Qiskit Runtime Sampler는 관리형 서비스이므로 먼저 계정을 초기화해야 합니다. 그런 다음 계산을 실행할 장치를 선택할 수 있습니다.

계정 초기화, 사용 가능한 Backend 확인, 토큰 작업 방법에 대한 자세한 내용은 REST API를 사용하여 IBM Quantum Platform 설정하기를 참조하세요.

2. QASM Circuit 만들기

Sampler Primitive에 대한 입력으로 최소한 하나의 Circuit이 필요합니다.

QASM 양자 Circuit을 정의합니다:

qasm_string='''
OPENQASM 3;
include "stdgates.inc";
qreg q[2];
creg c[2];
x q[0];
cx q[0], q[1];
c[0] = measure q[0];
c[1] = measure q[1];
'''

아래 코드 스니펫은 qasm_string이 새 문자열 resulting_qasm으로 트랜스파일되었다고 가정합니다.

3. Sampler V2 API를 사용하여 양자 Circuit 실행

참고

아래 Job들은 Qiskit Runtime V2 Primitive를 사용합니다. SamplerV2는 하나 이상의 Primitive Unified Bloc(PUB)을 입력으로 받습니다. 각 PUB는 하나의 Circuit과 해당 Circuit에 브로드캐스트되는 데이터(여러 매개변수가 될 수 있음)를 포함하는 튜플이며, PUB당 하나의 결과를 반환합니다.

import requests

url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"

headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[resulting_qasm],[resulting_qasm,None,500]]
}}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")

4. Job 상태 확인 및 결과 가져오기

다음으로, job_id를 API에 전달합니다:

response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)
response_status_singlejob.json().get('state')

출력

>>> Job ID: 58223448-5100-4dec-a47a-942fb30edced
>>> Job Status: JobStatus.RUNNING

Job 결과 가져오기:

response_result= requests.get(url+'/'+job_id+'/results', headers=headers)

res_dict=response_result.json()

# Get results for the first PUB
counts=res_dict['results'][0]['data']['c']['samples']

print(counts[:20])

출력

['0x3', '0x0', '0x2', '0x1', '0x0', '0x3', '0x0', '0x3', '0x1', '0x2', '0x2', '0x0', '0x2', '0x0', '0x3', '0x3', '0x2', '0x0', '0x1', '0x0']

5. Qiskit Runtime 옵션 사용하기

오류 완화 기법을 사용하면 실행 시점의 장치 노이즈를 모델링하여 Circuit 오류를 완화할 수 있습니다. 이는 일반적으로 모델 훈련과 관련된 양자 전처리 오버헤드와, 생성된 모델을 사용하여 원시 결과의 오류를 완화하기 위한 고전 후처리 오버헤드를 초래합니다.

Primitive에 내장된 오류 완화 기법은 고급 복원력 옵션입니다. 이러한 옵션을 지정하려면 Job을 제출할 때 resilience_level 옵션을 사용하세요. Sampler V2는 복원력 레벨 지정을 지원하지 않습니다. 그러나 개별 오류 완화/억제 방법을 켜거나 끌 수 있습니다.

다음 예제에서는 동적 분리 및 트월링의 기본 옵션을 보여줍니다. 더 많은 옵션과 자세한 내용은 오류 완화 및 억제 기법 항목을 참조하세요.

동적 분리

import requests

url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"

headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[resulting_qasm]],
"options": {
"dynamical_decoupling": {
"enable": True,
"sequence_type": 'XpXm',
"extra_slack_distribution": 'middle',
"scheduling_method": 'alap',
},
},
}
}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")

트월링

import requests

url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"

headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[resulting_qasm]],
"options": {
"twirling": {
"enable_gates": True,
"enable_measure": True,
"num_randomizations": "auto",
"shots_per_randomization": "auto",
"strategy": "active-accum",
},
},
}
}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")

매개변수화된 Circuit

1. 계정 초기화

Qiskit Runtime은 관리형 서비스이므로 먼저 계정을 초기화해야 합니다. 그런 다음 계산을 실행할 장치를 선택할 수 있습니다.

계정 초기화, 사용 가능한 Backend 확인, 토큰 무효화 방법에 대한 자세한 내용은 이 항목을 참조하세요.

2. 매개변수 정의

import requests
import qiskit_ibm_runtime
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.qasm3 import dumps
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit import transpile

service = QiskitRuntimeService(channel='ibm_quantum')
backend = service.backend("<SPECIFY BACKEND>")

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)

theta = Parameter('theta')
phi = Parameter('phi')
# In case we want to pass a dictionary:
parameter_values = {'theta': 1.57, 'phi': 3.14}

3. 양자 Circuit 생성 및 매개변수화된 게이트 추가

qc = QuantumCircuit(2)

# Add parameterized gates
qc.rx(theta, 0)
qc.ry(phi, 1)
qc.cx(0, 1)
qc.measure_all()

# Draw the original circuit
qc.draw('mpl')

# Get an ISA circuit
isa_circuit = pm.run(qc)

4. QASM 3 코드 생성

qasm_str = dumps(isa_circuit)
print("Generated QASM 3 code:")
print(qasm_str)

5. Sampler V2 API를 사용하여 양자 Circuit 실행

import requests

url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"

headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}

job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
# Choose one option: direct parameter transfer or through a dictionary
# # primitive unified blocs (PUBs) containing one circuit each:
#"pubs": [[qasm_str,[1,2],500]],

# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[qasm_str,parameter_values,500]],
}}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print(f"Job created: {response.text}")
else:
print(f"Error: {response.status_code}")
print(response.text)

6. Job 상태 확인 및 결과 가져오기

다음으로, job_id를 API에 전달합니다:

response_status_singlejob = requests.get(f"{url}/{job_id}", headers=headers)
response_status_singlejob.json().get('state')

출력

{'status': 'Completed'}

Job 결과 가져오기:

response_result = requests.get(f"{url}/{job_id}/results", headers=headers)

res_dict=response_result.json()

# Get results for the first PUB
counts=res_dict['results'][0]['data']['c']['samples']

print(counts[:20])

출력

['0x1', '0x2', '0x1', '0x2', '0x1', '0x2', '0x0', '0x2', '0x1', '0x1', '0x2', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1']

다음 단계

권장 사항
  • 워크로드를 실행하는 방법은 필요에 따라 여러 가지가 있습니다: Job 모드, 세션 모드, 배치 모드. 세션 모드와 배치 모드를 사용하는 방법은 실행 모드 항목에서 알아보세요. Open Plan 사용자는 세션 Job을 제출할 수 없습니다.
  • REST API를 사용하여 계정을 초기화하는 방법을 알아보세요.
  • IBM Quantum Learning의 비용 함수 레슨을 통해 Primitive 연습을 하세요.
  • Transpile 섹션에서 로컬 트랜스파일 방법을 알아보세요.