דלג לתוכן הראשי
פרויקט זה בשלב בטא. מצאת באג? פתח issue ב-GitHub. יש שאלה או רעיון? שאל ב-Discussions — נשמח לשמוע ממך!
מה איכות התרגום בדף זה?

התחלה מהירה


title: התחלה מהירה description: מדריך התחלה מהירה לתוסף Qiskit בשם Shaded lightcones (qiskit-addon-slc)​

המדריך הזה מדגים דוגמה מינימלית עובדת של החבילה qiskit-addon-slc. הוא מחשב shaded lightcone כדי להפחית את עלות הדגימה של probabilistic error cancellation (PEC).

PEC מקזזת רעש של שערים על ידי דגימה מפירוק קוואזי-הסתברותי של ערוץ הרעש ההפוך. עלות הדגימה שלה גדלה עם כל איבר שגיאה שצריך לקזז; אבל לא כל שגיאה משפיעה על ה-observable באותה מידה. שגיאה מחוץ לחרוט האור הסיבתי של ה-observable לא יכולה להשפיע על ערך התצפית שנמדד, וגם בתוך חרוט האור יש שגיאות שפוגעות יותר מאחרות. shaded lightcone מכמת את זה על ידי חסימת ההשפעה של כל איבר שגיאת פאולי על ה-observable. קיצוץ איברי השגיאה עם ההשפעה הקטנה ביותר מכווץ את מודל הרעש ש-PEC צריכה לקזז, ומוריד את עלות הדגימה בתמורה להטיה קטנה וחסומה.

כדי לראות איך בונים זרימת עבודה מציאותית ומריצים על חומרה קוונטית, אפשר לעיין במדריך Probabilistic error cancellation with shaded lightcones ב-IBM Quantum Platform.

1. הכנת הקלטים ל-SLC​

קודם כל, בונים מעגל Ising עם שדה רוחבי בקירוב Trotter על 10 קיוביטים, ובוחרים observable של ZZ חד-קיוביטי על הקיוביט האמצעי.

# 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 פועל על שכבות השערים הדו-קיוביטיים הרועשות של המעגל. כאן אנחנו משתמשים ב-samplomatic כדי לקבץ את השערים לקופסאות מאונטות ולצרף הערת הזרקת רעש לכל שכבה דו-קיוביטית. SLC דורש שלכל קופסה רועשת יהיה modifier_ref ייחודי, וזה מה ש-inject_noise_strategy="individual_modification" מספק; עם אסטרטגיית ברירת המחדל של samplomatic, החסמים יוצאים שגויים או שהחישוב שלהם אף פעם לא מסתיים. אחר כך generate_noise_model_paulis מונה את איברי שגיאת הפאולי של כל שכבה רועשת ייחודית.

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. חישוב ה-shaded lightcone​

ה-shaded lightcone מורכב על ידי הקצאת סקאלה לכל איבר שגיאת פאולי במודל הרעש, לפי מידת ההשפעה שלו על ערך התצפית של ה-observable. הסקאלות האלה נגזרות מחסמי השגיאה קדימה ואחורה של כל איבר שגיאה (מתוארים בהמשך), וכן משיעור השגיאה שלו:

  • compute_forward_bounds מקדמת כל איבר שגיאה קדימה עד סוף המעגל כדי לחסום את השפעתו על ה-observable שנמדד שם.

  • compute_backward_bounds מקדמת כל איבר שגיאה אחורה עד תחילת המעגל כדי לחסום את השפעתו על המצב ההתחלתי.

merge_bounds משלבת את השניים לחסם אחד לכל איבר שגיאה. כל חסם מוכפל בשיעור השגיאה של האיבר. השיעורים האלה בדרך כלל מגיעים מניסוי למידת רעש (כמו NoiseLearnerV3); המדריך הזה משתמש בשיעורים אקראיים כדי לפשט.

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.

בהדמיית ה-shaded lightcone שלמטה, כל קופסה מוצללת לפי עד כמה חזקה ההשפעה של השגיאות באתר הזה על ה-observable. קופסאות בהירות נושאות את החסמים הגדולים ביותר, וקופסאות שמתמזגות עם הרקע מכילות איברי שגיאה עם השפעה קטנה על החישוב -- השגיאות האלה הן מועמדות טבעיות להסרה ממודל הרעש. הערכים בהדמיה שלמטה הם סכומים של חסמי השגיאה של כל שגיאות הפאולי באתר הזה, ולכן חלק מהערכים גדולים מ-2.0, החסם לכל שגיאת פאולי בודדת.

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. הפחתת עלות הדגימה​

compute_local_scales הופכת את ה-shaded lightcone לתצורת PEC קונקרטית. היא נותנת עדיפות לאיברי שגיאה לפי ההשפעה החסומה שלהם על ה-observable, וקוצצת את אלה עם ההשפעה הקטנה ביותר עד שמגיעים ל-bias_tolerance המבוקש. היא מחזירה סקאלות לכל איבר שגיאה: 0.0 לאיברים שיש להתעלם מהם בזמן הקיזוז ו--1.0 לאיברים שצריך לקזז. הפונקציה מחזירה גם את תקורת עלות הדגימה (γ2\gamma^2) וחסם על ההטיה השיורית שנגרמה מהקיצוץ.

הגדרת bias_tolerance=0.0 מקזזת כל איבר שגיאה בתוך חרוט האור הסיבתי של ה-observable ונותנת עלות דגימה בסיסית. מתן אפשרות להטיה קטנה מאפשר ל-SLC להוריד את האיברים עם ההשפעה הנמוכה ולהקטין את העלות הזו עוד יותר.

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