Skip to main content
IBM Quantum Platform

リアルタイムのベンチマークによるバックエンドプロパティの更新

推定所要時間:ibm_kingston で 3 分(注:これはあくまで目安です。 (実行時間は環境によって異なる場合があります。)


学習成果

  • QPUが報告するプロパティが、デバイスの現在の動作より遅れることがある理由、および自分で再測定する価値がある場合について
  • 5つの標準的な特性評価実験(リードアウト、単一量子ビットランダム化ベンチマーク、階層型2量子ビットランダム化ベンチマーク、 T1T_1、および T2T_2 )のそれぞれが測定する内容
  • 1回の呼び出しで、あるいは段階的に、完全な特性評価スイートを実行し、プロパティが更新されたバックエンドオブジェクトを取得する方法
  • 測定された特性と報告された特性をどのように比較すべきか、また、なぜ一部の差異はデバイスのドリフトではなく測定方法に起因するものなのか

前提条件


背景

すべての IBM Quantum® QPUは、各量子ビットが現在どの程度正常に動作しているかを示す一連のプロパティを報告します。具体的には、リラクゼーション時間( T1T_1 )、コヒーレンス時間( T2T_2 )、読み出しエラー、および1量子ビットゲートおよび2量子ビットゲートのエラーです。 実務上、これらの数値は重要です。 トランスパイラーは、これらを用いて回路をどの物理キュービット上で実行すべきかを決定し、エラー軽減手法もこれらに依存しています。また、実験を行う上でデバイスが十分に正常に動作しているかどうかを判断する際にも、これらを活用できるでしょう。

報告されている特性値は、通常1日に1回程度実施される校正手順に基づいています。 しかし、超伝導量子ビットはより短い時間スケールでドリフトを起こす可能性があり、一過性の欠陥(いわゆる2準位系)によって、キャリブレーション時には良好に見えた量子ビットが一時的に性能を低下させることがある。 さらに、ジョブは実際に実行されるかなり前にトランスパイルされることが多いため、報告されたプロパティに基づいて下された判断は、古い情報に基づいている可能性があります。 チュートリアル「 量子ビット選択のリアルタイムベンチマーク 」では、これらの特性が日によってどれほど変動するかを示し、個々の Qiskit実験から手作業で完全な特性評価ワークフローを構築します。

このチュートリアルでは、 Qiskit Device Benchmarking の BackendCharacterization ユーティリティを使用して、そのワークフローを効率化したバージョンを紹介します。このユーティリティを使えば、実験の構築、ジョブの送信、曲線フィッティングをわずか数回の呼び出しにまとめることができます。 QPU時間を約70秒消費すると、 その時点のデバイスの状態を反映したプロパティを持つバックエンドオブジェクトが返されます。このオブジェクトは、報告された値と比較したり、下流のツールに渡したりする準備ができています。

特性評価実験

このスイートには5つのプロパティが含まれており、それぞれに標準的な実験が設定されています:

  • 読み出しエラー (readout): 各量子ビットは、 ∣0⟩|0\rangle または ∣1⟩|1\rangle の状態で準備され、直ちに測定される。 誤った状態を読み取る確率から、状態準備・測定(SPAM)誤差が導かれる。
  • 単一量子ビットゲートエラー (rb_1q): ランダム化ベンチマーク (RB) では、理想的には恒等ゲートに合成されるような、ランダムな単一量子ビットクリフォードゲートのシーケンスを実行する。 生存確率がシーケンス長に応じて減少する様子から、SPAMエラーとは無関係なゲートあたりの平均誤差が導き出される。
  • 2量子ビットゲート誤差 (rb_2q): レイヤー 忠実度実験と同様に、同時に実行される、重なり合わない2量子ビットゲートで構成される完全なレイヤーに、同じRBの考え方を適用したものである。 多くのゲートが同時に動作するため、その結果として生じるエラー率にはクロストークの影響が含まれており、実際の深層回路で発生するエラー率により近い値となります。
  • T1T_1 (t1): 各量子ビットは、遅延時間を徐々に長くしながら励起され、測定される。 励起状態の占有数の減衰によって、緩和時間が決まる。
  • T2T_2 (t2): ハーンエコー実験では、各量子ビットを重ね合わせ状態に置き、遅延時間の半分が経過した時点でエコーパルスを印加し、位相コヒーレンスが失われる速度を測定する。 デフォルトではシングルエコーが使用されます。マルチエコー(CPMGスタイル)のバリエーションについては、このチュートリアルの最後に紹介しています。

「リフレッシュ」でできること、できないこと

このワークフローを使用する際は、次の3つの点に留意してください:

  • 更新されたプロパティは、返されるバックエンドオブジェクト内にのみ存在します。 デバイス自体や、 IBM Quantum が他のユーザーに報告するキャリブレーションデータには、何の変更もありません。
  • 測定値は、特定の手法を用いて取得されたその時点の状況を示すものです。 特に、階層的な2量子ビットエラーや並列シングルエコーの T2T_2 値など、一部の項目については、報告されている校正データとは測定方法が異なるため、観測される差異の一部はドリフトではなく、測定方法に起因するものです。 このチュートリアルでは、それがどこで発生するかを説明しています。
  • 特性評価そのものにQPUの処理時間(Heronの r2 プロセッサで全テストスイートを実行する場合、約70秒)がかかりますが、これは最新の情報を入手するための代償と言えます。

このワークフローは、Qiskitのパターンにおける4つのステップに従っています:

  • ステップ1:古典的な入力を量子問題に写像する。 測定対象のデバイスと、測定するプロパティのセットを選択してください。
  • ステップ2:量子ハードウェアでの実行に向けて問題を最適化する。 このユーティリティは、デバイスのネイティブゲート上に実験用回路を直接構築し、チップ全体でそれらを並列化します。
  • ステップ 3: Qiskit primitives を使用して実行します。 実験は、バッチ内のサンプラージョブとして実行されます。
  • ステップ4:後処理を行い、結果を所望の従来の形式で出力する。 測定データをクビットごとのエラーマップに当てはめ、バックエンドを更新し、測定された特性を報告された値と比較する。

要件

このチュートリアルを始める前に、以下のものがインストールされていることを確認してください:

  • Qiskit SDK v2.0 またはそれ以降で、 可視化機能を備えたもの
  • Qiskit Runtime v0.40 またはそれ以降 (pip install qiskit-ibm-runtime)
  • Qiskit Device Benchmarking( Qiskit Experiments も同時にインストールされます)(pip install git+https://github.com/qiskit-community/qiskit-device-benchmarking.git)

セットアップ

必要なライブラリをインポートします。

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,
)

特性評価スイートは、いくつかの実験を構築し、複数のジョブを送信し、結果のフィッティングを行うため、合計で数分かかる場合があります。 INFOレベルのロギングを有効にし、各ステージで進行状況がリアルタイムで表示されるようにします。

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

小規模シミュレータの例

このチュートリアルには、シミュレータでのサンプルは含まれていません。 このワークフローでは、特定のデバイスの物理的な欠陥、すなわち、その量子ビットがどれくらいの速さで緩和・位相消滅するか、またゲートや読み出しがどれくらいの頻度で失敗するかを測定します。 理想的なシミュレータにはこうした不完全性が一切ないため、特徴づけるべき点は何もない。 合成ノイズモデルを偽のバックエンドに組み込むことは可能ですが、その場合、実験では自分が入力した数値しか復元できなくなってしまいます。 そのため、ここではQiskitのパターンに沿って4つのステップに分けて、直接ハードウェアの説明に進みます。


大規模なハードウェアの例

ステップ1:古典的な入力を量子問題に写像する

このワークフローにおいて、「問題」となるのはデバイスそのものです。従来の入力として、特性評価対象のQPUと測定する特性のリストが指定され、量子実験としては、それらに基づいて生成された特性評価回路が用いられます。

まず、バックエンドを選択してください。 このチュートリアルでは ibm_kingston、156キュービットのHeron r2 プロセッサを使用していますが、手元にある任意の IBM Quantum デバイスで代用することも可能です(あるいは、[... ]を備えたデバイスを選択することもできます service.least_busy())。

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

次に、測定するプロパティを選択してください。 以下の実験のうち、任意の部分セットに合格することができます:

  • readout: SPAM(状態の準備と測定)実験
  • rb_1q: 孤立した単一量子ビットを用いたランダム化ベンチマーク
  • rb_2q: レイヤー忠実度実験に基づく、2量子ビットの同時ランダム化ベンチマーク
  • t2: T2T_2 ハーン・エコー実験(デフォルトでは単一のエコー)
  • t1: T1T_1 リラクゼーション実験

デバイスの全体像を把握するには、テストスイート全体を実行してください。特定のプロパティのみが重要で、QPUの処理時間を節約したい場合は、リストから該当する項目を削除してください。

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

ステップ2:量子ハードウェアでの実行に向けて問題を最適化する

ほとんどのチュートリアルでは、この段階で回路をトランスパイルすることになります。 ここでは、内部でその処理 BackendCharacterization が行われます。 この手法では、実験回路をデバイスのネイティブゲート上に直接構築し、すべての量子ビットに対して単一量子ビット実験を並列に実行するとともに、結合マップの互いに交わらない層にわたって2量子ビットのベンチマークをスケジューリングすることで、わずかなジョブ数でデバイス全体を網羅できるようにしています。 この並列化により、スイート全体のQPU使用時間はわずか約70秒にとどまります。

ワークフローを管理するクラスを初期化します:

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

ステップ 3: Qiskit primitives を使用して実行する

このメソッド run_experiments は回路を構築し、それらを Sampler ジョブとして送信します。 コンテキスト Batch 内で実行し、ジョブがQPU上でまとめてスケジュールされ、すべてのジョブの送信が完了した時点でメソッドが返るよう設定してください。 (バッチファイルの外で実行することも、. の中で実行することもできます Session。)

Note

セッションコンテキストマネージャーが開いている間にバックエンドが渡されたという警告が表示される場合があります。 これは予期されたものであり、無視しても問題ありません。

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

このメソッドは、送信されたジョブを「experiment」をキーとする辞書として返します。これは、 IBM Quantum Platform のダッシュボード上でジョブを追跡したり、デバッグを行ったりする際に役立ちます。

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

ステップ 4:後処理を行い、希望する従来の形式で結果を返す

結果を分析する

このメソッド analyze_results は、ジョブの完了を待ち、測定データに適合させます。具体的には、 T1T_1 および T2T_2 については指数関数的な減衰、RB実験については生存確率の減衰、そして読み出しについては割り当て行列を適合させます。 これは、 エラーマップの辞書を返します。測定された各プロパティごとに1つのエントリがあり、それぞれが量子ビット(または量子ビットのペア)をその測定値にマッピングしています。

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

これらのマップには、読み出しエラー、単一量子ビットのエラー x およびゲート sx エラー、(lf_error_map層の忠実度実験に基づく)階層型2量子ビットエラー、ならびに T1T_1 および T2T_2 の所要時間(単位:秒)が示されています。

バックエンドのプロパティを更新する

このメソッド update_backend は、測定値をバックエンドのコピーのプロパティに書き込み、そのコピーを返します。 元のオブジェクト backend には報告されたキャリブレーションデータが保持されているため、以下に示すように、2つを比較することができます。 この更新は、 Python のセッション内でのみ有効であり、デバイス上や他のユーザーには何の影響も与えない点にご注意ください。

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

測定された物性を、報告されている物性と比較する

最後に、測定されたリアルタイムの特性と、バックエンドから報告された値とをプロットします。 各パネルでは、量子ビット(または量子ビットのペア)が測定値順に並べられているため、測定曲線は構造上滑らかになっており、その周囲に散らばる報告値のばらつきが、両者の不一致箇所を示している。 シングルクビットRBについては、ゲートごとの測定誤差が ゲート x``sx と ゲートの両方に同じ値が割り当てられているため、1つのプロットのみが示されている。 軸の範囲は、ごく少数の極端な外れ値によってプロットが圧縮されないよう、データの大半に基づいて選択されます。範囲外の点は、プロット上の注釈としてカウントされます(または、pass を指定 ylim して範囲を上書きすることもできます)。

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

これらのグラフは注意深く読み解く必要があります。なぜなら、2つの曲線の間にギャップがあるからといって、必ずしもデバイスのドリフトが発生しているとは限らないからです:

  • 読み出しと単一クビットのエラー :ほとんどのクビットについては、測定値が報告値と一致しているが、ごく一部のクビットについては、報告値が測定曲線から大きく外れている。 こうした局所的な意見の相違こそ、このワークフローが捕捉するように設計されているものです。
  • T1T_1 :2つのデータセットは互いに散在しており、系統的なずれは見られない。これは、 T1T_1 が時間の経過とともに自然に変動していることと一致している。
  • 2量子ビットのエラー :測定値は、報告されている値よりも体系的に高い値を示している。 これは予想される結果です。なぜなら、報告されている値は孤立したゲートで測定されたものであるのに対し、層の忠実度実験では多数のゲートを同時に動作させるため、クロストークが含まれているからです。 階層化された数値は、深層回路においてより重要ですが、報告されている較正データとは直接比較することはできません。
  • T2T_2 :ほとんどの量子ビットについて、測定値は報告値よりもかなり低い値を示している。 繰り返しになりますが、次の節で検討するように、方法論は大きな役割を果たしています。

個々の実験結果を確認する

また、property experiment_data を通じて個々の特性評価実験の生の結果を確認することも可能です。このプロパティは、基になる Qiskit Experiments オブジェクト ExperimentData を返します。 例えば、以下に単一量子ビットの T1T_1 の減衰曲線の測定結果を示します。これは、算出された数値を信頼する前に、フィットの精度を確認するのに役立ちます。

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

動的デカップリング列を用いた T2 の測定

デフォルトでは、 T2T_2 実験では単一のハーンエコーを適用し、すべての量子ビットを並列に測定します。上記比較グラフが示すように、これにより、バックエンドが報告する値よりも著しく低い T2T_2 値が得られる場合があります。 一つの仮説として、エコーの数が挙げられる。報告されている値は、低周波ノイズを抑制する動的デカップリングを用いて補正されている可能性がある。 これを確認するには、 T2T_2 による特性評価のみを実行し、パラメータを大きな値に設定 t2_num_echoes してください。これにより、CPMG方式のエコーパルス列が適用されます。 これらの遅延は、どちらの場合も自由進化時間の合計を表しているため、推定された T2T_2 の値は、シングルエコーの結果と直接比較することができます。

# 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

今回の実行では、追加のエコーによって結果はほとんど変わりませんでした。8エコーの中央値(56 µs)は、単一エコーの中央値(53 µs)に近く、どちらも報告されている中央値(142 µs)を大きく下回っています。 エコーの数だけではこの差を説明することはできません。他にも、較正手順の詳細や、各キュービットを個別にではなく並列に測定することなど、方法論上の違いが関係しています。

実用上の教訓として、異なる手法間における T2T_2 (および階層化された2量子ビット誤り)の比較には、慎重に取り組む必要がある。 更新された値は、実際のワークロードに近い条件下で取得された、内部的に整合性のあるスナップショットであり、クビット同士を比較したり、デバイスの経時的な変化を追跡したりするのに適しています。 しかし、報告されている校正データとの間に乖離が見られたとしても、それが必ずしもドリフトの証拠とは限りません。

手順1~4を1回の呼び出しにまとめました

日常的な使用では、中間結果が必要になることはめったにありません。 このメソッド run_and_update は、上記で行った一連の処理(構築、送信、フィッティング、更新)をすべて1つの呼び出しにまとめ、更新されたバックエンドを返します。 これは同じリスト experiments を受け付け(および などのオプションを転送し t2_num_echoes)、同様に または Batch コンテキスト Session でラップすることができます。

Note

次のセルは、すべてのジョブと後処理が完了するまで戻りません。

# 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

更新されたオブジェクト backend_updated は、ワークフロー内でバックエンドのプロパティが利用されるあらゆる場所で、すぐに使用できるようになりました。 回路のトランスパイルを行う際に、最も性能の高い量子ビットを選択するには、「 量子ビット選択のためのリアルタイムベンチマーク 」チュートリアルと併せて、この手順を試してみてください。 デバイスの値がずれていくため、実際にワークロードを実行する時刻に近いタイミングでプロパティを更新してください。


次のステップ

この作品に興味を持たれた方は、以下の資料もご参考になるかもしれません:

推奨事項
このページは役に立ちましたか?
バグや誤字の報告、またはコンテンツの要求はGitHubで行ってください。