Вступ до AI-транспілятора Qiskit
Оцінений час використання: 5 хвилин на IBM Heron (ПРИМІТКА: Це лише оцінка. Фактичний час може відрізнятися.)
Результати навчання
Після проходження цього посібника користувачі повинні розуміти:
- Як використовувати AI-транспілятор (
generate_ai_pass_manager) як заміну стандартного транспілятора - Як AI-транспілятор порівнюється зі стандартним транспілятором за глибиною двокубітних вентилів, кількістю вентилів та часом транспіляції
- Як використовувати дзеркальні схеми для оцінки якості транспіляції через виконання на реальному обладнанні
Передумови
Ми рекомендуємо користувачам ознайомитися з такими темами перед проходженням цього посібника:
Передмова
AI-транспілятор Qiskit впроваджує проходи транспіляції на основі машинного навчання, які можуть створювати коротші, більш апаратно-ефективні схеми, ніж традиційні евристичні методи, такі як SABRE. Коротші схеми накопичують менше шуму, що безпосередньо покращує якість результатів на реальному квантовому обладнанні.
У цьому посібнику ми порівнюємо дві стратегії транспіляції:
| Стратегія | API |
|---|---|
| Стандартна | generate_preset_pass_manager(optimization_level=3, ...) |
| AI | generate_ai_pass_manager(optimization_level=1, ai_optimization_level=3, ...) |
Для кожної стратегії ми вимірюємо три метрики: глибину двокубітних вентилів, загальну кількість вентилів та час транспіляції.
Бенчмарки AI-транспілятора
У бенчмаркінгових тестах AI-транспілятор постійно створював більш неглибокі схеми вищої якості порівняно зі стандартним транспілятором Qiskit. Для цих тестів ми використовували стандартну стратегію менеджера проходів Qiskit, налаштовану за допомогою generate_preset_pass_manager. Хоча ця стандартна стратегія часто є ефективною, вона може мати труднощі з більшими або складнішими схемами. Навпаки, AI-проходи досягли середнього зменшення кількості двокубітних вентилів на 24% та зменшення глибини схеми на 36% для великих схем (100+ кубітів) при транспіляції до топології heavy-hex апаратного забезпечення IBM Quantum®. Для отримання додаткової інформації про ці бенчмарки звернись до цього блогу.

Цей посібник досліджує ключові переваги AI-проходів та те, як вони порівнюються з традиційними методами.
Вимоги
Перед початком цього посібника переконайся, що у тебе встановлено наступне:
- Qiskit SDK v2.0 або пізніше, з підтримкою візуалізації
- Qiskit Runtime (
pip install qiskit-ibm-runtime) v0.22 або пізніше - Qiskit IBM Transpiler з AI локальним режимом (
pip install 'qiskit-ibm-transpiler[ai-local-mode]') - Qiskit Aer (
pip install qiskit-aer)
Налаштування
# 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)
Приклад малого масштабу на симуляторі
Крок 1: Відображення класичних входів на квантову задачу
Ми генеруємо 20 випадкових схем з глибиною 4, де кількість кубітів варіюється від шести до 25. Ці схеми слугуватимуть тестовими випадками для порівняння стратегій транспіляції.
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]
Крок 2: Оптимізація задачі для виконання на квантовому обладнанні
Ми будуємо стандартний (SABRE) менеджер проходів для вибраного бекенду. Обидві стратегії транспіляції орієнтовані на повну карту зв'язності бекенду. Локальна симуляція залишається можливою завдяки тому, що на кроці симуляції використовується remap_to_contiguous для перейменування кожної транспільованої схеми лише на її активні кубіти, тому Aer симулює лише ці кубіти, а не весь пристрій.
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%
Зведена таблиця показує середнє та стандартне відхилення кожної метрики для всіх 20 схем, а також середній відсоток покращення AI-транспілятора порівняно зі стандартним. Позитивні значення вказують на кращі результати AI-транспілятора; негативні — на кращі результати стандартного.
Для цього прикладу малого масштабу AI-транспілятор досягає приблизно на 16% меншої глибини двокубітних вентилів у середньому, але ціною приблизно на 9% більшої кількості вентилів. Це підкреслює ключовий компроміс між двома стратегіями: AI-транспілятор пріоритизує зменшення глибини (менше послідовних шарів двокубітних вентилів), тоді як стандартний транспілятор (SABRE) пріоритизує мінімізацію загальної кількості вентилів (менше вставок SWAP). Залежно від твого застосування, одна метрика може бути важливішою за іншу.
plot_metrics_and_pct(results_sim, "Small-Scale Random Circuits")


Глибина двокубітних вентилів: AI-транспілятор загалом створює схеми з меншою глибиною двокубітних вентилів. Глибина є однією з основних метрик, на оптимізацію якої навчена AI-модель маршрутизації, і покращення помітне для більшості розмірів схем, хоча SABRE іноді відповідає або перевершує її на окремих схемах.
Кількість вентилів: Результати близькі на цьому масштабі, з невеликою перевагою SABRE загалом. Евристика маршрутизації SABRE спеціально розроблена для мінімізації кількості вставлених SWAP-вентилів, що безпосередньо зменшує кількість вентилів. При малих розмірах схем різниця незначна.
Час транспіляції: Час роботи SABRE практично постійний незалежно від кількості кубітів, тому розмір схеми мало впливає на час її транспіляції на цьому масштабі. Основна логіка маршрутизації SABRE є надзвичайно оптимізованою (значна частина реалізована на Rust). AI-транспілятор займає помітно більше часу і масштабується з розміром схеми, хоча абсолютні значення залишаються розумними для інтерактивного використання.
Крок 3: Виконання за допомогою примітивів Qiskit
Щоб оцінити вплив транспіляції на якість схеми, побудуємо дзеркальні схеми для випадку з 10 кубітами та запустимо їх на симуляторі Aer з простою моделлю шуму. Очікуваний результат дзеркальної схеми завжди є бітрядком з одних нулів, тому ймовірність вимірювання демонструє, наскільки добре кожна стратегія транспіляції зберігає якість схеми.
# 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)
Ми запустили обидві дзеркальні схеми через симулятор Aer з простою деполяризуючою моделлю шуму. Ймовірність виживання, визначена як частка вимірювань, які повертають бітрядок з одних нулів, кількісно оцінює, скільки шуму вносить кожна стратегія транспіляції.
Крок 4: Постобробка та повернення результату в бажаному класичному форматі
Ми витягуємо ймовірність вимірювання бітрядку з одних нулів для обох запусків. Вища ймовірність виживання вказує на кращу якість, тобто транспіляція вносила менше шуму. Графік нижче показує доповнення 1 - P(|0...0>), тому нижчий стовпець вказує на кращу якість, а невеликі відмінності в похибці легше помітити.
# 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()
У цьому випадку стандартний транспілятор створив для цього конкретного 10-кубітного екземпляру і більш неглибоку, і меншу схему, тому його вища якість є очікуваною. Результати для кожної окремої схеми варіюються: як показує зведена таблиця вище, перевага AI-транспілятора полягає в меншій глибині двокубітних вентилів у середньому, а не на кожній окремій схемі. Яка стратегія дає вищу якість, залежить від величини різниці в кожній метриці, характеристик шуму обладнання та структури схеми. За умови рівномірної деполяризуючої моделі шуму загальна кількість вентилів часто має більш прямий вплив на накопичену похибку, ніж лише глибина.
Приклад великого масштабу на реальному обладнанні
Кроки 1-4
Тут всі ці деталі зводяться разом у чіткий робочий процес більшого масштабу, який потім запускається на реальному квантовому обладнанні.
Наведений нижче код генерує 25 випадкових схем з глибиною 8, де кількість кубітів варіюється від 26 до 50. Ці схеми транспілюються обома стратегіями та збираються ті самі метрики. Потім ми будуємо дзеркальні схеми для випадку з 26 кубітами та відправляємо їх на реальний бекенд.
# -------------------------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)
Аналіз результатів
Результати великого масштабу підтверджують тенденції, спостережені в прикладі малого масштабу, тепер на більш вимогливому рівні.
Глибина двокубітних вентилів: AI-транспілятор продовжує забезпечувати помітно меншу глибину двокубітних вентилів у повному діапазоні розмірів схем. Оптимізація глибини є однією з основних цілей, на яку навчена AI-модель маршрутизації, і перевага більш виражена при більшій кількості кубітів, коли задача маршрутизації стає складнішою для евристичних методів.
Кількість вентилів: Стандартний транспілятор (SABRE) стабільно створює схеми з меншою кількістю вентилів для всіх розмірів схем у цьому діапазоні. Евристика SABRE спеціально розроблена для мінімізації кількості вентилів, і на цьому масштабі перевага є чіткою та рівномірною.
Час транспіляції: Розрив у часі транспіляції збільшується на більших масштабах. SABRE залишається практично постійним, тоді як час роботи AI-транспілятора зростає більш стрімко. Незважаючи на це, час роботи AI-транспілятора залишається практичним для більшості робочих процесів.
Якість дзеркальних схем: Обидва методи виробляють ймовірності виживання значно нижче 1% на цьому масштабі, залишаючи мало придатного сигналу. При загальній кількості вентилів близько 10 000 і глибині двокубітних вентилів, що перевищує 1 000, деполяризуючий шум, накопичений у дзеркальній схемі, заглушає більшу частину сигналу. Це підкреслює ключове обмеження підходу дзеркальних схем: хоча він простий і не вимагає класичного моделювання, він погано масштабується для великих або глибоких схем, де обидва методи наближаються до порогу шуму і невеликий сигнал, що залишився, домінується накопиченою похибкою.
Хоча ці результати підкреслюють ефективність AI-транспілятора, важливо зазначити його обмеження. Метод синтезу AI наразі доступний лише для певних карт зв'язності, що може обмежити його ширшу застосовність. Це обмеження слід враховувати при оцінці його використання в різних сценаріях.
Наступні кроки
Якщо ця робота тебе зацікавила, тобі може бути цікавий наступний матеріал: