Actualizar las propiedades del backend con pruebas comparativas en tiempo real
Tiempo estimado de uso: 3 minutos en ibm_kingston (NOTA: Se trata únicamente de una estimación. (El tiempo de ejecución puede variar.)
Resultados del aprendizaje
- Por qué las propiedades que indica una QPU pueden no reflejar el comportamiento actual del dispositivo, y cuándo conviene volver a medirlas por tu cuenta
- Lo que mide cada uno de los cinco experimentos de caracterización estándar (lectura, pruebas comparativas aleatorias de un solo qubit, pruebas comparativas aleatorias en capas de dos qubits, y )
- Cómo ejecutar el conjunto completo de caracterización en una sola llamada o paso a paso, y obtener como resultado un objeto backend con propiedades actualizadas
- Cómo comparar las propiedades medidas con las declaradas, y por qué algunas diferencias se deben a la metodología de medición y no a la deriva del dispositivo
Requisitos previos
- El flujo de trabajo de Qiskit Patterns
- Qiskit Runtime modos de ejecución, en particular el modo por lotes
- Cómo consultar la información de la QPU, como las propiedades del backend y los datos de calibración
En segundo plano
Cada QPU de IBM Quantum® proporciona un conjunto de propiedades que describen el rendimiento actual de cada uno de sus qubits: tiempos de relajación ( ), tiempos de coherencia ( ), errores de lectura y errores en las puertas de uno y dos qubits. Estas cifras son importantes en la práctica. El transpilador los utiliza para decidir en qué qubits físicos debe ejecutarse tu circuito; las técnicas de mitigación de errores se basan en ellos, y tú mismo puedes utilizarlos para evaluar si un dispositivo funciona lo suficientemente bien como para un experimento.
Las propiedades registradas proceden de procedimientos de calibración que suelen realizarse aproximadamente una vez al día. Sin embargo, los qubits superconductores pueden sufrir desviaciones en escalas de tiempo más cortas, y los defectos transitorios (los denominados «sistemas de dos niveles») pueden degradar temporalmente un qubit que parecía estar en perfectas condiciones en el momento de la calibración. Además, a menudo un trabajo se compila en tiempo de ejecución mucho antes de que se ejecute realmente, por lo que las decisiones basadas en las propiedades indicadas pueden basarse en información obsoleta. El tutorial «Pruebas de rendimiento en tiempo real para la selección de qubits» muestra hasta qué punto estas propiedades pueden variar de un día para otro y describe cómo crear manualmente un flujo de trabajo completo de caracterización a partir de experimentos individuales de Qiskit.
Este tutorial muestra la versión optimizada de ese flujo de trabajo, utilizando la utilidad BackendCharacterization de Qiskit Device Benchmarking, que agrupa la creación del experimento, el envío del trabajo y el ajuste de curvas en unas pocas llamadas. Se emplean aproximadamente 70 segundos de tiempo de la QPU y se obtiene un objeto de backend cuyas propiedades reflejan el estado actual del dispositivo, listo para ser comparado con los valores comunicados o para ser transferido a herramientas posteriores.
Los experimentos de caracterización
El paquete incluye cinco propiedades, cada una con un experimento estándar:
- Error de lectura (
readout): Cada qubit se prepara en o y se mide inmediatamente. La probabilidad de obtener un resultado erróneo al leer el estado da lugar al error de preparación y medición del estado (SPAM). - Error de puerta de un solo qubit (
rb_1q): El benchmarking aleatorio (RB) ejecuta secuencias de puertas de Clifford aleatorias de un solo qubit que, en teoría, se combinan para dar como resultado la identidad. La forma en que la probabilidad de supervivencia disminuye con la longitud de la secuencia da como resultado el error medio por puerta, independientemente de los errores SPAM. - Error de puerta de dos qubits (
rb_2q): La misma idea de RB aplicada a capas completas de puertas de dos qubits no superpuestas ejecutadas simultáneamente, como en un experimento de fidelidad de capa. Dado que muchas puertas lógicas funcionan a la vez, las tasas de error resultantes incluyen efectos de diafonía y se acercan más a lo que experimenta realmente un circuito profundo. - (
t1): Cada qubit se excita y se mide tras unos retrasos cada vez mayores. El decaimiento de la población en estado excitado determina el tiempo de relajación. - (
t2): En un experimento de eco de Hahn, se coloca cada qubit en una superposición, se aplica un pulso de eco a mitad del retardo y se mide la rapidez con la que se pierde la coherencia de fase. Por defecto se utiliza un único eco; al final de este tutorial se muestra una variante con múltiples ecos (al estilo CPMG).
Lo que hace y lo que no hace la actualización
Ten en cuenta tres puntos al utilizar este flujo de trabajo:
- Las propiedades actualizadas solo se encuentran en el objeto de backend que se te devuelve. No se produce ningún cambio en el propio dispositivo ni en los datos de calibración que IBM Quantum comunica a otros usuarios.
- Los valores medidos constituyen una instantánea obtenida mediante una metodología concreta. Algunos de ellos, en particular los errores de dos qubits en capas y los valores de « » de eco único en paralelo, se miden de forma diferente a los datos de calibración publicados, por lo que parte de cualquier discrepancia que se observe se debe a cuestiones metodológicas y no a la deriva. Este tutorial explica dónde ocurre eso.
- La propia caracterización consume tiempo de la QPU (unos 70 segundos para el conjunto completo de pruebas en un procesador Heron r2 ), lo cual es el precio que hay que pagar por disponer de información actualizada.
El flujo de trabajo sigue los cuatro pasos de un patrón de Qiskit:
- Paso 1: Asignar las entradas clásicas a un problema cuántico. Elige el dispositivo y el conjunto de propiedades que deseas medir.
- Paso 2: Optimizar el problema para su ejecución en hardware cuántico. La utilidad crea los circuitos experimentales directamente en las puertas lógicas nativas del dispositivo y los paraleliza a lo largo del chip.
- Paso 3: Ejecuta el comando « Qiskit primitives ». Los experimentos se ejecutan como tareas de Sampler dentro de un lote.
- Paso 4: Realizar el posprocesamiento y obtener el resultado en el formato clásico deseado. Introduce los datos de medición en los mapas de errores por qubit, actualiza el backend y compara las propiedades medidas con las comunicadas.
Requisitos
Antes de empezar este tutorial, asegúrate de tener instalado lo siguiente:
- Qiskit SDK v2.0 o posterior, con soporte para visualización
- Qiskit Runtime v0.40 o posterior (
pip install qiskit-ibm-runtime) - Pruebas de rendimiento de dispositivos con Qiskit, que también instala Qiskit Experiments (
pip install git+https://github.com/qiskit-community/qiskit-device-benchmarking.git)
Configuración
Importa las bibliotecas necesarias.
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,
)El conjunto de herramientas de caracterización genera varios experimentos, envía múltiples trabajos y ajusta los resultados, lo que puede llevar un par de minutos en total. Activa el registro de nivel INFO para que cada etapa muestre su progreso a medida que avanza.
logger = logging.getLogger("qiskit_device_benchmarking")
logger.setLevel(logging.INFO)
logger.addHandler(logging.StreamHandler(stream=sys.stdout))Ejemplo de simulador a pequeña escala
Este tutorial no incluye ningún ejemplo de simulador. El flujo de trabajo mide las imperfecciones físicas de un dispositivo concreto: la rapidez con la que sus qubits se relajan y pierden fase, y la frecuencia con la que fallan sus puertas y su lectura. Un simulador ideal no presenta ninguna de estas imperfecciones, por lo que no hay nada que caracterizar. Podrías asociar un modelo de ruido sintético a un backend falso, pero, en ese caso, los experimentos solo recuperarían los números que tú mismo introdujeras. Por ese motivo, pasamos directamente al hardware, dividido en los cuatro pasos de un patrón de Qiskit.
Ejemplo de hardware a gran escala
Paso 1: Asignar entradas clásicas a un problema cuántico
En este flujo de trabajo, el «problema» es el propio dispositivo: las entradas clásicas son la QPU que se desea caracterizar y la lista de propiedades que hay que medir, y los experimentos cuánticos son los circuitos de caracterización generados a partir de ellas.
En primer lugar, selecciona un backend. ibm_kingstonEn este tutorial se utiliza un procesador Heron de 156 qubits r2; puedes sustituirlo por cualquier dispositivo IBM Quantum al que tengas acceso (o elegir uno con service.least_busy()).
service = QiskitRuntimeService()
device = "ibm_kingston"
backend = service.backend(device)A continuación, elige qué propiedades quieres medir. Puedes superar cualquier subconjunto de los siguientes experimentos:
readout: Experimento SPAM (preparación y medición de estados)rb_1q: pruebas comparativas aleatorias con un solo qubit aisladorb_2q: evaluación comparativa aleatoria simultánea de dos qubits a partir de un experimento de fidelidad por capast2: Experimento de eco de Hahn (un único eco por defecto)t1: Experimento de relajación « »
Ejecuta el conjunto completo de pruebas para obtener una visión general del dispositivo; elimina entradas de la lista si solo te interesan algunas propiedades y quieres ahorrar tiempo de la QPU.
experiments = ["readout", "rb_1q", "rb_2q", "t1", "t2"]Paso 2: Optimizar el problema para su ejecución en hardware cuántico
En la mayoría de los tutoriales, aquí es donde se compilarían los circuitos. Aquí, BackendCharacterization se encarga de eso internamente. Crea los circuitos experimentales directamente en las puertas nativas del dispositivo, ejecuta los experimentos de un solo qubit en todos los qubits en paralelo y programa las pruebas comparativas de dos qubits en capas disjuntas del mapa de acoplamiento, de modo que todo el dispositivo quede cubierto con tan solo unas pocas tareas. Gracias a esta paralelización, el conjunto completo de pruebas solo consume unos 70 segundos de tiempo de la QPU.
Inicializa la clase que gestiona el flujo de trabajo:
# Initialize the class used to run the experiments
characterizer = BackendCharacterization(backend)Paso 3: Ejecutar con el comando « Qiskit primitives »
El método run_experiments crea los circuitos y los envía como trabajos de Sampler. Ejecútalo dentro de un contexto Batch para que los trabajos se programen conjuntamente en la QPU y el método devuelva un resultado una vez que se hayan enviado todos los trabajos. (También puedes ejecutarlo fuera de un archivo por lotes o dentro de uno Session.)
Es posible que aparezca una advertencia indicando que se ha pasado un backend mientras hay un gestor de contexto de sesión abierto. Esto es normal y se puede ignorar sin problema.
# 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']
El método devuelve los trabajos enviados en forma de diccionario con el experimento como clave, lo cual resulta útil para realizar un seguimiento de los mismos en el panel de control de IBM Quantum Platform o para la depuración.
# 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')>]}
Paso 4: Realizar el posprocesamiento y obtener el resultado en el formato clásico deseado
Analizar los resultados
El método analyze_results espera a que finalicen los trabajos y ajusta los datos de medición: decaimientos exponenciales para y , decaimientos de probabilidad de supervivencia para los experimentos RB y matrices de asignación para la lectura de resultados. Devuelve un diccionario de mapas de errores, con una entrada por cada propiedad medida, en el que cada mapa asocia un qubit (o un par de qubits) a su valor medido.
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
Los mapas recogen el error de lectura, los errores de los qubits individuales y x de las puertas sx , los errores de dos qubits en capas (lf_error_map, procedentes del experimento de fidelidad por capas), así como los tiempos de « » y « » en segundos.
Actualizar las propiedades del backend
El método update_backend escribe los valores medidos en las propiedades de una copia del backend y la devuelve. El objeto backend original conserva los datos de calibración registrados, lo que nos permite comparar ambos, tal y como se muestra a continuación. Recuerda que esta actualización es exclusivamente local para tu sesión de Python; no modifica nada en el dispositivo ni afecta a otros usuarios.
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
Compara las propiedades medidas con las indicadas
Por último, representa gráficamente las propiedades medidas en tiempo real en función de los valores que proporciona el backend. En cada panel, los qubits (o pares de qubits) se ordenan según el valor medido, por lo que la curva de medición es suave por su propia naturaleza y la dispersión de los valores registrados a su alrededor muestra en qué puntos difieren ambos. Se muestra un único gráfico para el RB de un solo qubit, ya que se asigna el mismo error medido por puerta tanto a las puertas sx como x a las. Los límites de los ejes se eligen a partir del conjunto de datos, de modo que unos pocos valores atípicos extremos no compriman los gráficos; los puntos que se encuentren fuera de ese rango se indican en una anotación en el gráfico (o se puede pasar un parámetro ylim para anular los límites).
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:
Estos gráficos deben interpretarse con cuidado, ya que no todas las diferencias entre las dos curvas significan que el dispositivo se haya desviado:
- Errores de lectura y de un solo qubit : los valores medidos coinciden con los comunicados en la mayoría de los qubits, mientras que el valor comunicado para unos pocos qubits se aleja considerablemente de la curva de los valores medidos. Esas discrepancias puntuales son precisamente lo que este flujo de trabajo está diseñado para detectar.
- : Los dos conjuntos de datos se distribuyen entre sí sin ningún desplazamiento sistemático, lo que concuerda con el hecho de que fluctúe de forma natural a lo largo del tiempo.
- Errores de dos qubits : los valores medidos se sitúan sistemáticamente por encima de los comunicados. Esto es de esperar, ya que los valores comunicados se miden en puertas aisladas, mientras que el experimento de fidelidad de capa analiza muchas puertas simultáneamente y, por lo tanto, incluye la diafonía. Las cifras por capas son más relevantes para los circuitos profundos, pero no son directamente comparables con los datos de calibración publicados.
- : Los valores medidos se sitúan muy por debajo de los comunicados para la mayoría de los qubits. Una vez más, la metodología desempeña un papel importante, tal y como se analiza en la siguiente sección.
Revisar los resultados de cada experimento
También puedes consultar los resultados sin procesar de los experimentos de caracterización individuales a través de la propiedad experiment_data , que devuelve los objetos ExperimentData «Qiskit Experiments» subyacentes. Por ejemplo, a continuación se muestra la curva de decaimiento medida de « » de un solo qubit, lo cual resulta útil para comprobar la calidad de un ajuste antes de dar por válida la cifra obtenida.
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
Medida « T2 » con una cadena de desacoplamiento dinámico
Por defecto, el experimento « » aplica un único eco de Hahn y mide todos los qubits en paralelo, lo que, como muestra el gráfico comparativo anterior, puede dar lugar a valores de « » notablemente inferiores a los que indica el backend. Una hipótesis se refiere al número de ecos: los valores registrados podrían estar calibrados mediante desacoplamiento dinámico, lo que suprime el ruido de baja frecuencia. Para comprobarlo, ejecuta una caracterización « » con el parámetro establecido t2_num_echoes en un valor mayor, lo que aplica una secuencia de pulsos de eco al estilo CPMG. Los retrasos representan el tiempo total de evolución libre en ambos casos, por lo que los valores ajustados de « » son directamente comparables con los resultados de un solo eco.
# 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
En esta ejecución, los ecos adicionales apenas modificaron el resultado: la mediana de los 8 ecos (56 µs) es similar a la del eco único (53 µs), y ambas se sitúan muy por debajo de la mediana publicada (142 µs). El número de ecos por sí solo no explica esta diferencia; también influyen otras diferencias metodológicas, como los detalles del procedimiento de calibración, la medición de todos los qubits en paralelo en lugar de de forma aislada, etc.
La lección práctica es que hay que tratar con cautela las comparaciones de « » (y de errores de dos qubits en capas) entre distintas metodologías. Los valores actualizados constituyen una instantánea coherente obtenida en condiciones similares a las de una carga de trabajo real, lo que los hace idóneos para comparar qubits entre sí o realizar un seguimiento de un dispositivo a lo largo del tiempo. Sin embargo, una discrepancia con respecto a los datos de calibración comunicados no es, por sí sola, indicio de deriva.
Pasos 1 a 4 agrupados en una sola llamada
En el día a día, rara vez se necesitan los resultados intermedios. El método run_and_update encadena todos los pasos que has realizado anteriormente (compilación, envío, ajuste y actualización) en una única llamada que devuelve el backend actualizado. Acepta la misma experiments lista (y reenvía opciones como t2_num_echoes), y también puede integrarse en un Session contexto Batch o.
La siguiente celda no finaliza hasta que se hayan completado todos los trabajos y el posprocesamiento.
# 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
El objeto backend_updated actualizado ya está listo para utilizarse en cualquier punto del flujo de trabajo en el que se incorporen propiedades del backend. Prueba este proceso junto con el tutorial «Comparativa en tiempo real para la selección de qubits» para elegir los qubits con mejor rendimiento al transpilar un circuito. Dado que el dispositivo sigue desviándose, actualiza las propiedades poco antes de ejecutar realmente tu carga de trabajo.
Próximos pasos
Si este trabajo te ha parecido interesante, quizá te interese el siguiente material:
- Utiliza las propiedades actualizadas para seleccionar mejores qubits en el tutorial «Comparativa en tiempo real para la selección de qubits».
- Descubre cómo se presentan los datos de calibración facilitados en la guía informativa de la QPU
- Explora los experimentos de caracterización individuales en la documentación de «Qiskit Experiments»
- Consulta más pruebas de rendimiento a nivel de dispositivo en el repositorio «Qiskit Device Benchmarking».