微软量子计算全栈开发实战:从Q#入门到Azure Quantum应用
1. 项目概述一场在微软内部展开的量子探索如果你关注科技前沿最近几年一定频繁听到“量子计算”这个词。它听起来既科幻又遥远仿佛是实验室里遥不可及的玩具。但事实是一场静默却激烈的“量子竞赛”早已在全球顶尖的科技公司内部展开而微软这家以软件和操作系统闻名的巨头正是其中一位重量级的、且路径独特的参赛者。我们今天要聊的就是微软内部的这场“量子探索”The Quantum Quest at Microsoft。这不仅仅是一个研究项目更是一项跨越硬件、软件、算法乃至整个计算生态的宏大工程。它的目标直指一个被称为“量子优势”的里程碑——即用量子计算机解决经典计算机在可接受时间内无法解决的现实问题。对于开发者、研究者或是科技爱好者而言理解微软的量子之路极具价值。因为它走的是一条与众不同的“全栈”路线从最底层的、基于拓扑量子比特的硬件设计到中间层的量子编程语言Q#和开发套件再到顶层的云服务集成。这意味着即使你完全不碰硬件今天也可以通过Azure Quantum服务在云端模拟或连接真实的量子硬件来运行你的量子程序。这场“探索”解决的核心问题是如何将量子计算从深奥的物理学概念转化为可编程、可访问、可集成的可靠计算资源。它适合任何对下一代计算范式感兴趣的人无论是想了解行业动态的观察者还是渴望亲手编写第一个量子程序的开发者。2. 微软量子战略的核心与众不同的拓扑量子比特之路当IBM和谷歌选择超导量子比特IonQ押注离子阱技术时微软却将宝押在了一个更为前沿、挑战也更大的方向上拓扑量子比特。这个选择是理解微软整个量子探索逻辑的起点也是其最大胆的赌注。2.1 为什么是拓扑量子比特稳定性与可扩展性的终极追求经典计算机的比特非0即1而量子比特Qubit可以同时处于0和1的叠加态这是量子并行计算能力的根源。但量子态极其脆弱极易受到环境热量、电磁噪声的干扰而丢失信息这种现象称为“退相干”。当前主流的超导量子比特其相干时间非常短暂通常以微秒计为了维持其状态需要极其昂贵的接近绝对零度的稀释制冷机。拓扑量子比特的理论基础源于拓扑物理学中的“马约拉纳零能模”。你可以把它想象成一个特别结实的绳结在微观世界里信息被编码在拓扑结构的整体特性中而非单个粒子的状态。就像你很难通过拉扯绳子的两端来解开一个牢固的绳结一样拓扑编码的量子信息对局部扰动具有天生的抵抗力。这意味着理论上拓扑量子比特具有内在的容错能力和更长的相干时间。微软选择这条路的深层逻辑在于可扩展性。构建一台有用的量子计算机需要成千上万个、甚至百万个逻辑量子比特经过纠错后的可靠量子比特。而用当前脆弱的物理量子比特去构建一个逻辑量子比特可能需要成千上万个物理比特进行纠错这构成了巨大的工程挑战。拓扑量子比特的先天稳定性有望大幅降低纠错开销从而更高效地实现大规模扩展。这是一场用前期的巨大科研难度换取后期工程化优势的豪赌。注意拓扑量子比特的研究仍处于材料科学和基础物理的攻坚阶段。微软的研究团队花了多年时间在寻找和验证马约拉纳零能模的证据上这个过程充满了科学争议和挑战。这意味着在拓扑量子比特硬件真正成熟之前微软的量子云服务需要依赖合作伙伴的其他类型硬件如离子阱、超导来提供即时的量子访问能力。2.2 全栈式布局从硬件到云端的完整价值链与许多公司只专注硬件或只提供软件模拟不同微软的量子探索是真正的“全栈”布局。这体现了其作为平台公司的基因不满足于只提供零件而是要定义整个开发和运行的标准与体验。底层硬件层除了自主研发拓扑量子比特微软通过Azure Quantum网络集成了多家第三方量子硬件供应商如Quantinuum离子阱、Rigetti超导等。这种策略非常务实既保持了自身对终极硬件的追求又在当下为用户提供了多样化的硬件后端选择。中间软件层这是微软目前最具优势、也是开发者最能直接接触的部分。其核心是Q# 量子编程语言和Quantum Development Kit (QDK)。Q#是一种专为量子计算设计的高级语言它允许你以抽象的方式表达量子算法而无需关心底层硬件的物理实现细节。QDK则包含了编译器、模拟器、库文件以及Visual Studio和VS Code的扩展插件形成了一个完整的本地开发环境。顶层云与生态层Azure Quantum服务将这一切串联起来。开发者可以在本地用Q#编写和调试程序然后无缝地提交到Azure云端在真实的量子硬件或高性能模拟器上运行。此外微软还积极构建算法库、教学资源并推动量子计算与传统高性能计算HPC、机器学习ML的融合。这种全栈模式解决了一个关键痛点开发者的学习曲线和可移植性。你用Q#写的算法今天可以在本机模拟器上测试明天可以提交到离子阱硬件未来拓扑量子比特成熟后理论上无需重写就能迁移运行。这为量子软件生态的早期培育提供了土壤。3. 核心工具链深度解析Q#与量子开发套件实战入门理论再美好也需要工具来落地。对于绝大多数开发者而言接触微软量子世界的第一站就是Q#和Quantum Development Kit。我们来深入拆解这套工具链的核心构成和使用逻辑。3.1 Q#语言设计哲学面向量子算法的领域特定语言Q#不是像Python或C#那样的通用语言而是一门领域特定语言。它的语法和结构完全围绕量子计算的核心概念设计量子比特、操作门、测量和叠加态。一个经典的Q#操作相当于函数看起来是这样的operation PrepareSuperposition(q : Qubit) : Unit { // 将量子比特从基态 |0⟩ 变换到叠加态 (|0⟩ |1⟩)/√2 H(q); } operation MeasureQubit(q : Qubit) : Result { // 测量量子比特结果会是 Zero 或 One return M(q); }关键设计解析Qubit类型这是Q#中的核心数据类型。你无法直接创建或访问一个Qubit的具体值只能通过标准操作如H、X、CNOT来操纵它。这强制了编程的抽象性符合量子力学中“不可克隆”等原理。Operation与FunctionOperation是包含量子操作可能改变量子态的例程而Function是纯经典的、确定性的计算。编译器会严格区分二者确保量子操作的正确性。资源管理Q#使用using块来分配量子比特并在块结束时自动释放“返还”。这模拟了量子比特作为稀缺物理资源的特性防止资源泄漏。与通用语言集成的模式Q#本身不处理文件IO、用户交互等经典任务。典型的量子程序由一个宿主程序用C#或Python编写和一个或多个Q#库组成。宿主程序负责经典控制流、参数输入和结果分析并调用Q#库中的量子操作。这种“经典-量子混合编程”模型精准反映了当前NISQ含噪声中等规模量子时代量子计算机作为协处理器的定位。3.2 开发环境搭建与第一个量子程序实操是理解的最佳途径。下面我们一步步搭建环境并运行著名的“量子随机数生成器”。这虽然简单但涵盖了量子编程的基本流程。环境准备安装 .NET SDK 建议使用长期支持版本。在命令行中安装量子开发模板dotnet new -i Microsoft.Quantum.ProjectTemplates使用VS Code并安装“Microsoft Quantum Development Kit”扩展以获得语法高亮和智能提示。创建并运行项目# 创建一个新的Q#应用程序项目 dotnet new console -lang Q# -o QuantumRandomNumber cd QuantumRandomNumber # 运行项目将在本地模拟器上执行 dotnet run让我们看看自动生成的Program.qs文件的核心部分经过简化namespace QuantumRandomNumber { open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Measurement; open Microsoft.Quantum.Convert; EntryPoint() operation GenerateRandomBit() : Result { // 1. 申请一个量子比特初始化为 |0⟩ use q Qubit(); // 2. 施加哈达玛门H使其进入叠加态 (|0⟩ |1⟩)/√2 H(q); // 3. 测量。测量会以50%的概率坍缩到 |0⟩ 或 |1⟩返回Zero或One return M(q); } }执行过程解读 当你运行dotnet run时.NET运行时加载Q#程序调用标记了EntryPoint()的操作。本地全状态模拟器会在内存中模拟一个量子比特的演化过程初始化、应用H门、然后进行概率性测量最后将ResultZero或One输出到控制台。每次运行结果都可能不同。实操心得初次接触时最容易混淆的是“模拟”与“真实”的区别。本地dotnet run使用的是全状态向量模拟器它可以完美模拟少量量子比特通常30的行为包括查看叠加态的振幅。但这本质上还是在经典计算机上模拟量子力学其资源消耗随量子比特数指数增长。真正的量子硬件体验需要通过Azure Quantum提交作业那里你会遇到噪声、有限的相干时间和特定的门集约束。3.3 本地模拟器家族针对不同场景的调试工具QDK提供了一系列本地模拟器用于算法开发的不同阶段这是微软工具链非常贴心的一点模拟器类型核心用途能力与限制适用场景全状态模拟器算法功能验证与调试精确模拟量子态演化可获取完整状态向量。受经典内存限制通常模拟≤30个量子比特。学习、小规模算法原型开发、单元测试。资源估算器评估算法资源消耗不实际执行算法而是分析其在不同量子硬件架构下所需的物理量子比特数、门操作深度等。评估算法在远期容错量子计算机上的可行性进行架构研究。噪声模拟器评估算法抗噪能力在模拟中引入特定的噪声模型如振幅阻尼、退相位噪声。为当前的NISQ设备优化算法测试错误缓解策略。Toffoli模拟器专用算法模拟高效模拟仅由X、CNOT、Toffoli门构成的电路适用于一些特定的量子算法。研究可逆计算、特定类型的量子算法。使用资源估算器示例 这是规划未来算法时极其有用的工具。你可以在Q#程序中为某个操作添加一个特殊属性然后以资源估算模式运行dotnet run --target ResourcesEstimator输出会是一份详细的报告告诉你运行一次这个操作在理想的容错架构下大概需要多少物理量子比特、多少个T门一种关键但昂贵的逻辑门等等。这能让你在算法设计初期就建立起“量子资源成本”的概念。4. 连接真实量子世界Azure Quantum 工作流详解在本地模拟器上验证了算法逻辑后下一步就是将其发送到真实的量子硬件上运行。Azure Quantum提供了统一的平台来完成这项工作。这个过程比本地模拟复杂涉及云资源、作业提交、队列管理和结果检索。4.1 配置与提交你的第一个云量子作业前期准备Azure账户与资源你需要一个Azure账户并在Azure门户中创建一个“Azure Quantum”工作区。这个工作区是你的量子计算资源的容器。安装Azure Quantum CLI便于在命令行中管理作业。通过pip install azure-quantum安装。身份认证使用az login登录你的Azure账户。编写面向硬件的Q#程序 在真实硬件上运行需要更多考虑。以下是一个针对IonQ硬件后端编写的贝尔态制备与测量程序示例namespace BellState { open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Measurement; open Microsoft.Quantum.Canon; EntryPoint() operation CreateBellState() : (Result, Result) { // 申请两个量子比特 use (q1, q2) (Qubit(), Qubit()); // 制备贝尔态 (|00⟩ |11⟩)/√2 H(q1); CNOT(q1, q2); // 测量两个量子比特 let m1 M(q1); let m2 M(q2); // 重置量子比特是良好习惯某些硬件要求这样做 Reset(q1); Reset(q2); return (m1, m2); } }关键点注意最后的Reset操作。在模拟器中量子比特在using块结束后会自动“释放”。但在真实硬件上明确将量子比特重置到 |0⟩ 状态是一个重要的规范以确保不影响后续电路。使用Python宿主程序提交作业 更常见的模式是用Python脚本作为驱动器。以下脚本展示了完整流程# 导入必要的包 from azure.quantum import Workspace from azure.quantum.qiskit import AzureQuantumProvider from qiskit import QuantumCircuit, transpile import numpy as np # 1. 连接到你的Azure Quantum工作区 workspace Workspace( resource_id /subscriptions/YOUR_SUB_ID/resourceGroups/YOUR_RG/..., location eastus ) provider AzureQuantumProvider(workspace) # 2. 选择后端例如选择Quantinuum的模拟器 backend provider.get_backend(quantinuum.sim.h1-1e) # 3. 创建量子电路这里用Qiskit示例实际中可调用编译后的Q#程序 qc QuantumCircuit(2) qc.h(0) qc.cx(0, 1) qc.measure_all() # 4. 将电路编译转换为目标后端支持的指令集 transpiled_qc transpile(qc, backend) # 5. 提交作业 job backend.run(transpiled_qc, shots1024) # shots指定重复运行次数 print(f作业已提交ID: {job.id()}) # 6. 轮询并获取结果 result job.result() counts result.get_counts() print(f测量结果统计: {counts})流程拆解认证与连接脚本首先通过工作区信息连接到Azure Quantum。选择后端从提供商列表IonQ, Quantinuum, Rigetti等中选择一个具体的量子处理器QPU或其模拟器。模拟器是云端的经典虚拟机专门用于模拟该硬件的行为通常免费或成本极低是测试硬件兼容性的首选。电路准备与编译你的量子程序无论是Q#编译而来还是Qiskit创建需要被编译成特定硬件支持的原始门集。例如某些硬件可能不支持直接的CNOT门需要分解为更基本的单量子比特门和特定的双量子比特门。这一步由后端的编译器自动完成。提交与排队作业被提交到云队列中。真实QPU是共享资源你可能需要排队等待。获取结果作业完成后结果通常是多次测量shots的统计计数会返回。对于贝尔态理想结果应大约50%为0050%为11。4.2 理解结果、噪声与错误缓解当你第一次拿到真实硬件的运行结果时可能会失望贝尔态的测量结果可能不是完美的50/50甚至会出现少量的01或10状态。这就是噪声的现实体现。噪声来源门错误量子门操作不完美。测量错误读取量子比特状态时出错。退相干在计算过程中量子比特与环境相互作用丢失量子信息。错误缓解技术入门 在容错量子计算实现之前我们只能使用“错误缓解”来部分修正噪声影响而非完全纠正。一种简单常用的技术是零噪声外推。基本思想故意在电路中引入已知的、更强的噪声例如通过插入额外的、无用的门操作来延长电路深度运行多次。然后观测结果如何随噪声强度变化并尝试外推回“零噪声”时的理想结果。在Azure Quantum中的实践 一些后端如Quantinuum直接提供了集成错误缓解功能的选项。你可以在提交作业时指定error_mitigation策略。更通用的方法是用Q#或Qiskit手动构造不同噪声尺度的电路版本分别提交作业然后自行在经典端进行数据分析。这个过程深刻地揭示了NISQ时代量子编程的现状算法设计必须将噪声纳入考量。你需要思考如何设计更浅的电路减少受噪声影响的时间如何利用特定的硬件拓扑来减少通信开销以及如何应用错误缓解后处理来提升结果可信度。5. 量子算法开发实战以量子化学模拟为例掌握了工具和流程后我们来看一个更有现实意义的应用场景量子化学模拟。这是量子计算最具潜力的应用领域之一旨在模拟分子和材料的电子结构从而加速新药研发、新材料设计等。微软的量子生态为此提供了强大的库支持。5.1 问题建模从薛定谔方程到量子比特哈密顿量经典计算机模拟一个分子系统时需要求解多体薛定谔方程其复杂度随电子数指数增长。量子计算的核心思路是用量子比特的状态来直接映射电子的量子态从而自然地在量子系统中模拟量子过程。关键步骤是将分子的电子结构问题映射为一个量子比特系统的基态能量求解问题。具体来说选择基组用一组基函数来描述分子轨道。第二量子化将电子哈密顿量用产生和湮灭算符表示。映射到量子比特通过如Jordan-Wigner变换或Bravyi-Kitaev变换将费米子算符映射到泡利算符X,Y,Z,I的张量积。最终分子的哈密顿量H被表达为一系列泡利字符串P_i的加权和H Σ_i c_i P_i其中c_i是经典可计算的系数P_i是作用在多个量子比特上的泡利算符组合。5.2 使用Q#化学库实现变分量子本征求解器对于NISQ设备最著名的算法是变分量子本征求解器。其思想是准备一个由参数θ控制的量子电路称为试探波函数或ansatz在量子处理器上测量该电路下哈密顿量的期望值E(θ) ψ(θ)|H|ψ(θ)然后利用经典优化器如梯度下降不断调整参数θ寻找使E(θ)最小化的值该最小值即为分子基态能量的近似。微软的Microsoft.Quantum.Chemistry库极大地简化了这一过程。以下是一个模拟氢分子基态能量的简化示例流程namespace HydrogenVQE { open Microsoft.Quantum.Chemistry; open Microsoft.Quantum.Chemistry.JordanWigner; open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Optimization; open Microsoft.Quantum.Characterization; operation RunVQEForH2() : Double { // 1. 定义氢分子在特定键长下的描述 let bondLength 0.7414; // 单位埃 let h2Data LoadHamiltonianDataForH2(bondLength); // 此函数为示意实际需从库中加载或计算 // 2. 将化学哈密顿量转换为泡利表示的量子比特哈密顿量使用Jordan-Wigner变换 let (jwHamiltonian, nQubits) JordanWignerEncoding(h2Data); // 3. 选择ansatz电路例如简单的幺正耦合簇UCCSD近似 let ansatz PrepareUCCSDAnsatz(/* 参数 */); // 4. 定义计算能量期望值的操作 operation EstimateEnergy(parameters: Double[]) : Double { use qubits Qubit[nQubits]; // 根据参数准备ansatz态 PrepareAnsatz(qubits, parameters); // 测量哈密顿量的期望值 return EstimateEnergyObservable(jwHamiltonian, qubits); } // 5. 使用经典优化器模拟寻找最优参数 let initialParams [0.0, 0.0]; // 初始猜测 let (optimizedParams, minEnergy) ApplyClassicalOptimizer(EstimateEnergy, initialParams); return minEnergy; } }代码流程解析加载化学数据库函数会根据分子描述如氢原子坐标、键长和选定的基组自动生成电子哈密顿量。编码JordanWignerEncoding函数完成从费米子算符到泡利算符的映射输出一个可以在量子电路上处理的jwHamiltonian对象。构建变分电路PrepareUCCSDAnsatz是一个示意函数实际中需要设计一个参数化的量子电路。UCCSD是一种常用的、基于化学直觉的ansatz。测量期望值EstimateEnergyObservable是核心。因为哈密顿量是许多泡利项的求和所以需要分别准备多次相同的量子态测量每一个泡利项P_i的期望值然后按系数c_i加权求和。这个过程需要在量子硬件上重复很多次shots以获得统计估计。经典优化循环这是一个混合循环经典优化器给出参数猜测 → Q#操作在量子设备上估计能量 → 返回能量值给经典优化器 → 优化器生成新参数。循环直至收敛。5.3 结果分析与扩展思考运行上述程序在模拟器或真实硬件上最终会输出一个接近氢分子在给定键长下的基态能量值。你可以改变键长重复计算得到一条能量曲线其最低点对应的键长就是预测的分子平衡几何结构。注意事项与心得Ansatz选择ansatz的设计是VQE成败的关键。一个不好的ansatz可能无法包含真实的基态导致结果不准。UCCSD对小型分子不错但对更大体系需要更高效或硬件友好的ansatz。“贫瘠高原”问题随着量子比特数增加随机参数化量子电路的梯度会指数级变小使得经典优化变得极其困难。这是当前VQE应用于大分子的主要障碍之一。测量开销对于包含M个泡利项的哈密顿量朴素方法需要O(M)次独立的电路运行来测量所有期望值。利用泡利项之间的对易关系进行分组可以并行测量多项减少开销这是算法工程化的重要部分。从模拟到实用当前的量子化学模拟大多是对已知小分子结果的验证。要展示“量子优势”需要处理经典方法难以处理的中等规模分子如催化剂或小蛋白质片段。这需要更多、更稳定的量子比特以及更高效的误差缓解技术。6. 开发挑战、常见问题与避坑指南在实际开发中你会遇到各种预料之外的问题。以下是我在探索过程中总结的一些典型挑战和解决方案。6.1 环境配置与依赖管理问题问题1.NET版本与QDK模板兼容性错误现象执行dotnet new安装模板或创建项目时失败提示模板不兼容或找不到。排查首先确认安装的是最新的稳定版.NET SDK。然后使用dotnet --list-templates查看已安装模板。QDK模板对.NET版本有要求。解决# 更新.NET SDK dotnet tool update -g dotnet # 清除旧模板缓存 dotnet new --debug:reinit # 重新安装模板 dotnet new -i Microsoft.Quantum.ProjectTemplates问题2Python宿主程序调用Q#库时导入失败现象在Python中import qsharp失败或无法找到Q#操作。排查确保在正确的Python环境下工作。Q#的Python包 (qsharp) 和核心包 (azure-quantum) 可能有依赖冲突。解决强烈建议使用conda或venv创建干净的虚拟环境。# 使用conda示例 conda create -n quantum-env python3.9 conda activate quantum-env pip install qsharp azure-quantum在运行Python脚本前确保在该环境中已通过qsharp.install()或dotnet build成功编译了相关的Q#项目。6.2 量子程序设计与调试陷阱问题3量子比特资源未释放导致模拟器错误现象在Q#中如果你没有在using块内释放所有分配的量子比特或者尝试在释放后再次使用它全状态模拟器会抛出清晰的异常。但在面向硬件时这可能导致不可预测的行为。最佳实践始终使用use关键字分配量子比特。在操作结束前显式将测量过的或不再需要的量子比特重置到 |0⟩ 状态Reset(q)这是一个良好的习惯能确保电路在重复执行时状态干净。避免在条件分支中部分分配和释放量子比特尽量保持资源管理的对称性。问题4算法在模拟器上完美但在真实硬件上结果很差现象这是NISQ时代的常态。系统性排查思路检查门集你的电路是否使用了硬件不支持的量子门例如某些硬件可能没有直接的S门或T门需要编译器分解。在Azure Portal中查看目标后端的“规格说明”了解其原生门集。检查拓扑双量子比特门如CNOT通常在硬件的特定量子比特对之间才能直接执行。如果你的电路需要在非直接连接的比特间执行CNOT编译器会插入多个SWAP门来路由这大大增加了电路深度和错误率。尽量使算法的通信模式匹配硬件的拓扑结构。电路深度在噪声模拟器上运行你的电路逐步增加噪声水平观察结果如何退化。如果对微小噪声都很敏感说明电路太深需要重新设计算法或使用编译优化选项如optimization_level3。测量校准查看硬件提供商提供的每日校准数据了解各量子比特的读出错误率、单/双量子比特门保真度。优先选择保真度高的量子比特作为数据比特。6.3 Azure Quantum 作业提交与管理问题5作业长时间处于“等待”或“执行”状态现象提交作业后状态迟迟不更新。可能原因与应对队列等待真实QPU资源紧张作业在排队。这是正常现象。Azure Quantum门户会显示队列预估时间。作业编译/预处理中对于首次提交的复杂电路后端需要时间进行编译和优化。作业失败但状态未及时更新定期使用job.status()查询状态。如果超过预估时间很久可以尝试取消并重新提交或检查作业的详细错误信息通常在门户的“输出”或“日志”部分。建议对于开发和测试始终先使用对应硬件的模拟器后端。模拟器通常秒级返回结果且免费或成本极低是验证电路正确性和硬件兼容性的必备步骤。问题6结果数据格式解析困难现象拿到的结果是一堆二进制字符串或字典不知如何分析。解析示例# 假设结果是 counts 字典 counts {00: 487, 11: 512, 01: 15, 10: 10} total_shots sum(counts.values()) # 计算 |00 和 |11 的概率对于贝尔态 prob_00 counts.get(00, 0) / total_shots prob_11 counts.get(11, 0) / total_shots # 计算误码率非期望态的概率 error_rate (total_shots - counts.get(00, 0) - counts.get(11, 0)) / total_shots print(f|00概率: {prob_00:.3f}, |11概率: {prob_11:.3f}, 误码率: {error_rate:.3f})对于更复杂的算法你需要根据理论预期编写相应的后处理代码来计算期望值、方差或其他度量指标。微软的量子探索是一场跨越数十年的长征目前我们仍处于非常早期的“工具锻造”和“路径探索”阶段。拓扑量子比特的硬件突破是这场征程中最艰险也最激动人心的部分而当下成熟的软件工具链和云平台则为我们提供了提前入场、学习和准备的绝佳窗口。我个人最深的一点体会是量子编程思维与经典编程有根本性的不同你需要时刻意识到测量的概率性、操作的不可克隆性以及资源的极度稀缺性。从在本地模拟器上运行第一个贝尔态到在云端真实硬件上看到带噪声的结果再到尝试实现一个简单的VQE算法这个过程会让你对“计算”本身产生全新的理解。它不再仅仅是确定性的指令执行而是在一个概率的、纠缠的物理世界中精巧地操纵信息的过程。