Skip to main content
IBM Quantum Platform

Clientseitiger Schätzer

qiskit_ibm_runtime.executor_estimator


Übersicht

qiskit_ibm_runtime.executor_estimator.Estimator ist eine Implementierung der Qiskit-Schnittstelle EstimatorV2 , die auf der Primitive Executor aufbaut. Es schätzt Erwartungswerte von Quantenobservablen, indem es ISA-Schaltkreise auf einem Backend des „ IBM Quantum “ ausführt.

Der wesentliche Unterschied zwischen der bisherigen serverseitigen Implementierung und Estimator dieser neuen Implementierung besteht darin, dass die gesamte Vor- und Nachbearbeitung auf dem Client-Rechner erfolgt. Dazu gehören die Vorbereitung der Schaltkreise (Twirling, Gate-Folding, dynamische Entkopplung und Rauscheinjektion) sowie die Nachbearbeitung der Ergebnisse (TREX-Skalierung, ZNE-Extrapolation und PEC-Quasi-Wahrscheinlichkeitsgewichtung). Die lokale Ausführung dieser Schritte ermöglicht ein schnelleres Feedback bei der Fehlersuche und bietet dem Benutzer mehr Kontrolle.

Wenn ein Benutzer einen Auftrag über [...], übermittelt run(), umfasst die zugrunde liegende Verarbeitung Folgendes:

  1. Die „Primitive Unified Blocs“ (PUBs) zusammenführen, die Standardwerte für die Ausfallsicherheit festlegen und die Anzahl der Schüsse bestimmen.
  2. Umwandlung der PUBs in ein QuantumProgram, wobei Schaltungstransformationen (Twirling, Gate-Folding, DD, Rauscheinjektion) entsprechend den festgelegten Optionen angewendet werden.
  3. Aufruf, Executor um das Quantenprogramm an das Backend zu übermitteln.
  4. Nach Abschluss des Auftrags werden aus den Rohmessdaten Erwartungswerte geschätzt und bei Bedarf eine Nachbearbeitung zur Fehlerminderung durchgeführt.
Anmerkung

Bei umfangreichen oder komplexen Arbeitslasten können die clientseitigen Vor- und Nachbearbeitungsschritte ressourcenintensiv sein und zu einer Verzögerung führen, bevor der Auftrag übermittelt wird. Stellen Sie den Logger qiskit_ibm_runtime auf ein, INFO um die clientseitige Verarbeitung zu überwachen:

import logging
logger = logging.getLogger("qiskit_ibm_runtime")
logger.setLevel(logging.INFO)

Grundlegende Verwendung

Beispiel 1 – Minimal (keine Fehlerbehebung)

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
from qiskit_ibm_runtime.executor_estimator import Estimator

# Select a backend.
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
observable = SparsePauliOp("ZZ")

# Transform the circuit and observable into ISA format.
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)
isa_obs = observable.apply_layout(isa_qc.layout)

estimator = Estimator(mode=backend)
estimator.options.resilience_level = 0
job = estimator.run([(isa_qc, isa_obs)])
result = job.result()
print(result[0].data.evs)   # expectation value

Beispiel 2 – Resilienzstufe 2 (Minderung von Messfehlern + Gate-Folding-ZNE)

estimator = Estimator(mode=backend)
estimator.options.resilience_level = 2  # TREX + ZNE (gate folding)
job = estimator.run([(isa_qc, isa_obs)])
result = job.result()
print(result[0].data.evs)                 # zero-noise extrapolated expectation value
print(result[0].data.evs_noise_factors)   # raw values at each noise amplification level

Beispiel 3 – PEC (erfordert explizites Rauschlernen)

Im Gegensatz zur bisherigen serverseitigen Implementierung erfordert Estimator diese clientseitige Variante ein explizites Rauschlernen für die Fehlerminderungsmethoden, die ein Rauschmodell benötigen (PEC und PEA).

Verwenden Sie, um find_unique_layers() die eindeutigen Gate-Schichten aus Ihren PUBs zu extrahieren, übergeben Sie die Schichten an, NoiseLearnerV3 um deren Rauschen in einem separaten Job zu ermitteln, und weisen Sie anschließend die ermittelten Rauschkarten zu layer_noise_model.

from qiskit_ibm_runtime.noise_learner_v3 import NoiseLearnerV3

pubs = [(isa_qc, isa_obs)]

estimator = Estimator(mode=backend)
estimator.options.resilience.pec_mitigation = True

# Step 1. Extract the unique boxed gate layers from your PUBs.
layers = estimator.find_unique_layers(pubs)

# Step 2. Learn the noise model for those layers.
nl_result = NoiseLearnerV3(mode=backend).run(layers).result()

# Step 3. Convert the NoiseLearnerV3 result to Pauli-Lindblad maps and pass them
# to the Estimator. The maps follow the same order as the input layers, so they can
# be zipped positionally.
pauli_lindblad_maps = nl_result.to_pauli_lindblad_maps()
estimator.options.resilience.layer_noise_model = zip(layers, pauli_lindblad_maps)

job = estimator.run(pubs)
result = job.result()
print(result[0].data.evs)

Eingaben

Jeder Aufruf von run() erfordert eine Liste von PUBs. Jede „ PUB “-Datei hat folgendes Format:

(<single circuit>, <one or more observables>, <optional parameter values>, <optional precision>)

Weitere Informationen zu den Ein- und Ausgängen des Schätzers finden Sie unter „Ein- und Ausgänge des Schätzers“.

Elemente aus Observables und Parameterwerten werden gemäß den in „Primitive Ein- und Ausgänge“ beschriebenen „ NumPy “-Broadcasting-Regeln kombiniert.


Optionen

Beim Instanziieren Estimatorvon können Sie Optionen mithilfe von oder EstimatorOptions einem Wörterbuch übergeben. Häufig verwendete Optionen, wie beispielsweise resilience_level, befinden sich auf der ersten Ebene. Weitere Optionen sind in Kategorien zusammengefasst, wie zum Beispiel execution. Geben Sie die Optionen in diesem Format an: options.<category>.<option> = <value>. Zum Beispiel: options.dynamical_decoupling.enable = True.

Einen Überblick über die Angabe von Basisoptionen finden Sie unter „Einführung in Optionen “. Weitere Informationen zu den Optionen des Estimators finden Sie unter „Estimator-Optionen festlegen“ und „Rauschmanagement mit dem Estimator konfigurieren “.


Ausgaben

run() gibt ein RuntimeJobV2. zurück. Der Aufruf gibt job.result() eine Reihe von PrimitiveResult Objekten EstimatorPubResult zurück – eines pro Eingabe- PUB :

result = job.result()
pub_result = result[0]        # EstimatorPubResult for the first PUB
pub_result.data               # DataBin holding numerical arrays
pub_result.metadata           # dictionary with per-PUB metadata
result.metadata               # dictionary with job-level metadata

Der Inhalt von pub_result.data hängt von der angegebenen Schutzmaßnahme ab.

Keine Maßnahmen / ausschließlich Messmaßnahmen (Resilienzstufen 0 und 1)

Alle folgenden Felder haben die Form pub_shape, die gleich ist broadcast(param_shape, obs_shape).

  • data.evs — Erwartungswerte.
  • data.stds — Standardabweichungen. Gibt die Streuung über die Twirling-Zufallsgenerierungen wieder, wenn Twirling aktiviert ist; entspricht, ensemble_standard_error wenn Twirling deaktiviert ist.
  • data.ensemble_standard_error — Standardfehler unter der Annahme eines unabhängig und identisch verteilten Schussrauschens (ohne Driftbeitrag).

Wenn die Messwertkorrektur (TREX) aktiv ist, werden die Werte evs mithilfe einer Kalibrierschaltung, die automatisch parallel zu den Hauptschaltungen betrieben wird, um Ablesefehler korrigiert.

PEC

PEC erzeugt dieselben drei Felder wie das Szenario ohne Minderungsmaßnahmen: evs, stds, und ensemble_standard_error. Der Gamma-Quasi-Wahrscheinlichkeitsfaktor wird intern während der Nachbearbeitung angewendet und erscheint nicht als separates Ausgabefeld.

Die Werte stds werden mit dem Gamma-Faktor skaliert, sodass sie bei gleicher Schusszahl in der Regel größer sind als im Fall ohne Minderung. Dies ist der grundlegende Nachteil von PEC: Unverzerrte Schätzungen gehen mit einer erhöhten Varianz einher, die proportional zum Stichprobenaufwand ist (gamma^2).

ZNE (Gate-Folding) und PEA

In resilience.zne_mitigation=Truediesem Fall lässt der Schätzer die Schaltung bei verschiedenen Rauschverstärkungsstufen durchlaufen und passt eine Kurve an, um auf ein Rauschen von Null zu extrapolieren. Das Ergebnis enthält sowohl die extrapolierte Schätzung als auch die Rohdaten für jedes Rauschpegel.

  • data.evs — Rauschfreie extrapolierte Erwartungswerte (beste heterogene Anpassung – bei mehrgliedrigen Observablen wird der Extrapolator für jeden Glied einzeln gewählt). Form: pub_shape.
  • data.stds — Standardabweichungen der extrapolierten Werte. Gleiche Form wie evs. Abgeleitet aus der Streuung bei „Twirling“-Zufallsgenerierung, wenn „Twirling“ aktiviert ist.
  • data.evs_noise_factors — Rohwerte (nicht extrapolierte Erwartungswerte) bei jedem Rauschverstärkungsgrad. Form: (*pub_shape, num_noise_factors).
  • data.stds_noise_factors — Standardabweichungen bei jedem Rauschfaktor. Gleiche Form wie evs_noise_factors. Gibt die Streuung bei aktivierter Twirling-Funktion an; entspricht ensemble_stds_noise_factors bei deaktivierter Twirling-Funktion.
  • data.ensemble_stds_noise_factors — Standardfehler des Ensembles bei jedem Rauschfaktor unter der Annahme, dass das Schussrauschen unabhängig und identisch verteilt ist. Form: (*pub_shape, num_noise_factors).
  • data.evs_extrapolated — Erwartungswerte der einzelnen angeforderten Extrapolatoren, berechnet an jedem Punkt in resilience.zne.extrapolated_noise_factors. Es handelt sich hierbei um erzwungene homogene Anpassungen – auf alle Terme einer mehrtermigen Observablen wird derselbe Extrapolator angewendet –, d. h. eine Anpassung pro Extrapolator. Form: (*pub_shape, num_extrapolators, num_eval_points).
  • data.stds_extrapolated — Standardabweichungen, die … entsprechen evs_extrapolated. Gleiche Form.
Anmerkung

Bei Observablen mit mehreren Termen (zum Beispiel {"XX": 0.5, "XY": 0.5}) stds verwenden evs und eine heterogene Anpassung: Der am besten passende Extrapolator wird für jeden Pauli-Term unabhängig ausgewählt. evs_extrapolated und stds_extrapolated verwenden Sie eine homogene Anpassung pro Extrapolator, was für den Vergleich von Modellen nützlich ist. Wenn für Ihre Analyse ein einziger Extrapolator konsistent angewendet werden muss, teilen Sie die aus mehreren Termen bestehende Observable in einzelne Observables auf, sodass jeder Term für sich allein angepasst wird.

ZNE-Ergebnisse können mit und draw_zne_evs() visualisiert werden ( draw_zne_extrapolators() erfordert plotly).

Metadaten auf Jobebene

result.metadata ist ein, das Folgendes enthält dict :

  • "options" — die endgültige Fassung EstimatorOptions, als Wörterbuch. Inaktive Unteroptionen für die Resilienz werden entfernt (beispielsweise wird das Unterwörterbuch zne weggelassen, wenn zne_mitigation=False), und das Rauschmodell (sofern vorhanden) wird entfernt.
  • "target_precision" — die aus den PUBs ermittelte Genauigkeit und das precision Argument von run(), oder, None falls keines von beiden angegeben ist. In diesem Fall stammt die Schussanzahl aus default_shots, wobei auf zurückgegriffen wird default_precision.
  • "shots" — die Gesamtzahl der für die Ausführung verwendeten Schüsse.
  • "executor" — die Metadaten des zugrunde liegenden Executor-Ergebnisses.

Migrationshandbuch

Diese clientseitige Implementierung des Estimators ist im Wesentlichen ein direkter Ersatz für die bisherige Version. Befolgen Sie die unten aufgeführten Schritte, um auf die neue Implementierung umzustellen, und beachten Sie dabei die folgenden Verhaltensänderungen:

  • Die Vor- und Nachbearbeitung erfolgt auf der Client-Seite. Im bisherigen Estimator werden alle Schaltungstransformationen (Twirling, Gate-Folding und Rauscheinjektion) sowie die Nachbearbeitung der Ergebnisse (ZNE-Extrapolation, TREX-Skalierung und PEC-Gewichtung) serverseitig durchgeführt. Bei dieser clientseitigen Implementierung werden diese Schritte vollständig auf dem Client-Rechner ausgeführt.
  • Das Lernen von Rauschen ist ein separater Schritt. Im bisherigen Estimator ist das Rauschlernen für PEC und PEA in den Estimator-Job selbst integriert und wird serverseitig implizit abgewickelt. In dieser neuen Implementierung ist das Rauschlernen ein separater Arbeitsablauf, der explizit durchgeführt werden muss.
  • Executor-Jobs werden übermittelt. Der clientseitige Estimator nutzt den Executor zum Einreichen von Aufträgen, wodurch diese zu Executor-Aufträgen und nicht zu Estimator-Aufträgen werden. Job-Attribute wie und primitive_id inputsliefern Informationen zum Executor-Job zurück.

Schritt 1 – Aktualisieren Sie die Importe.

Bisher:

from qiskit_ibm_runtime import Estimator
from qiskit_ibm_runtime.options import EstimatorOptions

Nachher:

from qiskit_ibm_runtime.executor_estimator import Estimator
from qiskit_ibm_runtime.options_models import EstimatorOptions

Schritt 2 – Führen Sie das Rauschlernen explizit durch (falls PEC oder PEA verwendet wird).

Wenn Ihr Code PEC (pec_mitigation=True) oder ZNE mit PEA (zne.amplifier="pea") verwendet, müssen Sie das Rauschlernen explizit mithilfe von durchführen NoiseLearnerV3.

Bisher:

from qiskit_ibm_runtime import Estimator

pubs = [...]  # Your PUBs
estimator = Estimator(mode=backend)
estimator.options.resilience.pec_mitigation = True  # or zne_mitigation + pea amplifier

job = estimator.run(pubs)

Nachher:

from qiskit_ibm_runtime.executor_estimator import Estimator
from qiskit_ibm_runtime import NoiseLearnerV3

pubs = [...]  # Your PUBs
estimator = Estimator(mode=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(mode=backend)
learner_job = learner.run(layers)
learner_result = learner_job.result()

# Convert the result to Pauli-Lindblad noise maps.
pauli_lindblad_maps = learner_result.to_pauli_lindblad_maps()

# Assign the learned noise maps so PEA/PEC uses them.
# The result objects returned by NoiseLearnerV3 follow the same order as the input
# layers, so the positional zip can be used here.
estimator.options.resilience.layer_noise_model = zip(layers, pauli_lindblad_maps)

# Now execute the target PUBs.
job = estimator.run(pubs)

Schritt 3 – Einen Auftrag in mehrere Aufträge aufteilen (falls die PUBs unterschiedliche Genauigkeitswerte verwenden).

Gemischte Genauigkeiten werden nicht mehr unterstützt: Ein Auftrag darf keine PUBs mehr enthalten, die unterschiedliche Genauigkeitswerte anfordern; IBMInputValueError andernfalls wird ein Fehler run() ausgelöst. Gruppieren Sie die PUBs nach Präzision und reichen Sie pro Gruppe einen Auftrag ein, wobei Sie ein verwenden, Batch damit die Gruppen weiterhin gemeinsam ausgeführt werden.

Bisher:

from qiskit_ibm_runtime import Estimator

# PUBs with different precision values.
pubs = [(isa_circuit, isa_obs, None, 0.1), (isa_circuit1, isa_obs1, None, 0.5)]
estimator = Estimator(mode=backend)

job = estimator.run(pubs)

Nachher:

from qiskit_ibm_runtime.executor_estimator import Estimator
from qiskit_ibm_runtime import Batch

# Group the PUBs by precision, one group per job.
with Batch(backend=backend) as batch:
    estimator = Estimator(mode=batch)

    jobs = [
        estimator.run([(isa_circuit, isa_obs)], precision=0.1),
        estimator.run([(isa_circuit1, isa_obs1)], precision=0.5),
    ]

results = [job.result() for job in jobs]

Klassen

Kolumne „ 1 “
Kolumne „ 2 “
EstimatorClientseitige „Estimator“-Primitive für „ IBM Quantum Compute “ (früher „ Qiskit Runtime “).
EstimatorV2Alias von Estimator
War diese Seite hilfreich?
Melden Sie auf GitHub einen Fehler, einen Tippfehler oder fordern Sie Inhalte an.