Lumaktaw sa pangunahing nilalaman

Mag-migrate mula sa NoiseLearner patungo sa NoiseLearnerV3

Gagabayan ka ng gabay na ito sa pag-migrate mula sa IBM Quantum® NoiseLearner patungo sa NoiseLearnerV3. Parehong nagsasagawa ang dalawang class ng mga eksperimento na nagkakarakter sa mga proseso ng noise batay sa Pauli-Lindblad noise model, ngunit medyo magkaiba ang mga input at output.

Kaligiran​

Ang NoiseLearner class ay ginawa para payagan ang mga user na magsagawa ng explicit na noise learning. Ang resultang noise model ay maaari ring ipasa sa IBM Quantum Estimator para mag-apply ng mga error mitigation technique tulad ng PEA at PEC.

Dinisenyo ang NoiseLearner para gumana kasama ang Estimator, kaya implicit nitong ginagamit ang parehong layer finding strategy ng Estimator. Hindi maaaring baguhin ang strategy na ito; kung hindi, ang mga kasunod na hakbang sa mitigation ay hindi gagana nang tama.

Simula sa qiskit-ibm-runtime v0.47.0, mayroon nang bagong NoiseLearnerV3 class na compatible sa Executor primitive at sa Modelo ng directed execution. Nagbibigay ang bagong modelong ito ng white-box na karanasan sa pamamagitan ng pagbibigay ng mga piraso para makuha ang design intent sa client side, at isang solong server-side na primitive (Executor) ang nagpoproseso ng mga input na iyon nang eksakto ayon sa direksyon — hindi ito gumagawa ng anumang implicit na desisyon para sa iyo. Hindi tulad ng orihinal na NoiseLearner, ikaw ang may kontrol kung paano i-stratify ang iyong mga circuit kapag ginamit mo ang NoiseLearnerV3, at kinukuha lang ng class ang isang listahan ng mga boxed circuit instruction (halimbawa, unique layers) bilang input nito.

Sinusuportahan din ng NoiseLearnerV3 ang measurement noise learning. Para sa bawat instruction sa input list, pinapatakbo nito ang Pauli-Lindblad learning protocol kung ang box ay naglalaman ng one- at two-qubit gates, at ang TREX protocol kung ang box ay naglalaman ng measurements.

Dapat ka bang mag-migrate?​

Gumagana lang ang NoiseLearner kasama ang legacy na server-side na Estimator, at gumagana lang ang NoiseLearnerV3 kasama ang Executor at ang client-side na Estimator. Kailangan mong mag-migrate patungo sa NoiseLearnerV3 kung ginagamit mo ang Executor o client-side na Estimator. Ang legacy na server-side na Estimator ay deprecated na at pinalitan ng katumbas nitong client-side sa qiskit-ibm-runtime v0.50.0.

tala

Kung ginagamit mo ang qiskit-ibm-runtime v0.50.0 o mas bago, basahin muna ang gabay na Mag-migrate mula sa server-side patungo sa client-side na Sampler at Estimator para mag-migrate sa mga client-side na primitive.

Mga hakbang sa migration​

Hakbang 1: Baguhin ang mga import​

NoiseLearner:

from qiskit_ibm_runtime.noise_learner import NoiseLearner

NoiseLearnerV3:

from qiskit_ibm_runtime import NoiseLearnerV3

Hakbang 2: I-update ang mga input​

Kinukuha ng run() method ng NoiseLearner ang listahan ng mga circuit o PUB, samantalang kinukuha ng run() method ng NoiseLearnerV3 ang listahan ng mga instruction, kung saan ang bawat isa ay dapat isang twirling-annotated na BoxOp na naglalaman ng ISA operations. May mga convenience method na available para sa paggawa ng mga annotated box, depende sa kung aling primitive ang plano mong gamitin.

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, kapag ginagamit kasama ang client-side na Estimator:

Kung plano mong gamitin ang client-side na Estimator para sa circuit execution, maaari mong gamitin ang find_unique_layers method mula sa Estimator para gumawa ng mga annotated box (layers):

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, kapag ginagamit kasama ang Executor:

Kung plano mong gamitin ang Executor para sa circuit execution, isaalang-alang ang paggamit ng function na generate_boxing_pass_manager mula sa Samplomatic para gumawa ng mga 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)

Hakbang 3: I-convert ang mga opsyon​

Karamihan sa mga field ng NoiseLearnerOptions ay direktang naka-map sa NoiseLearnerV3Options, maliban sa mga sumusunod:

  • max_layers_to_learn: Sa NoiseLearnerV3, ang bilang ng mga layer na matututunan ay batay sa bilang ng mga layer na ipinasa.

  • twirling_strategy: Sa NoiseLearnerV3, tinutukoy ang twirling strategy base sa kung paano na-box at na-annotate ang mga instruction (tulad ng kapag ginamit ang 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, kapag ginagamit kasama ang client-side na Estimator:

Kung plano mong gamitin ang client-side na Estimator para sa circuit execution, maaari mong i-set ang opsyon ng Estimator na 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, kapag ginagamit kasama ang Executor:

Kung plano mong gamitin ang Executor para sa circuit execution, maaari mong ipasa ang opsyong twirling_strategy sa function na generate_boxing_pass_manager.

Tandaan na sa generate_boxing_pass_manager(), gumagamit ng underscores ang mga value ng twirling_strategy ("active_accum", "active_circuit"), samantalang gumagamit ng hyphens ang mga value ng NoiseLearnerOptions.twirling_strategy ("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])

Hakbang 4: Suriin ang mga resulta​

Ang mga output ng NoiseLearner at NoiseLearnerV3 ay naglalaman ng magkatulad na impormasyon ngunit nasa magkaibang format. I-update ang iyong code kung sinusuri nito ang output nang explicit.

Pag-map ng result attribute:

(learner_result ang output ng learner job)

AttributeNoiseLearnerNoiseLearnerV3
Uri ng resultaNoiseLearnerResultNoiseLearnerV3Results, isang sequence-like na container ng NoiseLearnerV3Result
Bilang ng mga natutunang layerlen(learner_result.data)len(learner_result)
Data para sa unang layerlayer_error = learner_result.data[0]noise_map = learner_result[0].to_pauli_lindblad_map()
Uri ng resulta ng bawat layerLayerError (type(layer_error))PauliLindbladMap (type(noise_map))
Mga generator para sa error channellayer_error.error.generatorsnoise_map.generators()
Mga error ratelayer_error.error.ratesnoise_map.rates

Hakbang 5: I-input ang noise model sa isang primitive​

Gumagana lang ang NoiseLearner kasama ang legacy na server-side na Estimator, at gumagana lang ang NoiseLearnerV3 kasama ang Executor at ang client-side na Estimator. Medyo naiiba ang paraan ng pagtukoy ng noise model depende sa kung aling primitive ang ginagamit.

NoiseLearner, kapag ginagamit kasama ang legacy na server-side na 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, kapag ginagamit kasama ang client-side na Estimator:

Gamitin muli ang parehong Estimator na gumawa ng layers sa hakbang 2. Ang mga noise map na ibinalik ng learner ay positionally tumutugma sa mga layer na iyon, kaya kailangan silang i-assign sa Estimator kung saan sila nanggaling. Naka-enable na ang PEA/PEC dito sa hakbang 2.

Tandaan na habang sinusuportahan ng NoiseLearnerV3 ang parehong Pauli-Lindblad at TREX protocol, ang Estimator ay tumatanggap lang ng mga noise model para sa two-qubit layers na natutunan gamit ang Pauli-Lindblad protocol.

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, kapag ginagamit kasama ang 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)

Kumpletong mga halimbawa​

NoiseLearnerV3 at 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 at 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()

Mga Sanggunian​