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

อินพุตและเอาต์พุตของ Estimator

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

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

qiskit[all]~=2.5.2
qiskit-ibm-runtime~=0.47.0

หน้านี้ให้ภาพรวมของอินพุตและเอาต์พุตของ Estimator primitive ของ IBM Quantum ซึ่งรัน workloads บน IBM Quantum® compute resources Estimator ให้คุณกำหนด vectorized workloads ได้อย่างมีประสิทธิภาพโดยใช้โครงสร้างข้อมูลที่เรียกว่า Primitive Unified Bloc (PUB) ซึ่งใช้เป็น inputs ของเมธอด run() สำหรับ Estimator primitive ซึ่งรัน workload ที่กำหนดเป็น job จากนั้น หลังจาก job เสร็จสิ้น ผลลัพธ์จะถูกส่งคืนในรูปแบบที่ขึ้นอยู่กับทั้ง PUBs ที่ใช้และ runtime options ที่ระบุจาก primitive

Inputs​

แต่ละ PUB อยู่ในรูปแบบนี้:

(<single circuit>, <one or more observables>, <optional one or more parameter values>, <optional precision>),

ตัวเลือก parameter values สามารถเป็น list หรือ parameter เดียวก็ได้ Elements จาก observables และ parameter values จะถูกรวมกันโดยทำตาม NumPy broadcasting rules ตามที่อธิบายในหัวข้อ Primitive inputs and outputs และจะคืนค่า expectation value estimate หนึ่งค่าสำหรับแต่ละ element ของ broadcasted shape

ข้อมูล

ถ้า input มีการวัด จะถูก ignore

สำหรับ Estimator primitive PUB สามารถมีได้สูงสุดสี่ค่า:

  • QuantumCircuit เดียว ซึ่งอาจมี object Parameter หนึ่งรายการหรือมากกว่า
  • List ของ observables หนึ่งรายการหรือมากกว่า ซึ่งระบุ expectation values ที่จะประมาณ จัดเป็น array (ตัวอย่างเช่น observable เดียวแสดงเป็น 0-d array, list ของ observables เป็น 1-d array และอื่นๆ) ข้อมูลสามารถอยู่ในรูปแบบ ObservablesArrayLike ใดก็ได้ เช่น Pauli, SparsePauliOp, PauliList หรือ str
    Commuting observables
    • Commuting observables ใน PUB เดียวกัน จะถูกจัดกลุ่มโดยใช้ วิธีนี้
    • Commuting observables ใน PUBs ที่แตกต่างกัน แม้ว่าจะมี circuit เดียวกัน จะไม่ถูกประมาณโดยใช้การวัดเดียวกัน แต่ละ PUB แสดง basis ที่แตกต่างกันสำหรับการวัด ดังนั้น จำเป็นต้องวัดแยกกันสำหรับแต่ละ PUB
    • เพื่อให้แน่ใจว่า commuting observables ถูกประมาณโดยใช้การวัดเดียวกัน จัดกลุ่มไว้ใน PUB เดียวกัน
  • คอลเลกชันของค่า parameter ที่จะ bind เข้ากับ circuit ซึ่งระบุเป็น array-like object เดียว โดย index สุดท้ายไล่ตาม circuit Parameter objects หรือละเว้น (หรือเทียบเท่ากัน ตั้งเป็น None) ถ้า circuit ไม่มี Parameter objects
  • (ทางเลือก) Target precision สำหรับ expectation values ที่จะประมาณ

โค้ดต่อไปนี้แสดงตัวอย่างชุดอินพุตแบบเวกเตอร์ไปยัง primitive Estimator และรันบน backend ของ IBM® ในรูปแบบอ็อบเจ็กต์ RuntimeJobV2 เดียว

# 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"}
_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.circuit import (
Parameter,
QuantumCircuit,
)
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp

from qiskit_ibm_runtime import QiskitRuntimeService

# 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

import numpy as np

# Instantiate runtime service and get
# the least busy backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

# Define a circuit with two parameters.
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.ry(Parameter("a"), 0)
circuit.rz(Parameter("b"), 0)
circuit.cx(0, 1)
circuit.h(0)

# Transpile the circuit
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
transpiled_circuit = pm.run(circuit)
layout = transpiled_circuit.layout

# Now define a sweep over parameter values, the last axis of dimension 2 is
# for the two parameters "a" and "b"
params = np.vstack(
[
np.linspace(-np.pi, np.pi, 100),
np.linspace(-4 * np.pi, 4 * np.pi, 100),
]
).T

# Define three observables. The inner length-1 lists cause this array of
# observables to have shape (3, 1), rather than shape (3,) if they were
# omitted.
observables = [
[SparsePauliOp(["XX", "IY"], [0.5, 0.5])],
[SparsePauliOp("XX")],
[SparsePauliOp("IY")],
]
# Apply the same layout as the transpiled circuit.
observables = [
[observable.apply_layout(layout) for observable in observable_set]
for observable_set in observables
]

# Estimate the expectation value for all 300 combinations of observables
# and parameter values, where the pub result will have shape (3, 100).
#
# This shape is due to our array of parameter bindings having shape
# (100, 2), combined with our array of observables having shape (3, 1).
estimator_pub = (transpiled_circuit, observables, params)

# Instantiate the new Estimator object, then run the transpiled circuit
# using the set of parameters and observables.
estimator = Estimator(mode=backend)
job = estimator.run([estimator_pub])
result = job.result()

Outputs​

หลังจากส่ง PUBs หนึ่งรายการหรือมากกว่าไปยัง QPU เพื่อรัน และ job เสร็จสำเร็จ ข้อมูลจะถูกส่งคืนเป็น container object PrimitiveResult ที่เข้าถึงได้โดยการเรียกเมธอด RuntimeJobV2.result()

PrimitiveResult มี iterable list ของ object PubResult ที่มีผลการรันสำหรับแต่ละ PUB

แต่ละ element ของ list นี้สอดคล้องกับแต่ละ PUB ที่ส่งไปยังเมธอด run() ของ primitive (ตัวอย่างเช่น job ที่ส่งกับ 20 PUBs จะส่งคืน PrimitiveResult object ที่มี list ของ PubResult objects 20 รายการ หนึ่งสอดคล้องกับแต่ละ PUB)

แต่ละ PubResult สำหรับ Estimator primitive มีอย่างน้อย array ของ expectation values (PubResult.data.evs) และ standard deviations ที่เกี่ยวข้อง (ไม่ว่าจะเป็น PubResult.data.stds หรือ PubResult.data.ensemble_standard_error ขึ้นอยู่กับ resilience_level ที่ใช้) แต่อาจมีข้อมูลเพิ่มเติมขึ้นอยู่กับ error mitigation options ที่ระบุ

แต่ละ PubResult object มีทั้ง data และ metadata attribute

  • Attribute data เป็น DataBin ที่กำหนดเองซึ่งมีค่าการวัดจริง standard deviations และอื่นๆ
  • DataBin มี attributes ต่างๆ ขึ้นอยู่กับ shape หรือโครงสร้างของ PUB ที่เกี่ยวข้อง รวมถึง error mitigation options ที่ระบุโดย primitive ที่ใช้ส่ง job (เช่น ZNE หรือ PEC)
  • Attribute metadata มีข้อมูลเกี่ยวกับ runtime และ error mitigation options ที่ใช้ (อธิบายในส่วน Result metadata ของหน้านี้)

ต่อไปนี้คือโครงร่างภาพของโครงสร้างข้อมูล PrimitiveResult สำหรับ Estimator output:

└── PrimitiveResult
├── PubResult[0]
│ ├── metadata
│ └── data ## In the form of a DataBin object
│ ├── evs
│ │ └── List of estimated expectation values in the shape
| | specified by the first pub
│ └── stds
│ └── List of calculated standard deviations in the
| same shape as above
├── PubResult[1]
| ├── metadata
| └── data ## In the form of a DataBin object
| ├── evs
| │ └── List of estimated expectation values in the shape
| | specified by the second pub
| └── stds
| └── List of calculated standard deviations in the
| same shape as above
├── ...
├── ...
└── ...

พูดง่ายๆ คือ job เดียวส่งคืน PrimitiveResult object และมี list ของ PubResult objects หนึ่งรายการหรือมากกว่า PubResult objects เหล่านี้เก็บข้อมูลการวัดสำหรับแต่ละ PUB ที่ส่งไปยัง job

code snippet ด้านล่างอธิบายรูปแบบ PrimitiveResult (และ PubResult ที่เกี่ยวข้อง) สำหรับ job ที่สร้างด้านบน

print(
f"The result of the submitted job had {len(result)} "
f"PUBs and has a value:\n {result}\n"
)
print(
"The associated PubResult of this job has the following data bins:\n "
"{result[0].data}\n"
)
print(f"And this DataBin has attributes: {result[0].data.keys()}")
print(
"Recall that this shape is due to our array of parameter binding sets"
"having shape (100, 2), where 2 is the number of parameters in the "
"circuit, combined with our array of observables having shape (3, 1). \n"
)
with np.printoptions(threshold=200):
print(
"The expectation values measured from this PUB are: \n"
"{result[0].data.evs}\n"
)
The result of the submitted job had 1 PUBs and has a value:
PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(3, 100), dtype=float64>), stds=np.ndarray(<shape=(3, 100), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 100), dtype=float64>), shape=(3, 100)), 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})

The associated PubResult of this job has the following data bins:
{result[0].data}

And this DataBin has attributes: dict_keys(['evs', 'stds', 'ensemble_standard_error'])
Recall that this shape is due to our array of parameter binding setshaving shape (100, 2), where 2 is the number of parameters in the circuit, combined with our array of observables having shape (3, 1).

The expectation values measured from this PUB are:
{result[0].data.evs}

วิธีที่ Estimator primitive คำนวณ error​

นอกจากการประมาณ mean ของ observables ที่ส่งใน input PUBs (field evs ของ DataBin) Estimator ยังพยายามให้การประมาณ error ที่เกี่ยวข้องกับ expectation values เหล่านั้น Estimator queries ทั้งหมดจะ populate field stds ด้วยปริมาณที่คล้ายกับ standard error of the mean สำหรับแต่ละ expectation value แต่ error mitigation options บางอย่างให้ข้อมูลเพิ่มเติม เช่น ensemble_standard_error

พิจารณา observable เดียว O\mathcal{O} ในกรณีที่ไม่มี ZNE คุณสามารถคิดว่าแต่ละ shot ของการรัน Estimator ให้ point estimate ของ expectation value ⟨O⟩\langle \mathcal{O} \rangle ถ้า pointwise estimates อยู่ใน vector Os ค่าที่ส่งคืนใน ensemble_standard_error เทียบเท่ากับสิ่งต่อไปนี้ (ใน σO\sigma_{\mathcal{O}} คือ standard deviation ของ expectation value estimate และ NshotsN_{shots} คือจำนวน shots):

σONshots,\frac{ \sigma_{\mathcal{O}} }{ \sqrt{N_{shots}} },

ซึ่งถือว่า shots ทั้งหมดเป็นส่วนหนึ่งของ ensemble เดียว ถ้าคุณร้องขอ gate twirling (twirling.enable_gates = True) คุณสามารถจัด pointwise estimates ของ ⟨O⟩\langle \mathcal{O} \rangle เป็น sets ที่แบ่งปัน twirl ร่วม เรียก sets ของ estimates เหล่านี้ว่า O_twirls ซึ่งมีทั้งหมด num_randomizations ชุด (เท่ากับจำนวน twirls) จากนั้น stds คือ standard error of the mean ของ O_twirls ดังใน

σONtwirls,\frac{ \sigma_{\mathcal{O}} }{ \sqrt{N_{twirls}} },

โดยที่ σO\sigma_{\mathcal{O}} คือ standard deviation ของ O_twirls และ NtwirlsN_{twirls} คือจำนวน twirls เมื่อคุณไม่เปิดใช้งาน twirling stds และ ensemble_standard_error จะเท่ากัน

ถ้าคุณเปิดใช้งาน ZNE stds ที่อธิบายด้านบนจะกลายเป็น weights ใน non-linear regression ไปยัง extrapolator model สิ่งที่ส่งคืนใน stds ในกรณีนี้คือความไม่แน่นอนของ fit model ที่ประเมินที่ noise factor เป็นศูนย์ เมื่อ fit ไม่ดีหรือมีความไม่แน่นอนในการ fit มาก stds ที่รายงานอาจมีขนาดใหญ่มาก เมื่อเปิดใช้งาน ZNE pub_result.data.evs_noise_factors และ pub_result.data.stds_noise_factors ก็จะ populate ด้วย เพื่อให้คุณสามารถ extrapolate ด้วยตัวเอง

Metadata ของผลลัพธ์​

นอกจากผลการรัน ทั้ง PrimitiveResult และ PubResult objects มี metadata attribute เกี่ยวกับ job ที่ส่ง metadata ที่มีข้อมูลสำหรับ PUBs ที่ส่งทั้งหมด (เช่น runtime options ต่างๆ ที่มี) สามารถพบได้ใน PrimitiveResult.metatada ในขณะที่ metadata เฉพาะสำหรับแต่ละ PUB พบได้ใน PubResult.metadata

Estimator ฝั่ง client ส่งเวิร์กโหลดของมันเป็น Job ของ Executor เมทาดาทาของผลลัพธ์ Executor เบื้องหลัง ซึ่งรวมข้อมูลเวลาการรันที่เรียกว่า execution spans อยู่ภายใต้ key "executor" ของ PrimitiveResult.metadata

หมายเหตุ

ในฟิลด์ metadata primitive แต่ละ implementation สามารถส่งคืนข้อมูลใดๆ เกี่ยวกับการรันที่เกี่ยวข้องกับตัวเองได้ และไม่มี key-value pairs ที่รับประกันโดย base primitive ดังนั้น metadata ที่ส่งคืนอาจแตกต่างกันใน implement primitive ที่แตกต่างกัน

# Print out the results metadata
print("The metadata of the PrimitiveResult is:")
for key, val in result.metadata.items():
print(f"'{key}' : {val},")

print("\nThe metadata of the PubResult result is:")
for key, val in result[0].metadata.items():
print(f"'{key}' : {val},")
The metadata of the PrimitiveResult is:
'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,

The metadata of the PubResult result is:
'shots' : 4096,
'target_precision' : 0.015625,
'circuit_metadata' : {},
'resilience' : {},
'num_randomizations' : 32,

ดู execution span​

Estimator ฝั่ง client รันเป็น Job ของ Executor ซึ่งรันงานบน QPU เป็น chunk เวลาของแต่ละ chunk อยู่ใน result.metadata["executor"].chunk_timing ซึ่งเป็นลิสต์ของอ็อบเจกต์ ChunkSpan แต่ละ ChunkSpan มี timestamp start และ stop และลิสต์ของ parts โดยแต่ละ part ระบุ index ของ item (idx_item) และจำนวน configuration จาก item นั้น (size) ที่รันใน chunk

idx_item คือ index ของ item ในโปรแกรม Executor ที่ Estimator สร้างจาก PUB ของคุณ ซึ่งไม่จำเป็นต้องตรงกับ index ของ PUB เพราะ Estimator อาจเพิ่ม program item ขึ้นอยู่กับตัวเลือก error mitigation เช่น มันเพิ่ม Circuit สำหรับ calibration ข้อผิดพลาดการวัดเมื่อเปิดใช้ TREX

หากต้องการ visualize เวลา ให้ส่งลิสต์ไปยัง draw_chunk_timings ดังที่แสดงในตัวอย่างต่อไปนี้

หากต้องการทราบว่า timestamp ของ chunk หมายถึงอะไร อ่านพล็อตอย่างไร และเหตุใดจึงเกิดช่องว่างระหว่าง chunk ได้ ดู View execution spans ในคู่มือ Executor inputs and outputs

from qiskit_ibm_runtime.visualization import draw_chunk_timings

# Note the "executor" key: the timing comes from the underlying Executor job
chunk_timing = result.metadata["executor"].chunk_timing

for idx, span in enumerate(chunk_timing):
duration = (span.stop - span.start).total_seconds()
print(f"Chunk {idx}: {span.start} to {span.stop} ({duration:.3f} s)")
for part in span.parts:
print(f" Item {part.idx_item}: {part.size} configurations")

fig = draw_chunk_timings(chunk_timing, names="Estimator job")

# Uncomment the following line to display the figure
# fig.show(renderer="notebook")

# Save to a file
# fig.write_html("chunk_timings.html")
Chunk 0: 2026-11-06 01:39:01.509471+00:00 to 2026-11-06 01:39:35.171288+00:00 (33.662 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 1: 2026-11-06 01:39:48.299074+00:00 to 2026-11-06 01:40:21.826190+00:00 (33.527 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 2: 2026-11-06 01:40:22.855454+00:00 to 2026-11-06 01:40:53.781896+00:00 (30.926 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 3: 2026-11-06 01:40:54.993867+00:00 to 2026-11-06 01:41:26.068319+00:00 (31.074 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 4: 2026-11-06 01:41:41.019968+00:00 to 2026-11-06 01:42:15.956573+00:00 (34.937 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 5: 2026-11-06 01:42:47.834717+00:00 to 2026-11-06 01:43:21.436255+00:00 (33.602 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 6: 2026-11-06 01:43:22.698235+00:00 to 2026-11-06 01:43:53.647547+00:00 (30.949 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 7: 2026-11-06 01:43:54.710995+00:00 to 2026-11-06 01:44:25.762574+00:00 (31.052 s)
Item 0: 800 configurations
Item 1: 4 configurations