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

รันงานในโหมด Batch

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

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

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1

ใช้โหมด batch เพื่อส่ง primitive job หลายรายการพร้อมกัน ต่อไปนี้เป็นตัวอย่างการทำงานกับ batch

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

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

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime import (
QiskitRuntimeService,
Batch,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)

service = QiskitRuntimeService()

เปิด batch

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

Batch class

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

Context manager

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

from qiskit_ibm_runtime import (
Batch,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)

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

ระยะเวลา Batch

กำหนดเวลาสูงสุดที่ batch จะมีชีวิต (TTL) ได้ด้วย parameter max_time ควรตั้งค่าให้มากกว่าเวลา execute ของ job ที่ยาวที่สุด timer นี้เริ่มนับเมื่อ batch เริ่มทำงาน เมื่อถึงค่าที่กำหนด batch จะปิดลง job ที่กำลังรันอยู่จะทำงานจนเสร็จ แต่ job ที่ยังรออยู่ใน queue จะถูก fail

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

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

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

ประเภท InstanceMaximum TTL เริ่มต้น
แผนแบบเสียเงินทุกประเภท8 ชั่วโมง
Open10 นาที

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

ปิด batch

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

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()

params = np.random.uniform(size=(2, 3)).T
observables = [
[
SparsePauliOp(["XX", "IY"], [0.5, 0.5]).apply_layout(
transpiled_circuit.layout
)
],
[SparsePauliOp("XX").apply_layout(transpiled_circuit.layout)],
[SparsePauliOp("IY").apply_layout(transpiled_circuit.layout)],
]

sampler_pub = (transpiled_circuit_sampler, params)
estimator_pub = (transpiled_circuit_sampler, observables, params)
with Batch(backend=backend) as batch:
estimator = Estimator()
sampler = Sampler()
job1 = estimator.run([estimator_pub])
job2 = sampler.run([sampler_pub])

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

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

batch = Batch(backend=backend)

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

# Manually close the batch. Running and queued jobs will run to completion.
batch.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:47:58', stop='2026-01-15 07:48:05', size=24576>)])}, 'version': 2})

ดูรายละเอียด batch

เพื่อดูภาพรวมโดยละเอียดของการตั้งค่าและสถานะของ batch รวมถึง interactive และ max TTL ให้ใช้ method batch.details()

from qiskit_ibm_runtime import (
QiskitRuntimeService,
batch,
SamplerV2 as Sampler,
)

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

with Batch(backend=backend) as batch:
print(batch.details())
{'id': 'ce8cf08d-b18e-4d56-ab51-eaff0b8190f4', 'backend_name': 'ibm_torino', 'interactive_timeout': 1, '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': 'batch', 'usage_time': None}

ปรับแต่ง job เพื่อประมวลผลแบบขนาน

มีหลายวิธีในการปรับแต่ง job เพื่อใช้ประโยชน์จากการประมวลผลแบบขนานที่ batch มอบให้ ตัวอย่างต่อไปนี้แสดงวิธีการแบ่ง Circuit รายการยาวออกเป็น job หลายรายการและรันเป็น batch เพื่อใช้ประโยชน์จากการประมวลผลแบบขนาน

from qiskit_ibm_runtime import SamplerV2 as Sampler, Batch
from qiskit.circuit.random import random_circuit

max_circuits = 100
circuits = [pm.run(random_circuit(5, 5)) for _ in range(5 * max_circuits)]
for circuit in circuits:
circuit.measure_active()
all_partitioned_circuits = []
for i in range(0, len(circuits), max_circuits):
all_partitioned_circuits.append(circuits[i : i + max_circuits])
jobs = []
start_idx = 0

with Batch(backend=backend):
sampler = Sampler()
for partitioned_circuits in all_partitioned_circuits:
job = sampler.run(partitioned_circuits)
jobs.append(job)
ข้อควรระวัง

ถ้าตั้งค่า backend=backend ใน primitive โปรแกรมจะรันในโหมด job แม้จะอยู่ภายใน batch หรือ session context ก็ตาม การตั้งค่า backend=backend เป็น deprecated ตั้งแต่ Qiskit Runtime v0.24.0 แนะนำให้ใช้ parameter mode แทน

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

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