PyTorch 集成 {#guide-pytorch}#

什么时候进入本页#

当你希望将量子电路集成到 PyTorch 模型中进行混合量子-经典训练时,阅读本页。

本页解决的问题#

  • 如何在 PyTorch 模型中使用参数化量子电路

  • 如何通过 parameter-shift 规则计算梯度

  • 如何构建量子-经典混合神经网络

前置条件#

阅读本页前,建议你已经:

安装#

PyTorch 集成是可选功能,需要单独安装:

pip install unified-quantum[pytorch]

这会安装 torch>=2.0 作为依赖。

QuantumLayer#

QuantumLayer 是一个 PyTorch nn.Module,用于将参数化量子电路封装为可训练层。

基本用法#

import torch
from uniqc.pytorch import QuantumLayer
from uniqc.circuit_builder import Circuit, Parameter
from uniqc.simulator import OriginIR_Simulator

# 定义电路模板
def build_circuit(theta_value):
    c = Circuit()
    theta = Parameter("theta")
    theta.bind(theta_value)
    c.rx(0, theta.evaluate())
    c.measure(0)
    return c

# 定义期望值函数
def expectation(circuit):
    sim = OriginIR_Simulator()
    result = sim.simulate(circuit.originir, shots=1000)
    # 计算 <Z> 期望值
    return result.get_expectation([0])

# 创建 QuantumLayer
layer = QuantumLayer(
    circuit_template=build_circuit,
    expectation_fn=expectation,
    param_names=["theta"],
    shift=0.5
)

在模型中使用#

import torch.nn as nn

model = nn.Sequential(
    nn.Linear(10, 4),
    nn.ReLU(),
    layer,  # QuantumLayer
    nn.Linear(1, 1)
)

训练#

optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

for epoch in range(100):
    optimizer.zero_grad()
    
    # 前向传播
    output = model(torch.randn(1, 10))
    
    # 计算损失
    loss = output.sum()
    
    # 反向传播(自动计算量子梯度)
    loss.backward()
    
    # 更新参数
    optimizer.step()
    
    print(f"Epoch {epoch}: loss = {loss.item():.4f}")

Parameter-Shift 梯度#

QuantumLayer 使用 parameter-shift 规则计算量子参数的梯度:

\[\frac{\partial f(\theta)}{\partial \theta} = \frac{f(\theta + s) - f(\theta - s)}{2s}\]

其中 \(s\) 是 shift 参数(默认 0.5)。

自定义 shift 值#

layer = QuantumLayer(
    circuit_template=build_circuit,
    expectation_fn=expectation,
    param_names=["theta"],
    shift=0.25  # 自定义 shift 值
)

多参数电路#

对于有多个参数的电路:

def build_multi_param(params):
    c = Circuit()
    theta = Parameter("theta")
    phi = Parameter("phi")
    theta.bind(params[0])
    phi.bind(params[1])
    c.rx(0, theta.evaluate())
    c.ry(1, phi.evaluate())
    c.cnot(0, 1)
    c.measure(0, 1)
    return c

layer = QuantumLayer(
    circuit_template=build_multi_param,
    expectation_fn=expectation,
    param_names=["theta", "phi"],
    shift=0.5
)

完整示例:VQE#

以下是一个简单的 VQE(变分量子本征求解器)示例:

import torch
import torch.nn as nn
from uniqc.pytorch import QuantumLayer
from uniqc.circuit_builder import Circuit, Parameter
from uniqc.simulator import OriginIR_Simulator
import numpy as np

# 定义哈密顿量 H = Z0 + Z1 + X0X1
def hamiltonian_expectation(circuit):
    sim = OriginIR_Simulator()
    result = sim.simulate(circuit.originir, shots=1000)
    
    # 计算 <Z0 + Z1 + X0X1>
    # 这里简化为只计算 Z0 + Z1
    exp_z0 = result.get_expectation([0])
    exp_z1 = result.get_expectation([1])
    
    return exp_z0 + exp_z1

# 定义 ansatz
def ansatz(params):
    c = Circuit()
    theta = Parameter("theta")
    theta.bind(params[0])
    
    # 初始化
    c.h(0)
    c.h(1)
    
    # 变分层
    c.cnot(0, 1)
    c.rz(1, theta.evaluate())
    
    c.measure(0, 1)
    return c

# 创建量子层
vqe_layer = QuantumLayer(
    circuit_template=ansatz,
    expectation_fn=hamiltonian_expectation,
    param_names=["theta"],
    shift=0.5
)

# 优化
param = torch.tensor([0.1], requires_grad=True)
optimizer = torch.optim.Adam([param], lr=0.1)

for epoch in range(50):
    optimizer.zero_grad()
    
    # 前向传播
    energy = vqe_layer(param)
    
    # 反向传播
    energy.backward()
    
    # 更新参数
    optimizer.step()
    
    print(f"Epoch {epoch}: Energy = {energy.item():.4f}")

批量执行#

当需要并行执行多个电路时,可以使用 batch_execute 工具:

from uniqc.pytorch import batch_execute, batch_execute_with_params
from uniqc.simulator import OriginIR_Simulator

# 定义执行函数
def simulate(circuit):
    sim = OriginIR_Simulator()
    return sim.simulate(circuit.originir, shots=1000)

# 批量执行多个电路
results = batch_execute(
    circuits=[c1, c2, c3],
    executor=simulate,
    n_workers=4
)

# 对同一模板绑定不同参数后批量执行
param_sets = [{'theta': 0.1}, {'theta': 0.2}, {'theta': 0.3}]
results = batch_execute_with_params(
    circuit_template=parametric_circuit,
    param_values=param_sets,
    executor=simulate,
    n_workers=4
)

批量执行使用 ThreadPoolExecutor 实现并行,适用于:

  • 梯度计算(每个参数需要 2 次电路执行)

  • 超参数搜索

  • 集成电路评估

性能优化建议#

  1. 减少 shots 数量:调试时使用较少的 shots,最终训练时再增加。

  2. 批量执行:使用 batch_execute 并行化电路评估,充分利用多核 CPU。

  3. 缓存中间结果:对于不变的哈密顿量项,可以预计算并缓存结果。

  4. 参数 shift 值

    • 默认 \(\pi/2\) 适用于大多数旋转门

    • 对于特定门(如 RX、RY),可以根据门特性调整

    • 值过小会放大采样噪声,过大会降低梯度精度

  5. GPU 注意事项

    • QuantumLayer 的参数存储在 GPU 上(如果可用)

    • 量子电路模拟在 CPU 上执行

    • 数据传输开销可能影响性能,建议批量处理

注意事项#

  1. 期望值函数expectation_fn 必须返回一个标量值,用于计算梯度。

  2. 模拟器开销:每次梯度计算需要执行 \(2n\) 次电路模拟(\(n\) 为参数数量),对于复杂电路可能较慢。

  3. 数值稳定性:shift 值的选择会影响梯度计算的精度,通常 0.1 到 0.5 之间效果较好。

  4. GPU 支持:QuantumLayer 的参数在 GPU 上,但量子计算本身在 CPU 上执行。

相关 API#

  • uniqc.pytorch — PyTorch 集成模块

  • uniqc.pytorch.QuantumLayer — 量子层封装

  • uniqc.pytorch.parameter_shift_gradient() — Parameter-shift 梯度计算

  • uniqc.pytorch.batch_execute() — 并行电路执行

  • uniqc.pytorch.batch_execute_with_params() — 参数化批量执行

  • uniqc.pytorch.compute_all_gradients() — 计算所有参数梯度

下一步#