量子糾錯(QEC)是當今量子運算領域最活躍的研究方向之一。 QEC 的目標是保護儲存在量子位元中的脆弱量子資訊免受雜訊和退相干的影響。
量子位元可靠性的衡量標準是基於錯誤機率,目前物理量子位元的錯誤率可以達到每10,000次閘操作中出現1次錯誤(\(10^{-4}\))。然而,為了達到完全高效,門錯誤率至少需要達到十億分之一(\(10^{-9}\)),甚至萬億分之一(\(10^{-12}\))。

本備忘錄旨在從實現的角度提供一份簡潔的量子糾錯 (QEC) 指南。第一部分概述了創建邏輯量子位元所需的各種糾錯計算方法。第二部分探討了在邏輯糾錯後的量子位元上實現閘操作的可能性。最後一部分介紹了 Cuda-QEC 框架及其用於創建量子糾錯系統的程式設計方法。
QEC試圖解決什麼問題,以及如何解決?
乍看之下,量子糾錯演算法(QEC)面臨的挑戰很簡單:先偵測錯誤何時發生,然後修正它。但問題是,這一切都必須在不測量或坍縮量子位元量子態的情況下完成。這就是糾纏輔助量子位元概念發揮作用的地方:
量子糾纏計算(QEC)並非將資訊儲存在單一量子位元中,而是將一個邏輯量子位元編碼到多個物理量子位元上,這些物理量子位元分為兩類:資料量子位元和輔助量子位元(也稱為測量量子位元)。這組量子位元形成糾纏態,使得讀取輔助量子位元而不破壞資料量子位元的狀態成為可能。下圖中的紅線展示了幾種可能的邏輯量子位元到物理量子位元的映射關係。

假設我們要對一個邏輯量子位元進行糾錯,該邏輯量子位元被編碼成多個實體量子位元。當發生錯誤時,其中一個實體量子位元可能會翻轉,翻轉形式可以是位元翻轉(X),也可以是相位翻轉(Z),或兩者兼有(Y)。
為了檢測翻轉,QEC 會週期性地執行*伴隨測量*,這涉及測量與數據量子位元相互作用的特定輔助量子位元。輔助量子位元先與資料量子位元糾纏,然後進行讀出。糾纏持續時間很短,剛好足以完成讀出操作。在Google的案例中,這種糾纏是透過 CZ(控制-Z)門實現的,而 CZ 門本身也利用了糾纏。
(圖片來源:Google Quantum AI - 實作表面碼邏輯量子位元)
一旦獲得綜合徵數據,即可進行校正;為此,經典演算法會確定可能發生的錯誤。然後,系統會套用相應的校正(X、Y 或 Z 門)。在Google的案例中,也使用了額外的動態解耦 (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。
將多量子比特閘應用於邏輯量子比特,是透過根據程式碼結構對編碼後的物理量子位元進行操作來實現的:
橫向閘:邏輯區塊的實體量子位元之間的成對閘。
輔助型角色:使用傳送或魔法狀態方法。
拓樸運算:執行幾何運算,如編織或晶格手術。
我需要向那些勇敢地讀到這裡的讀者致歉:這部分內容比較淺顯,只停留在表面,缺乏深入探討。目前大家要了解的是,邏輯量子位元的單量子位元/多量子位元閘並非只有一個解決方案,而是有一系列方法可以應用在每種閘和量子碼類型。

早在 2024 年,英偉達的 Quantum 團隊就推出了 CUDA-QX,作為開源 CUDA-Q 平台的最佳化,提供量子程式庫的最佳化,作為開源平台 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)應該作為量子演算法的附加組件,也就是說,負責將量子閘序列翻譯成控制棧可執行指令的編譯器,是否也負責“內聯”門操作以獲得表面代碼讀出;還是應該作為“可靠量子計算機器”的“後台”操作?
- 如果您想知道應該使用 Ancillary 還是 Auxiliary,那麼正確的詞是 Ancillary(拉丁語 ancilla:女僕),其意思是“為主要功能提供必要的支持”,而 Auxiliary(拉丁語 auxilium:幫助)的意思是“提供額外的幫助或備用支持”。
這條註解是在最初的備忘錄撰寫之後加上的:
- IEEE QCE24上有一篇關於「用於量子糾錯和最優控制的GPU和QPU緊密整合」的有趣教程,影片錄影可在此處,觀看了上述問題和許多問題,該教學似乎對上述問題未決。我將在以後的備忘錄中詳細討論這篇教學。目前,其想法是:電路可以重寫以適應給定的量子程式碼,降低電路的複雜度以適應表面拓撲結構,並進行後處理以產生允許的閘門(克利福德閘)。

# 參考