引言
绝大多数量子编程都停留在「门级」:写 qc.h(0)、qc.cx(0, 1),然后交给编译器。但在编译器之下,还有一层更接近硬件的东西——脉冲。每个门最终都被翻译成一条微波脉冲,脉冲的包络形状、振幅、相位、频率共同决定了这次操作的保真度。当你需要把单门保真度从 99.9% 推到 99.99%,或者实现一个标准门库里没有的操作时,就必须下探到这一层。
OpenPulse 是 Qiskit 为这一层提供的编程接口:它让你直接描述「在哪个通道上、什么时刻、播放什么形状的脉冲」。本文系统讲解脉冲级编程:先从「为什么要下探」讲起,再讲脉冲的物理描述与 OpenPulse 的核心概念,然后是自定义门、DRAG 校正、测量采集、校准实验编排、硬件限制,最后讨论与门级编译的关系以及 Qiskit 版本迁移。目标:让你既能读懂 backend.defaults() 里的脉冲定义,也能自己写出一个自定义门。
前置:量子比特校准与噪声表征 、Qiskit 编程入门 、量子比特与门基础 。
目录
- 1. 从门级到脉冲级
- 2. 脉冲的物理描述
- 3. OpenPulse 的核心概念
- 4. 用 Qiskit Pulse 实现自定义门
- 5. 测量与采集
- 6. 校准实验编排
- 7. 硬件限制
- 8. 与门级编译的关系
- 9. 平台支持与版本迁移
- 速查表
- 延伸阅读
1. 从门级到脉冲级
门级抽象的局限:
门级视角:qc.x(0) 就是「一个 X 门」
但硬件实际执行的是:
在 DriveChannel(0) 上播放一条时长为 d、振幅为 A 的复数脉冲
A 与 d 共同决定旋转角 θ = Ω_R · d
→ 门级隐藏了「用哪条脉冲实现」的自由度
下探到脉冲级的三个动机:
1. 更短的电路
多个相邻门可合并成一条脉冲(如 Rz 可虚拟化、相位可累加)
→ 减少脉冲数量、缩短总时长
2. 更高的保真度
调整包络形状(DRAG、高斯平方、slepian)压制泄漏与串扰
→ 单门保真度可从 99.9% 推到 99.99%
3. 校准与误差缓解
直接编排 Rabi / Ramsey / RB 等校准实验
自定义读出脉冲以优化信噪比
→ 这三条构成了「脉冲级编程」的全部价值
层次从高到低是:门级(QuantumCircuit,算法开发者写电路)、编译级(transpile,编译器做映射与优化)、脉冲级(Schedule / OpenPulse,硬件与校准工程师做自定义门与校准)、仪器级(AWG 与采集卡,实验室控制波形、采样与触发)。
心智:门级是「面向算法」的抽象,脉冲级是「面向硬件」的抽象——下探的理由只有三个:更短的电路、更高的保真度、更灵活的校准。若你的目标只是跑通算法,不必下探;若你要压榨保真度或实现门库外的操作,脉冲级是必经之路。
2. 脉冲的物理描述
脉冲 = 复数包络 × 载波:
物理输出信号:
s(t) = Re{ A(t) · e^(i(ω_d t + φ)) }
= I(t)·cos(ω_d t) - Q(t)·sin(ω_d t)
A(t) 是复数包络:A(t) = I(t) + i·Q(t)
ω_d 是驱动频率,φ 是初始相位
旋转坐标系下,脉冲的作用等价于:
H(t) = (Ω(t)/2)·[cos(φ)σ_x + sin(φ)σ_y]
Ω(t) ∝ |A(t)|,旋转轴由 φ 决定
→ 包络的「面积」∫Ω(t)dt 决定总旋转角
dt 时间单位与采样率:
硬件以固定采样率输出波形,最小时间单位为 dt
典型 dt ≈ 0.222 ns(对应采样率 4.5 GSa/s)
→ 脉冲时长必须是 dt 的整数倍
换算:
duration = 160(单位 dt)→ 实际时长 ≈ 35.5 ns
时间(秒)= duration × dt
→ 所有 OpenPulse 中的时长都以 dt 为单位
常见包络形状:
Gaussian(duration, amp, sigma)
经典高斯脉冲,适合长脉冲;短脉冲时频谱泄漏严重
GaussianSquare(duration, amp, sigma, width)
高斯上升/下降 + 方波平台,适合双门与读出
Drag(duration, amp, sigma, beta)
高斯 + DRAG 校正(beta 项),压制泄漏到 |2⟩
Constant(duration, amp)
方波,简单但频谱最差
心智:脉冲的本质是「一条复数包络」——振幅给旋转角度(面积决定总角度),相位给旋转轴,时长以 dt 为单位。选择包络形状就是在「时域短」与「频域窄」之间做取舍:时域越短,频域越宽,越容易误驱动邻近能级与比特。
3. OpenPulse 的核心概念
通道(Channel):
DriveChannel(i) :比特 i 的驱动通道(微波脉冲)
ControlChannel(i) :比特 i 的控制通道(双门调制)
MeasureChannel(i) :比特 i 的读出通道(探测脉冲)
AcquireChannel(i) :比特 i 的采集通道(ADC 采样窗口)
指令(Instruction):
Play(pulse, channel) :在通道上播放脉冲
Delay(duration, channel) :等待若干 dt
ShiftPhase / SetPhase :相对 / 绝对设置通道相位(虚拟 Z 门)
ShiftFrequency / SetFrequency:相对 / 绝对设置通道频率
Acquire(duration, acq_ch, reg_slot, kernel):采集并存入寄存器
Schedule 与 Builder:
Schedule:由 (开始时间, 指令) 组成的脉冲序列
带通道对齐规则(如 align_left / align_right / align_sequential)
pulse.build():上下文管理器,自动处理通道与对齐
→ 这是构造脉冲序列的推荐方式
from qiskit import pulse
from qiskit.pulse.library import Gaussian, Drag, GaussianSquare
with pulse.build(backend, name="my_gate") as sched:
d0 = pulse.DriveChannel(0)
m0 = pulse.MeasureChannel(0)
a0 = pulse.AcquireChannel(0)
reg = pulse.MemorySlot(0)
pulse.play(Gaussian(160, 0.15, 40), d0) # 驱动脉冲
pulse.play(GaussianSquare(1600, 0.2, 64, 1200), m0) # 读出脉冲
pulse.acquire(1600, a0, reg) # 采集
心智:OpenPulse 的三要素是「通道 + 指令 + 时序」——通道决定「作用在哪」,指令决定「做什么」,Schedule 决定「什么时候」。
pulse.build()把这些包装成声明式代码,对齐规则帮你处理时序冲突。
4. 用 Qiskit Pulse 实现自定义门
一个自定义旋转门(绕任意轴):
from qiskit import pulse
from qiskit.pulse.library import Gaussian
def rotation_schedule(backend, qubit, angle, axis_phase):
"""绕 axis_phase 指定的轴旋转 angle 弧度"""
d = pulse.DriveChannel(qubit)
amp = 0.15 * (angle / (3.14159265 / 2)) # 面积 ∝ angle
with pulse.build(backend) as sched:
pulse.shift_phase(axis_phase, d)
pulse.play(Gaussian(160, amp, 40), d)
pulse.shift_phase(-axis_phase, d) # 恢复相位
return sched
DRAG 拖尾校正:
问题:短的高斯脉冲频谱宽,会把布居泄漏到 |2⟩
DRAG:Q(t) = -λ · (1/α) · dI(t)/dt
α:比特非简谐度,λ:可调缩放因子
→ 用 I 的导数生成 Q,抵消 |1⟩↔|2⟩ 的跃迁路径
from qiskit.pulse.library import Drag
with pulse.build(backend, name="x_drag") as sched:
# beta = DRAG 参数,正比于 1/alpha,典型 0.3 ~ 0.5
pulse.play(Drag(duration=160, amp=0.15, sigma=40, beta=0.35),
pulse.DriveChannel(0))
虚拟 Z 门(零时长):
Rz(θ) 不需要真实脉冲:
只需 shift_phase(θ, DriveChannel) 平移后续脉冲的相位
→ 零时长、零误差
→ 这就是编译器能把 Rz 门「免费」处理的原因
心智:脉冲级编程的「杀手级应用」是 DRAG 与虚拟 Z 门——DRAG 用包络导数换更少的泄漏,虚拟 Z 门用相位平移换零时长的 Z 旋转。理解这两者,就理解了「为什么脉冲级能把保真度再往上推」。
5. 测量与采集
读出的脉冲序列:
measure(qubit) 展开为:
1. 在 MeasureChannel 上播放读出脉冲(GaussianSquare)
2. 在 AcquireChannel 上开一个采集窗口(Acquire)
3. 采样得到的信号经「核函数(kernel)」积分 → 单发判读
with pulse.build(backend) as measure_sched:
pulse.play(
GaussianSquare(duration=1600, amp=0.2, sigma=64, width=1200),
pulse.MeasureChannel(0),
)
pulse.acquire(1600, pulse.AcquireChannel(0), pulse.MemorySlot(0))
kernel 与鉴别器:
kernel:把 ADC 采样的时域信号加权积分成一个复数(I + iQ)
常用「最优核」= 区分 |0⟩ 与 |1⟩ 信号点的判别方向
判别器(discriminator):把复数点映射到 0/1
标定方式:制备 |0⟩ 与 |1⟩,统计两点分布,取分界线
→ 读出保真度由「信号分离度 / 噪声」与 kernel 共同决定
四者的可调参数分别是:MeasureChannel 脉冲的振幅、时长与形状;AcquireChannel 窗口的采集时长与延迟;kernel 的核权重(由标定得出);discriminator 的分界线与阈值。
心智:读出的质量取决于「脉冲 + 采集 + 核 + 判别器」四件套——脉冲决定探测强度,采集窗口决定信噪比,kernel 决定如何把时域信号压成一个点,判别器决定如何切开两类。脉冲级编程让你能逐项调优这四者。
6. 校准实验编排
用 Schedule 编排 Rabi 扫描:
import numpy as np
from qiskit import pulse
from qiskit.pulse.library import Gaussian
def rabi_schedules(backend, qubit, amp=0.15, max_dur=400, step=8):
d = pulse.DriveChannel(qubit)
for dur in np.arange(step, max_dur, step):
with pulse.build(backend) as sched:
pulse.play(Gaussian(dur, amp, dur / 4), d)
pulse.measure(qubit)
yield dur, sched
Ramsey / 回波 / RB 的编排要点:
Ramsey:
pi/2 -- delay(tau) -- pi/2 -- measure
关键:两个 pi/2 之间用 pulse.delay 精确控制自由演化时间
回波:
pi/2 -- delay(tau/2) -- pi -- delay(tau/2) -- pi/2 -- measure
RB:
用随机 Clifford 序列,每条 Clifford 展开为脉冲序列
需保证「不同 Clifford 的脉冲时长一致」以避免引入额外误差
校准流水线的自动化:
1. 生成一批 Schedule(扫描参数)
2. 批量提交到后端(backend.run(schedules))
3. 收集计数 → 拟合 → 提取参数(π 时长、失谐、T1/T2)
4. 用新参数更新 backend.defaults() 或构建新的 Schedule
5. 定时/触发式重复
→ 这正是「自动校准流水线」在脉冲层的实现
心智:校准实验的本质是「用 Schedule 编排一次参数扫描」——Rabi 扫描时长、Ramsey 扫描延迟、RB 扫描序列长度,都是同一套「生成 Schedule 批 → 提交 → 拟合」的流程。把这套流程自动化,就是脉冲级的校准流水线。
7. 硬件限制
1. 带宽限制
AWG 与混频器的可用带宽有限
脉冲越短 → 频谱越宽 → 越容易超出带宽、误驱动邻近能级
2. 采样率限制
时长必须是 dt 的整数倍 → 无法实现任意精度的时序
3. 串扰
DriveChannel 之间的电磁串扰、ControlChannel 的调制泄漏
→ 驱动一个比特时邻居被部分旋转
4. 泄漏到 |2⟩
短脉冲的高频分量会激发 |1⟩↔|2⟩ 跃迁
→ 靠 DRAG 与更长的脉冲压制
5. 频率拥挤
比特频率与读出腔频率接近时,驱动会误触读出腔
6. 热噪声与仪器漂移
AWG 输出漂移、衰减器温度漂移 → 需要周期性重校准
对应的缓解手段是:带宽限制靠加长脉冲与整形包络;采样率限制靠用 dt 的整数倍规划时序;串扰靠频率规划与串扰抵消脉冲;泄漏到 |2⟩ 靠 DRAG 与更长脉冲;仪器漂移靠周期性重校准。
心智:脉冲级编程的每一条「自由度」都被硬件限制反向约束——带宽限制包络的频谱宽度、采样率限制时序精度、串扰限制并行驱动、泄漏限制脉冲时长。好的脉冲设计就是在这组约束下寻找最优解。
8. 与门级编译的关系
门级到脉冲级的编译链:
QuantumCircuit
↓ transpile(映射、路由、优化)
Transpiled Circuit
↓ 门 → 脉冲展开(schedule 生成)
Schedule
↓ assemble(打包成 Qobj / 后端可执行格式)
Backend Job
→ 脉冲级编译的产物就是一个 Schedule
脉冲级优化能做什么:
1. 相位累加:把连续的 Rz 合并成一次 shift_phase
2. 门合并:把相邻的旋转合并成一条脉冲
3. 对齐优化:让并行的门共享时间窗口,缩短总时长
4. 串扰抵消:在空闲通道上插入补偿脉冲
→ 这些优化在门级看不到,必须下探到脉冲级
门级与脉冲级的边界:
门级该做的:算法表达、逻辑优化、映射路由
脉冲级该做的:物理保真度、校准、串扰与泄漏压制
→ 两者的分工是「逻辑正确性」与「物理正确性」
不要用脉冲级去做门级该做的事(可移植性会崩)
心智:脉冲级编译的目标是「物理保真度」,门级编译的目标是「逻辑正确性」——脉冲级能做的优化(相位累加、门合并、串扰抵消)在门级不可见,但代价是丧失硬件无关性。因此脉冲级代码通常与具体后端强绑定。
9. 平台支持与版本迁移
平台支持现状:
- IBM Quantum:早期通过 OpenPulse 提供脉冲级访问
但近年逐步收紧,多数公开后端不再开放 pulse 接口
- 自研超导平台:Qiskit Pulse 仍是主流控制框架
- 其他厂商(Rigetti、IQM 等):有各自的脉冲级 SDK
→ 脉冲级编程目前更多是「实验室 / 自研平台」的能力
而非通用云服务的能力
迁移到 Qiskit 1.x / 2.x 的变化:
1. qiskit.pulse 在 Qiskit 1.0 中被标记为「实验性」,后续逐步弱化,
官方推荐用 qiskit-experiments 做校准
2. Qiskit 1.x 引入 BackendV2,target 对象承载指令与时长信息,
旧的 backend.defaults() / backend.configuration() 被替换
3. Qiskit 2.x 进一步精简 pulse 生态,部分厂商转向自研控制栈
→ 迁移要点:用 target 读校准数据、用 qiskit-experiments 做实验,
把脉冲级代码与具体后端解耦以降低迁移成本
心智:脉冲级编程正在从「通用云服务能力」退回「自研平台能力」——IBM 等厂商逐步收紧公开的 pulse 接口,把校准与脉冲控制收回内部。对多数团队而言,现实的策略是用
qiskit-experiments做校准、用target读数据,只在自研硬件上才深入 OpenPulse。
速查表
| 主题 | 结论 |
|---|---|
| 下探动机 | 更短电路、更高保真、灵活校准 |
| 脉冲本质 | 复数包络 × 载波,面积定角度、相位定轴 |
| dt 单位 | 时长以 dt 计,典型 dt ≈ 0.222 ns |
| 四类通道 | Drive / Control / Measure / Acquire |
| 核心指令 | Play、Delay、ShiftPhase、SetFrequency、Acquire |
| Schedule | (开始时间, 指令) 序列,带对齐规则 |
| DRAG | Q(t) = -λ(1/α)dI/dt,压制泄漏到 |2⟩ |
| 虚拟 Z 门 | shift_phase 实现零时长 Rz |
| 读出四件套 | 脉冲 + 采集 + kernel + 判别器 |
| 校准编排 | 生成 Schedule 批 → 提交 → 拟合 → 更新 |
| 硬件限制 | 带宽、采样率、串扰、泄漏、漂移 |
| 与门级关系 | 脉冲级管物理保真,门级管逻辑正确 |
| 平台现状 | 通用云服务收紧,回归自研平台能力 |
| 版本迁移 | pulse 弱化,用 target + qiskit-experiments |
一句话记忆:脉冲级编程是「门级之下」的一层抽象,下探的动机只有三个——更短的电路(相位累加、门合并)、更高的保真度(DRAG、包络整形)、更灵活的校准(Rabi/Ramsey/RB 编排);脉冲的本质是一条复数包络,面积决定旋转角、相位决定旋转轴、时长以 dt 为单位;OpenPulse 用「通道 + 指令 + Schedule」描述脉冲序列,用 pulse.build() 声明式构造;DRAG 用包络导数压制泄漏到 |2⟩,虚拟 Z 门用相位平移实现零时长 Rz;读出质量取决于「脉冲 + 采集 + kernel + 判别器」四件套;每条自由度都被带宽、采样率、串扰、泄漏、漂移这些硬件限制反向约束;脉冲级管物理保真度、门级管逻辑正确性,两者分工明确;当前脉冲级接口正从通用云服务收紧为自研平台能力,迁移要点是用 target 读数据、用 qiskit-experiments 做校准。(延伸见 量子比特校准与噪声表征 、Qiskit 编程入门 。)
延伸阅读
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。