Langkau ke kandungan utama

Migrasi daripada NoiseLearner ke NoiseLearnerV3

Panduan ini membimbing anda melalui migrasi daripada IBM Quantum® NoiseLearner kepada NoiseLearnerV3. Kedua-dua kelas ini melakukan eksperimen yang mencirikan proses hingar berdasarkan model hingar Pauli-Lindblad, tetapi input dan outputnya sedikit berbeza.

Latar Belakang​

Kelas NoiseLearner dicipta untuk membolehkan pengguna melakukan pembelajaran hingar eksplisit. Model hingar yang terhasil kemudian boleh dihantar kepada IBM Quantum Estimator untuk menerapkan teknik pengurangan ralat seperti PEA dan PEC.

NoiseLearner direka untuk berfungsi dengan Estimator, dan oleh itu ia secara tersirat menggunakan strategi pencarian lapisan yang sama seperti Estimator. Strategi ini tidak boleh diubah; jika tidak, langkah pengurangan ralat seterusnya tidak akan berfungsi dengan betul.

Bermula dengan qiskit-ibm-runtime v0.47.0, terdapat kelas NoiseLearnerV3 baharu yang serasi dengan primitif Executor dan model pelaksanaan terarah. Model baharu ini memberikan pengalaman kotak putih dengan menyediakan bahagian-bahagian untuk menangkap niat reka bentuk pada sisi klien, dan satu primitif sisi pelayan (Executor) memproses input tersebut dengan tepat seperti yang diarahkan — ia tidak membuat sebarang keputusan tersirat bagi pihak anda. Tidak seperti NoiseLearner asal, anda mengawal cara menstratakan litar anda apabila anda menggunakan NoiseLearnerV3, dan kelas tersebut hanya menerima senarai arahan litar berkotak (contohnya, lapisan unik) sebagai inputnya.

NoiseLearnerV3 juga menyokong pembelajaran hingar pengukuran. Untuk setiap arahan dalam senarai input, ia menjalankan protokol pembelajaran Pauli-Lindblad jika kotak tersebut mengandungi gate satu dan dua qubit, dan protokol TREX jika kotak tersebut mengandungi pengukuran.

Perlukah anda migrasi?​

NoiseLearner hanya berfungsi dengan Estimator sisi pelayan warisan, dan NoiseLearnerV3 hanya berfungsi dengan Executor dan Estimator sisi klien. Anda mesti migrasi ke NoiseLearnerV3 jika anda menggunakan Executor atau Estimator sisi klien. Estimator sisi pelayan warisan telah dinyahkekalkan dan digantikan dengan persamaan sisi klien dalam qiskit-ibm-runtime v0.50.0.

nota

Jika anda menggunakan qiskit-ibm-runtime v0.50.0 atau lebih baharu, baca panduan Migrasi daripada Sampler dan Estimator sisi pelayan 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: Kemas kini input​

Kaedah run() NoiseLearner menerima senarai litar atau PUB, manakala kaedah run() NoiseLearnerV3 menerima senarai arahan, setiap satunya mesti berupa BoxOp beranotasi-twirling yang mengandungi operasi ISA. Kaedah kemudahan tersedia untuk menjana kotak beranotasi tersebut, bergantung pada primitif yang anda rancang 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, apabila bekerja dengan Estimator sisi klien:

Jika anda merancang untuk menggunakan Estimator sisi klien untuk pelaksanaan litar, anda boleh menggunakan kaedah find_unique_layers daripada Estimator untuk mencipta kotak beranotasi (lapisan):

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

Jika anda merancang untuk menggunakan Executor untuk pelaksanaan litar, pertimbangkan untuk menggunakan fungsi generate_boxing_pass_manager daripada Samplomatic untuk mencipta kotak beranotasi:

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: Tukar pilihan​

Kebanyakan medan NoiseLearnerOptions dipetakan terus kepada NoiseLearnerV3Options, kecuali yang berikut:

  • max_layers_to_learn: Dengan NoiseLearnerV3, bilangan lapisan yang perlu dipelajari adalah berdasarkan bilangan lapisan yang dihantar masuk.

  • twirling_strategy: Dengan NoiseLearnerV3, strategi twirling ditakrifkan oleh cara arahan dikotakkan dan dianotasi (seperti apabila 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, apabila bekerja dengan Estimator sisi klien:

Jika anda merancang untuk menggunakan Estimator sisi klien untuk pelaksanaan litar, anda boleh menetapkan pilihan 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, apabila bekerja dengan Executor:

Jika anda merancang untuk menggunakan Executor untuk pelaksanaan litar, anda boleh menghantar pilihan twirling_strategy kepada fungsi generate_boxing_pass_manager.

Ambil perhatian bahawa dengan generate_boxing_pass_manager(), nilai twirling_strategy menggunakan garis bawah ("active_accum", "active_circuit"), manakala nilai NoiseLearnerOptions.twirling_strategy menggunakan sengkang ("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 NoiseLearner dan NoiseLearnerV3 mengandungi maklumat yang serupa tetapi dalam format yang berbeza. Kemas kini kod anda jika ia memeriksa output secara eksplisit.

Pemetaan atribut hasil:

(learner_result ialah output kerja pembelajar)

AtributNoiseLearnerNoiseLearnerV3
Jenis hasilNoiseLearnerResultNoiseLearnerV3Results, bekas seperti jujukan bagi NoiseLearnerV3Result
Bilangan lapisan yang dipelajarilen(learner_result.data)len(learner_result)
Data untuk lapisan pertamalayer_error = learner_result.data[0]noise_map = learner_result[0].to_pauli_lindblad_map()
Jenis hasil setiap lapisanLayerError (type(layer_error))PauliLindbladMap (type(noise_map))
Penjana untuk saluran ralatlayer_error.error.generatorsnoise_map.generators()
Kadar ralatlayer_error.error.ratesnoise_map.rates

Langkah 5: Hantar model hingar kepada primitif​

NoiseLearner hanya berfungsi dengan Estimator sisi pelayan warisan, dan NoiseLearnerV3 hanya berfungsi dengan Executor dan Estimator sisi klien. Cara model hingar dinyatakan berbeza sedikit bergantung pada primitif yang digunakan.

NoiseLearner, apabila bekerja dengan Estimator sisi pelayan warisan:

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

Guna semula Estimator yang sama yang menghasilkan layers dalam langkah 2. Peta hingar yang dikembalikan oleh pembelajar dipadankan mengikut kedudukan kepada lapisan tersebut, jadi ia mesti diberikan kepada Estimator yang menghasilkannya. PEA/PEC telahpun didayakan padanya dalam langkah 2.

Ambil perhatian bahawa walaupun NoiseLearnerV3 menyokong kedua-dua protokol Pauli-Lindblad dan TREX, Estimator hanya menerima model hingar untuk lapisan 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, apabila 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 bahagian 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()

Rujukan​