Corecția erorilor cuantice, cunoscută și sub numele de QEC, este una dintre cele mai active domenii de cercetare în domeniul calculului cuantic în prezent. Obiectivul QEC este de a proteja informația cuantică fragilă, stocată în qubiți, de zgomot și decoerență.
Măsura fiabilității unui qubit se bazează pe probabilitatea de eroare, iar qubiții fizici de astăzi pot atinge ordinul de mărime de aproximativ 1 eroare la 10.000 (\(10^{-4}\)) de operare a porții. Cu toate acestea, pentru a fi pe deplin eficientă, rata de eroare a porții trebuie să poată atinge cel puțin 1 la 1 miliard (\(10^{-9}\)) sau chiar una la un trilion (\(10^{-12}\)).

Acest memoriu își propune să ofere un ghid ușor și concis pentru înțelegerea QEC din perspectiva implementării. Prima secțiune oferă o prezentare generală a diferitelor metode de calcul pentru corecția erorilor necesare pentru a crea Qubiți Logici. A doua secțiune examinează potențiala implementare a operațiilor de porți pe qubiți corectați logic. Iar ultima secțiune introduce framework-ul Cuda-QEC și abordarea sa programatică pentru a crea sisteme de corecție a erorilor cuantice.
Ce încearcă QEC să rezolve și cum?
Link to heading
Provocarea pentru QEC este, la prima vedere, simplă: mai întâi detectarea momentului în care s-a produs o eroare și apoi corectarea acesteia. Doar că acest lucru trebuie să se întâmple fără a măsura sau a colapsa stările cuantice ale qubitilor. Aici intervine conceptul de qubiti entailed ancilla (înlănțuiți):
În loc să stocheze informații într-un singur qubit, QEC codifică un qubit logic pe mai mulți qubiti fizici, împărțiți în două categorii: qubiti de date și qubiti auxiliari (cunoscuți și sub denumirea de qubiti de măsurare). Grupul de qubiti formează o stare entangled astfel încât devine posibilă citirea qubitilor auxiliari fără a se restrânge starea qubitului de date. În imaginea de mai jos, linia roșie arată mai multe mapări logice posibile ale qubitilor la qubitul fizic.

Să presupunem că vrem să corectăm eroarea unui qubit logic, care este codificat în mai mulți qubiți fizici. Când apare o eroare, unul dintre qubiții fizici se poate inversa, fie sub forma unei inversări de bit (X), fie sub forma unei inversări de fază (Z), sau ambele (Y).
Pentru a verifica existența inversării, QEC efectuează periodic măsurători ale sindromului, care implică măsurarea unor qubiți ancilla specifici care interacționează cu qubiții de date. Qubitul ancilla este mai întâi înlănțuit cu qubitul de date, iar apoi se efectuează citirea. Înlănțuirea se face pentru o perioadă scurtă de timp, suficient de lungă pentru ca citirea să poată fi efectuată. În cazul Google, această înlănțuire se realizează folosind porți CZ (control-Z), care, la rândul lor, utilizează și înlănțuirea.
(sursa imaginii: Google Quantum AI - Implementarea qubit-urilor logice de cod de suprafață)
Odată ce sindroamele au fost obținute, se poate efectua corecția; pentru aceasta, un algoritm clasic determină probabila eroare care a apărut. Sistemul aplică apoi corecția relevantă (poarta X, Y sau Z). În cazul Google, se utilizează o decuplare dinamică (DD) suplimentară pentru a atenua erorile de defazare (T2?).
Qubiții de date și de măsurare sunt distribuiți non-local, astfel încât o eroare la unul sau doi qubiți nu distruge consistența grupului. Această distribuție este denumită cod cuantic. Sistemele reale utilizează coduri mai mari și mai sofisticate:
Cod Shor (9 qubiți): corectează atât erorile de inversare a bitului, cât și cele de inversare a fazei.
Cod Steane (7 qubiți): primul cod complet corector de erori cuantice.
Coduri de suprafață (\(2n^2-1\) qubiți) — Aranjează qubiții pe o grilă 2D. Distanța codului de suprafață \(n\) se referă la câte erori pot fi corectate simultan
În practică, fiecare qubit de măsurare este responsabil pentru măsurarea proiectivă a unui operator de stabilizare, care este utilizat pentru logica decizională a algoritmului clasic. Un cod de stabilizare este generalizarea cuantică a codurilor liniare în corecția clasică a erorilor, care utilizează verificări de paritate pentru a detecta erori pe biții de zgomot.
Cum se execută un algoritm cuantic pe qubiți logici?
Link to heading
Executarea unui algoritm cuantic pe qubiți fizici înseamnă operarea porților pe qubiți fizici. Dar ce se întâmplă când se abordează qubiți logici? Aceasta poate părea o întrebare simplă, dar răspunsul nu este atât de direct și există mai multe modalități de a aborda porțile logice pe qubiți. Să începem mai întâi cu porți cu un singur qubit și, mai târziu, să abordăm provocarea porților cu mai mulți qubiți.
Aplicarea porților cu un singur qubit la qubiți logici
Link to heading
Tipuri de implementări de porți logice:
- porți transversale: O poartă transversală acționează independent asupra fiecărui qubit fizic.
O poartă logică de qubit este echivalentă cu aplicarea aceleiași porți fiecăruia dintre cei 7 qubiți fizici 𝑛. De exemplu, cu codul Steane pe 7 qubiți, o poartă logică Hadamard este implementată prin aplicarea unei porți fizice H fiecăruia dintre cei 7 qubiți fizici.
În codurile de suprafață, qubiții logici sunt codificați ca porțiuni mari de qubiți fizici. Operațiile logice sunt implementate prin îmbinarea și divizarea porțiunilor sau prin împletirea defectelor, ceea ce modifică topologia codului.
Imaginea din dreapta de la arxiv.2505.15907 prezintă o operație de chirurgie lattică efectuată prin unirea a două patch-uri de cod de-a lungul marginii. Această operație necesită runde O(d) pentru a obține toleranță la erori.
Aplicarea porților multi-qubit la qubiți logici
Link to heading
Porți transversale multi-qubit : Multe dintre codurile cuantice (de exemplu, Steane, Bacon-Shor), CNOT logic poate fi realizat transversal: \( CNOT_L=\sum_{i=1}^n CNOT(a_i,b_i) \)
Adică, pentru fiecare qubit fizic \(a_i\) din blocul de control, se aplică un CNOT fizic qubitului corespunzător \(b_i\) din blocul țintă.
Porți logice multi-qubit bazate pe ancilla : Atunci când o implementare transversală nu este posibilă, porțile multi-qubit logic pot fi realizate prin intermediul qubiților ancilla și al circuitelor de teleportare.
De exemplu, poarta CCNOT (Toffoli) nu poate fi implementată transversal în majoritatea codurilor (*). În schimb, este implementată prin crearea de stări magice, care sunt stări „teleportate” condiționat, de exemplu, cu un CNOT. Rețineți că, în acest caz, poarta de teleportare este o operație logică a porții.
Porți multi-logice-qubit în codurile de suprafață : În codurile topologice, cum ar fi codul de suprafață, porțile multi-qubit sunt implementate diferit în funcție de poartă.
De exemplu, CNOT prin chirurgie în rețea și CZ prin împletitură.
Aplicarea porților multi-qubit la qubiții logici se face prin operarea asupra qubiților lor fizici codificați conform structurii codului:
- Transversal: Porți în perechi între qubiți fizici ai blocurilor logice.
Bazat pe Ancilla: Folosește teleportare sau metode de stare magică.
- Topologic: Efectuează operații geometrice precum împletitura sau chirurgia reticulară.
Trebuie să-mi cer scuze cititorului care a avut curajul să citească până la acest punct: această secțiune este puțin cam superficială și mult prea aproape de suprafață, în loc să fie o analiză profundă. Ceea ce trebuie să știm deocamdată este că nu există o singură soluție pentru poarta cu un singur/multi-qubit a unui qubit logic, ci un set de rețete care pot fi aplicate pentru fiecare tip de poartă și cod cuantic.
Abordare programatică: Cadrul Cuda-QX QEC
Link to heading

În 2024, echipa Quntum de la Nvidia a introdus CUDA-QX, ca o extensie a platformei open-source CUDA-Q, oferind biblioteci optimizate pentru dezvoltatorii cuantici. Două dintre bibliotecile incluse în CUDA-QX sunt CUDA-Q QEC (primitive și decodoare de corecție a erorilor cuantice) și CUDA-Q Solvers (VQE/ADAPT-VQE, ajutoare QAOA).
Să aruncăm o privire rapidă asupra abordării lor de a expune o API programatică pentru implementarea personalizată a logicii clasice a operatorului de stabilizare. Mai jos este un exemplu minimal care implementează cel mai simplu decodor, utilizat pentru a detecta erorile de inversare a bitului pe un singur qubit. Decodorul funcționează verificând dacă sindromul se potrivește cu o singură coloană a matricei de paritate Hz, caz în care qubitul este detectat ca inversat:
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
Partea importantă a algoritmului de mai sus este că matricea de paritate și observabilele prezise sunt obținute din codul cuantic Stean predefinit. Un decodor simplu poate fi apoi implementat astfel:
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
Odată ce decodorul este instalat, este acum posibilă rularea algoritmului.
nShots = 1000
nLogicalErrors = run_simple_code_capacity(nShots)
print(f"Shots = {nShots}, Logical error rate ≈ {nLogicalErrors/nShots:.4f}")
După cum se poate observa, Cuda QEC este în esență bazat pe furnizarea de instrumente și biblioteci eficiente pentru implementarea logicii clasice de calcul a QEC. Întrebarea care rămâne este cum se poate conecta acest Cuda QEC la o stivă cuantică reală și, în special, cum sunt comunicate sindroamele de la stiva de control la decodorul QEC și cum informează decodoarele stiva de control, în schimb, despre porțile corective care trebuie aplicate. Aici intervine fascinantul cadru Cuda-Q, dar voi păstra această investigație pentru o notă viitoare!
Voilà, este clar că aprofundarea lumii Corecției Erorilor Cuantice este un job cu normă întreagă, așa că va trebui să rămân la un nivel destul de înalt pentru a menține impulsul în arhitectura mașinilor de calcul cuantic. Deocamdată, mă întreb dacă ar trebui să spun o mașină de calcul cuantic „corectă din punct de vedere logic” sau doar o „mașină de calcul cuantic fiabilă”? În primul caz, accentul se pune pe modelul care face ca mașina să fie corectă, în timp ce în al doilea, accentul se pune pe comportament.
De asemenea, nu-mi este clar, așa cum am menționat într-o postare anterioară, dacă QEC ar trebui aplicat ca o decorațiune a algoritmului cuantic, adică compilatorul responsabil de traducerea secvenței porților cuantice în ceva acționabil de către stiva de control este, de asemenea, responsabil pentru „integrarea” operațiunilor porților pentru a obține citirea codului de suprafață. Sau dacă ar trebui făcut ca o operațiune „de fundal” a „mașinii de calcul cuantic fiabile”?
- Dacă vă întrebați dacă ar trebui să folosiți „Ancillary” sau „Auxiliary”, atunci cuvântul potrivit este „Ancillary” (latină: ancilla: servitoare), al cărui sens este „a oferi sprijinul necesar unei funcții primare”, în timp ce „Auxiliary” (latină: auxilium: ajutor) înseamnă „a oferi ajutor suplimentar sau a rezerva sprijin”.
Această notă a fost adăugată după ce a fost redactată nota inițială:
- Există un tutorial interesant despre „Integrarea strânsă a GPU-urilor și QPU-urilor pentru corecția erorilor cuantice și controlul optim” de la IEEE QCE24, cu o înregistrare video disponibilă aici, care pare să ofere multe răspunsuri și perspective la întrebările deschise de mai sus. Voi prelucra acest tutorial într-un viitor memoriu. Deocamdată, ideea este că un circuit poate fi rescris pentru a se potrivi unui anumit cod cuantic, coborât pentru a se potrivi unei topologii la nivel de suprafață și post-procesat pentru porți care permit acest lucru (porți Clifford).
