开始一个量子计算项目时会遇到一个实际问题:你应该直接用 Qiskit 编写电路,还是在其之上使用 HLQuantum 的抽象层?两者都是合理的选择,正确答案取决于你要构建什么。
本文提供一个具体的、以代码为驱动的比较,帮助你做出决定。
核心区别
Qiskit 是 IBM 的量子 SDK。它让你对每一个门、量子比特、测量和编译步骤都拥有直接、精确的控制。它原生面向 IBM 硬件,并且拥有针对 IBM 特定工作流最深厚的生态系统。
HLQuantum 是一个统一的 API,位于 Qiskit、Cirq、PennyLane、Braket、CUDA-Q 和 IonQ 之上。你编写一个电路;它会翻译并分派到你所指定的任意后端。它用一部分底层控制换取了可移植性和简洁性。
并排对比:Bell 态
原生 Qiskit:
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
sim = AerSimulator()
result = sim.run(qc, shots=1000).result()
print(result.get_counts()) # {'00': 501, '11': 499}
HLQuantum:
import hlquantum as hlq
qc = hlq.Circuit(2)
qc.h(0).cx(0, 1).measure_all()
result = hlq.run(qc, backend='qiskit', shots=1000)
print(result.counts) # {'00': 501, '11': 499}
对于单个后端,两者的冗长程度大致相同。当你添加更多后端时,差异才会显现出来。
并排对比:在多个后端上运行
原生 Qiskit(要添加第二个后端,你需要重写):
# Qiskit Aer
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
qc_qiskit = QuantumCircuit(2, 2)
qc_qiskit.h(0); qc_qiskit.cx(0, 1); qc_qiskit.measure_all()
result_qiskit = AerSimulator().run(qc_qiskit, shots=1000).result()
# PennyLane — completely different API, rewrite circuit
import pennylane as qml
dev = qml.device('default.qubit', wires=2)
@qml.qnode(dev)
def bell():
qml.Hadamard(wires=0)
qml.CNOT(wires=[0, 1])
return qml.probs(wires=[0, 1])
result_pennylane = bell()
# CUDA-Q — yet another API, rewrite again
import cudaq
@cudaq.kernel
def bell():
qvec = cudaq.qvector(2)
h(qvec[0]); cx(qvec[0], qvec[1]); mz(qvec)
result_cudaq = cudaq.sample(bell, shots_count=1000)
HLQuantum(一个电路,任意后端):
import hlquantum as hlq
qc = hlq.Circuit(2)
qc.h(0).cx(0, 1).measure_all()
# Switch backends with one word
result_qiskit = hlq.run(qc, backend='qiskit')
result_pennylane = hlq.run(qc, backend='pennylane')
result_cudaq = hlq.run(qc, backend='cudaq') # GPU
result_cirq = hlq.run(qc, backend='cirq')
result_ionq = hlq.run(qc, backend='ionq', device='aria-1')
result_ibm = hlq.run(qc, backend='qiskit', device='ibm_sherbrooke')
这正是 HLQuantum 发挥价值的地方——在本地模拟器上原型开发,然后无需重写电路即可部署到 QPU。
并排对比:VQE
原生 Qiskit VQE:
from qiskit_nature.second_q.drivers import PySCFDriver
from qiskit_nature.second_q.mappers import JordanWignerMapper
from qiskit_nature.second_q.circuit.library import UCCSD
from qiskit_algorithms import VQE
from qiskit_algorithms.optimizers import COBYLA
from qiskit.primitives import Estimator
driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.735')
problem = driver.run()
mapper = JordanWignerMapper()
hamiltonian = mapper.map(problem.second_q_ops()[0])
ansatz = UCCSD(
problem.num_spatial_orbitals,
problem.num_particles,
mapper,
initial_state=problem.reference_state,
)
vqe = VQE(Estimator(), ansatz, COBYLA())
result = vqe.compute_minimum_eigenvalue(hamiltonian)
print(f"H2 ground state: {result.eigenvalue.real:.4f} Ha")
HLQuantum VQE:
import hlquantum as hlq
result = hlq.algorithms.vqe(
molecule='H2',
basis='sto-3g',
backend='qiskit',
optimizer='COBYLA',
)
print(f"H2 ground state: {result.energy:.4f} Ha")
# Switch to GPU:
result_gpu = hlq.algorithms.vqe(molecule='H2', backend='cudaq')
原生 Qiskit 让你对 ansatz、mapper 和 driver 拥有完全的控制。HLQuantum 的一行代码最适合用来比较后端或快速获得结果;当你需要自定义 ansatz 或算法调优时,原生 Qiskit 更胜一筹。
何时使用原生 Qiskit
在以下情况下直接使用 Qiskit:
- 你仅面向 IBM 硬件 — Qiskit 的转译器和 IBM Runtime 原语在 IBM QPU 上能给你最佳性能。HLQuantum 的抽象会增加额外开销。
- 你需要细粒度的电路控制 — 自定义门分解、特定的转译器 pass、脉冲级控制、带中间电路测量的动态电路。
- 你在做 IBM 生态系统的研究 — 使用
qiskit-nature、qiskit-finance、qiskit-optimization或qiskit-machine-learning——这些与原生 Qiskit 的集成最为深入。 - 性能至关重要 — 直接的 Qiskit 代码比 HLQuantum 中的翻译层开销更小。
- 你在为 Qiskit 生态系统做贡献 — 编写 Qiskit 插件、教程或以 Qiskit 作为参考实现的研究论文。
何时使用 HLQuantum
在以下情况下使用 HLQuantum:
- 你需要后端灵活性 — 比较模拟器性能、在不同架构上对电路进行基准测试,或访问多个云端 QPU。
- 你在为算法做原型 — 编写一次,随处测试。从本地模拟切换到 GPU 再到真实硬件时,无需重新布线电路。
- 你在教学或学习 — 跨所有后端的统一 API 让学习更容易。无需学习 6 种不同的 API。
- 你想要内置算法 —
hlq.algorithms.vqe()、hlq.algorithms.qaoa()、hlq.algorithms.grover()会处理样板代码。 - 你在构建多后端应用 — 如果你的应用需要在队列最短或成本最低的任意 QPU 上运行,HLQuantum 的分派器可以处理这一点。
迁移:Qiskit → HLQuantum
如果你已有现成的 Qiskit 代码,HLQuantum 可以直接使用 Qiskit 电路:
import hlquantum as hlq
from qiskit import QuantumCircuit
# Existing Qiskit circuit
qc = QuantumCircuit(3)
qc.h(0); qc.cx(0, 1); qc.cx(1, 2)
# Wrap and run on any backend
result = hlq.run(hlq.from_qiskit(qc), backend='pennylane')
result_gpu = hlq.run(hlq.from_qiskit(qc), backend='cudaq')
无需重写——你可以增量式地为现有的 Qiskit 代码添加 HLQuantum 的多后端能力。
决策清单
Starting a new project?
├── Need IBM-specific features (Qiskit Runtime, pulse control)? → Raw Qiskit
├── Need to run on multiple backends or compare performance? → HLQuantum
├── Learning quantum computing for the first time? → HLQuantum
└── Building a research paper targeting IBM hardware? → Raw Qiskit
Migrating existing Qiskit code?
├── Want to add GPU acceleration? → HLQuantum (from_qiskit + cudaq)
├── Want to try IonQ hardware? → HLQuantum (from_qiskit + ionq)
└── Want to stay IBM-only? → Stay with Qiskit
两者并非互斥。许多工作流以原生 Qiskit 进行电路设计,然后用 HLQuantum 封装以实现多后端部署。
开始使用: HLQuantum 指南 · Qiskit SDK 指南 · 比较所有 SDK