ข้ามไปยังเนื้อหาหลัก

รันงานใน Session

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

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

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
scipy~=1.16.3
หมายเหตุ

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

ใช้ Session เมื่อต้องการสิทธิ์การเข้าถึง QPU แบบ dedicated และ exclusive

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

ก่อนเริ่ม session ต้องตั้งค่า Qiskit Runtime และ initialize เป็น service ก่อน:

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime scipy
from qiskit_ibm_runtime import (
QiskitRuntimeService,
Session,
SamplerV2 as Sampler,
EstimatorV2 as 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)
# 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,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)

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

ระยะเวลา 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=133>), shape=(3, 2)), metadata={'circuit_metadata': {}})], metadata={'execution': {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-01-15 07:53:15', stop='2026-01-15 07:53:21', 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 ให้ใช้ method session.details()

ข้อควรระวัง

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

from qiskit_ibm_runtime import (
QiskitRuntimeService,
Session,
EstimatorV2 as Estimator,
)

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

with Session(backend=backend) as session:
print(session.details())
{'id': 'be84569d-86b5-4a7f-be5e-7d33e80dc220', 'backend_name': 'ibm_torino', '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
from qiskit_ibm_runtime import EstimatorV2 as 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()

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

คำแนะนำ
Source: IBM Quantum docs — updated 27 เม.ย. 2569
English version on doQumentation — updated 7 พ.ค. 2569
This translation based on the English version of 11 มี.ค. 2569