Lewati ke konten utama

Migrasi dari NoiseLearner ke NoiseLearnerV3

Panduan ini memandu kamu melalui proses migrasi dari IBM Quantum® NoiseLearner ke NoiseLearnerV3. Kedua kelas melakukan eksperimen yang mengkarakterisasi proses noise berdasarkan model noise Pauli-Lindblad, tetapi input dan outputnya sedikit berbeda.

Latar Belakang​

Kelas NoiseLearner dibuat untuk memungkinkan pengguna melakukan pembelajaran noise secara eksplisit. Model noise hasilnya kemudian bisa diberikan ke Estimator IBM Quantum untuk menerapkan teknik mitigasi error seperti PEA dan PEC.

NoiseLearner dirancang untuk bekerja dengan Estimator, dan oleh karena itu secara implisit menggunakan strategi pencarian layer yang sama dengan Estimator. Strategi ini tidak bisa diubah; jika tidak, langkah mitigasi selanjutnya tidak akan bekerja dengan benar.

Mulai dari qiskit-ibm-runtime v0.47.0, ada kelas NoiseLearnerV3 baru yang kompatibel dengan primitif Executor dan directed execution model. Model baru ini memberikan pengalaman white-box dengan menyediakan bagian-bagian untuk menangkap maksud desain di sisi klien, dan satu primitif sisi server (Executor) memproses input tersebut persis seperti yang diarahkan — ia tidak membuat keputusan implisit atas namamu. Berbeda dengan NoiseLearner asli, kamu mengontrol bagaimana cara menstratifikasi circuit-mu ketika kamu menggunakan NoiseLearnerV3, dan kelas tersebut cukup menerima daftar instruksi circuit yang di-box (misalnya, layer unik) sebagai inputnya.

NoiseLearnerV3 juga mendukung pembelajaran noise pengukuran. Untuk setiap instruksi dalam daftar input, ia menjalankan protokol pembelajaran Pauli-Lindblad jika box berisi gate satu dan dua qubit, dan protokol TREX jika box berisi pengukuran.

Haruskah kamu migrasi?​

NoiseLearner hanya bekerja dengan Estimator sisi server versi lama, dan NoiseLearnerV3 hanya bekerja dengan Executor dan Estimator sisi klien. Kamu harus migrasi ke NoiseLearnerV3 jika kamu menggunakan Executor atau Estimator sisi klien. Estimator sisi server versi lama sudah usang (deprecated) dan digantikan oleh padanan sisi klien di qiskit-ibm-runtime v0.50.0.

catatan

Jika kamu menggunakan qiskit-ibm-runtime v0.50.0 atau lebih baru, baca panduan Migrasi dari Sampler dan Estimator sisi server ke sisi klien untuk migrasi ke primitif sisi klien terlebih dahulu.

Langkah migrasi​

Langkah 1: Ubah import​

NoiseLearner:

from qiskit_ibm_runtime.noise_learner import NoiseLearner

NoiseLearnerV3:

from qiskit_ibm_runtime import NoiseLearnerV3

Langkah 2: Perbarui input​

Metode run() dari NoiseLearner menerima daftar circuit atau PUB, sedangkan metode run() dari NoiseLearnerV3 menerima daftar instruksi, yang masing-masing harus berupa BoxOp yang dianotasi twirling dan berisi operasi ISA. Metode praktis tersedia untuk menghasilkan box yang dianotasi, tergantung pada primitif mana yang kamu rencanakan untuk digunakan.

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, saat bekerja dengan Estimator sisi klien:

Jika kamu berencana menggunakan Estimator sisi klien untuk eksekusi circuit, kamu bisa menggunakan metode find_unique_layers dari Estimator untuk membuat box (layer) yang dianotasi:

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, saat bekerja dengan Executor:

Jika kamu berencana menggunakan Executor untuk eksekusi circuit, pertimbangkan untuk menggunakan fungsi generate_boxing_pass_manager dari Samplomatic untuk membuat box yang dianotasi:

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)

Langkah 3: Konversi opsi​

Sebagian besar field NoiseLearnerOptions dipetakan langsung ke NoiseLearnerV3Options, kecuali berikut ini:

  • max_layers_to_learn: Dengan NoiseLearnerV3, jumlah layer yang dipelajari didasarkan pada jumlah layer yang diberikan.

  • twirling_strategy: Dengan NoiseLearnerV3, strategi twirling ditentukan oleh cara instruksi di-box dan dianotasi (seperti saat menggunakan 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, saat bekerja dengan Estimator sisi klien:

Jika kamu berencana menggunakan Estimator sisi klien untuk eksekusi circuit, kamu bisa menetapkan opsi Estimator twirling.strategy:

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, saat bekerja dengan Executor:

Jika kamu berencana menggunakan Executor untuk eksekusi circuit, kamu bisa memberikan opsi twirling_strategy ke fungsi generate_boxing_pass_manager.

Perhatikan bahwa dengan generate_boxing_pass_manager(), nilai twirling_strategy menggunakan underscore ("active_accum", "active_circuit"), sedangkan nilai NoiseLearnerOptions.twirling_strategy menggunakan tanda hubung ("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])

Langkah 4: Periksa hasil​

Output dari NoiseLearner dan NoiseLearnerV3 berisi informasi yang serupa tetapi dalam format yang berbeda. Perbarui kodemu jika kode tersebut memeriksa output secara eksplisit.

Pemetaan atribut hasil:

(learner_result adalah output dari job learner)

AtributNoiseLearnerNoiseLearnerV3
Tipe hasilNoiseLearnerResultNoiseLearnerV3Results, container mirip sequence dari NoiseLearnerV3Result
Jumlah layer yang dipelajarilen(learner_result.data)len(learner_result)
Data untuk layer pertamalayer_error = learner_result.data[0]noise_map = learner_result[0].to_pauli_lindblad_map()
Tipe hasil dari setiap layerLayerError (type(layer_error))PauliLindbladMap (type(noise_map))
Generator untuk error channellayer_error.error.generatorsnoise_map.generators()
Tingkat errorlayer_error.error.ratesnoise_map.rates

Langkah 5: Masukkan model noise ke primitif​

NoiseLearner hanya bekerja dengan Estimator sisi server versi lama, dan NoiseLearnerV3 hanya bekerja dengan Executor dan Estimator sisi klien. Cara model noise ditentukan sedikit berbeda tergantung pada primitif mana yang digunakan.

NoiseLearner, saat bekerja dengan Estimator sisi server versi lama:

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, saat bekerja dengan Estimator sisi klien:

Gunakan kembali Estimator yang sama yang menghasilkan layers di langkah 2. Noise map yang dikembalikan oleh learner dicocokkan secara posisional dengan layer tersebut, sehingga harus diberikan ke Estimator tempat asalnya. PEA/PEC sudah diaktifkan padanya di langkah 2.

Perhatikan bahwa meskipun NoiseLearnerV3 mendukung protokol Pauli-Lindblad dan TREX, Estimator hanya menerima model noise untuk layer dua-qubit yang dipelajari dengan protokol 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, saat bekerja dengan 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)

Contoh lengkap​

NoiseLearnerV3 dan Estimator sisi klien​

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

Referensi​