Actualiser les propriétés du backend grâce à des tests de performance en temps réel
Estimation de la durée d'utilisation : 3 minutes sur ibm_kingston (REMARQUE : il ne s'agit que d'une estimation. (Votre temps d'exécution peut varier.)
Acquis d'apprentissage
- Pourquoi les propriétés renvoyées par une QPU peuvent ne pas refléter le comportement actuel du périphérique, et dans quels cas il est utile de les mesurer à nouveau soi-même
- Ce que mesure chacune des cinq expériences de caractérisation standard (lecture, benchmark aléatoire à un qubit, benchmark aléatoire à deux qubits en couches, et )
- Comment exécuter l'ensemble complet de la suite de caractérisation en une seule fois ou étape par étape, et obtenir en retour un objet backend dont les propriétés ont été mises à jour
- Comment comparer les propriétés mesurées à celles indiquées, et pourquoi certaines différences sont davantage liées à la méthode de mesure qu'à une dérive de l'appareil
Prérequis
- Le flux de travail « Patterns » de Qiskit
- Qiskit Runtime modes d'exécution, notamment le mode batch
- Comment consulter les informations relatives au QPU, telles que les propriétés du backend et les données d'étalonnage
Arrière-plan
Chaque QPU « IBM Quantum® » communique un ensemble de propriétés décrivant les performances actuelles de chacun de ses qubits : temps de relaxation ( ), temps de cohérence ( ), erreurs de lecture, ainsi que les erreurs liées aux portes à un et deux qubits. Ces chiffres ont une importance concrète. Le transpileur s'en sert pour déterminer sur quels qubits physiques votre circuit doit s'exécuter; les techniques d'atténuation des erreurs s'appuient sur ces informations, et vous pouvez vous en servir pour évaluer si un dispositif fonctionne suffisamment bien pour une expérience.
Les caractéristiques indiquées proviennent de procédures d'étalonnage qui sont généralement effectuées environ une fois par jour. Les qubits supraconducteurs peuvent toutefois subir une dérive à des échelles de temps plus courtes, et des défauts transitoires (ce qu’on appelle des « systèmes à deux niveaux ») peuvent temporairement dégrader un qubit qui semblait parfait au moment de l’étalonnage. De plus, une tâche est souvent transcompilée bien avant son exécution effective; les décisions fondées sur les propriétés signalées peuvent donc reposer sur des informations obsolètes. Le tutoriel « Benchmarking en temps réel pour la sélection des qubits » montre à quel point ces propriétés peuvent varier d’un jour à l’autre et présente la mise en place manuelle d’un workflow complet de caractérisation à partir d’expériences Qiskit individuelles.
Ce tutoriel présente une version simplifiée de ce workflow, grâce à l'utilisation de l'utilitaire BackendCharacterization de Qiskit Device Benchmarking, qui regroupe la création de l'expérience, la soumission de la tâche et l'ajustement des courbes en quelques appels seulement. Cela vous prend environ 70 secondes de temps de traitement sur le QPU et vous obtenez en retour un objet backend dont les propriétés reflètent l'état actuel de l'appareil, prêt à être comparé aux valeurs communiquées ou transmis aux outils en aval.
Les expériences de caractérisation
La suite comprend cinq propriétés, chacune associée à une expérience standard :
- Erreur de lecture (
readout): Chaque qubit est préparé dans l'état « » ou « » et immédiatement mesuré. La probabilité de lire un état erroné correspond à l'erreur de préparation et de mesure de l'état (SPAM). - Erreur de porte à un qubit (
rb_1q): L'évaluation aléatoire (RB) consiste à exécuter des séquences de portes de Clifford aléatoires à un qubit qui, dans l'idéal, se combinent pour former la porte d'identité. La façon dont la probabilité de survie diminue avec la longueur de la séquence permet de déterminer l'erreur moyenne par porte, indépendamment des erreurs SPAM. - Erreur de porte à deux qubits (
rb_2q): Le même principe RB appliqué à des couches entières de portes à deux qubits non superposées exécutées simultanément, comme dans une expérience de fidélité de couche. Comme de nombreuses portes fonctionnent simultanément, les taux d'erreur qui en résultent tiennent compte des effets de diaphonie et se rapprochent davantage de ceux observés dans un circuit profond. - (
t1): Chaque qubit est excité puis mesuré après des délais croissants. La décroissance de la population à l'état excité détermine le temps de relaxation. - (
t2): Une expérience d'écho de Hahn place chaque qubit dans un état de superposition, applique une impulsion d'écho à mi-parcours d'un délai, puis mesure la vitesse à laquelle la cohérence de phase se perd. Par défaut, un seul écho est utilisé; une variante à échos multiples (de type CPMG) est présentée à la fin de ce tutoriel.
Ce que la réinitialisation fait et ne fait pas
Gardez trois points à l'esprit lorsque vous utilisez ce processus :
- Les propriétés mises à jour ne figurent que dans l'objet backend qui vous est renvoyé. Rien ne change sur l'appareil lui-même ni dans les données d'étalonnage qu' IBM Quantum transmet aux autres utilisateurs.
- Les valeurs mesurées constituent un instantané obtenu selon une méthodologie particulière. Certaines d'entre elles, notamment les erreurs superposées à deux qubits et les valeurs d' s à écho unique en parallèle, sont mesurées différemment des données d'étalonnage publiées; ainsi, une partie de l'écart que vous observez est d'ordre méthodologique plutôt que due à une dérive. Ce tutoriel explique où cela se produit.
- La caractérisation elle-même nécessite du temps de calcul sur le QPU (environ 70 secondes pour la suite complète sur un processeur Heron r2 ), ce qui est le prix à payer pour disposer d'informations à jour.
Le flux de travail suit les quatre étapes d'un modèle Qiskit :
- Étape 1 : Mettre en correspondance les entrées classiques avec un problème quantique. Sélectionnez l'appareil et l'ensemble des propriétés à mesurer.
- Étape 2 : Optimiser le problème pour son exécution sur un matériel quantique. Cet utilitaire construit les circuits d'expérimentation directement dans les portes natives du dispositif et les parallélise à l'échelle de la puce.
- Étape 3 : Exécutez la commande à l'aide d' Qiskit primitives. Les expériences sont exécutées sous forme de tâches Sampler au sein d'un lot.
- Étape 4 : Effectuer le post-traitement et restituer le résultat dans le format classique souhaité. Intégrer les données de mesure dans des cartes d'erreurs par qubit, actualiser le backend, puis comparer les propriétés mesurées à celles indiquées.
Exigences
Avant de commencer ce tutoriel, assurez-vous d'avoir installé les éléments suivants :
- Qiskit SDK v2.0 ou version ultérieure, avec prise en charge de la visualisation
- Qiskit Runtime v0.40 ou version ultérieure (
pip install qiskit-ibm-runtime) - Qiskit Device Benchmarking, qui installe également Qiskit Experiments (
pip install git+https://github.com/qiskit-community/qiskit-device-benchmarking.git)
Configuration
Importez les bibliothèques nécessaires.
import logging
import sys
import numpy as np
from qiskit_ibm_runtime import Batch, QiskitRuntimeService
from qiskit_device_benchmarking.utilities.characterization_utils import (
BackendCharacterization,
plot_characterization_comparison,
)La suite de caractérisation met en place plusieurs expériences, envoie plusieurs tâches et effectue l'ajustement des résultats, ce qui peut prendre quelques minutes au total. Activez la journalisation de niveau INFO afin que chaque étape affiche sa progression au fur et à mesure.
logger = logging.getLogger("qiskit_device_benchmarking")
logger.setLevel(logging.INFO)
logger.addHandler(logging.StreamHandler(stream=sys.stdout))Exemple de simulateur à petite échelle
Ce tutoriel ne comprend pas d'exemple de simulation. Ce processus permet de mesurer les imperfections physiques d'un dispositif donné : la vitesse à laquelle ses qubits se relâchent et se déphasent, ainsi que la fréquence à laquelle ses portes logiques et ses lectures échouent. Un simulateur idéal ne présente aucune de ces imperfections; il n'y a donc rien à caractériser. Vous pourriez associer un modèle de bruit synthétique à un backend fictif, mais les expériences ne feraient alors que reproduire les chiffres que vous auriez vous-même saisis. C'est pourquoi nous passons directement au matériel, en suivant les quatre étapes d'un modèle Qiskit.
Exemple de matériel à grande échelle
Étape 1 : Mettre en correspondance les entrées classiques avec un problème quantique
Dans ce flux de travail, le « problème » est le dispositif lui-même : les entrées classiques sont le QPU que l'on souhaite caractériser et la liste des propriétés à mesurer, tandis que les expériences quantiques correspondent aux circuits de caractérisation générés à partir de ces données.
Commencez par choisir un backend. Ce tutoriel utilise un processeur Heron r2 de 156 qubits ibm_kingston; vous pouvez le remplacer par n'importe quel appareil IBM Quantum auquel vous avez accès (ou en choisir un avec service.least_busy()).
service = QiskitRuntimeService()
device = "ibm_kingston"
backend = service.backend(device)Choisissez ensuite les propriétés que vous souhaitez mesurer. Vous pouvez réussir n'importe quel sous-ensemble des épreuves suivantes :
readout: Expérience SPAM (préparation et mesure des états)rb_1q: tests de performance aléatoires sur un qubit isolérb_2q: Évaluation comparative aléatoire simultanée de deux qubits à partir d'une expérience de fidélité par couchest2: Expérience d'écho de Hahn (un seul écho par défaut)t1: Expérience de relaxation « »
Lancez la suite complète pour obtenir une vue d'ensemble de l'appareil; supprimez les entrées de la liste si seules certaines propriétés vous intéressent et que vous souhaitez économiser du temps de calcul sur la QPU.
experiments = ["readout", "rb_1q", "rb_2q", "t1", "t2"]Étape 2 : Optimisation du problème en vue de son exécution sur un matériel quantique
Dans la plupart des tutoriels, c'est à ce stade que vous devriez transcompiler vos circuits. Ici, s'en BackendCharacterization charge en interne. Il construit les circuits d'expérimentation directement dans les portes natives du dispositif, exécute les expériences sur un seul qubit sur tous les qubits en parallèle, et planifie les tests de performance sur deux qubits sur des couches disjointes de la carte de couplage, de sorte que l'ensemble du dispositif soit couvert par une poignée de tâches. Grâce à cette parallélisation, l'ensemble de la suite ne nécessite qu'environ 70 secondes de temps de calcul sur le QPU.
Initialisez la classe qui gère le flux de travail :
# Initialize the class used to run the experiments
characterizer = BackendCharacterization(backend)Étape 3 : Exécutez la commande à l'aide d' Qiskit primitives
Cette méthode run_experiments crée les circuits et les soumet sous forme de tâches Sampler. Exécutez-la dans un contexte Batch afin que les tâches soient planifiées ensemble sur le QPU et que la méthode renvoie un résultat une fois que toutes les tâches ont été soumises. (Vous pouvez également l'exécuter en dehors d'un fichier batch, ou à l'intérieur d'un Session.)
Il se peut qu'un message d'avertissement s'affiche, indiquant qu'un backend a été transmis alors qu'un gestionnaire de contexte de session est ouvert. Ce phénomène est normal et peut être ignoré sans risque.
# Run the characterization experiments inside a Batch
with Batch(backend=backend):
jobs = characterizer.run_experiments(experiments=experiments)Output:
base_primitive.get_mode_service_backend:WARNING:2026-07-14 14:23:02,051: A backend was passed in as the mode but a session context manager is open so this job will run inside this session/batch instead of in job mode.
Building readout experiments
Building 1Q RB experiments
Building 2Q RB experiments
Building T1 experiments
Building T2 experiments
Layered two-qubit RB submitted: ['d9b7tfu6hjac73ffba2g', 'd9b7tjug26ic73dfju3g', 'd9b7u3u6hjac73ffban0', 'd9b7u7rv6alc73csmicg']
Readout job submitted: d9b7u8bv6alc73csmidg
T1 experiment submitted: ['d9b7u8ug26ic73dfjuqg']
T2 (Hahn) experiment submitted: ['d9b7u9fu62qs738othg0']
Single-qubit RB submitted: ['d9b7v8m6hjac73ffbc40', 'd9b7veeg26ic73dfk040']
Cette méthode renvoie les tâches soumises sous la forme d'un dictionnaire dont les clés correspondent aux expériences, ce qui est utile pour les suivre sur le tableau de bord de IBM Quantum Platform ou à des fins de débogage.
# Print all the job IDs for debugging purposes
jobsOutput:
{'rb_2q': [<RuntimeJobV2('d9b7tfu6hjac73ffba2g', 'sampler')>,
<RuntimeJobV2('d9b7tjug26ic73dfju3g', 'sampler')>,
<RuntimeJobV2('d9b7u3u6hjac73ffban0', 'sampler')>,
<RuntimeJobV2('d9b7u7rv6alc73csmicg', 'sampler')>],
'readout': [<RuntimeJobV2('d9b7u8bv6alc73csmidg', 'sampler')>],
't1': [<RuntimeJobV2('d9b7u8ug26ic73dfjuqg', 'sampler')>],
't2': [<RuntimeJobV2('d9b7u9fu62qs738othg0', 'sampler')>],
'rb_1q': [<RuntimeJobV2('d9b7v8m6hjac73ffbc40', 'sampler')>,
<RuntimeJobV2('d9b7veeg26ic73dfk040', 'sampler')>]}
Étape 4 : Traitement ultérieur et restitution du résultat dans le format classique souhaité
Analyser les résultats
La méthode analyze_results attend que les tâches soient terminées, puis effectue l'ajustement des données de mesure : des décroissances exponentielles pour et , des décroissances de probabilité de survie pour les expériences RB, et des matrices d'affectation pour la lecture. Elle renvoie un dictionnaire de tables d'erreurs, avec une entrée par propriété mesurée, chacune associant un qubit (ou une paire de qubits) à sa valeur mesurée.
error_maps = characterizer.analyze_results()print(f"The following error maps are available: {list(error_maps.keys())}")
readout_q0 = error_maps["readout_error"][0]
print(f"For example, readout error for qubit 0 is {readout_q0}")Output:
The following error maps are available: ['readout_error', 'oneq_error_x', 'oneq_error_sx', 'lf_error_map', 't1_map', 't2_map']
For example, readout error for qubit 0 is 0.007600000000000051
Les graphiques présentent les erreurs de lecture, les erreurs de porte sx sur un seul qubit et x les erreurs de porte, les erreurs de deux qubits par couches (lf_error_mapissues de l'expérience sur la fidélité par couche), ainsi que les temps de « » et de « » exprimés en secondes.
Mettre à jour les propriétés du backend
Cette méthode update_backend enregistre les valeurs mesurées dans les propriétés d'une copie du backend, puis renvoie cette copie. L'objet backend d'origine conserve les données d'étalonnage enregistrées, ce qui nous permet de comparer les deux, comme illustré ci-dessous. N'oubliez pas que cette mise à jour ne concerne que votre session « Python »; elle n'entraîne aucun changement sur l'appareil ni pour les autres utilisateurs.
backend_updated = characterizer.update_backend()Output:
Updating readout error
Updating single-qubit X error
Updating single-qubit SX error
Updating two-qubit error
Updating T1
Updating T2
Comparez les propriétés mesurées à celles indiquées
Enfin, tracez un graphique comparant les propriétés mesurées en temps réel aux valeurs fournies par le backend. Dans chaque panneau, les qubits (ou paires de qubits) sont classés en fonction de la valeur mesurée; ainsi, la courbe de mesure est lisse par nature et la dispersion des valeurs indiquées autour de celle-ci met en évidence les points de divergence entre les deux. Un seul graphique est présenté pour le RB à un seul qubit, car la même erreur mesurée par porte est attribuée à la fois aux portes sx et x . Les limites des axes sont choisies à partir de l'ensemble des données afin d'éviter que quelques valeurs aberrantes extrêmes ne déforment les graphiques; les points situés en dehors de cette plage sont indiqués dans une annotation sur le graphique (ou utilisez la commande « pass » pour ylim remplacer ces limites).
plot_characterization_comparison(
old_props=backend.properties().to_dict(),
new_props=backend_updated.properties().to_dict(),
plots=["readout", "rb_1q", "rb_2q", "t1", "t2"],
)Output:
Ces graphiques doivent être interprétés avec précaution, car tous les écarts entre les deux courbes ne signifient pas nécessairement que l'appareil a dérivé :
- Lecture et erreurs sur un seul qubit : les valeurs mesurées correspondent à celles rapportées pour la plupart des qubits, tandis que la valeur rapportée pour quelques-uns d'entre eux s'écarte considérablement de la courbe mesurée. Ce sont précisément ces divergences ponctuelles que ce processus de travail est censé détecter.
- : Les deux ensembles de données se répartissent de manière aléatoire l’un par rapport à l’autre, sans décalage systématique, ce qui corrobore l’hypothèse selon laquelle l’ e fluctue naturellement au fil du temps.
- Erreurs sur deux qubits : les valeurs mesurées sont systématiquement supérieures à celles rapportées. Ce résultat est prévisible, car les valeurs rapportées sont mesurées sur des grilles isolées, tandis que l'expérience sur la fidélité de la couche porte sur de nombreuses grilles simultanément et inclut donc la diaphonie. Les chiffres par couches sont plus pertinents pour les circuits profonds, mais ils ne sont pas directement comparables aux données d'étalonnage publiées.
- : Les valeurs mesurées sont nettement inférieures à celles rapportées pour la plupart des qubits. Là encore, la méthodologie joue un rôle important, comme nous le verrons dans la section suivante.
Consulter les résultats de chaque expérience
Vous pouvez également consulter les résultats bruts des différentes expériences de caractérisation grâce à la propriété experiment_data , qui renvoie les objets ExperimentData Qiskit Experiments sous-jacents. Par exemple, le graphique suivant présente la courbe de décroissance mesurée de l' e d'un qubit unique, ce qui permet de vérifier la qualité d'un ajustement avant de se fier aux résultats obtenus.
t1_data = characterizer.experiment_data["t1"]
# Each qubit has its own fit figure
n_figs = len(t1_data.figure_names)
print(f"{n_figs} figures available, e.g. {t1_data.figure_names[0]}")
# Show the T1 decay curve of the first qubit
t1_data.figure(0)Output:
156 figures available, e.g. T1_Q0_c78ef792.svg
Mesure de l' T2 e à l'aide d'un train de découplage dynamique
Par défaut, l'expérience « » utilise un seul écho de Hahn et mesure tous les qubits en parallèle, ce qui, comme le montre le graphique comparatif ci-dessus, peut donner des valeurs d' ion nettement inférieures à celles indiquées par le backend. Une hypothèse concerne le nombre d'échos : les valeurs rapportées pourraient avoir été calibrées à l'aide d'un découplage dynamique, qui supprime le bruit à basse fréquence. Pour vérifier cela, lancez une caractérisation « » avec le paramètre réglé t2_num_echoes sur une valeur plus élevée, ce qui applique une séquence d’impulsions d’écho de type CPMG. Ces retards correspondent à la durée totale d'évolution libre dans les deux cas; les valeurs d' s obtenues par ajustement sont donc directement comparables aux résultats obtenus avec un seul écho.
# Run a T2-only characterization using a CPMG-style train of 8 echoes
characterizer_dd = BackendCharacterization(backend)
backend_updated_dd = characterizer_dd.run_and_update(
experiments=["t2"], t2_num_echoes=8
)Output:
Building T2 experiments
T2 (Hahn) experiment submitted: ['d9b96s6g26ic73dflcn0']
Updating T2
# Compare the multi-echo T2 against the backend-reported values
plot_characterization_comparison(
old_props=backend.properties().to_dict(),
new_props=backend_updated_dd.properties().to_dict(),
plots=["t2"],
title_prefix="8-echo CPMG",
)
# Compare medians across the reported values, the single-echo run,
# and the 8-echo run
reported_t2s = [
prop["value"]
for qubit in backend.properties().to_dict()["qubits"]
for prop in qubit
if prop["name"] == "T2"
]
t2_reported = np.median(reported_t2s)
t2_single = np.median(list(error_maps["t2_map"].values())) * 1e6
t2_dd = (
np.median(list(characterizer_dd.analyze_results()["t2_map"].values()))
* 1e6
)
print(
f"Median T2 — reported: {t2_reported:.0f} us | "
f"single echo: {t2_single:.0f} us | 8-echo CPMG: {t2_dd:.0f} us"
)Output:
Median T2 — reported: 142 us | single echo: 53 us | 8-echo CPMG: 56 us
Dans cette série de mesures, les échos supplémentaires n'ont pratiquement pas modifié le résultat : la médiane obtenue avec 8 échos (56 µs) est proche de celle obtenue avec un seul écho (53 µs), et toutes deux restent bien en deçà de la médiane rapportée (142 µs). Le nombre d'échos à lui seul ne suffit pas à expliquer cet écart; d'autres différences méthodologiques entrent en ligne de compte, telles que les détails de la procédure d'étalonnage, la mesure de tous les qubits en parallèle plutôt qu'individuellement, etc.
La leçon à en tirer est qu'il faut considérer avec prudence les comparaisons entre les méthodes concernant l'erreur de type « » (et l'erreur de type « layered two-qubit »). Les valeurs actualisées constituent un instantané cohérent, obtenu dans des conditions proches d'une charge de travail réelle, ce qui les rend particulièrement adaptées à la comparaison entre différents qubits ou au suivi d'un dispositif au fil du temps. Un écart par rapport aux données d'étalonnage communiquées ne constitue toutefois pas automatiquement une preuve de dérive.
Étapes 1 à 4 regroupées en un seul appel
Dans le cadre d'une utilisation quotidienne, on a rarement besoin des résultats intermédiaires. Cette méthode run_and_update regroupe toutes les opérations que vous avez effectuées ci-dessus (compilation, envoi, ajustement et mise à jour) en un seul appel qui renvoie le backend actualisé. Elle accepte la même experiments liste (et transmet des options telles que t2_num_echoes), et peut également être placée dans un Session contexte Batch ou.
La cellule suivante ne renvoie pas de résultat tant que toutes les tâches et le post-traitement ne sont pas terminés.
# Initialize a fresh characterizer
characterizer = BackendCharacterization(backend)
# Run all of the experiments and update the backend in a single call
backend_updated = characterizer.run_and_update(experiments=experiments)Output:
Building readout experiments
Building 1Q RB experiments
Building 2Q RB experiments
Building T1 experiments
Building T2 experiments
Layered two-qubit RB submitted: ['d9b7oqnu62qs738otat0', 'd9b7p76g26ic73dfjolg', 'd9b7pnm6hjac73ffb57g', 'd9b7q4fu62qs738otce0']
Readout job submitted: d9b7q4mg26ic73dfjprg
T1 experiment submitted: ['d9b7q57u62qs738otcfg']
T2 (Hahn) experiment submitted: ['d9b7q5m6hjac73ffb5pg']
Single-qubit RB submitted: ['d9b7r4e6hjac73ffb71g', 'd9b7reu6hjac73ffb7d0']
Updating readout error
Updating single-qubit X error
Updating single-qubit SX error
Updating two-qubit error
Updating T1
Updating T2
L'objet backend_updated mis à jour est désormais prêt à être utilisé partout où les propriétés du backend alimentent votre flux de travail. Essayez cette méthode en complément du tutoriel « Benchmarking en temps réel pour la sélection des qubits » afin de choisir les qubits les plus performants lors de la transpilation d'un circuit. Comme l'appareil ne cesse de dériver, actualisez ses propriétés peu avant l'exécution effective de votre charge de travail.
Etapes suivantes
Si ce travail vous a paru intéressant, les documents suivants pourraient vous intéresser :
- Utilisez les propriétés actualisées pour sélectionner de meilleurs qubits dans le tutoriel « Évaluation en temps réel de la sélection des qubits ».
- Découvrez comment les données d'étalonnage déclarées sont présentées dans le guide d'information sur la QPU
- Découvrez les différentes expériences de caractérisation dans la documentation « Qiskit Experiments »
- Découvrez d'autres tests de performance au niveau des appareils dans le référentiel « Qiskit Device Benchmarking »