Skip to main content
IBM Quantum Platform

Aggiornamento delle proprietà del backend con analisi comparativa in tempo reale

Stima della durata: 3 minuti su ibm_kingston (NOTA: si tratta solo di una stima. (La durata potrebbe variare.)


Risultati di apprendimento

  • Perché le proprietà riportate da una QPU possono non essere aggiornate rispetto al comportamento attuale del dispositivo, e quando conviene ricalcolarle autonomamente
  • Cosa misura ciascuno dei cinque esperimenti standard di caratterizzazione (readout, benchmarking randomizzato su singolo qubit, benchmarking randomizzato a due qubit stratificato, “ T1T_1 ” e “ T2T_2 ”)
  • Come eseguire la suite completa di caratterizzazione in un'unica chiamata o passo dopo passo e ottenere un oggetto backend con proprietà aggiornate
  • Come confrontare le proprietà misurate con quelle riportate, e perché alcune differenze sono dovute alla metodologia di misurazione piuttosto che alla deriva del dispositivo

Prerequisiti


Sfondo

Ogni QPU IBM Quantum® riporta una serie di proprietà che descrivono il livello di funzionamento attuale di ciascuno dei suoi qubit: tempi di rilassamento ( T1T_1 ), tempi di coerenza ( T2T_2 ), errori di lettura ed errori relativi ai gate a uno e a due qubit. Questi numeri contano nella pratica. Il transpiler li utilizza per decidere su quali qubit fisici debba funzionare il circuito; le tecniche di mitigazione degli errori si basano su di essi e potresti usarli per valutare se un dispositivo funziona abbastanza bene da poter essere utilizzato per un esperimento.

I valori riportati derivano da procedure di calibrazione che vengono eseguite in genere una volta al giorno. I qubit superconduttori, tuttavia, possono subire derive su scale temporali più brevi, e i difetti transitori (i cosiddetti sistemi a due livelli) possono degradare temporaneamente un qubit che al momento della calibrazione appariva in condizioni eccellenti. Inoltre, spesso un’operazione viene transpila ben prima della sua effettiva esecuzione, quindi le decisioni basate sulle proprietà riportate potrebbero fondarsi su informazioni non aggiornate. Il tutorial “Benchmarking in tempo reale per la selezione dei qubit” mostra quanto queste proprietà possano variare di giorno in giorno e illustra come costruire manualmente un flusso di lavoro completo di caratterizzazione a partire dai singoli esperimenti di Qiskit.

Questo tutorial illustra la versione semplificata di tale flusso di lavoro, utilizzando l'utilità BackendCharacterization di Qiskit Device Benchmarking, che riunisce la creazione dell'esperimento, l'invio del lavoro e l'adattamento della curva in poche chiamate. Si impiegano circa 70 secondi di tempo QPU e si ottiene un oggetto backend le cui proprietà rispecchiano lo stato attuale del dispositivo, pronto per essere confrontato con i valori riportati o trasmesso agli strumenti a valle.

Gli esperimenti di caratterizzazione

La suite comprende cinque proprietà, ciascuna con un esperimento standard:

  • Errore di lettura (readout): Ogni qubit viene preparato in uno stato di tipo “ ∣0⟩|0\rangle ” o “ ∣1⟩|1\rangle ” e misurato immediatamente. La probabilità di rilevare uno stato errato determina l'errore di preparazione e misurazione dello stato (SPAM).
  • Errore di gate su un singolo qubit (rb_1q): Il benchmarking randomizzato (RB) esegue sequenze di gate di Clifford casuali su un singolo qubit che, idealmente, si combinano per formare il gate identità. Il modo in cui la probabilità di sopravvivenza diminuisce al crescere della lunghezza della sequenza determina l’errore medio per gate, indipendentemente dagli errori SPAM.
  • Errore di gate a due qubit (rb_2q): lo stesso concetto di RB applicato a livelli completi di gate a due qubit non sovrapposti eseguiti simultaneamente, come in un esperimento sulla fedeltà dei livelli. Poiché molti gate funzionano contemporaneamente, i tassi di errore che ne derivano includono effetti di diafonia e sono più vicini a quelli che si verificano effettivamente in un circuito profondo.
  • T1T_1 (t1): Ogni qubit viene eccitato e misurato dopo ritardi crescenti. Il decadimento della popolazione dello stato eccitato determina il tempo di rilassamento.
  • T2T_2 (t2): In un esperimento di eco di Hahn, ogni qubit viene posto in una sovrapposizione, viene applicato un impulso di eco a metà del ritardo e viene misurata la velocità con cui si perde la coerenza di fase. Per impostazione predefinita viene utilizzato un singolo eco; alla fine di questo tutorial viene illustrata una variante con eco multiplo (in stile CPMG).

Cosa fa e cosa non fa il refresh

Quando si utilizza questo flusso di lavoro, è bene tenere a mente tre punti:

  • Le proprietà aggiornate sono presenti solo nell'oggetto backend che ti viene restituito. Non cambia nulla sul dispositivo stesso né nei dati di calibrazione che IBM Quantum comunica agli altri utenti.
  • I valori misurati rappresentano un’istantanea ottenuta con una metodologia specifica. Alcuni di essi, in particolare gli errori a due qubit stratificati e i valori di " T2T_2 " a eco singolo parallelo, vengono misurati in modo diverso rispetto ai dati di calibrazione riportati; pertanto, parte dello scostamento osservato è di natura metodologica piuttosto che dovuto alla deriva. Questo tutorial spiega dove ciò avviene.
  • La caratterizzazione stessa richiede tempo di elaborazione della QPU (circa 70 secondi per la suite completa su un processore Heron r2 ), il che rappresenta il prezzo da pagare per disporre di informazioni aggiornate.

Il flusso di lavoro segue le quattro fasi di un modello Qiskit:

  • Fase 1: Mappare gli input classici su un problema quantistico. Scegli il dispositivo e l'insieme di proprietà da misurare.
  • Fase 2: Ottimizzare il problema per l'esecuzione su hardware quantistico. L'utilità realizza i circuiti sperimentali direttamente nei gate nativi del dispositivo e li parallelizza su tutto il chip.
  • Passaggio 3: Eseguire il comando utilizzando " Qiskit primitives ". Gli esperimenti vengono eseguiti come processi Sampler all’interno di un batch.
  • Fase 4: Eseguire la post-elaborazione e restituire il risultato nel formato classico desiderato. Inserire i dati di misura nelle mappe di errore per singolo qubit, aggiornare il backend e confrontare le proprietà misurate con quelle riportate.

Requisiti

Prima di iniziare questo tutorial, assicurati di avere installato quanto segue:

  • Qiskit SDK v2.0 o versioni successive, con supporto alla visualizzazione
  • Qiskit Runtime v0.40 o versioni successive (pip install qiskit-ibm-runtime)
  • Qiskit Device Benchmarking, che installa anche Qiskit Experiments (pip install git+https://github.com/qiskit-community/qiskit-device-benchmarking.git)

Configura

Importa le librerie necessarie.

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 di caratterizzazione avvia diversi esperimenti, invia più lavori ed elabora i risultati; l’operazione può richiedere in totale un paio di minuti. Abilita la registrazione a livello INFO in modo che ogni fase visualizzi lo stato di avanzamento man mano che procede.

logger = logging.getLogger("qiskit_device_benchmarking")
logger.setLevel(logging.INFO)
logger.addHandler(logging.StreamHandler(stream=sys.stdout))

Esempio di simulatore su piccola scala

Questo tutorial non include un esempio di simulazione. Il flusso di lavoro misura le imperfezioni fisiche di un dispositivo specifico: la velocità con cui i suoi qubit si rilassano e subiscono una defasatura, nonché la frequenza con cui i suoi gate e le operazioni di lettura falliscono. Un simulatore ideale non presenta nessuna di queste imperfezioni, quindi non c'è nulla da caratterizzare. Si potrebbe associare un modello di rumore sintetico a un backend fittizio, ma in tal caso gli esperimenti riproducerebbero solo i numeri inseriti dall'utente stesso. Per questo motivo, passiamo direttamente all’hardware, suddividendo il processo nei quattro passaggi tipici di un modello Qiskit.


Esempio di hardware su larga scala

Fase 1: Mappare gli input classici su un problema quantistico

In questo flusso di lavoro il "problema" è il dispositivo stesso: gli input classici sono la QPU che si desidera caratterizzare e l'elenco delle proprietà da misurare, mentre gli esperimenti quantistici sono i circuiti di caratterizzazione generati a partire da essi.

Per prima cosa, seleziona un backend. Questo tutorial utilizza un processore Heron r2 da 156 qubit ibm_kingston; è possibile sostituirlo con qualsiasi dispositivo IBM Quantum a cui si abbia accesso (oppure sceglierne uno con service.least_busy()).

service = QiskitRuntimeService()
device = "ibm_kingston"
backend = service.backend(device)

Successivamente, scegli quali proprietà misurare. È possibile superare qualsiasi sottoinsieme dei seguenti esperimenti:

  • readout: Esperimento SPAM (preparazione e misurazione dello stato)
  • rb_1q: benchmarking randomizzato su un singolo qubit isolato
  • rb_2q: benchmarking randomizzato simultaneo su due qubit derivante da un esperimento sulla fedeltà a livello di strato
  • t2: T2T_2 Esperimento di eco di Hahn (un singolo eco per impostazione predefinita)
  • t1: Esperimento di rilassamento “ T1T_1 ”

Esegui la suite completa per ottenere un quadro completo del dispositivo; elimina le voci dall'elenco se ti interessano solo alcune proprietà e vuoi risparmiare tempo di elaborazione della QPU.

experiments = ["readout", "rb_1q", "rb_2q", "t1", "t2"]

Fase 2: Ottimizzare il problema per l'esecuzione su hardware quantistico

Nella maggior parte dei tutorial, è proprio a questo punto che si procederebbe alla transpilazione dei circuiti. In questo caso, BackendCharacterization se ne occupa internamente. Costruisce i circuiti sperimentali direttamente nei gate nativi del dispositivo, esegue gli esperimenti su singolo qubit su tutti i qubit in parallelo e pianifica i test di benchmarking a due qubit su livelli disgiunti della mappa di accoppiamento, in modo che l’intero dispositivo venga coperto con una manciata di processi. Grazie a questa parallelizzazione, l'intera suite richiede solo circa 70 secondi di tempo di elaborazione della QPU.

Inizializza la classe che gestisce il flusso di lavoro:

# Initialize the class used to run the experiments
characterizer = BackendCharacterization(backend)

Passaggio 3: Eseguire il comando utilizzando Qiskit primitives

Il metodo run_experiments crea i circuiti e li invia come processi Sampler. Eseguirlo all’interno di un contesto Batch in modo che i lavori vengano pianificati insieme sulla QPU e che il metodo restituisca un risultato solo dopo che tutti i lavori sono stati inviati. (È anche possibile eseguirlo al di fuori di un batch o all'interno di un Session.)

Note

Potresti visualizzare un avviso relativo al passaggio di un backend mentre è aperto un gestore del contesto di sessione. Si tratta di un fenomeno previsto e può essere tranquillamente ignorato.

# 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']

Il metodo restituisce i lavori inviati sotto forma di dizionario con chiave "esperimento", utile per monitorarli sulla dashboard di IBM Quantum Platform o per il debug.

# Print all the job IDs for debugging purposes
jobs

Output:

{'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')>]}

Fase 4: Elaborazione successiva e restituzione del risultato nel formato classico desiderato

Analizzare i risultati

Il metodo analyze_results attende il completamento dei lavori e effettua l'adattamento dei dati di misurazione: decadimenti esponenziali per T1T_1 e T2T_2, decadimenti della probabilità di sopravvivenza per gli esperimenti RB e matrici di assegnazione per la lettura dei risultati. Restituisce un dizionario di mappe di errore, con una voce per ogni proprietà misurata, ciascuna delle quali associa un qubit (o una coppia di qubit) al relativo valore misurato.

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

Le mappe riportano l’errore di lettura, gli errori relativi al singolo qubit e x ai gate sx , gli errori a due qubit stratificati (lf_error_mapderivati dall’esperimento sulla fedeltà a livelli) e i tempi di T1T_1 e e di T2T_2 e espressi in secondi.

Aggiorna le proprietà del backend

Il metodo update_backend scrive i valori misurati nelle proprietà di una copia del backend e la restituisce. L'oggetto backend originale conserva i dati di calibrazione riportati, in modo da poterli confrontare, come illustrato di seguito. Ricorda che questo aggiornamento riguarda esclusivamente la tua sessione su Python; non comporta alcuna modifica sul dispositivo né per gli altri utenti.

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

Confronta le proprietà misurate con quelle riportate

Infine, tracciare un grafico delle proprietà misurate in tempo reale rispetto ai valori riportati dal backend. In ogni pannello i qubit (o le coppie di qubit) sono ordinati in base al valore misurato, quindi la curva di misura risulta per definizione regolare e la dispersione dei valori riportati attorno ad essa evidenzia i punti in cui i due dati non coincidono. Per l'RB a singolo qubit viene mostrato un unico grafico, poiché lo stesso errore misurato per gate viene assegnato sia al gate che x al gate sx . I limiti degli assi vengono scelti in base alla maggior parte dei dati, in modo che pochi valori anomali estremi non comprimano i grafici; eventuali punti al di fuori dell'intervallo vengono indicati in un'annotazione sul grafico (oppure si può scegliere ylim di sovrascrivere i limiti).

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:

Output of the previous code cell Output of the previous code cell Output of the previous code cell Output of the previous code cell Output of the previous code cell

Questi grafici richiedono un'attenta lettura, poiché non tutti gli scostamenti tra le due curve indicano necessariamente una deriva del dispositivo:

  • Lettura e errori sui singoli qubit : i valori misurati corrispondono a quelli riportati per la maggior parte dei qubit, mentre il valore riportato per alcuni qubit si discosta notevolmente dalla curva dei valori misurati. Sono proprio queste discrepanze localizzate che questo flusso di lavoro è stato progettato per individuare.
  • T1T_1 : I due insiemi di dati presentano una distribuzione casuale l’uno rispetto all’altro, senza alcun scostamento sistematico, il che è coerente con il fatto che l’ T1T_1 e fluttui naturalmente nel tempo.
  • Errori a due qubit : i valori misurati risultano sistematicamente superiori a quelli riportati. Ciò è prevedibile, poiché i valori riportati sono stati misurati su gate isolati, mentre l'esperimento sulla fedeltà dello strato prevede il funzionamento simultaneo di molti gate e quindi include il crosstalk. I valori stratificati sono più rilevanti per i circuiti profondi, ma non sono direttamente comparabili ai dati di calibrazione riportati.
  • T2T_2 e: I valori misurati sono nettamente inferiori a quelli riportati per la maggior parte dei qubit. Anche in questo caso, la metodologia riveste un ruolo importante, come vedremo nella sezione successiva.

Esaminare i risultati dei singoli esperimenti

È inoltre possibile esaminare i risultati grezzi dei singoli esperimenti di caratterizzazione tramite la proprietà experiment_data , che restituisce gli oggetti ExperimentData Qiskit Experiments sottostanti. Ad esempio, il grafico seguente mostra la curva di decadimento misurata dell' T1T_1 e di un singolo qubit; ciò è utile per verificare la qualità di un adattamento prima di considerare attendibile il valore ottenuto.

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
Output of the previous code cell

Misura dell’ T2 e con una catena di disaccoppiamento dinamico

Per impostazione predefinita, l'esperimento " T2T_2 " applica un singolo eco di Hahn e misura tutti i qubit in parallelo; ciò, come ha mostrato il grafico di confronto riportato sopra, può portare a valori di " T2T_2 " notevolmente inferiori rispetto a quelli riportati dal backend. Un'ipotesi riguarda il numero di echi: i valori riportati potrebbero essere stati calibrati mediante disaccoppiamento dinamico, che sopprime il rumore a bassa frequenza. Per verificarlo, eseguire una caratterizzazione “ T2T_2 ” con il parametro impostato t2_num_echoes su un valore più elevato, in modo da applicare una sequenza di impulsi di eco in stile CPMG. I ritardi rappresentano il tempo totale di evoluzione libera in entrambi i casi, pertanto i valori di T2T_2 e ricavati sono direttamente comparabili ai risultati ottenuti con l’eco singolo.

# 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:

Output of the previous code cell
Median T2 — reported: 142 us | single echo: 53 us | 8-echo CPMG: 56 us

In questa esecuzione, gli echi aggiuntivi non hanno praticamente modificato il risultato: la mediana degli 8 echi (56 µs) è vicina a quella del singolo eco (53 µs) ed entrambe rimangono ben al di sotto della mediana riportata (142 µs). Il numero di echi da solo non spiega questo divario; entrano in gioco altre differenze metodologiche, quali i dettagli della procedura di calibrazione, la misurazione di tutti i qubit in parallelo anziché singolarmente, e così via.

La lezione pratica è quella di considerare con cautela i confronti relativi all’ T2T_2 e (e all’errore a due qubit a più livelli) tra le diverse metodologie. I valori aggiornati costituiscono un’istantanea coerente, ottenuta in condizioni simili a quelle di un carico di lavoro reale, il che li rende particolarmente adatti per confrontare i qubit tra loro o per monitorare l’andamento di un dispositivo nel tempo. Una discrepanza rispetto ai dati di calibrazione riportati, tuttavia, non costituisce automaticamente una prova di deriva.

I passaggi da 1 a 4 raggruppati in un'unica chiamata

Nell'uso quotidiano, i risultati intermedi servono raramente. Il metodo run_and_update raggruppa tutte le operazioni eseguite in precedenza (creazione, invio, adattamento e aggiornamento) in un'unica chiamata che restituisce il backend aggiornato. Accetta lo stesso experiments elenco (e inoltra opzioni come t2_num_echoes), e può anch’esso essere racchiuso in un contesto Session Batch o.

Note

La cella seguente non restituisce alcun risultato finché tutti i lavori e le operazioni di post-elaborazione non sono stati completati.

# 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'oggetto backend_updated aggiornato è ora pronto per essere utilizzato ovunque le proprietà del backend vengano integrate nel tuo flusso di lavoro. Prova questa procedura insieme al tutorial “Benchmarking in tempo reale per la selezione dei qubit” per scegliere i qubit più performanti durante la transpilazione di un circuito. Poiché il dispositivo continua a presentare una deriva, aggiorna le proprietà in prossimità del momento in cui esegui effettivamente il tuo carico di lavoro.


Passi successivi

Se questo lavoro ti è sembrato interessante, potrebbero interessarti i seguenti materiali:

Suggerimenti
Questa pagina è stata utile?
Segnala un bug, un errore di battitura o richiedi contenuti su GitHub.