Optionen festlegen
Paketversionen
Der Code auf dieser Seite wurde mit den folgenden Anforderungen entwickelt. Wir empfehlen die Verwendung dieser oder neuerer Versionen.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
Du kannst Optionen verwenden, um die Primitives Estimator und Sampler anzupassen. Dieser Abschnitt erklärt, wie du Optionen für Qiskit Runtime Primitives festlegst. Obwohl die Schnittstelle der run()-Methode der Primitives bei allen Implementierungen gleich ist, sind ihre Optionen es nicht. Weitere Informationen zu den Optionen von qiskit.primitives und qiskit_aer.primitives findest du in den entsprechenden API-Referenzen.
Hinweise zum Festlegen von Optionen in den Primitives:
SamplerV2undEstimatorV2haben separate Optionsklassen. Du kannst die verfügbaren Optionen einsehen und Optionswerte während oder nach der Initialisierung des Primitives ändern.- Verwende die Methode
update(), um Änderungen am Attributoptionsvorzunehmen. - Wenn du keinen Wert für eine Option angibst, erhält sie den speziellen Wert
Unsetund es werden die Standardwerte des Servers verwendet. - Das Attribut
optionshat den Python-Typdataclass. Du kannst die eingebaute Methodeasdictverwenden, um es in ein Dictionary umzuwandeln.
Optionen für Primitives festlegen
Du kannst Optionen bei der Initialisierung des Primitives, nach der Initialisierung oder in der run()-Methode festlegen. Lies den Abschnitt zu den Vorrangregeln, um zu verstehen, was passiert, wenn dieselbe Option an mehreren Stellen angegeben wird.
Initialisierung des Primitives
Du kannst bei der Initialisierung eines Primitives eine Instanz der Optionsklasse oder ein Dictionary übergeben, woraufhin eine Kopie dieser Optionen erstellt wird. Änderungen am ursprünglichen Dictionary oder an der ursprünglichen Optionsinstanz wirken sich daher nicht auf die Optionen aus, die dem Primitive gehören.
Optionsklasse
Beim Erstellen einer Instanz der Klasse EstimatorV2 oder SamplerV2 kannst du eine Instanz der Optionsklasse übergeben. Diese Optionen werden dann angewendet, wenn du run() zur Durchführung der Berechnung verwendest. Gib die Optionen in diesem Format an: options.option.sub-option.sub-sub-option = choice. Zum Beispiel: options.dynamical_decoupling.enable = True
Beispiel:
SamplerV2 und EstimatorV2 haben separate Optionsklassen (EstimatorOptions und SamplerOptions).
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator
from qiskit_ibm_runtime.options import EstimatorOptions
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
options = EstimatorOptions(
resilience_level=2,
resilience={"zne_mitigation": True, "zne": {"noise_factors": [1, 3, 5]}},
)
# or...
options = EstimatorOptions()
options.resilience_level = 2
options.resilience.zne_mitigation = True
options.resilience.zne.noise_factors = [1, 3, 5]
estimator = Estimator(mode=backend, options=options)
Dictionary
Du kannst Optionen bei der Initialisierung des Primitives als Dictionary angeben.
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# Setting options during primitive initialization
estimator = Estimator(
backend,
options={
"resilience_level": 2,
"resilience": {
"zne_mitigation": True,
"zne": {"noise_factors": [1, 3, 5]},
},
},
)
Optionen nach der Initialisierung aktualisieren
Du kannst Optionen in diesem Format angeben: primitive.options.option.sub-option.sub-sub-option = choice, um die Autovervollständigung zu nutzen, oder die Methode update() für Massenaktualisierungen verwenden.
Die Optionsklassen SamplerV2 und EstimatorV2 (EstimatorOptions und SamplerOptions) müssen nicht instanziiert werden, wenn du Optionen nach der Initialisierung des Primitives festlegst.
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
estimator = Estimator(mode=backend)
# Setting options after primitive initialization
# This uses auto-complete.
estimator.options.default_shots = 4000
# This does bulk update.
estimator.options.update(
default_shots=4000, resilience={"zne_mitigation": True}
)
Methode Run()
Die einzigen Werte, die du an run() übergeben kannst, sind die in der Schnittstelle definierten: shots für Sampler und precision für Estimator. Diese überschreiben alle für default_shots oder default_precision für den aktuellen Lauf festgelegten Werte.
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit.circuit.library import random_iqp
from qiskit.transpiler import generate_preset_pass_manager
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
circuit1 = random_iqp(3)
circuit1.measure_all()
circuit2 = random_iqp(3)
circuit2.measure_all()
pass_manager = generate_preset_pass_manager(
optimization_level=3, backend=backend
)
transpiled1 = pass_manager.run(circuit1)
transpiled2 = pass_manager.run(circuit2)
sampler = Sampler(mode=backend)
# Default shots to use if not specified in run()
sampler.options.default_shots = 500
# Sample two circuits at 128 shots each.
sampler.run([transpiled1, transpiled2], shots=128)
# Sample two circuits with different numbers of shots.
# 100 shots is used for transpiled1 and 200 for transpiled.
sampler.run([(transpiled1, None, 100), (transpiled2, None, 200)])
<RuntimeJobV2('d5k96cn853es738djikg', 'sampler')>
Sonderfälle
Resilienz-Level (nur Estimator)
Der Resilienz-Level ist keine Option, die die Primitive-Abfrage direkt beeinflusst, sondern gibt einen kuratierten Basissatz von Optionen vor. Im Allgemeinen deaktiviert Level 0 alle Fehlerminderungsmaßnahmen, Level 1 aktiviert Optionen zur Messfehlerminderung und Level 2 aktiviert Optionen zur Gate- und Messfehlerminderung.
Alle Optionen, die du zusätzlich zum Resilienz-Level manuell angibst, werden auf den durch den Resilienz-Level definierten Basissatz aufgesetzt. Theoretisch könntest du den Resilienz-Level auf 1 setzen, aber dann die Messfehlerminderung deaktivieren – auch wenn das nicht empfohlen wird.
Im folgenden Beispiel deaktiviert das Setzen des Resilienz-Levels auf 0 zunächst zne_mitigation, aber estimator.options.resilience.zne_mitigation = True überschreibt die entsprechende Einstellung von estimator.options.resilience_level = 0.
from qiskit_ibm_runtime import EstimatorV2, QiskitRuntimeService
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
estimator = EstimatorV2(backend)
estimator.options.default_shots = 100
estimator.options.resilience_level = 0
estimator.options.resilience.zne_mitigation = True
Shots (nur Sampler)
Die Methode SamplerV2.run akzeptiert zwei Argumente: eine Liste von PUBs, von denen jeder einen PUB-spezifischen Wert für shots angeben kann, sowie ein Schlüsselwortargument shots. Diese Shot-Werte sind Teil der Sampler-Ausführungsschnittstelle und unabhängig von den Optionen des Runtime Samplers. Sie haben Vorrang vor allen als Optionen angegebenen Werten, um der Sampler-Abstraktion zu entsprechen.
Wenn shots jedoch weder von einem PUB noch im run-Schlüsselwortargument angegeben wird (oder wenn alle None sind), wird der Shot-Wert aus den Optionen verwendet, insbesondere default_shots.
Zusammenfassend gilt für jeden PUB folgende Vorrangreihenfolge bei der Angabe von shots im Sampler:
- Wenn der PUB shots angibt, wird dieser Wert verwendet.
- Wenn das Schlüsselwortargument
shotsinrunangegeben wird, wird dieser Wert verwendet. - Wenn
num_randomizationsundshots_per_randomizationalstwirling-Optionen angegeben werden, entspricht die Shot-Anzahl dem Produkt dieser Werte. - Wenn
sampler.options.default_shotsangegeben wird, wird dieser Wert verwendet.
Wenn shots an allen möglichen Stellen angegeben werden, wird derjenige mit dem höchsten Vorrang (shots im PUB) verwendet.
Präzision (nur Estimator)
Präzision ist analog zu shots, wie im vorherigen Abschnitt beschrieben, mit dem Unterschied, dass die Estimator-Optionen sowohl default_shots als auch default_precision enthalten. Da Gate-Twirling standardmäßig aktiviert ist, hat das Produkt aus num_randomizations und shots_per_randomization Vorrang vor diesen beiden Optionen.
Für jeden Estimator-PUB gilt im Einzelnen:
- Wenn der PUB eine Präzision angibt, wird dieser Wert verwendet.
- Wenn das Schlüsselwortargument precision in
runangegeben wird, wird dieser Wert verwendet. - Wenn
num_randomizationsundshots_per_randomizationalstwirling-Optionen angegeben werden (standardmäßig aktiviert), wird ihr Produkt zur Steuerung der Datenmenge verwendet. - Wenn
estimator.options.default_shotsangegeben wird, wird dieser Wert zur Steuerung der Datenmenge verwendet. - Wenn
estimator.options.default_precisionangegeben wird, wird dieser Wert verwendet.
Wenn beispielsweise die Präzision an allen vier Stellen angegeben wird, wird derjenige mit dem höchsten Vorrang (Präzision im PUB) verwendet.
Die Präzision skaliert umgekehrt proportional zur Nutzung. Das heißt: Je niedriger die Präzision, desto mehr QPU-Zeit wird für die Ausführung benötigt.
Häufig verwendete Optionen
Es gibt viele verfügbare Optionen, aber die folgenden werden am häufigsten verwendet:
Shots
Für einige Algorithmen ist das Festlegen einer bestimmten Anzahl von shots ein wesentlicher Bestandteil ihrer Routinen. Shots (oder Präzision) können an mehreren Stellen angegeben werden. Sie werden in folgender Reihenfolge priorisiert:
Für jeden Sampler-PUB:
- Ganzzahliger shots-Wert im PUB
- Der Wert
run(...,shots=val) - Der Wert
options.default_shots
Für jeden Estimator-PUB:
- Gleitkomma-Präzisionswert im PUB
- Der Wert
run(...,precision=val) - Der Wert
options.default_shots - Der Wert
options.default_precision
Beispiel:
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit.circuit.library import random_iqp
from qiskit.transpiler import generate_preset_pass_manager
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
circuit1 = random_iqp(3)
circuit1.measure_all()
circuit2 = random_iqp(3)
circuit2.measure_all()
pass_manager = generate_preset_pass_manager(
optimization_level=3, backend=backend
)
transpiled1 = pass_manager.run(circuit1)
transpiled2 = pass_manager.run(circuit2)
# Setting shots during primitive initialization
sampler = Sampler(mode=backend, options={"default_shots": 4096})
# Setting options after primitive initialization
# This uses auto-complete.
sampler.options.default_shots = 2000
# This does bulk update. The value for default_shots is overridden if you specify shots with run() or in the PUB.
sampler.options.update(
default_shots=1024, dynamical_decoupling={"sequence_type": "XpXm"}
)
# Sample two circuits at 128 shots each.
sampler.run([transpiled1, transpiled2], shots=128)
<RuntimeJobV2('d5k96icjt3vs73ds5t0g', 'sampler')>
Maximale Ausführungszeit
Die maximale Ausführungszeit (max_execution_time) begrenzt, wie lange ein Job laufen kann. Wird diese Zeitgrenze überschritten, wird der Job zwangsweise abgebrochen. Dieser Wert gilt für einzelne Jobs, unabhängig davon, ob sie im Job-, Session- oder Batch-Modus ausgeführt werden.
Der Wert wird in Sekunden angegeben und basiert auf der Quantenzeit (nicht der Echtzeit), also der Zeit, die der QPU für die Verarbeitung deines Jobs gewidmet ist. Er wird beim lokalen Testmodus ignoriert, da dieser Modus keine Quantenzeit verwendet.
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
estimator = Estimator(mode=backend)
estimator.options.max_execution_time = 2500
Alle Fehlerminderung und Fehlerunterdrückung deaktivieren
Du kannst alle Fehlerminderung und Fehlerunterdrückung deaktivieren, wenn du beispielsweise eigene Minderungstechniken erforschst. Setze dazu bei EstimatorV2 den resilience_level = 0. Für SamplerV2 sind keine Änderungen erforderlich, da standardmäßig keine Fehlerminderung oder Fehlerunterdrückung aktiviert ist.
Beispiel:
Alle Fehlerminderung und Fehlerunterdrückung im Estimator deaktivieren.
from qiskit_ibm_runtime import EstimatorV2 as Estimator, QiskitRuntimeService
# Define the service. This allows you to access IBM QPU.
service = QiskitRuntimeService()
# Get a backend
backend = service.least_busy(operational=True, simulator=False)
# Define Estimator
estimator = Estimator(backend)
options = estimator.options
# Turn off all error mitigation and suppression
options.resilience_level = 0
Nächste Schritte
- Weitere Details zu den Methoden von
EstimatorV2findest du in der Estimator API-Referenz. - Weitere Details zu den Methoden von
SamplerV2findest du in der Sampler API-Referenz. - Details zur Konfiguration von Fehlerunterdrückung und Fehlerminderung findest du in den entsprechenden Abschnitten.
- Entscheide, in welchem Ausführungsmodus du deinen Job ausführen möchtest.