Migrace z NoiseLearner na NoiseLearnerV3
Tento průvodce tě provede migrací z IBM Quantum® NoiseLearner na NoiseLearnerV3. Obě
třídy provádějí experimenty, které charakterizují šumové procesy na základě
Pauliho-Lindbladova modelu šumu, ale vstupy a
výstupy jsou mírně odlišné.
Kontext
Třída NoiseLearner
byla vytvořena, aby uživatelům umožnila provádět explicitní učení šumu. Výsledný
model šumu pak lze předat IBM Quantum Estimator pro aplikaci technik zmírnění chyb,
jako jsou PEA a PEC.
NoiseLearner byl navržen pro práci s Estimator, a proto implicitně používá stejnou
strategii hledání vrstev jako Estimator. Tuto strategii nelze změnit; jinak by následné
kroky zmírnění nefungovaly správně.
Počínaje qiskit-ibm-runtime v0.47.0 existuje nová třída
NoiseLearnerV3,
která je kompatibilní s primitivem Executor a
modelem řízeného spouštění.
Tento nový model poskytuje zkušenost typu white-box tím, že poskytuje prvky pro zachycení záměru návrhu
na straně klienta, a jediné serverové primitivum (Executor) zpracovává tyto vstupy přesně tak,
jak je nasměrováno — nedělá za tebe žádná implicitní rozhodnutí. Na rozdíl od původního NoiseLearner,
kontroluješ, jak rozvrstvit své obvody, když používáš NoiseLearnerV3, a třída jednoduše přijímá seznam zabalených instrukcí obvodu
(například jedinečných vrstev) jako svůj vstup.
NoiseLearnerV3 také podporuje učení šumu měření. Pro každou instrukci ve vstupním seznamu spouští
protokol učení Pauliho-Lindblad, pokud box obsahuje jedno- a dvouqubitová hradla, a
protokol TREX,
pokud box obsahuje měření.
Máš migrovat?
NoiseLearner funguje pouze se starším serverovým Estimator a NoiseLearnerV3 funguje pouze s
Executor a klientským Estimator. Musíš migrovat na NoiseLearnerV3, pokud používáš
Executor nebo klientský Estimator. Starší serverový Estimator je zastaralý a nahrazen klientským ekvivalentem v qiskit-ibm-runtime v0.50.0.
Pokud používáš qiskit-ibm-runtime v0.50.0 nebo novější, nejprve si přečti průvodce Migrace ze serverového na klientský Sampler a Estimator, abys migroval na klientská primitiva.
Kroky migrace
Krok 1: Změň importy
NoiseLearner:
from qiskit_ibm_runtime.noise_learner import NoiseLearner
NoiseLearnerV3:
from qiskit_ibm_runtime import NoiseLearnerV3
Krok 2: Aktualizuj vstupy
Metoda run() třídy NoiseLearner přijímá seznam obvodů nebo PUB, zatímco metoda run() třídy NoiseLearnerV3 přijímá seznam instrukcí, z nichž každá musí být anotovaný twirlingem BoxOp obsahující operace ISA.
K dispozici jsou pomocné metody pro generování anotovaných boxů, v závislosti na tom,
které primitivum plánuješ použít.
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, při práci s klientským Estimatorem:
Pokud plánuješ použít klientský Estimator pro spouštění obvodů, můžeš použít metodu find_unique_layers z Estimatoru k vytvoření anotovaných boxů (vrstev):
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, při práci s Executorem:
Pokud plánuješ použít Executor pro spouštění obvodů, zvaž použití funkce generate_boxing_pass_manager z Samplomatic k vytvoření anotovaných 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)
Krok 3: Převeď možnosti
Většina polí NoiseLearnerOptions se mapuje přímo na NoiseLearnerV3Options, kromě následujících:
-
max_layers_to_learn: SNoiseLearnerV3je počet vrstev k naučení založen na počtu předaných vrstev. -
twirling_strategy: SNoiseLearnerV3je strategie twirlingu definována tím, jak jsou instrukce zabaleny a anotovány (například při použití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, při práci s klientským Estimatorem:
Pokud plánuješ použít klientský Estimator pro spouštění obvodů, můžeš
nastavit možnost Estimatoru 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, při práci s Executorem:
Pokud plánuješ použít Executor pro spouštění obvodů, můžeš předat možnost twirling_strategy funkci generate_boxing_pass_manager.
Všimni si, že s generate_boxing_pass_manager() hodnoty twirling_strategy používají podtržítka
("active_accum", "active_circuit"), zatímco hodnoty NoiseLearnerOptions.twirling_strategy používají spojovníky ("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])
Krok 4: Zkontroluj výsledky
Výstupy NoiseLearner a NoiseLearnerV3 obsahují podobné informace, ale v odlišných formátech. Aktualizuj svůj kód, pokud výstup explicitně zkoumá.
Mapování atributů výsledku:
(learner_result je výstup úlohy learneru)
| Atribut | NoiseLearner | NoiseLearnerV3 |
|---|---|---|
| Typ výsledku | NoiseLearnerResult | NoiseLearnerV3Results, kontejner podobný sekvenci obsahující NoiseLearnerV3Result |
| Počet naučených vrstev | len(learner_result.data) | len(learner_result) |
| Data pro první vrstvu | layer_error = learner_result.data[0] | noise_map = learner_result[0].to_pauli_lindblad_map() |
| Typ výsledku každé vrstvy | LayerError (type(layer_error)) | PauliLindbladMap (type(noise_map)) |
| Generátory chybového kanálu | layer_error.error.generators | noise_map.generators() |
| Chybovost | layer_error.error.rates | noise_map.rates |
Krok 5: Vstup modelu šumu do primitiva
NoiseLearner funguje pouze se starším serverovým Estimator a NoiseLearnerV3 funguje pouze s Executor a klientským Estimator. Způsob, jakým je model šumu specifikován, se mírně liší podle toho, které primitivum se používá.
NoiseLearner, při práci se starším serverovým Estimatorem:
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, při práci s klientským Estimatorem:
Znovu použij stejný Estimator, který vytvořil layers v kroku 2. Mapy šumu vrácené
learnerem jsou pozičně přiřazeny k těmto vrstvám, takže musí být přiřazeny Estimatoru,
od kterého pocházejí. PEA/PEC na něm bylo již povoleno v kroku 2.
Všimni si, že zatímco NoiseLearnerV3 podporuje jak protokol Pauli-Lindblad, tak TREX, Estimator přijímá pouze modely šumu pro dvouqubitové vrstvy naučené protokolem 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, při práci s Executorem:
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)
Kompletní příklady
NoiseLearnerV3 a Estimator na straně klienta
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 a 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()