Skip to main content
IBM Quantum Platform


title: "Schnellstart" description: "Eine Schnellstartanleitung für das Qiskit-Add-on „Shaded Lightcones“ (qiskit-addon-slc)"

Schnellstart

Diese Anleitung zeigt ein minimales, funktionsfähiges Beispiel für das Paket qiskit-addon-slc . Wir berechnen einen abgeschatteten Lichtkegel, um den Rechenaufwand bei der probabilistischen Fehlerkompensation (PEC) zu reduzieren.

PEC reduziert das Gate-Rauschen durch Abtastung aus einer Quasiprobabilitätszerlegung des inversen Rauschkanals. Die Kosten für die Stichprobenziehung steigen mit jedem Fehlerterm, den sie ausgleichen muss; allerdings wirkt sich nicht jeder Fehler gleichermaßen auf die beobachtbare Größe aus. Ein Fehler außerhalb des kausalen Lichtkegels des Beobachters kann den gemessenen Erwartungswert überhaupt nicht beeinflussen, und selbst innerhalb des Lichtkegels sind manche Fehler schwerwiegender als andere. Ein schattierter Lichtkegel quantifiziert dies, indem er den Einfluss jedes Pauli-Fehlerterms auf die Observable begrenzt. Durch das Abschneiden der Fehlerterme mit dem geringsten Einfluss wird das Rauschmodell, das PEC kompensieren muss, verkleinert, wodurch die Abtastkosten im Gegenzug für eine kleine, begrenzte Verzerrung reduziert werden.

Um zu erfahren, wie man einen realistischen Workflow aufbaut und auf Quantenhardware ausführt, sehen Sie sich das Tutorial „Probabilistic error cancellation with shaded lightcones“ auf der „ IBM Quantum Platform “ an.


1. Bereiten Sie die Eingaben für SLC vor

Hier bauen wir einen 6-Qubit-Trotter-Ising-Schaltkreis mit transversalem Feld auf und wählen für das mittlere Qubit eine Einzelqubit- ZZ -Beobachtungsgröße aus.

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 = 6
circuit = trotter_ising_circuit(
    num_qubits, num_steps=2, rx_angle=np.pi / 16, rzz_angle=-np.pi / 2
)

# 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)

Output:

Observable: IIZIII
Output of the previous code cell

SLC arbeitet auf den rauschbehafteten Zwei-Qubit-Gatter-Schichten der Schaltung. Hier verwenden wir, samplomatic um die Gatter in kommentierte Kästchen zu gruppieren, und fügen jeder Zwei-Qubit-Schicht eine Anmerkung zur Rauscheinjektion hinzu. generate_noise_model_paulis anschließend werden die Pauli-Fehlerterme jeder einzelnen verrauschten Schicht aufgezählt.

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",
    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}")

Output:

Noisy layers: 2
Pauli error terms across all layers: 102

2. Berechne den schattierten Lichtkegel

Der schattierte Lichtkegel wird gebildet, indem jedem Pauli-Fehlerterm im Rauschmodell ein Skalierungsfaktor zugewiesen wird, der davon abhängt, wie stark er den Erwartungswert der Observable beeinflusst. Diese Skalen leiten sich aus den Vorwärts- und Rückwärts-Fehlergrenzen (siehe unten) sowie aus der Fehlerrate des jeweiligen Fehlerterms ab:

  • compute_forward_bounds führt jeden Fehlerterm bis zum Ende der Schaltung weiter, um dessen Auswirkung auf die dort gemessene Größe zu begrenzen.
  • compute_backward_bounds führt jeden Fehlerterm rückwärts bis zum Anfang der Schaltung zurück, um dessen Auswirkung auf den Anfangszustand zu begrenzen.

merge_bounds kombiniert die beiden zu einem einzigen Bindungs-pro-Fehler-Term. Zusammenführung von Skalen, die jeweils durch die Fehlerquote des Terms begrenzt sind. Diese Raten stammen in der Regel aus einem Experiment zum Lernen mit Rauschen (z. B. NoiseLearnerV3); Der Einfachheit halber verwenden wir hier Zufallsraten.

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
)

In der untenstehenden Visualisierung des schattierten Lichtkegels wird jedes Feld entsprechend der Stärke der Auswirkungen der Fehler an diesem Ort auf die beobachtbare Größe schattiert: Helle Felder weisen die größten Grenzen auf, während Felder, die in den Hintergrund verblassen, Fehlerterme enthalten, die nur einen geringen Einfluss auf die Berechnung haben – diese Fehler kommen als Kandidaten für den Ausschluss aus dem Rauschmodell in Frage. Die Werte in der folgenden Visualisierung stellen die Summen der Fehlergrenzen aller Pauli-Fehler an dieser Stelle dar, weshalb einige der Werte größer werden als 2.0 – die Grenze 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)

Output:

Output of the previous code cell

3. Senkung der Kosten für die Probenahme

compute_local_scales wandelt den schattierten Lichtkegel in eine konkrete PEC-Konfiguration um. Es ordnet die Fehlerterme nach ihrem begrenzten Einfluss auf die Observable und schneidet diejenigen mit dem geringsten Einfluss ab, bis der gewünschte Wert erreicht bias_tolerance ist. Es gibt für jeden Fehlerterm Skalen zurück – 0.0 für Terme, die bei der Minderung ignoriert werden sollen, und -1.0 für Terme, die gemindert werden sollen. Die Funktion gibt außerdem den daraus resultierenden Overhead bei den Stichprobenkosten ( γ2\gamma^2 ) sowie eine Schranke für die durch die Trunkierung verursachte Restverzerrung zurück.

Durch die Einstellung werden alle Fehlerterme innerhalb des kausalen Lichtkegels der Observable bias_tolerance=0.0 gemildert und es ergibt sich ein Basiswert für die Abtastkosten. Durch die Zulassung einer geringen Verzerrung kann SLC die Terme mit geringem Einfluss vernachlässigen 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:.3f}, residual bias {full_bias:.3f}"
)
print(
    f"Shaded    (bias_tolerance=0.05): sampling cost {reduced_cost:.3f}, residual bias {reduced_bias:.3f}"
)
print(
    f"\nSampling-cost reduction: {(1 - reduced_cost / full_cost):.0%} for <= 0.05 bias"
)

Output:

Full PEC (bias_tolerance=0.0):  sampling cost 1.923, residual bias 0.000
Shaded    (bias_tolerance=0.05): sampling cost 1.441, residual bias 0.044

Sampling-cost reduction: 25% for <= 0.05 bias
War diese Seite hilfreich?
Melden Sie auf GitHub einen Fehler, einen Tippfehler oder fordern Sie Inhalte an.