ข้ามไปยังเนื้อหาหลัก
โครงการนี้อยู่ในช่วงเบต้า พบข้อผิดพลาด? สร้าง GitHub Issue มีคำถามหรือไอเดีย? ถามใน Discussions — ยินดีรับฟังความคิดเห็น!
คุณภาพการแปลในหน้านี้เป็นอย่างไร?

รันงานใน Session

เวอร์ชันของแพ็กเกจ

โค้ดในหน้านี้พัฒนาขึ้นโดยใช้ requirement ต่อไปนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า

qiskit[all]~=2.5.2
qiskit-ibm-runtime~=0.47.0
scipy~=1.17.1
หมายเหตุ

ผู้ใช้แผน Open ไม่สามารถส่ง session job ได้ งานต้องรันในโหมด job mode หรือ batch mode

ใช้ Session เมื่อต้องการสิทธิ์เข้าถึง QPU แบบเฉพาะและผูกขาด

ตั้งค่าเพื่อใช้งาน Session​

ก่อนเริ่ม session ต้องตั้งค่า IBM Quantum Compute client และ initialize เป็น service ก่อน:

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"numpy": "numpy", "qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime", "scipy": "scipy"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
from qiskit_ibm_runtime import QiskitRuntimeService, Session, Executor

# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Sampler, Estimator

# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_sampler import Sampler
from qiskit_ibm_runtime.executor_estimator import Estimator

service = QiskitRuntimeService()

เปิด Session​

เปิด runtime session ได้โดยใช้ context manager with Session(...) หรือสร้าง instance ของ class Session เมื่อเริ่ม session ต้องระบุ QPU โดยส่ง object backend เข้าไป session จะเริ่มทำงานเมื่อ job แรกเริ่ม execute

หมายเหตุ

ถ้าเปิด session แต่ไม่ส่ง job ใดเลยเป็นเวลา 30 นาที session จะปิดโดยอัตโนมัติ

Session class

ข้อควรระวัง

โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น

backend = service.least_busy(operational=True, simulator=False)
session = Session(backend=backend)
estimator = Estimator(mode=session)
sampler = Sampler(mode=session)
executor = Executor(mode=session)
# Close the session because no context manager was used.
session.close()

Context manager

Context manager จะเปิดและปิด session โดยอัตโนมัติ

ข้อควรระวัง

โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น

from qiskit_ibm_runtime import Session, Executor

# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Sampler, Estimator

# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_sampler import Sampler
from qiskit_ibm_runtime.executor_estimator import Estimator

backend = service.least_busy(operational=True, simulator=False)
with Session(backend=backend):
estimator = Estimator()
sampler = Sampler()
executor = Executor()

ระยะเวลา Session​

เวลาสูงสุดที่ session จะมีชีวิต (TTL) กำหนดว่า session จะรันได้นานแค่ไหน ตั้งค่านี้ได้ด้วย parameter max_time ควรตั้งให้มากกว่าเวลา execute ของ job ที่ยาวที่สุด

timer นี้เริ่มนับเมื่อ session เริ่มทำงาน เมื่อถึงค่าที่กำหนด session จะปิดลง job ที่กำลังรันอยู่จะทำงานจนเสร็จ แต่ job ที่ยังรออยู่ใน queue จะถูก fail

ข้อควรระวัง

โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น

with Session(backend=backend, max_time="25m"):
...

นอกจากนี้ยังมีค่า interactive time to live (interactive TTL) ที่ไม่สามารถปรับแต่งได้ ถ้าไม่มี session job ถูก queue ภายในช่วงเวลานั้น session จะถูกปิดการใช้งานชั่วคราว

ค่าเริ่มต้น:

ประเภท Instance (แผน Open หรือ Premium)Interactive TTLMaximum TTL
Premium Plan60 วินาที*8 ชั่วโมง*

* instance บางส่วนของ Premium Plan อาจตั้งค่าไว้แตกต่างออกไป

เพื่อดู max TTL หรือ interactive TTL ของ session ให้ทำตามขั้นตอนใน ดูรายละเอียด session และหาค่า max_time หรือ interactive_timeout ตามลำดับ

สิ้นสุด Session​

Session สิ้นสุดในกรณีต่อไปนี้:

  • ถึงค่า timeout สูงสุด (TTL) ส่งผลให้ job ทั้งหมดที่อยู่ใน queue ถูกยกเลิก

  • Session ถูกยกเลิกด้วยตนเอง ส่งผลให้ job ทั้งหมดที่อยู่ใน queue ถูกยกเลิก

  • Session ถูกปิดด้วยตนเอง session จะหยุดรับ job ใหม่แต่ยังคงรัน job ที่อยู่ใน queue ต่อไปโดยได้รับสิทธิ์ก่อน

  • ถ้าใช้ Session เป็น context manager นั่นคือ with Session() session จะปิดโดยอัตโนมัติเมื่อ context สิ้นสุด (พฤติกรรมเดียวกับการใช้ session.close())

ปิด Session​

Session จะปิดโดยอัตโนมัติเมื่อออกจาก context manager เมื่อออกจาก session context manager แล้ว session จะเข้าสู่สถานะ "In progress, not accepting new jobs" หมายความว่า session จะยังคงประมวลผล job ที่กำลังรันหรืออยู่ใน queue ทั้งหมดจนกว่าจะถึงค่า maximum timeout หลังจาก job ทั้งหมดเสร็จสิ้น session จะปิดทันที วิธีนี้ช่วยให้ scheduler รัน job ถัดไปได้โดยไม่ต้องรอ session interactive timeout จึงลดเวลา queue เฉลี่ยของ job ไม่สามารถส่ง job ไปยัง session ที่ปิดแล้วได้

ข้อควรระวัง

โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น

from qiskit.quantum_info import SparsePauliOp
from qiskit.circuit import QuantumCircuit, Parameter
from qiskit.transpiler import generate_preset_pass_manager
import numpy as np

# This cell is hidden from users
service = QiskitRuntimeService()
backend = service.least_busy()

# Define two circuits, each with one parameter with two parameters.
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.ry(Parameter("a"), 0)
circuit.cx(0, 1)
circuit.h(0)
circuit.measure_all()

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
transpiled_circuit = pm.run(circuit)
transpiled_circuit_sampler = transpiled_circuit
transpiled_circuit_sampler.measure_all()

# Create parameters and mapped observables to submit
params = np.random.uniform(size=(2, 3)).T
observables = [
SparsePauliOp(["XX", "IY"], [0.5, 0.5]),
SparsePauliOp("XX"),
SparsePauliOp("IY"),
]
mapped_observables = [
[observable.apply_layout(transpiled_circuit.layout)]
for observable in observables
]

sampler_pub = (transpiled_circuit_sampler, params)
estimator_pub = (transpiled_circuit_sampler, mapped_observables, params)
with Session(backend=backend) as session:
estimator = Estimator()
sampler = Sampler()
job1 = estimator.run([estimator_pub])
job2 = sampler.run([sampler_pub])

# The session is no longer accepting jobs but the submitted job will run to completion.
result = job1.result()
result2 = job2.result()
เคล็ดลับ

ถ้าไม่ได้ใช้ context manager ให้ปิด session ด้วยตนเองเพื่อหลีกเลี่ยงค่าใช้จ่ายที่ไม่ต้องการ ปิด session ได้ทันทีที่ส่ง job ครบแล้ว เมื่อปิด session ด้วย session.close() session จะไม่รับ job ใหม่ แต่ job ที่ส่งไปแล้วจะยังคงรันจนเสร็จและดึงผลลัพธ์ได้

ข้อควรระวัง

โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น

session = Session(backend=backend)

# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `session=`
estimator = Estimator(mode=session)
sampler = Sampler(mode=session)
job1 = estimator.run([estimator_pub])
job2 = sampler.run([sampler_pub])
print(f"Result1: {job1.result()}")
print(f"Result2: {job2.result()}")

# Manually close the session. Running and queued jobs will run to completion.
session.close()
Result1: PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(3, 2), dtype=float64>), stds=np.ndarray(<shape=(3, 2), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 2), dtype=float64>), shape=(3, 2)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})
Result2: PrimitiveResult([SamplerPubResult(data=DataBin(meas=BitArray(<shape=(3, 2), num_shots=4096, num_bits=2>), meas0=BitArray(<shape=(3, 2), num_shots=4096, num_bits=156>), shape=(3, 2)), metadata={'circuit_metadata': {}})], metadata={'execution': {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-09-01 08:34:17', stop='2026-09-01 08:34:24', size=24576>)])}, 'version': 2})

ตรวจสอบสถานะ Session​

ดูสถานะของ session เพื่อทำความเข้าใจสถานะปัจจุบันได้ด้วย session.status() หรือดูที่หน้า Workloads

สถานะของ session มีได้ดังนี้:

  • Pending: Session ยังไม่เริ่มหรือถูกปิดการใช้งานชั่วคราว session job ถัดไปต้องรอใน queue เหมือน job ทั่วไป

  • In progress, accepting new jobs: Session กำลังทำงานและรับ job ใหม่ได้

  • In progress, not accepting new jobs: Session กำลังทำงานแต่ไม่รับ job ใหม่ การส่ง job เข้า session จะถูกปฏิเสธ แต่ session job ที่ค้างอยู่จะรันจนเสร็จ session จะปิดโดยอัตโนมัติเมื่อ job ทั้งหมดเสร็จ

  • Closed: ถึงค่า maximum timeout ของ session หรือ session ถูกปิดอย่างชัดเจน

ดูรายละเอียด Session​

ถ้าต้องการดูภาพรวมของการตั้งค่าและสถานะของ session ให้ใช้ session.details() method

ข้อควรระวัง

โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น

from qiskit_ibm_runtime import QiskitRuntimeService, Session

# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Estimator

# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_estimator import Estimator

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

with Session(backend=backend) as session:
print(session.details())
{'id': 'ff7977a5-ae7b-4509-9c84-bd1d7ff9f619', 'backend_name': 'ibm_marrakesh', 'interactive_timeout': 60, 'max_time': 28800, 'active_timeout': 28800, 'state': 'open', 'accepting_jobs': True, 'last_job_started': None, 'last_job_completed': None, 'started_at': None, 'closed_at': None, 'activated_at': None, 'mode': 'dedicated', 'usage_time': None}

รูปแบบการใช้งาน​

Session มีประโยชน์อย่างมากสำหรับ algorithm ที่ต้องการการสื่อสารบ่อยครั้งระหว่าง classical และ quantum resources

ตัวอย่าง: รัน iterative workload ที่ใช้ classical SciPy optimizer เพื่อ minimize cost function ในโมเดลนี้ SciPy ใช้ output ของ cost function เพื่อคำนวณ input ถัดไป

ข้อควรระวัง

โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น

from scipy.optimize import minimize
from qiskit.circuit.library import efficient_su2

def cost_func(params, ansatz, hamiltonian, estimator):
# Return estimate of energy from estimator

energy = sum(
estimator.run([(ansatz, hamiltonian, params)]).result()[0].data.evs
)
return energy

hamiltonian = SparsePauliOp.from_list(
[("YZ", 0.3980), ("ZI", -0.3980), ("ZZ", -0.0113), ("XX", 0.1810)]
)
su2_ansatz = efficient_su2(hamiltonian.num_qubits)
pm = generate_preset_pass_manager(backend=backend, optimization_level=3)
ansatz = pm.run(su2_ansatz)
mapped_hamiltonian = [
operator.apply_layout(ansatz.layout) for operator in hamiltonian
]

num_params = ansatz.num_parameters
x0 = 2 * np.pi * np.random.random(num_params)

session = Session(backend=backend)

# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `session=`
estimator = Estimator(mode=session, options={"default_shots": int(1e4)})
res = minimize(
cost_func,
x0,
args=(ansatz, mapped_hamiltonian, estimator),
method="cobyla",
options={"maxiter": 25},
)

# Close the session because no context manager was used.
session.close()

รัน VQE สองตัวใน Session โดยใช้ threading​

ใช้ประโยชน์จาก session ได้มากขึ้นด้วยการรัน workload หลายรายการพร้อมกัน ตัวอย่างต่อไปนี้แสดงวิธีการรัน VQE algorithm สองตัวที่ใช้ classical optimizer ต่างกัน พร้อมกันภายใน session เดียว มีการใช้ job tag เพื่อแยกแยะ job จาก workload แต่ละรายการด้วย

ข้อควรระวัง

โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น

from concurrent.futures import ThreadPoolExecutor

# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Estimator

# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_estimator import Estimator

def minimize_thread(estimator, method):
return minimize(
cost_func,
x0,
args=(ansatz, mapped_hamiltonian, estimator),
method=method,
options={"maxiter": 25},
)

with Session(backend=backend), ThreadPoolExecutor() as executor:
estimator1 = Estimator()
estimator2 = Estimator()

# Use different tags to differentiate the jobs.
estimator1.options.environment.job_tags = ["cobyla"]
estimator2.options.environment.job_tags = ["nelder-mead"]

# Submit the two workloads.
cobyla_future = executor.submit(minimize_thread, estimator1, "cobyla")
nelder_mead_future = executor.submit(
minimize_thread, estimator2, "nelder-mead"
)

# Get workload results.
cobyla_result = cobyla_future.result()
nelder_mead_result = nelder_mead_future.result()

ขั้นตอนถัดไป​

คำแนะนำ