量子纠错(QEC)是当今量子计算领域最活跃的研究方向之一。QEC 的目标是保护存储在量子比特中的脆弱量子信息免受噪声和退相干的影响。

量子比特可靠性的衡量标准是基于错误概率,目前物理量子比特的错误率可以达到每10,000次门操作中出现1次错误(\(10^{-4}\))。然而,为了达到完全高效,门错误率至少需要达到十亿分之一(\(10^{-9}\)),甚至万亿分之一(\(10^{-12}\))。

本备忘录旨在从实现的角度提供一份简明扼要的量子纠错 (QEC) 指南。第一部分概述了创建逻辑量子比特所需的各种纠错计算方法。第二部分探讨了在逻辑纠错后的量子比特上实现门操作的可能性。最后一部分介绍了 Cuda-QEC 框架及其用于创建量子纠错系统的编程方法。

QEC试图解决什么问题,以及如何解决?

乍看之下,量子纠错算法(QEC)面临的挑战很简单:首先检测错误何时发生,然后纠正它。但问题是,这一切都必须在不测量或坍缩量子比特量子态的情况下完成。这就是纠缠辅助量子比特概念发挥作用的地方:

量子纠缠计算(QEC)并非将信息存储在单个量子比特中,而是将一个逻辑量子比特编码到多个物理量子比特上,这些物理量子比特分为两类:数据量子比特和辅助量子比特(也称为测量量子比特)。这组量子比特形成纠缠态,使得读取辅助量子比特而不破坏数据量子比特的状态成为可能。下图中的红线展示了几种可能的逻辑量子比特到物理量子比特的映射关系。

操作方式 链接到标题

假设我们要对一个逻辑量子比特进行纠错,该逻辑量子比特被编码成多个物理量子比特。当发生错误时,其中一个物理量子比特可能会翻转,翻转形式可以是比特翻转(X),也可以是相位翻转(Z),或者两者兼有(Y)。

为了检测翻转,QEC 会周期性地执行*伴随测量*,这涉及到测量与数据量子比特相互作用的特定辅助量子比特。辅助量子比特首先与数据量子比特纠缠,然后进行读出。纠缠持续时间很短,刚好足以完成读出操作。在谷歌的案例中,这种纠缠是通过 CZ(控制-Z)门实现的,而 CZ 门本身也利用了纠缠。

辅助量子比特测量> (图片来源:Google Quantum AI - 实现表面码逻辑量子比特)

一旦获得综合征数据,即可进行校正;为此,经典算法会确定可能发生的错误。然后,系统应用相应的校正(X、Y 或 Z 门)。在谷歌的案例中,还使用了一种额外的动态解耦 (DD) 来减轻失相 (T2?) 错误。

量子编码

数据和测量量子比特以非局域方式分布,使得一个或两个量子比特的错误不会破坏群的_一致性_。这种分布被称为_量子码_。实际系统使用更大、更复杂的码:

  • Shor 代码(9 个量子比特):可纠正比特翻转和相位翻转错误。

  • Steane 码 (7 量子比特):第一个完全量子纠错码。

  • 表面码 (\(2n^2-1\) 个量子比特)——它将量子比特排列在二维网格上。表面码距离 \(n\) 指的是可以同时纠正多少个错误。

实际上,每个测量量子比特负责投影测量一个稳定算符,该稳定算符用于经典算法的判决逻辑。稳定码是经典纠错中线性码的量子推广,它利用奇偶校验来检测噪声比特上的错误。

如何在逻辑量子比特上执行量子算法? 链接到标题

在物理量子比特上执行量子算法意味着对物理量子比特进行门。但如果要操作逻辑量子比特呢?这看似一个简单的问题,但答案并非如此直接,处理逻辑量子比特门的方法有很多种。我们先从单量子比特门入手,然后再探讨多量子比特门的挑战。

将单量子比特门应用于逻辑量子比特

逻辑门实现类型:

  • 横向门: 横向门独立地作用于每个物理量子比特。

逻辑量子比特门等价于对每个物理量子比特应用相同的门操作。例如,对于7量子比特的Steane码,逻辑Hadamard门是通过对每个物理量子比特应用物理H门来实现的。

在表面码中,逻辑量子比特被编码为大块的物理量子比特。逻辑运算通过合并和分割这些块或编织缺陷来实现,这会改变编码拓扑结构。

右侧图片(来自arxiv.2505.15907)展示了通过沿边缘连接两个代码块来执行格手术操作的过程。该操作需要 O(d) 轮才能实现容错。

将多量子比特门应用于逻辑量子比特

*横向多量子比特门:许多量子码(例如 Steane 码、Bacon-Shor 码)和逻辑 CNOT 门都可以横向实现:\( CNOT_L​=\sum_{i=1}^n ​CNOT(a_i​,b_i​) \)

也就是说,对于控制块中的每个物理量子比特 \(a_i\),对目标块中对应的量子比特 \(b_i\) 应用物理 CNOT 运算。

*基于辅助量子比特的多量子比特逻辑门:当横向实现不可行时,可以通过辅助量子比特和隐形传态电路实现多逻辑量子比特门。

例如,在大多数编码中,CCNOT(托福利)门无法横向实现(*)。相反,它通过创建魔法状态来实现,这些魔法状态是条件“传送”的状态,例如,通过CNOT门传送。请注意,在这种情况下,传送门是一个逻辑门操作。

*表面码中的多逻辑量子比特门:在像表面码这样的拓扑码中,多量子比特门的实现方式因门的不同而有所差异。

例如,通过晶格手术实现 CNOT,通过编织实现 CZ。

回顾 链接到标题

将多量子比特门应用于逻辑量子比特,是通过根据代码结构对编码后的物理量子比特进行操作来实现的:

  • 横向门:逻辑块的物理量子比特之间的成对门。

  • 辅助型角色:使用传送或魔法状态方法。

  • 拓扑运算:执行几何运算,如编织或晶格手术。

我需要向那些勇敢地读到这里的读者致歉:这一部分内容比较浅显,只停留在表面,缺乏深入探讨。目前大家需要了解的是,逻辑量子比特的单量子比特/多量子比特门并非只有一个解决方案,而是有一系列方法可以应用于每种门和量子码类型。

程序化方法:Cuda-QX QEC 框架 链接到标题

早在 2024 年,英伟达的 Quantum 团队就推出了 CUDA-QX,作为开源 CUDA-Q 平台的扩展,为量子开发者提供优化的库。CUDA-QX 中包含的两个库分别是 CUDA-Q QEC(量子纠错原语和解码器)和 CUDA-Q Solvers(VQE/ADAPT-VQE、QAOA 辅助函数)。

让我们快速了解一下他们如何为稳定器算子的经典逻辑的自定义实现提供编程 API。下面是一个最小示例,它实现了最简单的解码器,用于检测单量子比特翻转错误。解码器的工作原理是检查伴随式是否与奇偶校验矩阵 Hz 的某一列匹配,如果匹配,则检测量子比特是否翻转:

import cudaq_qec as qec

def run_simple_code_capacity( nShots=1000, errorProbability=0.1 ):

steane = qec.get_code("steane")         # get built-in Steane code from CUDA-Q QEC
parity_check_matrix = steane.get_parity_z()              # parity-check matrix for Z (bit-flip) errors
observable = steane.get_observables_z() # Get the Pauli Z observables of the code

decoder = MyCustomDecoder(Hz) # instantiate custom decoder

nLogicalErrors = 0
for _ in range(nShots):
# Generate noisy data
data = qec.generate_random_bit_flips(Hz.shape[1], errorProbability)

# Calculate which syndromes are flagged.
syndrome = (parity_check_matrix @ data) % 2

# Decode the syndrome to predict what happened to the data
result = decoder.decode(syndrome)
data_prediction = np.array(result.result, dtype=np.uint8)

# See if this prediction flipped the observable
predicted_observable = (observable @ data_prediction) % 2

# See if the observable was actually flipped
actual_observable = observable @ data % 2
if (predicted_observable != actual_observable):
nLogicalErrors += 1

return nLogicalErrors

上述算法的关键在于,奇偶校验矩阵和预测可观测量均由预定义的纯量子码获得。由此可以实现一个简单的解码器:

class SingleColumnMatchDecoder:
def __init__(self, Hz):  # Hz is a parity-check matrix shape (nChecks, nDataQubits)
self.Hz = np.array(Hz) % 2
self.n_qubits = self.Hz.shape[1]

class SimpleDecoderResult:
def __init__(self):
self.result = np.zeros(self.n_qubits, dtype=np.uint8)
def flipped(self, q):
self.result[q]=1
return self

def decode(self, syndrome):
# ensure syndrome is 1D numpy array of length nChecks
s = np.asarray(syndrome).flatten() % 2

# Initialize the flip prediction list
prediction = SimpleDecoderResult()

# Compare to each column of Hz: if any column equals the syndrome, pick that qubit
for q in range(self.n_qubits):
col = self.Hz[:, q] % 2
if np.array_equal(col, s):
return prediction.flipped(q)

# no single-column match -> predict no flips (all zeros)
return prediction

解码器安装完毕后,现在可以运行该算法了。

nShots = 1000
nLogicalErrors = run_simple_code_capacity(nShots)
print(f"Shots = {nShots}, Logical error rate ≈ {nLogicalErrors/nShots:.4f}")

正如大家所见,CUDA QEC 的核心在于提供高效的工具和库来实现 QEC 的经典计算逻辑。剩下的问题是如何将 CUDA QEC 连接到真正的量子堆栈,尤其是如何将协调信号从控制堆栈传递到 QEC 解码器,以及解码器如何反过来告知控制堆栈需要应用哪些校正门。这正是引人入胜的 Cuda-Q 框架发挥作用的地方,但我将在以后的备忘录中对此进行探讨!

# 结论

瞧,深入研究量子纠错领域显然是一项全职工作,所以我需要保持在较高的层面,才能在量子计算机架构方面保持研究动力。目前,我还在犹豫,应该说“逻辑正确”的量子计算机,还是仅仅说“可靠的量子计算机”?前者强调的是使机器逻辑正确的模型,而后者则强调的是机器的实际运行情况。

正如我在之前的帖子中提到的,我也不清楚量子执行控制(QEC)应该作为量子算法的附加组件,也就是说,负责将量子门序列翻译成控制栈可执行指令的编译器,是否也负责“内联”门操作以获得表面代码读出;还是应该作为“可靠量子计算机器”的“后台”操作?


备注 链接到标题

  1. 如果您想知道应该使用 Ancillary 还是 Auxiliary,那么正确的词是 Ancillary(拉丁语 ancilla:女仆),其意思是“为主要功能提供必要的支持”,而 Auxiliary(拉丁语 auxilium:帮助)的意思是“提供额外的帮助或备用支持”。

这条注释是在最初的备忘录撰写之后添加的:

  1. IEEE QCE24 上有一篇关于“用于量子纠错和最优控制的GPU和QPU紧密集成”的有趣教程,视频录像可在此处观看,该教程似乎对上述未决问题提供了许多答案和见解。我将在以后的备忘录中详细讨论这篇教程。目前,其思路是:电路可以重写以适应给定的量子代码,降低电路的复杂度以适应表面拓扑结构,并进行后处理以生成允许的门(克利福德门)。

Shor 算法结合量子纠错


# 参考