量子云用户全景指南
这份指南面向所有需要使用 pyqpanda3 量子云能力的人:第一次提交线路的学习者、需要批量实验的算法开发者、关注真实芯片约束的硬件用户,以及需要排查任务失败的工程团队。它把 pyqpanda3.qcloud 的主要用法串成一张路线图,并在每个任务后链接到更细的教程和 API 参考。
如果你只想快速跑通第一个云端任务,请从三分钟路径开始。如果你正在做生产实验,请直接看生产实验清单和排障手册。
实测环境与当前云端信息
本页结合 pyqpanda3 0.4.0 源码绑定 和真实 QCloud 服务在 2026-06-25 校准。实测账号可见后端如下:
| 后端 | 类型 | 实测可用性 | 实测要点 |
|---|---|---|---|
PQPUMESH8 | 真实 QPU | 可用 | 3 比特,拓扑 [[0, 1], [0, 2], [1, 2]],原生门 CZ、RPhi,单门时序 30,双门时序 40 |
WK_C180_2 | 真实 QPU | 可用 | 180 比特,原生门 RPhi、CZ,单门时序 25,双门时序 40,拓扑前缀包含 [0, 9]、[0, 10]、[1, 10] |
WK_C180 | 真实 QPU | 不可用 | 180 比特,仍可读取芯片元数据,单门时序 40,双门时序 40 |
HanYuan_01 | 真实 QPU | 不可用 | 100 比特,原生门 RPhi、CZ,当前拓扑为空 |
full_amplitude | 云模拟器 | 可用 | 可运行 Bell 态示例;实测返回概率,计数字典为空 |
partial_amplitude | 云模拟器 | 可用 | chip_info() 会报错,因为它不是真实 QPU 后端 |
single_amplitude | 云模拟器 | 可用 | chip_info() 会报错,因为它不是真实 QPU 后端 |
源码和云端实测还确认了一个容易踩坑的点:QCloudBackend 的 chip_backend()、run_instruction()、best_qubit_blocks() 等能力应以 backend = service.backend(name) 后的实例工作流为准;真实芯片元数据只对 QPU 后端有效,云模拟器调用 chip_info() 会报错。
你应该从哪里开始
| 你是谁 | 目标 | 建议路径 |
|---|---|---|
| 量子计算初学者 | 看懂云端执行和本地模拟有什么不同 | 先读量子云是什么,再跑三分钟路径 |
| pyqpanda3 新用户 | 已会构建线路,想提交到云端 | 读准备工作和提交线路 |
| 算法开发者 | 批量提交参数化线路、读概率和计数 | 读多个线路和读取结果 |
| 硬件工作流用户 | 使用芯片拓扑、保真度、时序和指令流 | 读面向真实芯片 |
| 运维或排障用户 | 追踪任务、读取错误、保存原始字段 | 读任务生命周期和排障手册 |
量子云是什么
本地模拟器适合开发和调试;量子云用于把程序交给远程资源执行。远程资源可能是真实 QPU,也可能是云端模拟器。
| 能力 | 用途 | 主要接口 |
|---|---|---|
| 后端发现 | 查看当前账号能访问哪些设备或模拟器 | QCloudService.backends() |
| 后端选择 | 打开一个具体执行目标 | QCloudService.backend(name) |
| 线路提交 | 提交单个或多个 QProg | QCloudBackend.run(...) |
| 指令提交 | 提交已经转译和调度的 instruction JSON | QCloudBackend.run_instruction(...) |
| 任务跟踪 | 查询任务 id、状态和结果 | QCloudJob.job_id() / status() / result() |
| 结果读取 | 读取概率、计数、振幅、层析结果、时间信息和原始 JSON | QCloudResult |
| 噪声模拟 | 给云端模拟器配置噪声模型 | QCloudNoiseModel |
| 芯片元数据 | 读取拓扑、门集、时序、保真度和补偿角 | ChipInfo / ChipBackend |
准备工作
安装 pyqpanda3
pip install pyqpanda3保存 API Key
不要把 API Key 写进代码或提交到仓库。推荐使用环境变量:
export QPANDA_QCLOUD_API_KEY="your_api_key_here"Windows PowerShell:
$env:QPANDA_QCLOUD_API_KEY="your_api_key_here"Python 中读取:
import os
from pyqpanda3.qcloud import QCloudService
service = QCloudService(os.environ["QPANDA_QCLOUD_API_KEY"])选择开发后端
开发时优先使用云端模拟器,确认线路正确后再切到真实 QPU。这样可以减少排队时间和硬件额度消耗。
for name, available in service.backends().items():
print(name, "available" if available else "unavailable")三分钟路径:提交第一个云端任务
这个示例构建 Bell 态,提交到 full_amplitude 云模拟器,并读取概率。默认后端名应按你的账号实际可用后端调整。
import os
from pyqpanda3.core import CNOT, H, QProg, measure
from pyqpanda3.qcloud import DataBase, JobStatus, QCloudService
service = QCloudService(os.environ["QPANDA_QCLOUD_API_KEY"])
backend = service.backend(os.environ.get("QPANDA_QCLOUD_BACKEND", "full_amplitude"))
prog = QProg()
prog << H(0)
prog << CNOT(0, 1)
prog << measure([0, 1], [0, 1])
job = backend.run(prog, shots=1000)
print("job id:", job.job_id())
print("status:", job.status())
result = job.result()
print("final status:", result.job_status())
print(result.get_probs(base=DataBase.Binary))
print(result.timing_info())
if result.job_status() == JobStatus.FAILED:
print(result.error_message())实测 full_amplitude 后端返回了接近 {'0x0': 0.51, '0x3': 0.49} 的概率分布(键为十六进制)。这个后端在本次实测中 get_counts() 返回 {},因此示例优先读取 get_probs()。真实硬件上可能会出现少量 01 或 10,这是噪声和读出误差带来的正常现象。
提交线路
单个线路
job = backend.run(prog, shots=3000)适合教学示例、单次算法验证和小规模实验。
多个线路
programs = []
for index in range(4):
circuit = QProg()
circuit << H(0)
circuit << CNOT(0, 1)
circuit << measure([0, 1], [0, 1])
programs.append(circuit)
job = backend.run(programs, shots=2000)
result = job.result()
print(result.get_counts_list(base=DataBase.Binary))适合参数扫描、算法对比和重复实验。结果使用 get_probs_list() 或 get_counts_list() 读取。
带执行选项
QCloudOptions 用于控制云端映射、优化、修正和概率计数行为。pyqpanda3 0.4.0 源码默认值为:
| 选项 | 默认值 | 读取方法 | 设置方法 |
|---|---|---|---|
| 映射 | True | is_mapping() | set_mapping(bool) |
| 优化 | True | is_optimization() | set_optimization(bool) |
| 修正 | True | is_amend() | set_amend(bool) |
| 概率计数 | True | is_prob_counts() | set_is_prob_counts(bool) |
| 点标签 | 1 | point_label() | set_point_label(int) |
| 指定物理比特块 | [] | specified_block() | set_specified_block(list[int]) |
面向真实 QPU 时通常保留默认映射和优化。如果你已经本地完成转译并提交 instruction,则通常关闭云端映射和优化。
from pyqpanda3.qcloud import QCloudOptions
options = QCloudOptions()
options.set_mapping(True)
options.set_optimization(True)
options.set_amend(True)
job = backend.run(prog, shots=3000, options=options)set_custom_option() 可以保存布尔值、整数、浮点数和字符串。源码中 get_custom_option() 通过 pybind 暴露了多种同名重载;如果需要稳定检查自定义选项,优先使用 has_custom_option() 和 get_custom_options()。
带噪声模型
噪声模型用于云端模拟器。真实 QPU 自带物理噪声,不能再叠加软件噪声模型。
from pyqpanda3.qcloud import NOISE_MODEL, QCloudNoiseModel
noise = QCloudNoiseModel(
NOISE_MODEL.DEPOLARIZING_KRAUS_OPERATOR,
[0.001],
[0.01],
)
job = backend.run(prog, shots=3000, model=noise)QCloudNoiseModel 的三参数构造函数只接受位置参数,不支持 model=... 这样的关键字参数。
任务生命周期
云端任务是异步执行的。backend.run(...) 返回的是任务引用,不代表任务已经完成。
flowchart LR
A["submit"] --> B["QUEUING"]
B --> C["WAITING"]
C --> D["COMPUTING"]
D --> E["FINISHED"]
B --> F["FAILED"]
C --> F
D --> F常见轮询方式:
import time
from pyqpanda3.qcloud import JobStatus
while True:
status = job.status()
print(status)
if status == JobStatus.FINISHED:
result = job.result()
break
if status == JobStatus.FAILED:
result = job.query()
print(result.error_message())
break
time.sleep(5)如果你需要在另一个脚本里恢复任务,保存 job.job_id(),再构造 QCloudJob(job_id)。
读取结果
概率和计数
from pyqpanda3.qcloud import DataBase
result = job.result()
probs = result.get_probs(base=DataBase.Binary)
counts = result.get_counts(base=DataBase.Binary)批量线路使用:
probs_list = result.get_probs_list(base=DataBase.Binary)
counts_list = result.get_counts_list(base=DataBase.Binary)原始字段、原始 JSON 与时间信息
pyqpanda3 0.4.0 源码绑定中,QCloudJob.query() 和 QCloudJob.result() 支持 keys= 或 key= 请求额外原始字段。常用字段包括 mappingQprog、mappingQubit、probCount、convertQProg、srcQubits、targetCbits 和 measureQubits:
result = job.result(keys=["mappingQprog", "mappingQubit", "probCount"])
if "mappingQubit" in result:
print(result.mapping_qubit())
if "probCount" in result:
print(result.prob_count_raw())你也可以使用下标访问已返回字段:
raw_mapping = result["mappingQprog"] if "mappingQprog" in result else ""需要完整排障时,使用 origin_data() 读取服务端返回的原始 JSON 字符串,再按服务端字段解析:
import json
raw = json.loads(result.origin_data())
print(raw["success"], raw["code"], raw["message"])
print(raw["obj"]["taskId"])
print(raw["obj"].get("taskResult"))
print(result.timing_info())timing_info() 会动态返回服务端给出的时间字段。本次 full_amplitude Bell 态任务返回了 startTime、totalTime、pulseTime、cirExecuteTime、compileTime、queueTime 等字段。字段集合会随后端和任务类型变化,不要写死固定键集合。
振幅、层析和保真度
专用后端或专用任务会返回额外结构:
amplitudes = result.get_amplitudes()
density = result.get_state_tomography_density()
fidelity = result.get_state_fidelity()只有对应任务类型返回这些字段时,调用才有意义。
面向真实芯片
真实 QPU 有拓扑、原生门集、时序、保真度和可用量子比特约束。提交前最好先查看芯片元数据。
chip_info = backend.chip_info()
print(chip_info.qubits_num())
print(chip_info.available_qubits())
print(chip_info.get_basic_gates())
print(chip_info.get_chip_topology())从云端标定生成本地 ChipBackend
ChipInfo.get_chip_backend() 会构造可传给本地转译器的 ChipBackend。它携带拓扑、原生门、时序、保真度和补偿角信息。
backend = service.backend("WK_C180_2")
chip_info = backend.chip_info()
chip_backend = backend.chip_backend([0, 10])典型硬件感知流程:
from pyqpanda3.core import CZ, H, QProg, measure
from pyqpanda3.qcloud import QCloudOptions
from pyqpanda3.transpilation import Transpiler, decompose
from pyqpanda3.visualization import draw_time_scheduling
prog = QProg()
prog << H(0)
prog << CZ(0, 1)
prog << measure(0, 0)
prog << measure(1, 1)
decomposed = decompose(prog, ["U3", "CZ"])
transpiled = Transpiler().transpile(decomposed, chip_backend, {}, 2, "fidelity")
instruction = transpiled.to_instruction(
chip_backend,
offset=1,
is_scheduling=True,
compensate_pulse=False,
)
figure = draw_time_scheduling(instruction, backend=chip_backend, output="plotly")
options = QCloudOptions()
options.set_mapping(False)
options.set_optimization(False)
options.set_amend(False)
options.set_specified_block([0, 10])
job = backend.run_instruction([instruction], shots=1000, options=options)这里关闭云端映射和优化,是因为线路已经在本地按同一份芯片元数据完成了转译和调度。
选择物理量子比特块
pyqpanda3 0.4.0 源码提供两个入口:
blocks_from_service = service.best_qubit_blocks("WK_C180_2", qubit_num=2, label=1, qubit_block_num=1)
blocks_from_backend = backend.best_qubit_blocks(qubit_num=2, label=1, qubit_block_num=1)如果你已经根据实时拓扑手动选择物理比特,可以使用 QCloudOptions.set_specified_block()。例如 WK_C180_2 当前拓扑包含 [0, 10] 这条边:
options = QCloudOptions()
options.set_specified_block([0, 10])
job = backend.run(prog, shots=1000, options=options)提交前请先用 chip_info.available_qubits() 和 chip_info.get_chip_topology() 确认这些物理比特当前可用且满足双比特门连接关系。
期望值任务
变分算法常需要直接计算哈密顿量或泡利算符期望值。
from pyqpanda3.hamiltonian import Hamiltonian, PauliOperator
from pyqpanda3.qcloud import QCloudOptions
hamiltonian = Hamiltonian({"X0 Y1": 1.1, "Z0 Z1": 0.5})
pauli_op = PauliOperator({"X0 Y1": 1.1, "Z0 Z1": 0.5})
value_h = backend.expval_hamiltonian(prog, hamiltonian, QCloudOptions())
value_p = backend.expval_pauli_operator(prog, pauli_op, QCloudOptions())模拟器上也可以传 shots 和 noise_model。
生产实验清单
提交到真实 QPU 前,按这张表检查:
| 检查项 | 原因 |
|---|---|
| API Key 来自环境变量 | 避免密钥泄漏 |
| 本地模拟已通过 | 先排除线路构造错误 |
| 后端当前可用 | 避免提交到维护中的设备 |
| 量子比特数不超过后端能力 | 超出会被服务端拒绝 |
| 双量子门符合拓扑或已开启映射 | 避免不可执行的连接关系 |
shots 数合理 | 控制排队时间和额度消耗 |
保存 job_id | 便于恢复、追踪和排障 |
需要排障时保存 origin_data() 和关键 raw 字段 | keys= 请求到的是字段切片,origin_data() 是完整响应 |
排障手册
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
KeyError: QPANDA_QCLOUD_API_KEY | 未设置环境变量 | 先设置 API Key,再运行脚本 |
| 后端不可用 | 设备维护、账号无权限或队列关闭 | 调用 service.backends() 查看可用后端 |
| 任务长时间排队 | QPU 队列繁忙 | 降低 shots,换云模拟器,或稍后恢复同一 job_id |
| 任务失败但没有明显错误 | 只读取了概率或计数 | 使用 job.query()、result.error_message() 和 result.origin_data() 查看服务端返回 |
job.result(keys=[...]) 报 TypeError | 运行环境不是 0.4.0 源码绑定,或安装包版本过旧 | 确认 pyqpanda3.__version__ 和实际绑定来源;0.4.0 源码支持 keys / key |
get_counts() 返回 {} | 某些云模拟器只返回概率结果 | 优先读取 get_probs();需要计数时检查后端和 QCloudOptions.is_prob_counts() |
chip_info() 报 “only for real QPU backend” | 在云模拟器上调用了芯片元数据接口 | 只对真实 QPU 后端调用 chip_info() |
噪声模型构造报 TypeError | 使用了关键字参数 | 改用 QCloudNoiseModel(NOISE_MODEL.X, [...], [...]) |
| 真实 QPU 结果与本地模拟不同 | 真实硬件存在噪声、读出误差和拓扑约束 | 查看芯片保真度,增加 shots,或使用修正选项 |
下一步
- 量子云计算教程:更长的端到端教学说明。
- QCloud API 参考:查看所有类、方法、重载和枚举。
- 转译教程:学习如何把抽象线路转换成硬件可执行线路。
- QCloud 保真度布局教程:连接云端标定、保真度布局和时序可视化。
- 时序可视化 API:提交 instruction 前检查调度结果。