量子编译器与电路转译:从逻辑线路到硬件脉冲

系统讲解量子编译器与电路转译:编译四阶段流水线、硬件原生门集与门分解、初始布局与 SABRE 路由算法、SWAP 插入与深度代价模型、调度与脉冲级编译、优化 Pass 与相位多项式化简、QIR 与 MLIR 中间表示,以及 Qiskit 与 tket 工具链实战。

引言

你写下的量子电路,几乎不可能直接在硬件上运行。原因很朴素:你用的是理想化的逻辑门(CNOT、Toffoli、任意单比特旋转),而硬件只提供少数几种物理门,且这些门只能在特定的量子比特对上执行。把「逻辑电路」翻译成「硬件能跑的电路」这件事,就是量子编译器与电路转译(transpilation)的工作。

这活儿的难度被严重低估。一个 100 量子比特、深度 1000 的电路,如果初始布局选得差,转译后可能需要插入上千个 SWAP 门,深度翻几倍,保真度直接崩掉。反过来,一个好的编译器能把同样的逻辑电路的两比特门数压掉 30%~50%。在 NISQ 时代,硬件噪声是主要瓶颈,编译质量几乎和硬件质量同等重要。

本文系统讲解量子编译:先讲编译流水线的四个阶段,再逐层拆解门分解、初始布局、路由与 SWAP 插入、调度,然后是脉冲级编译、优化 Pass 与代价模型、QIR 与 MLIR 中间表示,最后给出 Qiskit 与 tket 的实战代码。目标:理解「为什么转译会显著改变结果」,以及怎么读懂转译报告的每一个数字。

前置:量子电路优化 、Qiskit 编程 。前者讲的是电路层的化简技术,后者讲的是怎么把电路写出来。

编译流水线的四个阶段

量子编译的结构和经典编译惊人地相似,只是多了「空间」这个维度——经典编译管的是时间(指令顺序),量子编译还要管位置(量子比特放哪)。

逻辑电路
   │
   ├─ 1. 门分解 (decomposition / synthesis)
   │      任意单比特门 → 原生单比特门序列
   │      任意两比特门 → CNOT/CZ + 单比特门
   │
   ├─ 2. 初始布局 (initial layout)
   │      逻辑量子比特 → 物理量子比特的映射
   │
   ├─ 3. 路由 (routing / mapping)
   │      为不满足拓扑的 CNOT 插入 SWAP
   │
   ├─ 4. 调度 (scheduling)
   │      排定门的执行时刻,处理资源冲突
   │
   ▼
物理电路(原生门集 + 拓扑合法)
   │
   └─ 5. 脉冲级编译(可选)
          原生门 → 带定时的脉冲序列

这四个阶段互相耦合:布局影响路由的 SWAP 数量,路由会改变门顺序从而影响后续优化。所以现代编译器把布局与路由做成联合优化(SABRE 就是典型),而不是串行两遍。

阶段输入输出主要代价指标
门分解任意门原生门序列门数、单比特门数
初始布局逻辑电路物理映射后续 SWAP 数
路由映射 + 拓扑拓扑合法电路SWAP 数、深度
调度合法电路带时刻电路总时长、并行度
脉冲级原生门脉冲序列保真度、串扰

硬件原生门集与门分解

每个硬件平台都有自己的原生门集(native gate set)。你不能直接给硬件一个任意角度的 $R_y(\theta)$,除非它在原生门集里,或者能分解成原生门。

平台原生单比特门原生两比特门备注
IBM 超导RZ, SX, XECR / CXRZ 是虚拟门,几乎零成本
RigettiRX, RZCZ—
IonQR, RZMSMS 门任意角度可调
QuantinuumRZ, SX, XZZ / MS—
中性原子RZ, RXCZ需重排

注意 RZ 是虚拟门(virtual Z):它通过改变后续脉冲的相位实现,不需要实际施加微波,因此门时间接近零、保真度接近 100%。这个事实有重要后果——编译器应该尽量把旋转往 RZ 上搬,因为 RZ 几乎免费。

门分解的经典结果:

- 任意单比特幺正 → 最多 3 个旋转(ZYZ 分解)+ 全局相位
- 任意两比特幺正 → 最多 3 个 CNOT + 单比特门
- CNOT → CZ + 两个 Hadamard(若硬件原生是 CZ)
- Toffoli → 6 个 CNOT + 单比特门(T 门计数版本需 7 个 T)
- 多控门 → 线性数量的 CNOT(辅助比特方案)
# Qiskit: 把任意门分解到指定基底
from qiskit import QuantumCircuit
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke

qc = QuantumCircuit(3)
qc.h(0)
qc.mcx([0, 1], 2)      # 多控 X,硬件没有原生实现
qc.ry(0.37, 1)
qc.cx(1, 2)

backend = FakeSherbrooke()
pm = generate_preset_pass_manager(optimization_level=3, backend=backend)
isa_circuit = pm.run(qc)

print("原生门集:", backend.operation_names)
print("转译前门数:", qc.count_ops())
print("转译后门数:", isa_circuit.count_ops())
print("转译后深度:", isa_circuit.depth())

初始布局:把逻辑量子比特放对位置

布局(layout)决定哪个逻辑量子比特映射到哪个物理量子比特。这一步看似随意,实则决定路由代价的上限。

布局策略

策略思路适用
TrivialLayout第 i 个逻辑比特 → 第 i 个物理比特小电路、拓扑稠密
DenseLayout选连通性最好的子图中等电路
NoiseAdaptiveLayout选噪声最低的比特噪声差异大时
SabreLayout用路由反馈迭代优化布局大电路、稀疏拓扑
自定义按算法结构手工指定有先验知识时

一个经验事实:布局错了,后面怎么优化都补不回来。比如一个只需要在 (0,1)、(1,2)、(2,3) 之间通信的电路,如果被映射到一条 4 比特链上,SWAP 数是 0;如果被映射到一个星形拓扑的「叶子」上,可能要多出好几倍 SWAP。

用路由代价反推布局

SABRE 的核心思想很聪明:布局与路由不能分开做,因为「好布局」的定义依赖于路由结果。它的做法是交替迭代——先随机或贪心给一个布局,跑一遍 SABRE 路由统计 SWAP 数,根据路由过程中的「交换倾向」更新布局,再跑一遍,如此往复若干轮,取 SWAP 最少的那个。

# Qiskit: SABRE 布局 + 路由(optimization_level=3 时默认启用)
from qiskit.transpiler import CouplingMap
from qiskit.transpiler.passes import SabreLayout, SabreSwap

coupling = CouplingMap.from_heavy_hex(7)   # 127 比特 heavy-hex 拓扑
sabre_layout = SabreLayout(coupling, seed=42)
sabre_swap = SabreSwap(coupling, heuristic="decay", seed=42)

路由:SWAP 插入与代价模型

路由(routing)是量子编译最核心也最贵的部分:硬件拓扑上,两个相邻量子比特才能做两比特门。如果你的 CNOT 要作用在两个不相邻的物理比特上,就必须通过一串 SWAP 把它们的态「搬」到一起。

SWAP 是什么代价

SWAP 本身不是原生门,要分解成 3 个 CNOT:

SWAP = CNOT(a,b) · CNOT(b,a) · CNOT(a,b)      # 3 个 CX
     = 在 CZ 基底上 = 3 个 CZ + 若干 H

所以插入 1 个 SWAP 的代价是 3 个两比特门。一个深度 500 的电路,如果路由插了 200 个 SWAP,就凭空多出 600 个两比特门——而两比特门通常是保真度最低的操作。这就是为什么路由算法值得单独研究。

主要路由算法

算法思路复杂度特点
贪心 BFS每次找最短路径插入 SWAP高简单但易陷入局部
基于交换的搜索枚举可行 SWAP,评估代价很高质量好但慢
SABRE启发式 + 前瞻代价函数中工业界主流
tket 路由结合架构感知与门合并中与优化 Pass 协同
随机化路由多次随机跑取最优中用时间换质量

SABRE 的启发式代价函数同时考虑两个因素:距离(当前 SWAP 能否让待执行的门更近)和前瞻(未来若干层门的距离之和)。它维护一个「前导层(front layer)」集合,只对前导层里的门计算距离,避免扫描整个电路。

SABRE 单步逻辑:
  1. 从电路前面取若干未满足的门,构成 front layer
  2. 对每个候选 SWAP,计算代价:
       cost = Σ 前导层门两端的距离
              + 0.5 * Σ 扩展层门两端的距离   (前瞻项)
  3. 选代价最小的 SWAP 执行
  4. 更新电路状态,重复直到所有门满足拓扑

减少 SWAP 的三种手段

  1. 优化布局:把通信密集的比特放在连通性好的子图里。
  2. 门顺序重排:交换互不依赖的门顺序,让路由有更多选择。这属于经典编译里的指令调度,和经典编译器里做依赖分析与指令重排的思路一致。
  3. 远程门分解:某些平台支持远程门(如离子阱全连接),或在拓扑上做特殊分解(如线性最近邻 LNN 的专用算法)。

调度与脉冲级编译

电路合法了不等于能跑。还需要调度(scheduling):决定每个门在什么时刻执行,处理资源冲突(同一个物理比特不能同时参与两个门)、满足约束(有些硬件要求门之间有最小间隔)。

调度约束

约束类型说明典型值
数据依赖门必须等前驱完成由电路决定
资源冲突同一比特串行执行硬约束
最小间隔门之间需冷却/复位时间超导 ~ns,离子阱 ~µs
串扰规避相邻比特不同时操作取决于硬件
读出延迟测量后需复位~µs

调度目标是压缩总时长(wall-clock),而不是门数。这对相干时间短的平台(超导 ~100 µs)至关重要——如果电路总时长超过相干时间,结果就废了。

脉冲级编译

再往下一层,原生门也要编译成脉冲。这是 脉冲级控制 的领域,编译器在这里要处理的是:

- 门的脉冲实现(DRAG 脉冲参数、MS 门的激光包络)
- 并行门的串扰分析(同时打的两个门会不会互相干扰)
- 虚拟 Z 的相位跟踪(RZ 通过相位偏移实现)
- 校准表绑定(每个门绑定到具体校准数据)
# Qiskit 里查看门到脉冲的映射(示意)
from qiskit import schedule  # 旧 API;新版本用 Qiskit Dynamics
# 现代做法:用 backend.defaults() 查 gate 的 pulse 定义
# 或用 Qiskit Pulse 的 builder 构造自定义脉冲

脉冲级编译的难点是校准数据依赖:编译结果必须绑定到当前硬件校准。校准每天变,编译结果就得重新生成。这催生了「按需编译」的云服务模式——提交电路时才编译,保证用的是最新校准。

优化 Pass 与代价模型

转译不只是「翻译」,还包括大量优化。Qiskit 的 Transpiler 有 100 多个 Pass,tket 有自己的优化流水线。

常见优化 Pass

Pass作用收益
单比特门合并相邻单比特门合成一个减少门数
门抵消相邻的自逆门对消(HH=I)减少门数
模板匹配用预定义等价模板替换减少 CX
相位多项式化简把 CX-RZ 网络转成相位多项式大幅减少 CX
Clifford 化简用稳定子形式简化 Clifford 段大幅减少门
ZX 化简用 ZX 演算做图重写减少 CX 与深度
恒等门消除移除 0 角度旋转减少门数

相位多项式化简(phase polynomial / Paulihedral) 是收益最大的技术之一。它把电路中的 CX 网络与 RZ 门提取成一个「相位多项式」——每对量子比特的奇偶性对应一个相位项。因为 RZ 门对易,可以把同类项合并,把原本需要 $O(n)$ 个 CX 的电路压到 $O(n/\log n)$。这是经典编译里「公共子表达式消除」在量子场景的对应物。

代价模型

编译器需要量化「哪个方案更好」。常用指标:

cost = w1 * two_qubit_gates        # 两比特门数(保真度主导)
     + w2 * circuit_depth          # 深度(相干时间主导)
     + w3 * single_qubit_gates     # 单比特门数
     + w4 * total_duration         # 总时长(含调度)
     + w5 * crosstalk_penalty      # 串扰惩罚

权重不是常数。相干时间长的平台(离子阱)可以容忍更深但门数更少的电路;相干时间短的平台(超导)宁可多几个门也要压深度。所以**「同一个电路的最优编译」在不同平台上是不同的**,这就是为什么跨平台迁移电路需要重新编译。

工具链:Qiskit、tket、QIR 与 MLIR

工具语言特点适用
Qiskit TranspilerPythonPassManager 可组合、生态最大IBM 及通用
pytket (tket)Python/C++优化强、多后端、支持符号角跨平台
Cirq + OpenFermionPythonGoogle 系、适合化学模拟研究
QIRLLVM IR 扩展硬件无关中间表示跨工具链互操作
MLIR 量子方言MLIR多层 IR、可扩展下一代编译器
BQSKitPython数值合成强门合成研究

QIR(Quantum Intermediate Representation) 是 LLVM IR 的量子扩展,由微软与 Quantinuum 等推动。它把量子操作表达为对 Qubit 类型的函数调用,同时支持经典控制流。好处是能复用 LLVM 的优化基础设施,并让不同前端(Q#、Qiskit、Cirq)编译到同一表示。

; QIR 片段(示意)
%q = call %Qubit* @__quantum__rt__qubit_allocate()
call void @__quantum__qis__h__body(%Qubit* %q)
call void @__quantum__qis__mz__body(%Qubit* %q, %Result* %r)

MLIR 的量子方言则把编译分成多层:高层表示算法结构,中层做门优化,底层绑定硬件。这种多层设计让优化可以在合适的抽象层级进行——在高层合并大块结构,在低层做脉冲调度。这与经典编译器的分层 IR 思路一脉相承,与 TVM/MLIR 这类 AI 编译器 里讨论的 pass 管理是同一套方法论。

# pytket: 编译到特定后端并查看优化效果
from pytket import Circuit
from pytket.backends.ibm import IBMQBackend

c = Circuit(3)
c.H(0).CX(0, 1).CX(1, 2).Rz(0.3, 2)
# 指定架构与原生门集
compiled = backend.get_compiled_circuit(c, optimisation_level=2)
print("CX 数:", compiled.n_gates_of_type(OpType.CX))
print("深度:", compiled.depth())

转译报告怎么读

云平台返回的转译结果里有一堆数字,读懂它们才能判断电路能不能跑。

指标含义关注点
逻辑比特数电路声明的量子比特与物理可用数对比
物理比特数实际占用的物理比特布局是否浪费
深度关键路径上的门层数是否超过相干时间/门数
两比特门数主要误差来源与逻辑门数对比看开销
单比特门数次要误差来源是否被 RZ 虚拟门吸收
总时长含调度的 wall-clock与 T2 对比
SWAP 数路由开销布局是否合理

一条实用的检查清单:

转译后自检:
  [ ] 两比特门数 / 逻辑两比特门数 < 5?  (否则布局或路由有问题)
  [ ] 深度 × 单门时间 < T2 的 1/10?
  [ ] 是否用了噪声感知布局(噪声差异大时)?
  [ ] 是否有可手工优化的结构(如对称的 QFT)?
  [ ] 换一个 seed / 优化等级,结果差多少?

最后一条很重要:转译是启发式的,换随机种子结果会变。如果你的电路对 SWAP 数量敏感,跑几次不同 seed 取最优,往往能白捡 10%~20% 的改进。

编译时间与规模挑战

编译本身也要花时间,而且这个时间随电路规模超线性增长。

电路规模门数典型编译时间瓶颈
小< 100< 1 s几乎无感
中100~10^4数秒~分钟路由搜索
大10^4~10^6分钟~小时路由 + 优化 Pass
超大> 10^6小时~不可行内存与搜索空间

三个实际痛点:

  1. 路由的搜索空间爆炸。SABRE 每步要评估几十个候选 SWAP,每个候选要算前导层距离,复杂度与门数、比特数都相关。10^6 门级电路的路由可能跑几小时。
  2. 优化 Pass 的组合爆炸。Pass 之间有顺序依赖,同一组 Pass 换个顺序结果不同。有些框架尝试用自动搜索(类似经典编译里的 autotuning)找最优 Pass 序列,但搜索本身也很贵。
  3. 校准数据绑定。脉冲级编译要绑定当前校准,而校准每天更新,所以大规模电路难以「编译一次、多次运行」。云平台的做法是每次提交都重新编译,用户感知到的延迟就包含编译时间。

应对手段:

- 分块编译:把大电路切成子电路,分别编译后拼接
- 增量编译:只重编译变化的子电路(类似增量构建)
- 缓存 Pass 结果:不变的前缀直接复用
- 降低优化等级:optimization_level=1 换取编译速度
- 并行路由:多个 seed 并行跑,取最优(用多核或分布式)

最后一点值得展开:因为转译是启发式的、可并行的,用算力换电路质量是完全合理的策略。跑 32 个不同 seed 的转译,取两比特门数最少的那个,代价只是几十秒编译时间,收益可能是 20% 的保真度提升。这在经典编译里少见(编译结果通常确定),但在量子编译里是常态。

小结

量子编译器的核心任务是回答三个问题:用什么门(分解)、放哪里(布局)、怎么连线(路由)。

  • 编译流水线分门分解、初始布局、路由、调度四阶段,布局与路由必须联合优化。
  • 原生门集决定分解目标;RZ 是虚拟门几乎免费,应尽量把旋转搬过去。
  • SWAP 代价是 3 个两比特门,路由质量直接决定保真度。
  • SABRE 通过启发式代价函数与前瞻,在工业界成为事实标准。
  • 调度目标是压缩 wall-clock,脉冲级编译进一步绑定校准数据。
  • 相位多项式、ZX 化简等 Pass 能大幅削减 CX 数,代价模型需按平台调权重。
  • QIR 与 MLIR 提供硬件无关的中间表示,是跨工具链互操作的基础。

实践上,先写清楚逻辑电路,再用目标后端的 PassManager 转译,然后逐项对照转译报告,找出开销异常的部分。如果你的电路有结构性对称(QFT、量子傅里叶、组合优化中的对称约束),手工指定布局往往比自动布局更好。最后记住:转译不是一次性的,硬件校准变了、拓扑变了、优化等级变了,都要重新编译。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「quantum」更多文章

  1. 开放量子系统与退相干建模:密度矩阵、Kraus 与 Lindblad 方程
  2. 量子基准测试与性能指标:保真度、量子体积与 CLOPS
  3. 离子阱量子计算平台:囚禁原理、门操作与规模化