4. 参数化量子电路构建

变分量子本征求解器(VQE)的核心计算单元是参数化量子电路(Parameterized Quantum Circuit, PQC)。它由固定结构的量子门序列和一组可调参数 θ 组成,通过不断调整 θ 使测量得到的期望值逼近目标哈密顿量的基态能量。本节聚焦工程实现层面:如何用 Qiskit 和 PennyLane 搭建可微分电路、如何绑定参数、以及如何获得梯度接口。

一、参数化电路的基本结构

一个典型的 VQE 拟设(ansatz)由三部分组成:初态制备、参数化层、测量。以 4 量子比特的硬件高效拟设为例,初态通常为 |0000⟩,参数化层由交替的旋转门层和纠缠层构成。旋转层使用 Ry(θ) 或 Rz(θ) 对每个量子比特施加单比特旋转,纠缠层使用 CNOT 或 CZ 构建量子比特间的关联。层数 L 与量子比特数 n 共同决定参数总数:若每层每个量子比特一个旋转参数,则参数维度为 n×L。

选择拟设时需权衡表达能力与训练难度。硬件高效拟设参数少、易映射到真实拓扑,但可能无法覆盖目标基态;UCCSD 等化学启发拟设表达能力强,但参数多、电路深。工程上常从硬件高效拟设起步,若能量收敛不理想再增加层数或改用问题定制拟设。

4量子比特硬件高效拟设结构(L=2层) q0 q1 q2 q3 |0⟩ |0⟩ |0⟩ |0⟩ Ry(θ₀) Ry(θ₁) Ry(θ₂) Ry(θ₃) Ry(θ₄) Ry(θ₅) Ry(θ₆) Ry(θ₇) 测量⟨H⟩ 测量⟨H⟩ 测量⟨H⟩ 测量⟨H⟩ 参数化旋转层 纠缠层 CNOT 测量与期望值 参数维度 = n × L = 4 × 2 = 8

二、Qiskit 实现:从电路到梯度

在 Qiskit 中,参数化电路通过 QuantumCircuit 配合 Parameter 对象构建。每个可调角度用 Parameter('θ_i') 表示,电路构建完成后得到一个含自由参数的模板。参数绑定使用 assign_parameters() 方法,将具体数值字典注入模板,生成可执行的绑定电路。

from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
import numpy as np

n, L = 4, 2
params = [Parameter(f'θ{i}') for i in range(n * L)]
qc = QuantumCircuit(n)

idx = 0
for layer in range(L):
    for q in range(n):
        qc.ry(params[idx], q)
        idx += 1
    for q in range(n - 1):
        qc.cx(q, q + 1)

# 绑定一组具体参数
values = np.random.uniform(0, 2*np.pi, n * L)
bound = qc.assign_parameters(dict(zip(params, values)))

梯度计算方面,Qiskit 提供 Estimator 原语配合 Gradient 对象。参数移位规则(parameter-shift rule)是核心:对每个参数 θ_i,梯度由两个偏移电路期望值之差除以 2 得到,即 ∂⟨H⟩/∂θ_i = [⟨H⟩(θ_i+π/2) − ⟨H⟩(θ_i−π/2)] / 2。这一规则适用于所有形如 exp(−iθP/2) 的门,Ry、Rz、Rx 均满足。

from qiskit.primitives import Estimator
from qiskit.algorithms.gradients import ParamShiftEstimatorGradient

estimator = Estimator()
gradient = ParamShiftEstimatorGradient(estimator)
job = gradient.run([qc], [hamiltonian], [values])
grads = job.result().gradients[0]

需要注意:Estimator 返回的是每个观测量项的期望值加权和,梯度对象则对每个参数分别计算偏导。若哈密顿量有 M 项,参数移位法每轮需 2×n×L 次电路执行,工程上应尽量复用中间结果或采用伴随梯度(adjoint)降低开销。

三、PennyLane 实现:自动微分与接口统一

PennyLane 的设计哲学是“量子电路即函数”。用 @qml.qnode(dev) 装饰器将量子函数编译为可微节点,参数以张量形式传入,框架自动追踪计算图并调用反向传播或参数移位规则求梯度。与 Qiskit 相比,PennyLane 的接口更接近经典深度学习,适合与 PyTorch、TensorFlow、JAX 混合使用。

import pennylane as qml
from pennylane import numpy as pnp

dev = qml.device("default.qubit", wires=4)

@qml.qnode(dev, interface="autograd")
def circuit(params):
    for layer in range(2):
        for q in range(4):
            qml.RY(params[layer, q], wires=q)
        for q in range(3):
            qml.CNOT(wires=[q, q + 1])
    return qml.expval(hamiltonian)

params = pnp.random.uniform(0, 2*np.pi, (2, 4), requires_grad=True)
grad_fn = qml.grad(circuit)
grads = grad_fn(params)

PennyLane 的 qml.grad 默认对含参门使用参数移位规则,对 default.qubit 等模拟器也可启用反向传播(diff_method="backprop"),后者在参数较多时速度优势明显。若后端为真实硬件,则必须使用参数移位或有限差分,因为硬件无法执行反向传播。

四、参数绑定与梯度接口的工程要点

参数绑定不是一次性动作,而是优化循环中的高频操作。每次迭代都需要将当前参数向量注入电路模板,再提交执行。为降低开销,应尽量在编译阶段完成电路结构固定,仅将参数作为运行时输入。Qiskit 的 ParameterVector 和 PennyLane 的数组参数都支持这种“模板+绑定”模式。

梯度接口的选择直接影响训练效率与精度。参数移位规则精确但电路执行次数随参数线性增长;反向传播精确且一次前向即可得全部梯度,但仅适用于模拟器;有限差分实现简单但存在截断误差,步长选择敏感。工程建议:模拟器阶段优先用反向传播快速验证拟设与优化器;迁移到硬件前切换为参数移位,并检查梯度数值是否与模拟器一致。

梯度检查方法:选取一组随机参数,分别用解析梯度接口和有限差分(步长 1e-5)计算梯度,比较两者最大绝对误差。若误差在 1e-6 量级,说明梯度接口正确;若误差过大,检查参数绑定是否遗漏、测量观测量是否与哈密顿量一致。

五、一个可运行的训练片段

以下示例用 PennyLane 搭建 4 量子比特、2 层拟设,目标哈密顿量取横场伊辛模型的简化形式,优化器用 Adam,学习率 0.1,迭代 50 步。每步记录能量,观察是否单调下降并趋于稳定。

import pennylane as qml
from pennylane import numpy as pnp

dev = qml.device("default.qubit", wires=4)

# 示例哈密顿量:H = -Σ Z_i Z_{i+1} - 0.5 Σ X_i
coeffs = [-1.0]*3 + [-0.5]*4
obs = [qml.PauliZ(i) @ qml.PauliZ(i+1) for i in range(3)] + \
      [qml.PauliX(i) for i in range(4)]
H = qml.Hamiltonian(coeffs, obs)

@qml.qnode(dev, interface="autograd", diff_method="parameter-shift")
def cost(params):
    for layer in range(2):
        for q in range(4):
            qml.RY(params[layer, q], wires=q)
        for q in range(3):
            qml.CNOT(wires=[q, q+1])
    return qml.expval(H)

params = pnp.random.uniform(0, 2*np.pi, (2, 4), requires_grad=True)
opt = qml.AdamOptimizer(stepsize=0.1)

for step in range(50):
    params, energy = opt.step_and_cost(cost, params)
    if step % 10 == 0:
        print(f"step {step:3d}  energy = {energy:.6f}")

运行后典型输出会显示能量从初始随机值逐步下降,50 步后趋于某个稳定值。该稳定值是否接近真实基态能量,取决于拟设表达能力与优化是否收敛。若能量停滞在较高值,可尝试增加层数、更换纠缠拓扑或调整学习率。

常见陷阱:参数初始化若全部取零,旋转门不产生叠加,纠缠层输入为计算基态,梯度可能为零导致训练停滞。建议参数在 [0, 2π) 内均匀随机初始化,或使用小方差高斯初始化。此外,测量观测量必须与哈密顿量完全一致,遗漏项会导致能量偏低但梯度方向错误。