Von NoiseLearner zu NoiseLearnerV3 migrieren
Diese Anleitung führt Sie durch die Migration von IBM Quantum® NoiseLearner zu NoiseLearnerV3. In beiden
Kursen werden Experimente durchgeführt, die Rauschprozesse auf der Grundlage eines
Pauli-Lindblad-Rauschmodells charakterisieren, wobei sich die Eingaben und
Ausgaben jedoch geringfügig unterscheiden.
Hintergrund
Die NoiseLearner
Klasse wurde entwickelt, um Benutzern das explizite Lernen von Rauschen zu ermöglichen. Das daraus resultierende
Rauschmodell kann anschließend an „ IBM Quantum “ übergeben werden, um Estimator dort Fehlerminderungsverfahren
wie PEA und PEC anzuwenden.
NoiseLearner wurde für die Verwendung mit Estimator entwickelt und nutzt daher implizit dieselbe
Strategie zur Erkennung von Ebenen wie Estimator. Diese Strategie kann nicht geändert werden; andernfalls
würden die nachfolgenden
Abhilfemaßnahmen nicht ordnungsgemäß funktionieren.
Ab Version v0.47.0qiskit-ibm-runtime gibt es eine neue
NoiseLearnerV3
Klasse, die mit dem primitiven Executor und dem
gerichteten Ausführungsmodell kompatibel ist.
Dieses neue Modell bietet ein „White-Box“-Erlebnis, indem es die Elemente bereitstellt, mit denen die Designabsicht
auf der Client-Seite erfasst werden kann, und eine einzige serverseitige Primitive (Executor) verarbeitet diese Eingaben genau so, wie
es vorgegeben ist – es trifft keine impliziten Entscheidungen in Ihrem Namen. Im Gegensatz zum Original
NoiseLearnerkönnen Sie bei der VerwendungNoiseLearnerV3 selbst bestimmen, wie Ihre Schaltkreise unterteilt werden sollen, und die Klasse nimmt lediglich eine Liste von in Boxen verpackten Schaltkreisbefehlen
(beispielsweise eindeutige Ebenen) als Eingabe entgegen.
NoiseLearnerV3 unterstützt zudem das Lernen von Messrauschen. Für jede Anweisung in der Eingabeliste führt es das
Pauli-Lindblad-Lernprotokoll aus, wenn die Box Ein- und Zwei-Qubit-Gatter enthält, und das
TREX-Protokoll,
wenn die Box Messungen enthält.
Sollten Sie umsteigen?
NoiseLearner funktioniert nur mit der alten serverseitigen Version Estimatorund funktioniert NoiseLearnerV3 nur mit
Executor und der clientseitigen Version Estimator. Sie müssen auf umsteigen, NoiseLearnerV3 wenn Sie
Executor oder clientseitig verwenden Estimator. Die alte serverseitige Funktion ist Estimator veraltet und wird durch das clientseitige Äquivalent unter v0.50.0qiskit-ibm-runtime ersetzt.
Wenn Sie v0.50.0qiskit-ibm-runtime oder eine neuere Version verwenden, lesen Sie zunächst das Handbuch „Migration von serverseitigen zu clientseitigen Samplern und Estimatoren“, um die Migration zu clientseitigen Primitiven durchzuführen.
Migrationsschritte
Schritt 1: Ändern Sie die Importe
NoiseLearner:
from qiskit_ibm_runtime.noise_learner import NoiseLearnerNoiseLearnerV3:
from qiskit_ibm_runtime import NoiseLearnerV3Schritt 2: Aktualisieren Sie die Eingaben
Die Methode NoiseLearner``run() erwartet eine Liste von Schaltkreisen oder PUBs, während die Methode NoiseLearnerV3``run() eine Liste von Befehlen erwartet, von denen jeder ein mit „twirling“ annotiertes sein muss, das ISA-Operationen enthält BoxOp .
Je nachdem, welche
Grundform Sie verwenden möchten, stehen Ihnen praktische Methoden zur Erstellung der beschrifteten Rahmen zur Verfügung.
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, bei der Arbeit mit dem clientseitigen Estimator:
Wenn Sie vorhaben, den clientseitigen Estimator für die Schaltkreisauflösung zu verwenden, können Sie die find_unique_layers Methode aus dem Estimator nutzen, um annotierte Boxen (Ebenen) zu erstellen:
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, bei der Arbeit mit Executor:
Wenn Sie vorhaben, Executor für die Schaltkreisauflösung zu verwenden, sollten Sie die Funktion „generate_boxing_pass_manager“ aus Samplomatic in Betracht ziehen, um annotierte Boxen zu erstellen:
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)Schritt 3: Konvertieren Sie die Optionen
Die meisten Felder NoiseLearnerOptions lassen sich direkt zuordnen NoiseLearnerV3Options, mit Ausnahme der folgenden:
max_layers_to_learn: BeiNoiseLearnerV3richtet sich die Anzahl der zu lernenden Schichten nach der Anzahl der übergebenen Schichten.twirling_strategy: Bei wird die Twirling-Strategie dadurch bestimmtNoiseLearnerV3, wie die Anweisungen in Blöcke zusammengefasst und mit Anmerkungen versehen werden (beispielsweise bei der Verwendung vongenerate_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, bei der Arbeit mit dem clientseitigen Estimator:
Wenn Sie vorhaben, für die Schaltungsausführung den clientseitigen Estimator zu verwenden, können Sie
die twirling.strategy Estimator-Option wie folgt einstellen:
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, bei der Arbeit mit Executor:
Wenn Sie vorhaben, Executor für die Schaltkreisauflösung zu verwenden, können Sie die Option twirling_strategy an die Funktion generate_boxing_pass_manager übergeben.
Beachten Sie, dass bei die Werte twirling_strategy Unterstriche
("active_accum", "active_circuit") verwendengenerate_boxing_pass_manager(), während Werte NoiseLearnerOptions.twirling_strategy Bindestriche ("active-accum", "active-circuit") verwenden.
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])Schritt 4: Überprüfen Sie die Ergebnisse
Die Ausgaben von und NoiseLearner enthalten NoiseLearnerV3 ähnliche Informationen, liegen jedoch in unterschiedlichen Formaten vor. Passen Sie Ihren Code an, falls darin die Ausgabe explizit überprüft wird.
Zuordnung der Ergebnisattribute:
(learner_result Dies ist die Ausgabe des Lerners.)
Attribut | NoiseLearner | NoiseLearnerV3 |
|---|---|---|
| Ergebnistyp | NoiseLearnerResult | NoiseLearnerV3Results ist ein sequenzähnlicher Container von NoiseLearnerV3Result |
| Anzahl der trainierten Schichten | len( learner_result.data ) | len(learner_result) |
| Daten für die erste Ebene | layer_error = learner_result.data[0] | noise_map = learner_result[0].to_pauli_lindblad_map() |
| Ergebnistyp jeder Ebene | LayerError (type(layer_error)) | PauliLindbladMap (type(noise_map)) |
| Generatoren für den Fehlerkanal | layer_error.error.generators | noise_map.generators() |
| Fehlerraten | layer_error.error.rates | noise_map.rates |
Schritt 5: Rauschmodell in eine Primitive einfügen
NoiseLearner funktioniert nur mit der älteren serverseitigen Version Estimatorund funktioniert NoiseLearnerV3 nur mit der serverseitigen und Executor der clientseitigen Version Estimator. Wie ein Geräuschmodell spezifiziert wird, hängt leicht davon ab, welche Primitive verwendet wird.
NoiseLearner, bei der Arbeit mit dem älteren serverseitigen 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, bei der Arbeit mit dem clientseitigen Estimator:
Verwenden Sie dasselbe wieder, das Estimator in layers Schritt 2 erzeugt wurde. Die vom
Lernalgorithmus zurückgegebenen Rauschkarten sind positionsmäßig auf diese Schichten abgestimmt, daher müssen sie dem Schätzer
zugeordnet werden, von dem sie stammen. PEA/PEC wurde dort bereits in Schritt 2 aktiviert.
Beachten Sie, dass zwar sowohl das Pauli-Lindblad- als auch das TREX-Protokoll unterstützt NoiseLearnerV3 werden, jedoch nur Estimator Rauschmodelle für Zwei-Qubit-Schichten akzeptiert werden, die mit dem Pauli-Lindblad-Protokoll trainiert wurden.
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, bei der Arbeit mit 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)Vollständige Beispiele
NoiseLearnerV3 und clientseitiger Schätzer
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 und Testamentsvollstrecker
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()