Zum Hauptinhalt springen
Dieses Projekt befindet sich in der Beta-Phase. Einen Fehler gefunden? GitHub Issue erstellen. Frage oder Idee? In Discussions fragen — wir freuen uns über dein Feedback!
Wie ist die Übersetzungsqualität auf dieser Seite?

Schnellstart


title: Quickstart description: Eine Quickstart-Anleitung für das Qiskit-Addon Shaded lightcones (qiskit-addon-slc)​

Diese Anleitung zeigt ein minimales funktionierendes Beispiel für das Paket qiskit-addon-slc. Es berechnet einen Shaded Lightcone, um die Sampling-Kosten der probabilistischen Fehlerauslöschung (PEC) zu senken.

PEC mitigiert Gate-Rauschen, indem es aus einer Quasiwahrscheinlichkeits-Zerlegung des inversen Rauschkanals sampelt. Die Sampling-Kosten wachsen mit jedem Fehlerterm, der mitigiert werden muss; allerdings beeinflusst nicht jeder Fehler die Observable gleich stark. Ein Fehler außerhalb des kausalen Lightcones der Observablen kann den gemessenen Erwartungswert nicht beeinflussen, und auch innerhalb des Lightcones sind manche Fehler schädlicher als andere. Ein Shaded Lightcone quantifiziert dies, indem er die Wirkung jedes Pauli-Fehlerterms auf die Observable beschränkt. Das Abschneiden der Fehlerterme mit der geringsten Wirkung verkleinert das Rauschmodell, das PEC mitigieren muss, und senkt die Sampling-Kosten im Austausch gegen einen kleinen, beschränkten Bias.

Wie du einen realistischen Workflow aufbaust und auf Quantenhardware ausführst, siehst du im Tutorial Probabilistische Fehlerauslöschung mit Shaded Lightcones auf der IBM Quantum Platform.

1. Die Eingaben für SLC vorbereiten​

Baue zunächst einen Trotterisierten Transversalfeld-Ising-Circuit mit 10 Qubits und wähle eine ZZ-Observable auf einem einzelnen Qubit in der Mitte.

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"numpy": "numpy", "qiskit": "qiskit", "qiskit_addon_slc": "qiskit-addon-slc", "samplomatic": "samplomatic"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
import numpy as np
from qiskit import QuantumCircuit
from qiskit.quantum_info import Pauli

def trotter_ising_circuit(num_qubits, num_steps, rx_angle, rzz_angle):
"""Trotterized transverse-field Ising evolution on a 1D chain."""
circuit = QuantumCircuit(num_qubits)
for _ in range(num_steps):
circuit.rx(rx_angle, range(num_qubits))
circuit.barrier()
for start in (0, 1): # even then odd bonds
for i in range(start, num_qubits - 1, 2):
circuit.rzz(rzz_angle, i, i + 1)
circuit.barrier()
return circuit

num_qubits = 10
circuit = trotter_ising_circuit(
num_qubits, num_steps=4, rx_angle=np.pi / 16, rzz_angle=-np.pi / 3
)

# Measure <Z> on the middle qubit
observable = Pauli("I" * num_qubits).compose("Z", [num_qubits // 2])

print(f"Observable: {observable}")
circuit.draw("mpl", fold=-1, scale=0.7)
Observable: IIIIZIIIII

Output of the previous code cell

SLC arbeitet auf den verrauschten Zwei-Qubit-Gate-Schichten des Circuits. Hier verwenden wir samplomatic, um die Gates in annotierte Boxen zu gruppieren und jeder Zwei-Qubit-Schicht eine Rauschinjektions-Annotation zuzuweisen. SLC verlangt, dass jede verrauschte Box ein eindeutiges modifier_ref hat, was inject_noise_strategy="individual_modification" liefert; mit der Standardstrategie von samplomatic sind die Schranken falsch oder ihre Berechnung wird nie fertig. generate_noise_model_paulis zählt dann die Pauli-Fehlerterme jeder eindeutigen verrauschten Schicht auf.

from qiskit_addon_slc.utils import generate_noise_model_paulis
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic.utils import find_unique_box_instructions

# Group gates into boxes and annotate each two-qubit layer with a noise-injection point
boxing_pass = generate_boxing_pass_manager(
inject_noise_targets="all",
inject_noise_strategy="individual_modification", # required: one modifier_ref per box
inject_noise_site="after",
twirling_strategy="active",
remove_barriers="never",
)
boxed_circuit = boxing_pass.run(circuit)

# Enumerate the 1- and 2-weight Pauli error terms of each unique noisy layer
noise_model_paulis = generate_noise_model_paulis(
find_unique_box_instructions(boxed_circuit)
)

num_terms = sum(len(paulis) for paulis in noise_model_paulis.values())
print(f"Noisy layers: {len(noise_model_paulis)}")
print(f"Pauli error terms across all layers: {num_terms}")
Noisy layers: 2
Pauli error terms across all layers: 198

2. Den Shaded Lightcone berechnen​

Der Shaded Lightcone entsteht, indem jedem Pauli-Fehlerterm im Rauschmodell eine Skala zugewiesen wird, die davon abhängt, wie stark er den Erwartungswert der Observablen beeinflusst. Diese Skalen werden aus den Vorwärts- und Rückwärts-Fehlerschranken jedes Fehlerterms (unten beschrieben) sowie aus seiner Fehlerrate abgeleitet:

  • compute_forward_bounds entwickelt jeden Fehlerterm vorwärts bis zum Ende des Circuits, um seine Wirkung auf die dort gemessene Observable zu beschränken.

  • compute_backward_bounds entwickelt jeden Fehlerterm rückwärts bis zum Anfang des Circuits, um seine Wirkung auf den Anfangszustand zu beschränken.

merge_bounds kombiniert die beiden zu einer einzigen Schranke pro Fehlerterm. Jede Schranke wird mit der Fehlerrate des Terms skaliert. Diese Raten stammen typischerweise aus einem Noise-Learning-Experiment (etwa mit NoiseLearnerV3); diese Anleitung verwendet der Einfachheit halber zufällige Raten.

from qiskit.quantum_info import PauliLindbladMap, QubitSparsePauliList
from qiskit_addon_slc.bounds import (
compute_backward_bounds,
compute_forward_bounds,
merge_bounds,
)

forward_bounds = compute_forward_bounds(
boxed_circuit, noise_model_paulis, observable
)
backward_bounds = compute_backward_bounds(boxed_circuit, noise_model_paulis)

# Stand-in for rates that would be measured by a noise-learning experiment on hardware
rng = np.random.default_rng(42)
noise_rates = {
layer_id: PauliLindbladMap.from_components(
rng.random(len(paulis)) * 5e-3,
QubitSparsePauliList.from_sparse_list(
paulis.to_sparse_list(), paulis.num_qubits
),
)
for layer_id, paulis in noise_model_paulis.items()
}

merged_bounds = merge_bounds(
boxed_circuit, forward_bounds, backward_bounds, noise_rates
)
Optimal spacetime partitioning not implemented!Just partitioning list of noisy boxes.

In der Shaded-Lightcone-Visualisierung unten ist jede Box danach eingefärbt, wie stark die Fehler an dieser Stelle die Observable beeinflussen können. Helle Boxen tragen die größten Schranken, während Boxen, die in den Hintergrund verblassen, Fehlerterme enthalten, die kaum Einfluss auf die Berechnung haben -- diese Fehler sind natürliche Kandidaten, um sie aus dem Rauschmodell zu streichen. Die Werte in der Visualisierung unten sind Summen der Fehlerschranken aller Pauli-Fehler an dieser Stelle, weshalb manche Werte größer als 2.0 werden, die Schranke für einen einzelnen Pauli-Fehler.

from qiskit_addon_slc.visualization import draw_shaded_lightcone

draw_shaded_lightcone(
boxed_circuit, merged_bounds, noise_model_paulis, fold=-1, scale=0.5
)

Output of the previous code cell

3. Die Sampling-Kosten senken​

compute_local_scales verwandelt den Shaded Lightcone in eine konkrete PEC-Konfiguration. Die Funktion priorisiert Fehlerterme nach ihrer beschränkten Wirkung auf die Observable und schneidet die am wenigsten wirksamen ab, bis die angeforderte bias_tolerance erreicht ist. Sie liefert Skalen für jeden Fehlerterm: 0.0 für Terme, die bei der Mitigation ignoriert werden, und -1.0 für Terme, die mitigiert werden sollen. Die Funktion gibt außerdem den resultierenden Sampling-Kosten-Overhead (γ2\gamma^2) und eine Schranke für den durch das Abschneiden entstehenden Restbias zurück.

Mit bias_tolerance=0.0 wird jeder Fehlerterm innerhalb des kausalen Lightcones der Observablen mitigiert, und man erhält eine Baseline der Sampling-Kosten. Erlaubt man einen kleinen Bias, kann SLC die Terme mit geringer Wirkung weglassen und diese Kosten weiter senken.

from qiskit_addon_slc.bounds import compute_local_scales

_, full_cost, full_bias = compute_local_scales(
boxed_circuit, merged_bounds, noise_rates, bias_tolerance=0.0
)
local_scales, reduced_cost, reduced_bias = compute_local_scales(
boxed_circuit, merged_bounds, noise_rates, bias_tolerance=0.05
)

print(
f"Full PEC (bias_tolerance=0.0) : sampling cost {full_cost:6.3f}, residual bias {full_bias:5.3f}"
)
print(
f"Shaded (bias_tolerance=0.05): sampling cost {reduced_cost:6.3f}, residual bias {reduced_bias:5.3f}"
)
print(
f"\nSampling-cost reduction: {(1 - reduced_cost / full_cost):.0%} for <= 0.05 bias"
)
Full PEC (bias_tolerance=0.0) : sampling cost 21.206, residual bias 0.000
Shaded (bias_tolerance=0.05): sampling cost 5.403, residual bias 0.049

Sampling-cost reduction: 75% for <= 0.05 bias