Skip to main content
IBM Quantum Platform

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.

Note

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 NoiseLearner

NoiseLearnerV3:

from qiskit_ibm_runtime import NoiseLearnerV3

Schritt 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: Bei NoiseLearnerV3richtet sich die Anzahl der zu lernenden Schichten nach der Anzahl der übergebenen Schichten.
  • twirling_strategy: Bei wird die Twirling-Strategie dadurch bestimmt NoiseLearnerV3, wie die Anweisungen in Blöcke zusammengefasst und mit Anmerkungen versehen werden (beispielsweise bei der Verwendung von 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, 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
ErgebnistypNoiseLearnerResultNoiseLearnerV3Results ist ein sequenzähnlicher Container von NoiseLearnerV3Result
Anzahl der trainierten Schichtenlen( learner_result.data )len(learner_result)
Daten für die erste Ebenelayer_error = learner_result.data[0]noise_map = learner_result[0].to_pauli_lindblad_map()
Ergebnistyp jeder EbeneLayerError (type(layer_error))PauliLindbladMap (type(noise_map))
Generatoren für den Fehlerkanallayer_error.error.generatorsnoise_map.generators()
Fehlerratenlayer_error.error.ratesnoise_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()

Referenzen

War diese Seite hilfreich?
Melden Sie auf GitHub einen Fehler, einen Tippfehler oder fordern Sie Inhalte an.