La correction d’erreurs quantiques (QEC) est l’un des domaines de recherche les plus actifs en informatique quantique. Son objectif est de protéger l’information quantique, fragile et stockée dans les qubits, contre le bruit et la décohérence.
La fiabilité d’un qubit est mesurée par sa probabilité d’erreur. Les qubits physiques actuels atteignent un taux d’erreur de l’ordre de 1 erreur sur 10 000 (10⁻⁴) opérations de porte. Cependant, pour une efficacité optimale, ce taux doit être inférieur à 1 erreur sur 1 milliard (10⁻⁹), voire à 1 erreur sur 1 000 milliards (10⁻¹²).

Ce document vise à fournir un guide clair et concis pour comprendre la correction d’erreurs quantiques (QEC) du point de vue de sa mise en œuvre. La première section présente les différentes méthodes de calcul de correction d’erreurs nécessaires à la création de qubits logiques. La deuxième section examine l’implémentation potentielle des opérations de portes logiques sur les qubits logiquement corrigés. Enfin, la dernière section introduit le framework Cuda-QEC et son approche programmatique pour la création de systèmes de correction d’erreurs quantiques.
Le défi de la correction d’erreurs quantiques (QEC) est, à première vue, simple : détecter une erreur et la corriger. Or, cela doit se faire sans jamais mesurer ni effondrer les états quantiques des qubits. C’est là qu’intervient le concept de qubits auxiliaires intriqués.
Au lieu de stocker l’information dans un seul qubit, le QEC encode un qubit logique sur plusieurs qubits physiques, répartis en deux catégories : les qubits de données et les qubits auxiliaires (ou qubits de mesure). L’ensemble des qubits forme un état intriqué, permettant ainsi de lire les qubits auxiliaires sans effondrer l’état du qubit de données. Sur l’illustration ci-dessous, la ligne rouge représente plusieurs correspondances possibles entre un qubit logique et le qubit physique correspondant.

Supposons que nous souhaitions corriger une erreur sur un qubit logique, codé sur plusieurs qubits physiques. En cas d’erreur, l’un des qubits physiques peut basculer, soit par un basculement de bit (X), soit par un basculement de phase (Z), soit par les deux (Y).
Pour détecter les retournements de qubits, le QEC effectue des mesures périodiques de syndrome (extraction de syndrome), qui consistent à mesurer des qubits auxiliaires spécifiques interagissant avec les qubits de données. Le qubit auxiliaire est d’abord intriqué avec le qubit de données, puis la lecture est effectuée. L’intrication est maintenue pendant une courte période, juste le temps nécessaire à la lecture. Chez Google, cette intrication est réalisée à l’aide de portes CZ (contrôle-Z), qui exploitent elles-mêmes l’intrication.
(source de l’image : Google Quantum AI - Implémentation de qubits logiques à code de surface)
Une fois les syndromes identifiés, la correction peut être effectuée ; pour ce faire, un algorithme classique détermine l’erreur probable survenue. Le système applique ensuite la correction appropriée (porte X, Y ou Z). Dans le cas de Google, un découplage dynamique (DD) supplémentaire est utilisé pour atténuer les erreurs de déphasage (T2 ?).
Les qubits de données et de mesure sont distribués de manière non locale, de sorte qu’une erreur sur un ou deux qubits ne compromet pas la cohérence du groupe. Cette distribution est appelée code quantique. Les systèmes réels utilisent des codes plus grands et plus sophistiqués.
Code Shor (9 qubits) : corrige les erreurs de basculement de bit et de phase.
Code de Steane (7 qubits) : premier code correcteur d’erreurs entièrement quantique.
Codes de surface (\(2n^2-1\) qubits) — Ils disposent les qubits sur une grille 2D. La distance du code de surface \(n\) indique le nombre d’erreurs pouvant être corrigées simultanément.
En pratique, chaque qubit de mesure est chargé de mesurer projectivement un opérateur stabilisateur, utilisé pour la logique de décision de l’algorithme classique. Un code stabilisateur est la généralisation quantique des codes linéaires utilisés en correction d’erreurs classique ; il exploite les contrôles de parité pour détecter les erreurs sur les bits de bruit.
L’exécution d’un algorithme quantique sur des qubits physiques revient à manipuler des portes logiques. Mais qu’en est-il des qubits logiques ? La question peut paraître simple, mais la réponse est plus complexe, et il existe plusieurs approches pour les portes logiques. Commençons par les portes à un seul qubit, puis abordons le problème des portes à plusieurs qubits.
Application des portes à un seul qubit aux qubits logiques
Link to heading
Types d’implémentations de portes logiques :
Une porte logique qubit est équivalente à l’application de la même porte à chacun des 𝑛 qubits physiques. Par exemple, avec le code de Steane à 7 qubits, une porte de Hadamard logique est implémentée en appliquant une porte H physique à chacun des 7 qubits physiques.
Dans les codes de surface, les qubits logiques sont encodés sous forme de grands ensembles de qubits physiques. Les opérations logiques sont implémentées en fusionnant et en divisant ces ensembles, ou en créant des défauts de tressage, ce qui modifie la topologie du code.
L’image de droite, extraite de arxiv.2505.15907, illustre une opération de chirurgie de réseau consistant à joindre deux portions de code le long d’un bord. Cette opération nécessite O(d) itérations pour garantir la tolérance aux pannes.
Application des portes multi-qubits aux qubits logiques
Link to heading
- Portes multi-qubits transversales : De nombreux codes quantiques (par exemple, Steane, Bacon-Shor), CNOT logique peuvent être réalisés transversalement : \( CNOT_L=\sum_{i=1}^n CNOT(a_i,b_i) \)
Autrement dit, pour chaque qubit physique \(a_i\) dans le bloc de contrôle, appliquez un CNOT physique au qubit correspondant \( b_i \) dans le bloc cible.
Par exemple, la porte CCNOT (Toffoli) ne peut pas être implémentée transversalement dans la plupart des codes (*). Elle est plutôt implémentée en créant des états magiques, qui sont des états « téléportés » conditionnellement, par exemple avec un CNOT. Notez que dans ce cas, la porte de téléportation est une opération de porte logique.
Par exemple, CNOT via la chirurgie de réseau et CZ via le tressage.
L’application de portes multi-qubits aux qubits logiques s’effectue en opérant sur leurs qubits physiques encodés selon la structure du code :
Transversal : Portes par paires entre qubits physiques de blocs logiques.
Basé sur des ancillas : utilisez des méthodes de téléportation ou d’état magique.
Topologique : Effectuer des opérations géométriques telles que le tressage ou la chirurgie de réseau.
Je tiens à présenter mes excuses au lecteur qui aurait eu le courage de lire jusqu’ici : cette section est un peu superficielle et reste bien trop en surface, sans approfondir le sujet. Pour l’instant, il faut retenir qu’il n’existe pas de solution unique pour la porte logique mono-qubit/multi-qubit, mais un ensemble de méthodes applicables à chaque type de porte et de code quantique.
Approche programmatique : Le cadre QEC Cuda-QX
Link to heading

En 2024, l’équipe Quantum de Nvidia a présenté CUDA-QX, une extension de la plateforme open source CUDA-Q, fournissant des bibliothèques optimisées pour les développeurs en informatique quantique. Parmi les bibliothèques incluses dans CUDA-QX, on trouve CUDA-Q QEC (primitives et décodeurs de correction d’erreurs quantiques) et CUDA-Q Solvers (utilitaires VQE/ADAPT-VQE et QAOA).
Examinons rapidement leur approche visant à exposer une API programmable pour l’implémentation personnalisée de la logique classique de l’opérateur stabilisateur. Voici un exemple minimal implémentant le décodeur le plus simple, utilisé pour détecter les erreurs de basculement de bit sur un seul qubit. Le décodeur fonctionne en vérifiant si le syndrome correspond à une seule colonne de la matrice de parité Hz ; dans ce cas, le qubit est détecté comme basculé.
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
L’élément important de l’algorithme ci-dessus est que la matrice de parité et les observables prédites sont obtenues à partir du code quantique Stean prédéfini. Un décodeur simple peut alors être implémenté de cette manière :
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
Le décodeur étant en place, il est désormais possible d’exécuter l’algorithme.
nShots = 1000
nLogicalErrors = run_simple_code_capacity(nShots)
print(f"Shots = {nShots}, Logical error rate ≈ {nLogicalErrors/nShots:.4f}")
Comme on peut le constater, le QEC CUDA repose essentiellement sur la fourniture d’outils et de bibliothèques efficaces pour implémenter la logique de calcul classique du QEC. La question qui demeure est de savoir comment ce QEC CUDA peut être connecté à une véritable pile quantique, et plus particulièrement comment les syndromes sont communiqués de la pile de contrôle au décodeur QEC, et comment les décodeurs informent en retour la pile de contrôle des portes correctives à appliquer. C’est là qu’intervient le fascinant framework Cuda-Q, mais je réserve cette analyse pour un prochain article !
Voilà, il est clair que se plonger dans le monde de la correction d’erreurs quantiques est un travail à temps plein. Je dois donc maintenir un niveau d’expertise élevé pour faire progresser l’architecture des ordinateurs quantiques. Pour l’instant, je me demande s’il vaut mieux parler d’un ordinateur quantique « logiquement correct » ou simplement d’un ordinateur quantique « fiable ». Dans le premier cas, l’accent est mis sur le modèle qui garantit la correction de la machine, tandis que dans le second, l’accent est mis sur son comportement.
Comme mentionné dans un article précédent, il m’est également difficile de déterminer si le QEC doit être appliqué comme une simple décoration à l’algorithme quantique, c’est-à-dire si le compilateur chargé de traduire la séquence de portes quantiques en un code exploitable par la pile de contrôle est également responsable de l’« intégration » des opérations de portes pour obtenir la lecture du code de surface. Ou bien, cette opération doit-elle être effectuée en arrière-plan par la machine de calcul quantique fiable ?
- Si vous vous demandez s’il faut utiliser Ancillary ou Auxiliary, le mot correct est Ancillary (du latin ancilla : servante), dont le sens est de « fournir le soutien nécessaire à une fonction principale », tandis qu’Auxiliary (du latin auxilium : aide), dont le sens est de « fournir une aide supplémentaire ou un soutien de réserve ».
Cette note a été ajoutée après la rédaction de la note initiale :
- Un tutoriel intéressant intitulé « Intégration étroite des GPU et des QPU pour la correction d’erreurs quantiques et le contrôle optimal » (IEEE QCE24) est disponible (https://qce.quantum.ieee.org/2024/program/tutorials-abstracts/#tut13). Un enregistrement vidéo est disponible ici (https://video.computer.org/qce24-zoom/qce-5-room-518abc-20240917-190103.mp4.html). Ce tutoriel semble apporter de nombreuses réponses et des éclairages sur les questions ouvertes mentionnées ci-dessus. Je l’aborderai dans une prochaine note. Pour l’instant, l’idée principale est qu’un circuit peut être réécrit pour correspondre à un code quantique donné, simplifié pour correspondre à une topologie de surface, puis post-traité pour les portes logiques compatibles (portes Clifford).
