Einführung in den Qiskit AI-gestützten Transpiler
Geschätzte Nutzung: 5 Minuten auf IBM Heron (HINWEIS: Dies ist nur eine Schätzung. Deine Laufzeit kann abweichen.)
Lernziele
Nach diesem Tutorial sollten Nutzer verstehen:
- Wie man den AI-gestützten Transpiler (
generate_ai_pass_manager) als direkten Ersatz für den Standard-Transpiler verwendet - Wie der AI-gestützte Transpiler im Vergleich zum Standard-Transpiler hinsichtlich Zwei-Qubit-Tiefe, Gate-Anzahl und Transpilationszeit abschneidet
- Wie man Spiegelschaltungen nutzt, um die Transpilationsqualität durch Hardware-Ausführung zu bewerten
Voraussetzungen
Wir empfehlen, dass Nutzer mit den folgenden Themen vertraut sind, bevor sie dieses Tutorial durcharbeiten:
Hintergrund
Der Qiskit AI-gestützte Transpiler führt auf maschinellem Lernen basierende Transpilations-Passes ein, die kürzere, hardware-effizientere Schaltungen erzeugen können als traditionelle heuristische Methoden wie SABRE. Kürzere Schaltungen akkumulieren weniger Rauschen, was die Ergebnisqualität auf echter Quantenhardware direkt verbessert.
In diesem Tutorial vergleichen wir zwei Transpilationsstrategien:
| Strategie | API |
|---|---|
| Standard | generate_preset_pass_manager(optimization_level=3, ...) |
| AI | generate_ai_pass_manager(optimization_level=1, ai_optimization_level=3, ...) |
Wir messen drei Metriken für jede Strategie: Zwei-Qubit-Gate-Tiefe, Gesamt-Gate-Anzahl und Transpilations-Laufzeit.
Benchmarks des AI-gestützten Transpilers
In Benchmarking-Tests produzierte der AI-gestützte Transpiler konsistent flachere, qualitativ hochwertigere Schaltungen im Vergleich zum Standard-Qiskit-Transpiler. Für diese Tests verwendeten wir die Standard-Pass-Manager-Strategie von Qiskit, konfiguriert mit generate_preset_pass_manager. Während diese Standardstrategie oft effektiv ist, kann sie bei größeren oder komplexeren Schaltungen Schwierigkeiten haben. Im Gegensatz dazu erreichten AI-gestützte Passes eine durchschnittliche Reduzierung der Zwei-Qubit-Gate-Anzahl um 24 % und eine Reduzierung der Schaltungstiefe um 36 % für große Schaltungen (100+ Qubits) bei der Transpilation auf die Heavy-Hex-Topologie von IBM Quantum® Hardware. Weitere Informationen zu diesen Benchmarks findest du in diesem Blog.

Dieses Tutorial untersucht die wichtigsten Vorteile der AI-Passes und wie sie sich mit traditionellen Methoden vergleichen.
Anforderungen
Stelle vor Beginn dieses Tutorials sicher, dass du Folgendes installiert hast:
- Qiskit SDK v2.0 oder höher, mit Unterstützung für Visualisierung
- Qiskit Runtime (
pip install qiskit-ibm-runtime) v0.22 oder höher - Qiskit IBM Transpiler mit AI-Lokalmodus (
pip install 'qiskit-ibm-transpiler[ai-local-mode]') - Qiskit Aer (
pip install qiskit-aer)
Einrichtung
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib qiskit qiskit-aer qiskit-ibm-runtime qiskit-ibm-transpiler
from qiskit import QuantumCircuit
from qiskit.circuit.random import random_circuit
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2
from qiskit_ibm_transpiler import generate_ai_pass_manager
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel, depolarizing_error
import matplotlib.pyplot as plt
from statistics import mean, stdev
import time
import logging
seed = 42
def transpile_with_metrics(pass_manager, circuit):
"""Transpile a circuit and return the result along with key metrics."""
start = time.time()
qc_out = pass_manager.run(circuit)
elapsed = time.time() - start
depth_2q = qc_out.depth(lambda x: x.operation.num_qubits == 2)
gate_count = qc_out.size()
return qc_out, {
"depth_2q": depth_2q,
"gate_count": gate_count,
"time_s": round(elapsed, 3),
}
def remap_to_contiguous(tqc):
"""Remap a transpiled circuit to use contiguous qubit indices.
Transpiled circuits target specific physical qubits (e.g., qubit 45, 67)
on a large backend. This remaps them to 0, 1, 2, ... so Aer only
simulates the active qubits."""
active = sorted(
{tqc.find_bit(q).index for inst in tqc.data for q in inst.qubits}
)
qubit_map = {old: new for new, old in enumerate(active)}
new_qc = QuantumCircuit(len(active))
for inst in tqc.data:
old_indices = [tqc.find_bit(q).index for q in inst.qubits]
new_qc.append(inst.operation, [qubit_map[i] for i in old_indices])
return new_qc
def build_mirror_circuit(tqc, simulate=True):
"""Build a mirror circuit: U followed by U-dagger, with measurements.
The expected output is always |0...0>, so measuring the survival
probability reveals how much noise each transpilation strategy adds.
Args:
tqc: A transpiled circuit.
simulate: If True (default), remap to contiguous qubits so Aer
only simulates the active qubits. If False, keep the full
physical layout for hardware execution."""
if simulate:
tqc = remap_to_contiguous(tqc)
mirror = tqc.compose(tqc.inverse())
mirror.measure_all()
return mirror
def print_summary(results):
"""Print a summary of each metric as mean +/- stdev across all circuits,
along with the mean percentage improvement of AI over Default."""
metrics = [
("Depth 2Q", "Depth 2Q (Default)", "Depth 2Q (AI)"),
("Gate Count", "Gate Count (Default)", "Gate Count (AI)"),
("Time (s)", "Time (Default)", "Time (AI)"),
]
header = (
f"{'Metric':<12}{'Default (mean +/- std)':>24}"
f"{'AI (mean +/- std)':>22}{'AI % improvement':>22}"
)
print(header)
print("-" * len(header))
for label, col_def, col_ai in metrics:
defaults = [r[col_def] for r in results]
ais = [r[col_ai] for r in results]
pct = [(d - a) / d * 100 for d, a in zip(defaults, ais)]
default_str = f"{mean(defaults):.1f} +/- {stdev(defaults):.1f}"
ai_str = f"{mean(ais):.1f} +/- {stdev(ais):.1f}"
pct_str = f"{mean(pct):+.1f}% +/- {stdev(pct):.1f}%"
print(f"{label:<12}{default_str:>24}{ai_str:>22}{pct_str:>22}")
def plot_metrics_and_pct(results, title_prefix):
"""Plot metric comparisons and percentage improvement of AI over Default."""
qubits = [r["Qubits"] for r in results]
metrics = [
("Depth 2Q (Default)", "Depth 2Q (AI)", "Two-Qubit Depth"),
("Gate Count (Default)", "Gate Count (AI)", "Gate Count"),
("Time (Default)", "Time (AI)", "Transpilation Time"),
]
# Row 1: raw metric comparison
fig, axs = plt.subplots(1, 3, figsize=(21, 5))
fig.suptitle(
f"{title_prefix}: Metric Comparison",
fontsize=15,
fontweight="bold",
y=1.02,
)
for ax, (col_def, col_ai, label) in zip(axs, metrics):
ax.plot(qubits, [r[col_def] for r in results], "o-", label="Default")
ax.plot(qubits, [r[col_ai] for r in results], "s-", label="AI")
ax.set_title(label)
ax.set_xlabel("Number of Qubits")
ax.set_ylabel(label)
ax.legend()
plt.tight_layout()
plt.show()
# Row 2: percentage improvement
fig, axs = plt.subplots(1, 3, figsize=(21, 5))
fig.suptitle(
f"{title_prefix}: % Improvement of AI over Default",
fontsize=15,
fontweight="bold",
y=1.02,
)
for ax, (col_def, col_ai, label) in zip(axs, metrics):
pct = [(r[col_def] - r[col_ai]) / r[col_def] * 100 for r in results]
ax.axhline(
0, color="#1f77b4", linewidth=2, label="Default (baseline)"
)
ax.plot(qubits, pct, "s-", color="#ff7f0e", label="AI")
ax.fill_between(qubits, 0, pct, alpha=0.15, color="#ff7f0e")
ax.set_title(label)
ax.set_xlabel("Number of Qubits")
ax.set_ylabel("% Improvement")
ax.legend()
plt.tight_layout()
plt.show()
# Suppress verbose AI-powered transpiler logs
logging.getLogger(
"qiskit_ibm_transpiler.wrappers.ai_local_synthesis"
).setLevel(logging.WARNING)
Kleines Simulator-Beispiel
Schritt 1: Klassische Eingaben auf ein Quantenproblem abbilden
Wir generieren 20 zufällige Schaltungen mit Tiefe 4, wobei die Qubit-Anzahl von sechs bis 25 reicht. Diese Schaltungen dienen als Testfälle zum Vergleich der Transpilationsstrategien.
num_circuits_sim = 20
depth_sim = 4
qubit_range_sim = list(range(6, 26))
circuits_sim = [
# We have only two qubit gates, as those test how well the transpiler can optimize the circuit.
random_circuit(
num_qubits=n,
depth=depth_sim,
max_operands=2,
num_operand_distribution={2: 1},
seed=seed + i,
)
for i, n in enumerate(qubit_range_sim)
]
print(
f"Created {len(circuits_sim)} circuits with qubit counts: {qubit_range_sim}"
)
circuits_sim[0].draw(output="mpl", fold=-1)
Created 20 circuits with qubit counts: [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
Schritt 2: Problem für die Ausführung auf Quantenhardware optimieren
Wir erstellen den Standard-Pass-Manager (SABRE) für das gewählte Backend. Beide Transpilationsstrategien zielen auf die vollständige Coupling-Map des Backends ab. Die lokale Simulation bleibt später handhabbar, da der Simulationsschritt remap_to_contiguous verwendet, um jede transpilierte Schaltung auf nur ihre aktiven Qubits umzunummerieren, sodass Aer nur diese Qubits statt des gesamten Geräts simuliert.
service = QiskitRuntimeService()
backend = service.least_busy(
min_num_qubits=100, operational=True, simulator=False
)
pm_default_sim = generate_preset_pass_manager(
optimization_level=3,
backend=backend,
seed_transpiler=seed,
)
results_sim = []
for i, qc in enumerate(circuits_sim):
n = qubit_range_sim[i]
qc_default, m_default = transpile_with_metrics(pm_default_sim, qc)
# Create a fresh AI pass manager each iteration to avoid stale layout state
pm_ai = generate_ai_pass_manager(
optimization_level=1,
ai_optimization_level=3,
backend=backend,
)
qc_ai, m_ai = transpile_with_metrics(pm_ai, qc)
results_sim.append(
{
"Qubits": n,
"Depth 2Q (Default)": m_default["depth_2q"],
"Depth 2Q (AI)": m_ai["depth_2q"],
"Gate Count (Default)": m_default["gate_count"],
"Gate Count (AI)": m_ai["gate_count"],
"Time (Default)": m_default["time_s"],
"Time (AI)": m_ai["time_s"],
}
)
print_summary(results_sim)
Fetching 4 files: 0%| | 0/4 [00:00<?, ?it/s]
Metric Default (mean +/- std) AI (mean +/- std) AI % improvement
--------------------------------------------------------------------------------
Depth 2Q 33.0 +/- 12.9 26.4 +/- 8.0 +15.8% +/- 17.6%
Gate Count 522.0 +/- 266.0 560.5 +/- 279.1 -9.0% +/- 9.0%
Time (s) 0.0 +/- 0.0 0.2 +/- 0.1 -893.6% +/- 362.9%
Die Zusammenfassungstabelle zeigt den Mittelwert und die Standardabweichung jeder Metrik über alle 20 Schaltungen sowie die durchschnittliche prozentuale Verbesserung des AI-gestützten Transpilers gegenüber dem Standard. Positive Werte zeigen an, dass der AI-gestützte Transpiler bessere Ergebnisse lieferte; negative Werte zeigen an, dass der Standard besser war.
Für dieses kleine Beispiel erzielt der AI-gestützte Transpiler im Durchschnitt etwa 16 % geringere Zwei-Qubit-Tiefe, jedoch auf Kosten von etwa 9 % mehr Gates. Dies verdeutlicht einen wichtigen Kompromiss bei der Wahl zwischen den beiden Strategien: Der AI-gestützte Transpiler priorisiert die Tiefenreduzierung (weniger sequenzielle Schichten von Zwei-Qubit-Gates), während der Standard-Transpiler (SABRE) die Minimierung der Gesamt-Gate-Anzahl (weniger SWAP-Einfügungen) priorisiert. Je nach Anwendung kann eine Metrik wichtiger sein als die andere.
plot_metrics_and_pct(results_sim, "Small-Scale Random Circuits")


Zwei-Qubit-Tiefe: Der AI-gestützte Transpiler erzeugt im Allgemeinen Schaltungen mit geringerer Zwei-Qubit-Tiefe. Die Tiefe ist eine der primären Metriken, auf deren Optimierung das AI-Routing-Modell trainiert ist, und die Verbesserung ist bei den meisten Schaltungsgrößen sichtbar, obwohl SABRE ihn bei einzelnen Schaltungen einholt oder übertrifft.
Gate-Anzahl: Die Ergebnisse sind in diesem Maßstab eng beieinander, wobei SABRE insgesamt einen leichten Vorteil hat. Die Routing-Heuristik von SABRE ist darauf ausgelegt, die Anzahl der eingefügten SWAP-Gates zu minimieren, was die Gate-Anzahl direkt reduziert. Bei kleinen Schaltungsgrößen ist der Unterschied gering.
Transpilationszeit: Die Laufzeit von SABRE ist unabhängig von der Qubit-Anzahl nahezu konstant, sodass die Schaltungsgröße in diesem Maßstab wenig Einfluss auf die Transpilationszeit hat. Die Kernrouting-Logik von SABRE ist hochoptimiert (größtenteils in Rust implementiert). Der AI-gestützte Transpiler braucht deutlich länger und skaliert mit der Schaltungsgröße, obwohl die absoluten Zeiten für die interaktive Nutzung noch vertretbar bleiben.
Schritt 3: Ausführung mit Qiskit Primitives
Um den Einfluss der Transpilation auf die Schaltungs-Fidelität zu bewerten, erstelle Spiegelschaltungen aus dem 10-Qubit-Fall und führe sie auf dem Aer-Simulator mit einem einfachen Rauschmodell aus. Das erwartete Ergebnis einer Spiegelschaltung ist immer das Bitstring aus lauter Nullen, sodass die Wahrscheinlichkeit, zu messen, zeigt, wie gut jede Transpilationsstrategie die Fidelität erhält.
# Use the 10-qubit circuit (index where qubits == 10)
idx_10q = qubit_range_sim.index(10)
qc_10q = circuits_sim[idx_10q]
qc_default_10q, _ = transpile_with_metrics(pm_default_sim, qc_10q)
pm_ai = generate_ai_pass_manager(
optimization_level=1,
ai_optimization_level=3,
backend=backend,
)
qc_ai_10q, _ = transpile_with_metrics(pm_ai, qc_10q)
tqc_methods = {
"Default": qc_default_10q,
"AI": qc_ai_10q,
}
print(
f"Default: depth {qc_default_10q.depth()}, gates {qc_default_10q.size()}"
)
print(f"AI: depth {qc_ai_10q.depth()}, gates {qc_ai_10q.size()}")
Default: depth 84, gates 280
AI: depth 91, gates 343
# Build a simple depolarizing noise model
noise_model = NoiseModel()
noise_model.add_all_qubit_quantum_error(
depolarizing_error(0.001, 1),
["sx", "x", "rz"], # ~0.1% per 1Q gate
)
noise_model.add_all_qubit_quantum_error(
depolarizing_error(0.01, 2),
["cx", "ecr"], # ~1% per 2Q gate
)
aer_sim = AerSimulator(noise_model=noise_model)
shots = 10000
survival_probs = {}
for method, tqc in tqc_methods.items():
mirror = build_mirror_circuit(tqc, simulate=True)
sampler = SamplerV2(mode=aer_sim)
job = sampler.run([mirror], shots=shots)
counts = job.result()[0].data.meas.get_counts()
all_zeros = "0" * mirror.num_qubits
survival = counts.get(all_zeros, 0) / shots
survival_probs[method] = survival
print(
f"{method:8s} P(|00...0>) = {survival:.4f} ({counts.get(all_zeros, 0)}/{shots})"
)
Default P(|00...0>) = 0.8460 (8460/10000)
AI P(|00...0>) = 0.8121 (8121/10000)
Wir haben beide Spiegelschaltungen durch den Aer-Simulator mit einem einfachen depolarisierenden Rauschmodell laufen lassen. Die Überlebenswahrscheinlichkeit, definiert als der Anteil der Shots, der den Null-Bitstring zurückgibt, quantifiziert, wie viel Rauschen jede Transpilationsstrategie einführt.
Schritt 4: Nachbearbeitung und Rückgabe des Ergebnisses im gewünschten klassischen Format
Wir extrahieren die Wahrscheinlichkeit, den Null-Bitstring aus beiden Läufen zu messen. Eine höhere Überlebenswahrscheinlichkeit zeigt bessere Fidelität an, was bedeutet, dass die Transpilation weniger Rauschen eingeführt hat. Das folgende Diagramm zeigt das Komplement, 1 - P(|0...0>), sodass ein niedrigerer Balken bessere Fidelität anzeigt und kleine Unterschiede im Fehler leichter zu erkennen sind.
# Plot 1 - P(|0...0>), the probability of an erroneous (non-zero) outcome.
# A lower bar means the transpilation introduced less noise.
error_probs = {method: 1 - p for method, p in survival_probs.items()}
fig, ax = plt.subplots(figsize=(6, 4))
ax.bar(
error_probs.keys(),
error_probs.values(),
color=["steelblue", "coral"],
)
ax.set_ylabel("1 - P(|0...0>)")
ax.set_title("Mirror Circuit Error (10-qubit, Aer Simulator)")
ax.set_ylim(0, 1)
plt.tight_layout()
plt.show()
In diesem Fall erzeugte der Standard-Transpiler sowohl eine flachere als auch eine kleinere Schaltung für diese spezielle 10-Qubit-Instanz, sodass seine höhere Fidelität zu erwarten ist. Ergebnisse variieren von Schaltung zu Schaltung: Wie die obige Zusammenfassungstabelle zeigt, liegt der Vorteil des AI-gestützten Transpilers im Durchschnitt in geringerer Zwei-Qubit-Tiefe, nicht bei jeder einzelnen Schaltung. Welche Strategie höhere Fidelität liefert, hängt von der Größe des Unterschieds in jeder Metrik, den Rauscheigenschaften der Hardware und der Struktur der Schaltung ab. Bei einem gleichmäßigen depolarisierenden Rauschmodell hat die Gesamt-Gate-Anzahl oft einen direkteren Einfluss auf den akkumulierten Fehler als die Tiefe allein.
Großes Hardware-Beispiel
Schritte 1–4
Hier werden all diese Details in einem klaren Workflow in größerem Maßstab zusammengeführt und dann auf echter Quantenhardware ausgeführt.
Der folgende Code generiert 25 zufällige Schaltungen mit Tiefe 8, wobei die Qubit-Anzahl von 26 bis 50 reicht. Diese Schaltungen werden dann mit beiden Strategien transpiliert und die gleichen Metriken werden erfasst. Anschließend erstellen wir Spiegelschaltungen aus dem 26-Qubit-Fall und senden sie an das echte Backend.
# -------------------------Step 1-------------------------
num_circuits_hw = 25
depth_hw = 8
qubit_range_hw = list(range(26, 51))
circuits_hw = [
# We have only two qubit gates, as those test how well the transpiler can optimize the circuit.
random_circuit(
num_qubits=n,
depth=depth_hw,
max_operands=2,
num_operand_distribution={2: 1},
seed=seed + i,
)
for i, n in enumerate(qubit_range_hw)
]
print(
f"Created {len(circuits_hw)} circuits with qubit counts: {qubit_range_hw}"
)
Created 25 circuits with qubit counts: [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
# -------------------------Step 2-------------------------
pm_default = generate_preset_pass_manager(
optimization_level=3,
backend=backend,
seed_transpiler=seed,
)
results_hw = []
for i, qc in enumerate(circuits_hw):
n = qubit_range_hw[i]
qc_default, m_default = transpile_with_metrics(pm_default, qc)
# Create a fresh AI pass manager each iteration to avoid stale layout state
pm_ai = generate_ai_pass_manager(
optimization_level=1,
ai_optimization_level=3,
backend=backend,
)
qc_ai, m_ai = transpile_with_metrics(pm_ai, qc)
results_hw.append(
{
"Qubits": n,
"Depth 2Q (Default)": m_default["depth_2q"],
"Depth 2Q (AI)": m_ai["depth_2q"],
"Gate Count (Default)": m_default["gate_count"],
"Gate Count (AI)": m_ai["gate_count"],
"Time (Default)": m_default["time_s"],
"Time (AI)": m_ai["time_s"],
}
)
print_summary(results_hw)
Metric Default (mean +/- std) AI (mean +/- std) AI % improvement
--------------------------------------------------------------------------------
Depth 2Q 217.4 +/- 50.4 191.0 +/- 35.6 +10.9% +/- 10.7%
Gate Count 4513.3 +/- 1394.3 5227.1 +/- 1536.4 -16.4% +/- 5.8%
Time (s) 0.1 +/- 0.0 3.5 +/- 1.5 -3588.2% +/- 643.6%
plot_metrics_and_pct(results_hw, "Large-Scale Random Circuits")


# -------------------------Step 3-------------------------
# Build mirror circuits from the 26-qubit case
idx_26q = qubit_range_hw.index(26)
qc_26q = circuits_hw[idx_26q]
qc_default_26q, _ = transpile_with_metrics(pm_default, qc_26q)
pm_ai = generate_ai_pass_manager(
optimization_level=1,
ai_optimization_level=3,
backend=backend,
)
qc_ai_26q, _ = transpile_with_metrics(pm_ai, qc_26q)
mirror_default_hw = build_mirror_circuit(qc_default_26q, simulate=False)
mirror_ai_hw = build_mirror_circuit(qc_ai_26q, simulate=False)
# Re-transpile to basis gates (the inverse can introduce gates like sxdg)
pm_basis = generate_preset_pass_manager(
optimization_level=0,
backend=backend,
)
mirror_default_hw = pm_basis.run(mirror_default_hw)
mirror_ai_hw = pm_basis.run(mirror_ai_hw)
print(
f"Mirror circuit (Default): depth {mirror_default_hw.depth()}, gates {mirror_default_hw.size()}"
)
print(
f"Mirror circuit (AI): depth {mirror_ai_hw.depth()}, gates {mirror_ai_hw.size()}"
)
# Submit to real hardware
sampler_hw = SamplerV2(mode=backend)
sampler_hw.options.environment.job_tags = ["TUT_AITI"]
shots_hw = 500000
job_hw = sampler_hw.run([mirror_default_hw, mirror_ai_hw], shots=shots_hw)
print(f"Job submitted: {job_hw.job_id()}")
Mirror circuit (Default): depth 1577, gates 9672
Mirror circuit (AI): depth 1235, gates 11092
Job submitted: d8gt7vm6983c73dqbg0g
# -------------------------Step 4-------------------------
result_hw = job_hw.result()
survival_probs_hw = {}
for i, method in enumerate(["Default", "AI"]):
counts = result_hw[i].data.meas.get_counts()
mirror = [mirror_default_hw, mirror_ai_hw][i]
all_zeros = "0" * mirror.num_qubits
survival = counts.get(all_zeros, 0) / shots_hw
survival_probs_hw[method] = survival
print(
f"{method:8s} P(|00...0>) = {survival:.4f} ({counts.get(all_zeros, 0)}/{shots_hw})"
)
# Plot 1 - P(|0...0>), the probability of an erroneous (non-zero) outcome.
# A lower bar means the transpilation introduced less noise.
error_probs_hw = {method: 1 - p for method, p in survival_probs_hw.items()}
fig, ax = plt.subplots(figsize=(6, 4))
ax.bar(
error_probs_hw.keys(),
error_probs_hw.values(),
color=["steelblue", "coral"],
)
ax.set_ylabel("1 - P(|0...0>)")
ax.set_title(f"Mirror Circuit Error (26-qubit, {backend.name})")
ax.set_ylim(0, 1)
plt.tight_layout()
plt.show()
Default P(|00...0>) = 0.0005 (239/500000)
AI P(|00...0>) = 0.0050 (2516/500000)
Analyse der Ergebnisse
Die Ergebnisse im großen Maßstab bestätigen die im kleinen Beispiel beobachteten Trends, nun in einem anspruchsvolleren Rahmen.
Zwei-Qubit-Tiefe: Der AI-gestützte Transpiler liefert weiterhin deutlich geringere Zwei-Qubit-Tiefe über den gesamten Bereich der Schaltungsgrößen. Die Tiefenoptimierung ist eines der primären Ziele, auf die das AI-Routing-Modell trainiert ist, und der Vorteil ist bei größeren Qubit-Anzahlen ausgeprägter, wo das Routing-Problem für heuristische Methoden schwieriger wird.
Gate-Anzahl: Der Standard-Transpiler (SABRE) produziert konsistent Schaltungen mit weniger Gates über alle Schaltungsgrößen in diesem Bereich. Die Heuristik von SABRE ist speziell darauf ausgelegt, die Gate-Anzahl zu minimieren, und in diesem Maßstab ist der Vorteil klar und gleichmäßig.
Transpilationszeit: Die Lücke in der Transpilationszeit vergrößert sich bei größeren Maßstäben. SABRE bleibt nahezu konstant, während die Laufzeit des AI-gestützten Transpilers stärker ansteigt. Trotzdem bleibt die Laufzeit des AI-gestützten Transpilers für die meisten Workflows praktikabel.
Spiegelschaltungs-Fidelität: Beide Methoden erzeugen Überlebenswahrscheinlichkeiten weit unter 1 % in diesem Maßstab, was kaum ein nutzbares Signal lässt. Bei Gesamt-Gate-Anzahlen von etwa 10.000 und Zwei-Qubit-Tiefen über 1.000 überwiegt das depolarisierende Rauschen, das sich über die Spiegelschaltung ansammelt, den größten Teil des Signals. Dies verdeutlicht eine wesentliche Einschränkung des Spiegelschaltungsansatzes: Obwohl er einfach ist und keine klassische Simulation erfordert, skaliert er nicht gut für große oder tiefe Schaltungen, bei denen beide Methoden nahe an die Rauschgrenze gedrückt werden und das verbleibende kleine Signal von akkumulierten Fehlern dominiert wird.
Obwohl diese Ergebnisse die Wirksamkeit des AI-gestützten Transpilers unterstreichen, ist es wichtig, seine Einschränkungen zu beachten. Die AI-Synthesemethode ist derzeit nur für bestimmte Coupling-Maps verfügbar, was ihre breitere Anwendbarkeit einschränken kann. Diese Einschränkung sollte bei der Bewertung ihrer Verwendung in verschiedenen Szenarien berücksichtigt werden.
Nächste Schritte
Wenn du diese Arbeit interessant findest, könnten dich folgende Materialien interessieren: