QuantumFerry 用户使用手册

PennyLane 使用示范

使用 PennyLane 编写线路和测量,使用 QuantumFerry 执行实验。插件注册了 quantum_source.device:你可以保留 qml.Hadamard、qml.CNOT、qml.expval 等熟悉的写法,由插件完成格式转换、平台任务和测量结果还原。

插件如何工作

阶段插件负责的工作你使用的对象
编写线路接收 QNode 构造出的 QuantumScript,保留测量定义和 shots。QNode / tape
准备实验预处理测量与参数,生成逻辑 OpenQASM 2,准备实际任务及其报价。dev.prepare(tape)
执行实验批准已准备的任务,通过 Core SDK 提交并跟踪平台状态。prepared.confirm(...)
返回结果取得平台计数,按原来的测量定义恢复 counts、probs、expval 等结果。prepared.result(...)

本页用 2 比特 Bell 线路完成一次有限 shots 实验。第 1–6 步组成单任务流程,插件负责把 PennyLane 线路转换为平台程序。后续章节介绍独立设备、钱包选择和进阶测量,可按需要选用。

1. 建立设备连接

先安装 SDK,并设置 QUANTUM_SOURCE_API_URL、QUANTUM_SOURCE_BACKEND 和 QUANTUM_SOURCE_ORGANIZATION_ID。认证使用平台 SDK Key:设置 QUANTUM_SOURCE_SDK_KEY 为密钥 JSON 文件路径,或同时设置 QUANTUM_SOURCE_CLIENT_ID 与 QUANTUM_SOURCE_CLIENT_SECRET。下面的示例从环境读取这些配置。

安装 SDK 的 pennylane 扩展后,PennyLane 会自动识别 quantum_source.device;当前依赖范围为 PennyLane >=0.45.1,<0.46。本例显式传入一个共享 SchedulerClient,便于同时查询设备和管理提交。

python
import os
import pennylane as qml
from quantum_source_sdk import SchedulerClient

scheduler = SchedulerClient(
    base_url=os.environ["QUANTUM_SOURCE_API_URL"],
    currency="OPEN",  # 设备继承此选择;使用 FULL 时在准备前改为 "FULL"
)
dev = qml.device(
    "quantum_source.device",
    wires=2,
    backend=os.environ["QUANTUM_SOURCE_BACKEND"],
    organization_id=os.environ["QUANTUM_SOURCE_ORGANIZATION_ID"],
    scheduler=scheduler,
    auto_approve_quote=False,
)
参数本例取值用途
第一个参数quantum_source.device选择 QuantumFerry 插件。
wires2指定线路包含两个逻辑 wire。也可使用显式标签。
backend环境中的设备标识选择平台设备的 ID、short_code 或无歧义名称。
organization_id环境中的组织 ID指定任务所属的组织。
scheduler共享 SchedulerClient复用已有的平台连接与认证。
currency本例省略,继承 scheduler.currency与注入客户端同时显式填写时必须一致;冲突在本地报错。
auto_approve_quoteFalse直接执行 QNode 时要求先处理报价;本教程使用显式 prepare / confirm。

auto_approve_quote=False 适合先看报价、再执行的流程:先构造 tape,调用 dev.prepare(tape) 查看报价,再调用 prepared.confirm() 确认。本页采用这种方式。需要在程序中自动批准时,将 auto_approve_quote 设为 True,然后直接调用 QNode。

独立设备与共享客户端的钱包

共享客户端的设备继承 scheduler.currency。使用 FULL 时,在创建 scheduler 时设置 currency="FULL",设备沿用该选择。dev.currency 可查看当前钱包。下面演示独立设备的写法:由设备创建客户端,并为新报价选择 FULL。

python
dev = qml.device(
    "quantum_source.device",
    wires=2,
    backend=os.environ["QUANTUM_SOURCE_BACKEND"],
    organization_id=os.environ["QUANTUM_SOURCE_ORGANIZATION_ID"],
    base_url=os.environ["QUANTUM_SOURCE_API_URL"],
    currency="FULL",
    auto_approve_quote=False,
)
dev.currency

直接创建 QuantumSourceDevice(..., currency="FULL") 采用相同规则。独立设备默认使用 OPEN;钱包在创建设备时选定,随后生成的报价使用该币种。

2. 构造 Bell 电路

先建立 Bell 线路,再把 QNode 构造成可供准备的 tape。这一步只构造 Python 线路对象,不使用量子计算资源。

python
@qml.set_shots(128)
@qml.qnode(dev, diff_method=None)
def bell():
    qml.Hadamard(0)
    qml.CNOT(wires=[0, 1])
    return qml.counts(wires=[0, 1])

tape = bell.construct((), {})
代码含义
@qml.set_shots(128)把 128 次采样写入这条线路;新版 PennyLane 推荐在线路上设置 shots。
@qml.qnode(dev, diff_method=None)把线路绑定到 dev;本例只读计数,不计算梯度。
qml.Hadamard(0) 与 qml.CNOT(...)创建两个逻辑比特的 Bell 纠缠线路。
qml.counts(wires=[0, 1])请求按这两个 wire 的顺序返回位串频数。
bell.construct((), {})构造无参数调用对应的 QuantumScript;不调用 bell() 执行任务。

3. 准备本次任务

将 tape 交给设备,取得 PreparedPennyLaneBatch,它保存本次线路经过预处理后生成的实验及报价。

python
prepared = dev.prepare(tape)

dev.prepare 会展开当前线路、转换为 OpenQASM 2、上传并取得报价,此时尚未执行。本例通常是一条任务;参数广播或不同测量基可能产生多条任务,每条都有自己的 shots。

prepared 的属性返回内容用途
quote整批报价摘要查看任务数量、总 shots、金额和有效期。
task_count实际准备的任务数检查一个用户线路展开成多少次平台任务。
total_shots展开后所有任务的 shots 总和了解本次批次的总采样量。
programsOpenQASM 程序字符串组成的元组需要核对插件转换结果时查看。

4. 查看报价

python
prepared.quote

本例包含 1 条任务、总计 128 shots,费用由平台返回。若测量分成 3 条线路且每条 128 shots,总采样量为 384。梯度计算会生成额外线路,各次执行分别准备和计价。

当前平台使用 public + stand 单通道,按 dev.currency 选择 OPEN 或 FULL 报价。prepared 保存这一次线路的金额和币种。需要切换钱包时,使用新币种的客户端或设备重新准备报价。

5. 确认执行

核对报价后执行本段,批准并提交本次整批任务;这一步开始使用计算资源。

python
submission = prepared.confirm(wait=False)

prepared.confirm(wait=False) 提交后返回原 PreparedPennyLaneBatch,下一步使用 prepared.result(...) 读取测量结果。也可以用 counts = prepared.confirm() 一次完成确认和等待,直接取得 PennyLane 测量结果。

6. 读取 PennyLane 结果

python
counts = prepared.result(timeout=300)
counts

counts 是位串到整数频数的字典,本例所有频数之和为 128。prepared.result(timeout=300) 读取已确认任务的结果,并还原为第 2 步请求的 PennyLane 测量类型。

调用方式返回结果适用场景
dev.prepare(tape)PreparedPennyLaneBatch查看这条 tape 实际展开的完整报价。
prepared.confirm()原 tape 对应的测量值 / 元组确认后等待结果,一步完成。
prepared.confirm(wait=False)同一个 prepared 对象确认后先返回,后续再调 result。
prepared.result(timeout=300)原 tape 对应的测量值 / 元组只恢复原批次;不补发未提交项。
dev.prepare((tape_a, tape_b)) 后 confirm()按输入 tape 顺序排列的结果元组多个具体实验一起报价,保持各自测量结构。

如何返回不同测量结果

修改 QNode 的 return 即可选择测量类型。有限 shots 下,插件根据观测量加入测量基变换,读取平台 counts,再由 PennyLane 计算相应的测量结果。调整线路后,重新准备本次实验的报价。

请求当前行为
counts有限整数 shots,返回平台计数通道;来源以设备和 Adapter 为准。
probs有限 shots 时由平台 counts 得到频率向量;两 wire 顺序为 00、01、10、11。
expval、var有限 shots,必要时变换测量基并分组,再由平台 counts 还原。
sample从平台 counts 重建频数一致的统计样本,按位串频数组织。
state、density_matrix当前插件支持的测量类型为 counts、probs、expval、var 和 sample。
多组 shots分别构造带整数 shots 的 tapes,再批量准备实验。

支持原生 probabilities 的设备可以用 shots=None 请求单个 qml.probs,并通过 provider_probability_shots 设置执行预算。常规采样实验使用 qml.set_shots 指定采样次数。

设备选项:查询、配置和使用

通用选项在 qml.device(...) 中设置,例如组织、等待时间和是否自动批准。设备特有选项则由平台 schema 描述,放在 configuration_data 的同一层。以本源逻辑线路为例,在设备声明了对应字段时,可以在第 1 步加入 configuration_data={"mapping": True, "optimization": False}。

想了解或设置什么对应入口返回值 / 放置位置
平台设备能做什么dev.provider_capabilities统一的设备能力对象,包括设备提供的门、拓扑等信息。
厂商参数有哪些、允许填什么scheduler.get_backend_class(code).configuration_schema包含 properties 等内容的配置 schema 字典。
PennyLane 插件认识哪些操作dev.capabilities插件可处理的操作与测量;设备门集在 provider_capabilities 中查看。
为本次设备设置 mapping 等参数qml.device(..., configuration_data={...})先选择设备,再按其 schema 提供参数。

PennyLane 的设备参数在 qml.device(..., configuration_data={...}) 中设置;可选字段通过 scheduler.get_backend_class(code).configuration_schema 查询。dev.prepare(tape) 使用已建立设备的配置。

PennyLane 使用逻辑 wire 标签,例如 wires=[1, 11] 会序列化为逻辑 q[0]、q[1],由设备映射到物理比特。固定真机位置的实验可使用 Qiskit 的 physical_qubits 或 initial_layout 布局入口。

qml.device 创建参数参考

创建参数默认值作用
wires必填线路的逻辑 wire 数量或标签。
backend必须为非空设备标识设备 ID、short_code 或无歧义名称。
shotsNone兼容旧设备级 shots 默认;新 QNode 使用 @qml.set_shots(N),最终执行以 tape.shots 为准。
schedulerNone注入已有 SchedulerClient,复用其连接和认证。
base_url / api_urlNone自建客户端的平台根地址;两者同时提供必须一致。
client_id / client_secretNone成对提供平台凭据,也可通过环境配置或共享 scheduler 读取。
tokenNone使用平台令牌认证,与 Client ID / Secret 认证二选一。
currencyNone:独立设备用 OPEN,注入 scheduler 时继承可显式选择 FULL;与注入客户端冲突时报错;dev.currency 只读。
organization_idNone任务归属组织;省略时 Core 仅在恰好一个组织的情况下自动选择。
providerNone消除设备标识歧义或补厂商前缀;完整 short_code 通常不需要。
configuration_dataNone,内部整理为字典设置所选设备支持的平铺选项。
job_subcategory_idoth:oth实际平台任务子类别。
auto_confirmTrue兼容的自动批准开关;False 关闭自动批准。
auto_approve_quoteNone,按 True 参与计算与 auto_confirm 同时判断;任一为 False 时使用显式报价确认流程。
provider_probability_shotsNone支持原生概率的设备在 shots=None 模式下使用的执行预算。
job_timeout_seconds86400 秒默认等待时长;prepared.result(timeout=...) 可设置当前等待的时限。
job_name_prefixpennylane-job生成平台任务名称时使用的前缀。
verboseFalse每条准备成功后打印一条 job_prepared 事件。
execution_plan / queue_prioritypublic / stand当前平台使用的通道,保持默认即可。

通过 prepared.result(timeout=300) 设置本次等待时长。last_execution_metadata 提供最近一次批次的 circuit_count、shots_per_circuit 和 total_provider_shots;total_credits_used 累计当前设备实例已读取的完成任务费用。账号余额和完整账单在平台钱包中查看。

批量线路与迭代算法

多个 QuantumScript 使用 dev.prepare((tape_a, tape_b)) 批量准备。每个 tape 携带自己的 shots,prepared.quote 汇总展开后的实际任务,完成后按输入顺序还原结果。参数广播、测量分组和参数移位梯度会按计算需要生成额外线路。

自动运行优化循环时,将设备的 auto_approve_quote 设为 True,再按 PennyLane 的方式调用 QNode。每次执行都会准备报价并自动批准相应任务,使用平台余额和设备资源;训练费用由各次实际执行累积。

需要逐次审阅报价并取得完整 QNode 测量结果时,采用本页的 construct → dev.prepare → confirm 流程。自动求导或训练循环采用自动批准方式,使 PennyLane 能连续完成线路变换、执行和结果还原。

批次中部分任务已接受时,保留原 prepared,通过 job_ids 查看已建立任务,通过 unsubmitted_preparation_ids 查看尚待提交项。prepared.recover() 查询已尝试的提交;完整结果需等待本批所有必要任务成功。

超时与原任务恢复

等待超时后,再调用 prepared.result(timeout=300) 继续等待同一批实验。prepared.recover(wait=False) 查看当前提交进度;prepared.recover(wait=True, timeout=300) 等待这些任务结束。

python
prepared.recover(wait=False)
prepared.job_ids

prepared.job_ids 保存已建立的任务 ID。任务 ID 尚未生成时,使用 prepared.attempted_preparation_ids 中的提交标识调用 scheduler.get_submission(identifier)。状态暂时无法确认时,稍后继续查询同一记录。

异常用户应如何处理
APIError(HTTP 402)所选钱包余额不足。补足余额后继续确认;也可切换客户端钱包并重新准备报价。批次中已接受的任务继续执行。
PlatformSubmissionError平台暂时无法确认发送结果;保留原提交 ID,查询原记录。
ProviderSubmissionError包含厂商返回的公开错误说明。结合说明和原提交 ID 查询本次提交的状态。
PlatformStatusError当前状态无法确认,包含未识别的厂商状态;稍后查询同一个任务。
PlatformResultError结果暂时无法读取;查询原任务并再次读取原结果。
JobLimitReachedError组织当前任务名额已满;核对已有任务及本批已接受的部分。
JobNotCancelableError当前任务已不满足取消条件;继续查询原记录。

QuantumSourceDeviceError 表示配置或设备契约问题,QuantumSourceCircuitError 表示线路问题,QuantumSourceResultError 表示收到的真实结果不符合测量契约。SDK 的提交、额度、超时和查询异常保留其原类型,便于沿原对象恢复。

取消、中断与费用

需要取消实验时,使用 dev.cancel_job(submission_id) 或 scheduler.cancel_job(submission_id)。平台尚未领取的排队项可以取消,成功返回 None;已进入发送阶段的任务继续通过查询读取进度。

Ctrl+C 或 Jupyter 中断以 KeyboardInterrupt 到达本次执行时,插件会尝试取消本次仍待发送的任务。通过 prepared.cancellation_report 的 cancelled_ids、skipped_ids 和 failures 查看处理结果。等待超时或关闭连接后,任务继续由平台管理。

当前每个组织最多同时保有 10 个尚未结束的任务,组织内成员、SDK Key 和设备共享这些名额。平台接受确认后占用名额,在确认完成、失败或取消后释放;排队、发送中和等待核实的任务持续占用。名额已满时,等待已有任务结束后再提交。每次实验同时按账号授权检查 shots 额度。

最终状态为 Failed 的任务按原币种退款;同一批次中的成功任务按各自报价结算。OPEN 退款沿用原有效期,有效期内的部分恢复为可用余额。具体费用与退款记录可在平台钱包和账单中查看。

完成后关闭连接

完成本次结果读取或必要的恢复后关闭设备;示例中的共享 scheduler 由调用方创建,因此还要单独关闭。

python
dev.close()
scheduler.close()

下一步

下载本页 Jupyter Notebook

收录本页 Python 示例与说明,便于在 Jupyter Notebook 中学习和运行;安装命令保留为说明。

下载《PennyLane 入门与示例》Notebook(.ipynb)

输入关键词;所有搜索都在本机完成。