ย้ายจาก NoiseLearner ไปยัง NoiseLearnerV3
คู่มือนี้จะแนะนำคุณผ่านขั้นตอนการย้ายจาก IBM Quantum® NoiseLearner ไปยัง NoiseLearnerV3 ทั้งสอง
class ทำการทดลองที่กำหนดลักษณะของกระบวนการ noise โดยอ้างอิงจาก
Pauli-Lindblad noise model แต่ input และ
output แตกต่างกันเล็กน้อย
พื้นหลัง
class NoiseLearner
ถูกสร้างขึ้นเพื่อให้ผู้ใช้สามารถทำการเรียนรู้ noise ได้อย่างชัดเจน noise model ที่ได้
สามารถส่งไปยัง IBM Quantum Estimator เพื่อใช้เทคนิค error mitigation
เช่น PEA และ PEC
NoiseLearner ถูกออกแบบมาให้ทำงานร่วมกับ Estimator ดังนั้นมันจึงใช้กลยุทธ์การค้นหา
layer เดียวกันกับ Estimator โดยนัย กลยุทธ์นี้ไม่สามารถเปลี่ยนแปลงได้ มิฉะนั้น ขั้นตอน
mitigation ที่ตามมาจะทำงานไม่ถูกต้อง
เริ่มตั้งแต่ qiskit-ibm-runtime v0.47.0 มี class
NoiseLearnerV3
ใหม่ที่เข้ากันได้กับ primitive Executor และ
directed execution model
โมเดลใหม่นี้มอบประสบการณ์แบบ white-box โดยให้ส่วนประกอบสำหรับจับ design intent
บน client side และ server-side primitive เดียว (Executor) ประมวลผล input เหล่านั้นตามที่
กำหนดไว้อย่างเคร่งครัด — มันไม่ตัดสินใจโดยนัยแทนคุณ ต่างจาก NoiseLearner เดิม
คุณควบคุมวิธีการแบ่งชั้น circuit ของคุณเมื่อใช้ NoiseLearnerV3 และ class นี้เพียงแค่รับ list ของ boxed circuit instruction
(ตัวอย่างเช่น unique layers) เป็น input ของมัน
NoiseLearnerV3 ยังรองรับการเรียนรู้ noise ของการวัดด้วย สำหรับแต่ละ instruction ใน input list มันจะรัน
protocol การเรียนรู้ Pauli-Lindblad หากกล่องมี gate หนึ่งและสอง qubit และ protocol
TREX
หากกล่องมีการวัด
คุณควรย้ายหรือไม่?
NoiseLearner ทำงานได้เฉพาะกับ Estimator แบบ server-side รุ่นเก่าเท่านั้น และ NoiseLearnerV3 ทำงานได้เฉพาะกับ
Executor และ Estimator แบบ client-side คุณต้องย้ายไปใช้ NoiseLearnerV3 หากคุณกำลังใช้
Executor หรือ client-side Estimator Estimator แบบ server-side รุ่นเก่าถูก deprecate และแทนที่ด้วยตัวเทียบเท่าฝั่ง client-side ใน qiskit-ibm-runtime v0.50.0
หากคุณกำลังใช้ qiskit-ibm-runtime v0.50.0 หรือใหม่กว่า ให้อ่านคู่มือ Migrate from server-side to client-side Sampler and Estimator เพื่อย้ายไปใช้ client-side primitives ก่อน
ขั้นตอนการย้าย
ขั้นตอนที่ 1: เปลี่ยน imports
NoiseLearner:
from qiskit_ibm_runtime.noise_learner import NoiseLearner
NoiseLearnerV3:
from qiskit_ibm_runtime import NoiseLearnerV3
ขั้นตอนที่ 2: อัปเดต inputs
method run() ของ NoiseLearner รับ list ของ circuit หรือ PUB ในขณะที่ method run() ของ NoiseLearnerV3 รับ list ของ instruction ซึ่งแต่ละตัวต้องเป็น BoxOp ที่มี twirling annotation และมี ISA operation อยู่ภายใน
มี convenience method สำหรับสร้าง annotated box โดยขึ้นอยู่กับ
primitive ที่คุณวางแผนจะใช้
NoiseLearner:
from qiskit_ibm_runtime.noise_learner import NoiseLearner
learner = NoiseLearner(mode=backend)
# `circuits_to_learn` is a list of ISA QuantumCircuit
learner_job = learner.run(circuits_to_learn)
NoiseLearnerV3 เมื่อทำงานร่วมกับ client-side Estimator:
หากคุณวางแผนจะใช้ client-side Estimator สำหรับการ execute circuit คุณสามารถใช้ method find_unique_layers จาก Estimator เพื่อสร้าง annotated box (layer):
from qiskit_ibm_runtime.executor_estimator import Estimator
from qiskit_ibm_runtime import NoiseLearnerV3
pubs = [...] # Your PUBs
estimator = Estimator(backend)
estimator.options.resilience.pec_mitigation = True # or zne_mitigation + pea amplifier
# Identify the unique layers to learn.
layers = estimator.find_unique_layers(pubs)
# Learn the noise model for those layers (runs as a separate job).
learner = NoiseLearnerV3(backend)
learner_job = learner.run(layers)
NoiseLearnerV3 เมื่อทำงานร่วมกับ Executor:
หากคุณวางแผนจะใช้ Executor สำหรับการ execute circuit ให้พิจารณาใช้ function generate_boxing_pass_manager จาก Samplomatic เพื่อสร้าง annotated box:
from qiskit_ibm_runtime.noise_learner_v3 import NoiseLearnerV3
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic.utils import find_unique_box_instructions
# Run the boxing pass manager to group instructions into annotated boxes.
# `isa_circuit` is an ISA QuantumCircuit.
boxing_pm = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=False,
inject_noise_targets="gates", # no measurement mitigation
inject_noise_strategy="uniform_modification",
)
boxed_circuit = boxing_pm.run(isa_circuit)
# Find unique boxed instructions.
unique_box_instructions = find_unique_box_instructions(boxed_circuit.data)
# Instantiate a NoiseLearnerV3 object and execute the noise learning program.
learner = NoiseLearnerV3(backend)
learner_job = learner.run(unique_box_instructions)
ขั้นตอนที่ 3: แปลงตัวเลือก
field ส่วนใหญ่ของ NoiseLearnerOptions map ตรงกับ NoiseLearnerV3Options ยกเว้นสิ่งต่อไปนี้:
-
max_layers_to_learn: เมื่อใช้NoiseLearnerV3จำนวน layer ที่จะเรียนรู้ขึ้นอยู่กับจำนวน layer ที่ส่งเข้ามา -
twirling_strategy: เมื่อใช้NoiseLearnerV3กลยุทธ์ twirling ถูกกำหนดโดยวิธีการที่ instruction ถูก box และ annotate (เช่น เมื่อใช้generate_boxing_pass_manager())
NoiseLearner:
from qiskit_ibm_runtime.noise_learner import NoiseLearner
from qiskit_ibm_runtime.options import NoiseLearnerOptions
# Instantiate a NoiseLearnerOptions object
learner_options = NoiseLearnerOptions(
max_layers_to_learn=3, num_randomizations=32, twirling_strategy="all"
)
learner = NoiseLearner(mode=backend, options=learner_options)
learner_job = learner.run(circuits_to_learn)
NoiseLearnerV3 เมื่อทำงานร่วมกับ client-side Estimator:
หากคุณวางแผนจะใช้ client-side Estimator สำหรับการ execute circuit คุณสามารถ
ตั้งค่าตัวเลือก twirling.strategy ของ Estimator:
from qiskit_ibm_runtime.executor_estimator import Estimator
from qiskit_ibm_runtime import NoiseLearnerV3
from qiskit_ibm_runtime.options_models import NoiseLearnerV3Options
pubs = [...] # Your PUBs
estimator = Estimator(backend)
estimator.options.resilience.pec_mitigation = True # or zne_mitigation + pea amplifier
estimator.options.twirling.strategy = "all" # set twirling strategy here
# Identify the unique layers to learn.
layers = estimator.find_unique_layers(pubs)
# Instantiate a NoiseLearnerV3 object and execute the noise learning program
learner_options = NoiseLearnerV3Options(num_randomizations=32)
learner = NoiseLearnerV3(backend, options=learner_options)
# Learn just the first 3 layers.
learner_job = learner.run(layers[:3])
NoiseLearnerV3 เมื่อทำงานร่วมกับ Executor:
หากคุณวางแผนจะใช้ Executor สำหรับการ execute circuit คุณสามารถส่งตัวเลือก twirling_strategy ไปยัง function generate_boxing_pass_manager
โปรดทราบว่าเมื่อใช้ generate_boxing_pass_manager() ค่าของ twirling_strategy ใช้ underscore
("active_accum", "active_circuit") ในขณะที่ค่าของ NoiseLearnerOptions.twirling_strategy ใช้ hyphen ("active-accum", "active-circuit")
from qiskit_ibm_runtime.noise_learner_v3 import NoiseLearnerV3
from qiskit_ibm_runtime.options_models import NoiseLearnerV3Options
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic.utils import find_unique_box_instructions
# Run the boxing pass manager to group instructions into annotated boxes
# `isa_circuit` is an ISA QuantumCircuit
boxing_pm = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=False,
twirling_strategy="all", # twirling strategy can be specified here
inject_noise_targets="gates",
inject_noise_strategy="uniform_modification",
)
boxed_circuit = boxing_pm.run(isa_circuit)
# Find unique boxed instructions
unique_box_instructions = find_unique_box_instructions(boxed_circuit.data)
learner_options = NoiseLearnerV3Options(num_randomizations=32)
# Instantiate a NoiseLearnerV3 object and execute the noise learning program
learner = NoiseLearnerV3(backend, options=learner_options)
# Learn just the first 3 layers.
learner_job = learner.run(unique_box_instructions[:3])
ขั้นตอนที่ 4: ตรวจสอบผลลัพธ์
output ของ NoiseLearner และ NoiseLearnerV3 มีข้อมูลคล้ายกันแต่มีรูปแบบต่างกัน อัปเดตโค้ดของคุณหากมันตรวจสอบ output อย่างชัดเจน
การ map attribute ของผลลัพธ์:
(learner_result คือ output ของ learner job)
| Attribute | NoiseLearner | NoiseLearnerV3 |
|---|---|---|
| ประเภทผลลัพธ์ | NoiseLearnerResult | NoiseLearnerV3Results, container คล้าย sequence ของ NoiseLearnerV3Result |
| จำนวน layer ที่เรียนรู้แล้ว | len(learner_result.data) | len(learner_result) |
| ข้อมูลสำหรับ layer แรก | layer_error = learner_result.data[0] | noise_map = learner_result[0].to_pauli_lindblad_map() |
| ประเภทผลลัพธ์ของแต่ละ layer | LayerError (type(layer_error)) | PauliLindbladMap (type(noise_map)) |
| Generator สำหรับ error channel | layer_error.error.generators | noise_map.generators() |
| อัตรา error | layer_error.error.rates | noise_map.rates |
ขั้นตอนที่ 5: ป้อน noise model ให้กับ primitive
NoiseLearner ทำงานได้เฉพาะกับ Estimator แบบ server-side รุ่นเก่าเท่านั้น และ NoiseLearnerV3 ทำงานได้เฉพาะกับ Executor และ Estimator แบบ client-side วิธีการระบุ noise model จะแตกต่างกันเล็กน้อยขึ้นอยู่กับว่าใช้ primitive ใด
NoiseLearner เมื่อทำงานร่วมกับ legacy server-side Estimator:
from qiskit_ibm_runtime import Estimator as LegacyEstimator
learner_result = learner_job.result()
# Pass the noise model to the `estimator.options` attribute directly
estimator = LegacyEstimator(mode=backend)
estimator.options.resilience.layer_noise_model = learner_result
job = estimator.run(pubs)
NoiseLearnerV3 เมื่อทำงานร่วมกับ client-side Estimator:
ใช้ Estimator ตัวเดิมที่สร้าง layers ในขั้นตอนที่ 2 ซ้ำ noise map ที่ส่งคืนโดย
learner จะจับคู่ตามตำแหน่งกับ layer เหล่านั้น ดังนั้นจึงต้องถูกกำหนดให้กับ Estimator
ที่มันมาจาก PEA/PEC ถูกเปิดใช้งานไว้แล้วบนมันในขั้นตอนที่ 2
โปรดทราบว่าแม้ NoiseLearnerV3 จะรองรับทั้ง protocol Pauli-Lindblad และ TREX แต่ Estimator ยอมรับเฉพาะ noise model สำหรับ layer สอง qubit ที่เรียนรู้ด้วย protocol Pauli-Lindblad เท่านั้น
learner_result = learner_job.result()
# Convert results to Pauli-Lindblad noise maps.
pauli_lindblad_maps = learner_result.to_pauli_lindblad_maps()
# Assign the learned noise maps so PEA/PEC uses them.
estimator.options.resilience.layer_noise_model = zip(layers, pauli_lindblad_maps)
# Now execute the target PUBs.
job = estimator.run(pubs)
NoiseLearnerV3 เมื่อทำงานร่วมกับ Executor:
from qiskit_ibm_runtime import Executor
from qiskit_ibm_runtime.quantum_program import QuantumProgram
# Generate a quantum program
program = QuantumProgram(shots=1000)
# Convert the NoiseLearnerV3 result to a dictionary
learner_result = learner_job.result()
noise_maps = learner_result.to_dict(
instructions=unique_box_instructions, require_refs=False
)
# Append the samplex item and execute
program.append_samplex_item(
template_circuit,
samplex=samplex,
samplex_arguments={
"pauli_lindblad_maps": noise_maps,
},
)
executor = Executor(backend)
executor_job = executor.run(program)
ตัวอย่างแบบเต็ม
NoiseLearnerV3 และ client-side Estimator
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService, NoiseLearnerV3
from qiskit_ibm_runtime.executor_estimator import Estimator
# 1. Account + backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# 2. Circuit + observable
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
observable = SparsePauliOp("ZZ")
# 3. Transpile to ISA
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)
pubs = [(isa_circuit, isa_observable)]
# 4. Initialize Estimator with options
estimator = Estimator(backend)
estimator.options.resilience.pec_mitigation = True
# 5. Extract the unique boxed layers from PUBs
layers = estimator.find_unique_layers(pubs)
# 6. Learn the noise model for those layers
learner = NoiseLearnerV3(backend)
learner_job = learner.run(layers)
learner_result = learner_job.result()
# 7. Convert the result to Pauli-Lindblad maps and pass them to Estimator
pauli_lindblad_maps = learner_result.to_pauli_lindblad_maps()
estimator.options.resilience.layer_noise_model = zip(layers, pauli_lindblad_maps)
# 8. Execute the target PUBs
job = estimator.run(pubs)
result = job.result()
NoiseLearnerV3 และ Executor
from qiskit import QuantumCircuit
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService, Executor, NoiseLearnerV3
from qiskit_ibm_runtime.quantum_program import QuantumProgram
from samplomatic import build
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic.utils import find_unique_box_instructions
# 1. Account + backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# 2. Circuit + observable
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
# 3. Transpile to ISA
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)
# 4. Run the boxing pass manager to group instructions into annotated boxes
boxing_pm = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=False,
inject_noise_targets="gates", # no measurement mitigation
inject_noise_strategy="uniform_modification",
)
boxed_circuit = boxing_pm.run(isa_circuit)
# 5. Find unique boxed instructions (layers)
unique_box_instructions = find_unique_box_instructions(boxed_circuit.data)
# 6. Learn the noise model for those layers
learner = NoiseLearnerV3(backend)
learner_job = learner.run(unique_box_instructions)
learner_result = learner_job.result()
# 7. Convert the NoiseLearnerV3 result to a dictionary
noise_maps = learner_result.to_dict(
instructions=unique_box_instructions, require_refs=False
)
# 8. Build the template circuit and samplex pair
template_circuit, samplex = build(boxed_circuit)
# 9. Prepare a quantum program
program = QuantumProgram(shots=1000)
program.append_samplex_item(
template_circuit,
samplex=samplex,
samplex_arguments={
"pauli_lindblad_maps": noise_maps,
},
)
executor = Executor(backend)
job = executor.run(program)
result = job.result()