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

แนะนำ primitives

Package versions

The code on this page was developed using the following requirements. We recommend using these versions or newer.

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
โมเดลการรันใหม่ ขณะนี้อยู่ในช่วง beta

beta release ของโมเดลการรันใหม่พร้อมให้ใช้งานแล้ว โมเดล directed execution มอบความยืดหยุ่นมากขึ้นในการปรับแต่งขั้นตอน error mitigation ดูข้อมูลเพิ่มเติมได้ที่คู่มือ Directed execution model

ทำไม Qiskit ถึงแนะนำ primitives?

เช่นเดียวกับยุคแรกของคอมพิวเตอร์คลาสสิก ที่นักพัฒนาต้องจัดการ CPU register โดยตรง อินเทอร์เฟซแรกสุดของ QPU ก็แค่ส่งคืนข้อมูลดิบจากอุปกรณ์ควบคุมอิเล็กทรอนิกส์ เรื่องนี้ไม่ใช่ปัญหาใหญ่เมื่อ QPU ยังอยู่แค่ในห้องปฏิบัติการและให้เฉพาะนักวิจัยเข้าถึงโดยตรง เพื่อตอบโจทย์ที่นักพัฒนาส่วนใหญ่ไม่จำเป็นต้องรู้วิธีแปลงข้อมูลดิบเหล่านั้นเป็น 0 และ 1 Qiskit จึงแนะนำ backend.run ซึ่งเป็น abstraction แรกสำหรับการเข้าถึง QPU บนคลาวด์ ทำให้นักพัฒนาทำงานกับรูปแบบข้อมูลที่คุ้นเคยและโฟกัสกับภาพรวมได้มากขึ้น

เมื่อการเข้าถึง QPU แพร่หลายมากขึ้น และมีการพัฒนา quantum algorithm ใหม่ๆ มากมาย ความต้องการ abstraction ระดับสูงขึ้นก็เกิดขึ้นอีกครั้ง Qiskit จึงแนะนำอินเทอร์เฟซ primitives ที่ถูกออปติไมซ์สำหรับสองงานหลักในการพัฒนา quantum algorithm: การประมาณค่า expectation value (Estimator) และการสุ่มตัวอย่างจาก Circuit (Sampler) เป้าหมายคือช่วยให้นักพัฒนาโฟกัสที่นวัตกรรมมากขึ้นและลดเวลาที่ต้องใช้กับการแปลงข้อมูล อินเทอร์เฟซ primitives แทนที่อินเทอร์เฟซ backend.run เนื่องจาก Sampler ให้การเข้าถึง hardware โดยตรงแบบเดียวกับที่ backend.run เคยให้ไว้

primitive คืออะไร?

ระบบคอมพิวเตอร์ถูกสร้างขึ้นบน abstraction หลายชั้น abstraction ช่วยให้โฟกัสที่ระดับรายละเอียดที่เกี่ยวข้องกับงานนั้นๆ ได้ ยิ่งใกล้ hardware มากขึ้นเท่าไหร่ ระดับ abstraction ที่ต้องการก็ยิ่งต่ำลง (เช่น อาจต้องย้ายหรือจัดการข้อมูลในระดับคำสั่ง CPU) ยิ่งงานที่ต้องทำซับซ้อนมากขึ้นเท่าไหร่ abstraction ก็จะสูงขึ้น (เช่น อาจใช้ programming library สำหรับการคำนวณพีชคณิต)

ในบริบทนี้ primitive คือคำสั่งประมวลผลที่เล็กที่สุด บล็อคสร้างที่เรียบง่ายที่สุดที่สามารถสร้างสิ่งที่มีประโยชน์สำหรับระดับ abstraction ที่กำหนด

ความก้าวหน้าล่าสุดใน quantum computing ได้เพิ่มความจำเป็นในการทำงานที่ระดับ abstraction ที่สูงขึ้น เมื่อสาขานี้มุ่งไปสู่ quantum processing unit (QPU) ขนาดใหญ่และ workflow ที่ซับซ้อนขึ้น จุดโฟกัสจึงเปลี่ยนจากการโต้ตอบกับสัญญาณ Qubit แต่ละตัวไปสู่การมอง quantum device เป็นระบบที่ทำงานตามที่ต้องการ

สองงานที่พบบ่อยที่สุดสำหรับ quantum computer คือการสุ่มตัวอย่าง quantum state และการคำนวณ expectation value งานทั้งสองนี้เป็นแรงบันดาลใจในการออกแบบ Qiskit primitives: Estimator และ Sampler

  • Estimator คำนวณ expectation value ของ observable เทียบกับ state ที่เตรียมโดย quantum circuit
  • Sampler สุ่มตัวอย่างจาก output register จากการรัน quantum circuit

โดยสรุป โมเดลการคำนวณที่ Qiskit primitives แนะนำนั้นนำ quantum programming เข้าใกล้ classical programming ในปัจจุบันมากขึ้น ซึ่งโฟกัสน้อยลงที่รายละเอียด hardware และมากขึ้นที่ผลลัพธ์ที่ต้องการ

นิยามและการ implement primitives

Qiskit primitives มีสองประเภท: base class และ implementation ต่างๆ Qiskit primitives ถูกนิยามโดย primitive base class แบบ open-source ที่อยู่ใน Qiskit SDK (ใน module qiskit.primitives) Provider ต่างๆ (เช่น Qiskit Runtime) สามารถใช้ base class เหล่านี้เพื่อพัฒนา Sampler และ Estimator ของตนเอง ผู้ใช้ส่วนใหญ่จะโต้ตอบกับ provider implementation ไม่ใช่ base primitives โดยตรง

Base class

BaseEstimatorV2 และ BaseSamplerV2 - Abstract base class ที่นิยาม interface ทั่วไปสำหรับการ implement primitives คลาสอื่นๆ ทั้งหมดใน module qiskit.primitives สืบทอดจาก base class เหล่านี้ นักพัฒนาควรใช้สิ่งเหล่านี้หากสนใจสร้างโมเดลการรันแบบ primitives-based ของตนเองสำหรับ provider เฉพาะ class เหล่านี้อาจมีประโยชน์สำหรับผู้ที่ต้องการการประมวลผลแบบ custom สูงและพบว่า implementation primitives ที่มีอยู่ง่ายเกินไปสำหรับความต้องการของตน ผู้ใช้ทั่วไปจะไม่ใช้ base class โดยตรง

Implementations

นี่คือ implementation ของ primitives base class:

  • Qiskit Runtime primitives (EstimatorV2 และ SamplerV2) ให้ implementation ที่ซับซ้อนกว่า (เช่น รวม error mitigation) ในรูปแบบบริการบนคลาวด์ implementation นี้ของ base primitives ใช้สำหรับเข้าถึง IBM Quantum® hardware โดยเข้าถึงผ่าน IBM Qiskit Runtime

  • StatevectorEstimator และ StatevectorSampler - Reference implementation ของ primitives ที่ใช้ simulator ในตัวของ Qiskit สร้างด้วย Qiskit module quantum_info ผลิตผลลัพธ์จากการจำลอง statevector ที่สมบูรณ์แบบ เข้าถึงผ่าน Qiskit

  • BackendEstimatorV2 และ BackendSamplerV2 - ใช้ class เหล่านี้เพื่อ "ห่อ" ทรัพยากร quantum computing ใดก็ได้ให้เป็น primitive ทำให้เขียนโค้ดแบบ primitive-style สำหรับ provider ที่ยังไม่มีอินเทอร์เฟซแบบ primitives-based ใช้งาน class เหล่านี้เหมือน Sampler และ Estimator ปกติ ยกเว้นต้องระบุอาร์กิวเมนต์ backend เพิ่มเติมเพื่อเลือก quantum computer ที่ต้องการรัน เข้าถึงโดยใช้ Qiskit

ประโยชน์ของ Qiskit primitives

ด้วย primitives ผู้ใช้ Qiskit สามารถเขียน quantum code สำหรับ QPU เฉพาะโดยไม่ต้องจัดการทุกรายละเอียดอย่างชัดเจน นอกจากนี้ เนื่องจาก abstraction ชั้นเพิ่มเติม อาจเข้าถึงความสามารถ hardware ขั้นสูงของ provider ที่กำหนดได้ง่ายขึ้น ตัวอย่างเช่น ด้วย Qiskit Runtime primitives สามารถใช้ประโยชน์จากความก้าวหน้าล่าสุดใน error mitigation และ suppression โดยการสลับตัวเลือกเช่น resilience_level ของ primitive แทนที่จะสร้าง implementation ของเทคนิคเหล่านี้เอง

สำหรับ hardware provider การ implement primitives โดยตรงหมายความว่าให้วิธีที่ "ใช้งานได้ทันที" มากขึ้นสำหรับผู้ใช้เพื่อเข้าถึงฟีเจอร์ hardware เช่น เทคนิคการประมวลผลขั้นสูง จึงทำให้ผู้ใช้ได้รับประโยชน์จากความสามารถที่ดีที่สุดของ hardware ได้ง่ายขึ้น

รายละเอียด primitive

ดังที่กล่าวไว้ก่อนหน้า primitives ทั้งหมดถูกสร้างจาก base class ดังนั้นจึงมีโครงสร้างและการใช้งานทั่วไปแบบเดียวกัน ตัวอย่างเช่น รูปแบบ input สำหรับ Estimator primitives ทั้งหมดเหมือนกัน อย่างไรก็ตาม มีความแตกต่างใน implementation ที่ทำให้แต่ละอันมีเอกลักษณ์

หมายเหตุ

เนื่องจากผู้ใช้ส่วนใหญ่เข้าถึง Qiskit Runtime primitives ตัวอย่างในส่วนที่เหลือนี้จึงอิงตาม Qiskit Runtime primitives

Estimator

Estimator primitive คำนวณ expectation value สำหรับ observable หนึ่งตัวหรือมากกว่าเทียบกับ state ที่เตรียมโดย quantum circuit Circuit สามารถมีพารามิเตอร์ได้ ตราบใดที่ค่าพารามิเตอร์ถูกระบุเป็น input ให้ primitive ด้วย

Input คืออาร์เรย์ของ PUB แต่ละ PUB มีรูปแบบ:

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

โดย parameter values ที่เป็นตัวเลือกอาจเป็น list หรือพารามิเตอร์เดี่ยวก็ได้ Estimator implementation ต่างๆ รองรับตัวเลือกการกำหนดค่าหลากหลาย หาก input มีการวัด จะถูกละเว้น

Output คือ PubResult ที่มี expectation value ที่คำนวณต่อคู่และค่า standard error ในรูปแบบ PubResult แต่ละ PubResult มีทั้งข้อมูลและ metadata

Estimator รวม element จาก observable และค่าพารามิเตอร์โดยทำตามกฎ NumPy broadcasting ดังที่อธิบายในหัวข้อ Primitive inputs and outputs

ตัวอย่าง:

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
# This cell is hidden from users, it creates the circuits and observables to run

from qiskit_ibm_runtime import EstimatorV2, SamplerV2, QiskitRuntimeService
from qiskit.circuit.random import random_circuit
from qiskit.circuit import Parameter
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
import numpy as np

service = QiskitRuntimeService()
backend = service.least_busy()
phi = Parameter("phi")

circuit1 = random_circuit(10, 5, seed=12345)
circuit1.rzz(phi, 1, 2)
observable1 = SparsePauliOp.from_sparse_list(
[("ZXYZ", [1, 2, 3, 4], 1)], num_qubits=10
)
param_values1 = np.random.uniform(size=5).T

circuit2 = random_circuit(10, 5, seed=12345)
circuit2.rzz(phi, 1, 2)
observable2 = SparsePauliOp.from_sparse_list(
[("XZYX", [1, 2, 3, 4], 1)], num_qubits=10
)
param_values2 = np.random.uniform(size=5).T

shots1 = 164
shots2 = 1024

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
circuit1 = pm.run(circuit1)
circuit2 = pm.run(circuit2)
observable1 = observable1.apply_layout(circuit1.layout)
observable2 = observable2.apply_layout(circuit2.layout)
estimator = EstimatorV2(mode=backend)
estimator_job = estimator.run(
[
(circuit1, observable1, param_values1),
(circuit2, observable2, param_values2),
]
)

Sampler

งานหลักของ Sampler คือการสุ่มตัวอย่างจาก output register จากการรัน quantum circuit หนึ่งตัวหรือมากกว่า Circuit input สามารถมีพารามิเตอร์ได้ ตราบใดที่ค่าพารามิเตอร์ถูกระบุเป็น input ให้ primitive ด้วย

Input คือ PUB หนึ่งตัวหรือมากกว่า ในรูปแบบ:

(<single circuit>, <one or more optional parameter value>, <optional shots>),

โดยอาจมีรายการ parameter values หลายรายการ และแต่ละรายการอาจเป็นอาร์เรย์หรือพารามิเตอร์เดี่ยวก็ได้ ขึ้นอยู่กับ circuit ที่เลือก นอกจากนี้ input ต้องมีการวัด

Output คือ counts หรือการวัดต่อ shot ในรูปแบบ object PubResult โดยไม่มี weight อย่างไรก็ตาม result class มีเมธอดสำหรับคืน weighted sample เช่น counts ดู Primitive inputs and outputs สำหรับรายละเอียดทั้งหมด

ตัวอย่าง:

# This cell is hidden from users, add measurement instructions to circuits
circuit1.measure_active()
circuit2.measure_active()
sampler = SamplerV2(mode=backend)
sampler_job = sampler.run(
[
(circuit1, param_values1, shots1),
(circuit2, param_values2, shots2),
]
)

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

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