Skip to main content
IBM Quantum Platform

QESEM: QedmaによるQiskit関数

APIリファレンスを参照してください

  • このページのコードは、以下の要件に基づいて開発されました。 これらのバージョン、またはそれ以降のバージョンの使用をお勧めします。

    qiskit[all]~=2.5.0
    qiskit-ibm-runtime~=0.47.0
    

Qiskit 関数は、 IBM Quantum® Premium Plan、Flex Plan、およびオンプレム ( IBM Quantum Platform API 経由) Plan ユーザーだけが利用できる実験的な機能です。 これらはプレビューリリースの状態であり、変更される可能性がある。


概要

量子処理装置は近年著しく進歩したものの、ノイズや既存ハードウェアの不完全性に起因するエラーは、量子アルゴリズム開発者にとって依然として核心的な課題である。 量子計算が実用規模に近づき、古典的に検証できない段階に差し掛かるにつれ、保証された精度でノイズを打ち消す解決策がますます重要になってきている。 この課題を克服するため、Qedmaは量子エラー軽減(QESEM)を開発し、 IBM Quantum Platform に Qiskit関数としてシームレスに統合しました。

QESEM を使用することで、ユーザーはノイズの多い QPU 上で量子回路を実行し、QPU 時間のオーバーヘッドを最小限に抑えつつ、基本限界に近い高精度でエラーのない結果を得ることができます。 これを実現するため、QESEMは、特性評価とエラー低減のためにQedmaが開発した一連の独自手法を活用しています。 エラー低減手法には、ゲート最適化、ノイズを考慮したトランスパイレーション、エラー抑制(ES)、およびバイアスのないエラー軽減(EM)などがある。 これらの特性評価に基づく手法を組み合わせることで、ユーザーは汎用的な大規模量子回路について、信頼性が高く誤りのない結果を得ることができ、他の方法では実現できない応用分野を切り拓くことができます。

基盤となる構成要素の詳細な説明および実用規模の実証については、論文 『実用規模量子回路のための信頼性の高い高精度誤差軽減』 を参照のこと。


説明

Qedma社のQESEM機能を使用することで、誤差を抑制・軽減しながら簡単に回路を見積もり、実行することができ、より大きな回路ボリュームとより高い精度を達成することができます。 QESEMを使用するには、量子回路、測定する観測値のセット、各観測値の目標とする統計精度、そして選択したQPUを用意する。 目標精度まで回路を実行する前に、回路の実行を必要としない解析的な計算に基づいて、必要なQPU時間を見積もることができます。 QPUの時間見積もりに満足したら、QESEMで回路を実行します。

回路を実行すると、QESEMは回路に合わせて調整されたデバイス特性評価プロトコルを実行し、回路内で発生する誤差に対する信頼性の高いノイズモデルを生成します。 特性評価に基づき、QESEMはまずノイズを考慮したトランスパイレーションを実装し、入力回路を物理量子ビットとゲート群にマッピングする。これにより、対象観測量に影響するノイズを最小化する。 これには、ネイティブで利用可能なゲート( IBM® デバイス上のCX/CZ)に加え、QESEMによって最適化された追加ゲートが含まれ、QESEMの拡張ゲートセットを形成する。 QESEMはその後、QPU上で特性評価に基づくES回路とEM回路のセットを実行し、それらの測定結果を収集する。 これらはその後、要求された精度に対応する各観測量について、不偏期待値と誤差棒を提供するために従来通りの後処理が施される。

Qedma QESEMの概要

QESEMは、さまざまな量子アプリケーションで、現在実現可能な最大容量の回路で、高精度の結果を提供できることが実証されている。 QESEMには以下のようなユーザー向け機能があり、以下のベンチマークセクションで実証されています:

  • 保証された精度: QESEMは観測量の期待値に対する偏りのない推定値を出力する。 そのEM手法は理論的保証を備えており、Qedmaの最先端特性評価と相まって、ユーザー指定の精度までノイズのない回路出力への収束を保証する。 多くのヒューリスティックなEM法が系統的な誤差やバイアスを生じやすいのとは対照的に、QESEMの保証された精度は、汎用量子回路および観測量において信頼性の高い結果を得るために不可欠である。
  • 大規模QPUへの拡張性: QESEMのQPU処理時間は回路体積に依存するが、それ以外では量子ビット数に依存しない。 Qedmaは、 IBM Quantum の127量子ビットEagleデバイスおよび133量子ビットHeronデバイスを含む、現在利用可能な最大規模の量子デバイス上でQESEMを実証した。
  • アプリケーションにとらわれない: QESEMは、ハミルトニアンシミュレーション、VQE、QAOA、振幅推定など、さまざまなアプリケーションで実証されている。 ユーザーは測定したい量子回路や観測値を入力し、誤差のない正確な結果を得ることができる。 唯一の制限は、ハードウェアの仕様と割り当てられたQPU時間によって決まり、アクセス可能な回路ボリュームと出力精度を決定する。 対照的に、多くのエラー削減ソリューションは、アプリケーションに特化したものであったり、制御不能なヒューリスティックを含んでいたりするため、一般的な量子回路やアプリケーションには適用できない。
  • 拡張ゲートセット: QESEMは分数角度ゲートをサポートし、 IBM Quantum Heron およびEagleデバイス上でQedma最適化済み分数角度 Rzz(θ)Rzz(\theta) ゲートを提供します。 この拡張ゲートセットにより、コンパイル効率が向上し、デフォルトのCX/CZコンパイルと比較して最大2倍の回路容量を実現します。
  • マルチベース観測量 QESEMは、一般的なハミルトニアンのような多数の非共約パウリ文字列から構成される入力観測値をサポートしています。 測定ベースの選択とQPUのリソース割り当て(ショットと回路)の最適化は、QESEMによって自動的に実行され、要求された精度に対してQPUの所要時間を最小化します。 ハードウェアの忠実度と実行速度を考慮したこの最適化により、より深い回路を実行し、より高い精度を得ることができる。

ベンチマーク

QESEMは様々なユースケースやアプリケーションでテストされている。 以下の例は、QESEMで実行できるワークロードのタイプを評価するのに役立ちます。

与えられた回路と観測値に対して、エラー緩和と古典的シミュレーションの両方の困難さを定量化するための重要な数値は、 アクティブボリューム :回路内の観測値に影響を与えるCNOTゲートの数である。 アクティブボリュームは、回路の奥行きと幅、観測可能な重さ、そして観測可能なライトコーンを決定する回路構造に依存する。 詳細は、 2024年 IBM 量子サミットの講演をご覧ください。 QESEMは大容量領域で特に大きな価値を提供し、一般的な回路や観測値に対して信頼性の高い結果を与えます。

アクティブボリューム
アプリケーション
量子ビット数
デバイス
回路の説明
正確性
合計時間
ランタイム使用量
VQE回路8イーグル ( r3 )全21層、9測定ベース、 1D チェーン98%35 分14 最小
キック・イジング28イーグル ( r3 )独自レイヤー3層×3ステップ、 2D ヘビーヘキストポロジー97%22分4分
キック・イジング28イーグル ( r3 )独自レイヤー3層×8ステップ、 2D ヘビーヘキストポロジー97%116分23分
トロッター化ハミルトニアン・シミュレーション40イーグル ( r3 )2 ユニークレイヤー x 10 トロッターステップ、 1D チェーン97%3 時間25 分
トロッター化ハミルトニアン・シミュレーション119イーグル ( r3 )3ユニークレイヤー×9トロッターステップ、 2D ヘビーヘキストポロジー95%6.5 時間45 分
キック・イジング136ヘロン ( r2 )独自レイヤー3層×15ステップ、 2D ヘビーヘキストポロジー99%52分9 分

精度は観測値の理想値に対して相対的に測定されます: OidealϵOideal\frac{\langle O \rangle_{ideal} - \epsilon}{\langle O \rangle_{ideal}} ここで、' ϵ\epsilon ' は(ユーザー入力によって設定された)緩和の絶対精度であり、 Oideal\langle O \rangle_{ideal} はノイズのない回路での観測値である。 ランタイム使用量」はバッチモードでのベンチマークの使用量(個々のジョブの使用量の合計)を測定し、「合計時間」はセッションモードでの使用量(実験ウォール時間)を測定します。 QESEMは両方のモードで実行できるため、ユーザーは利用可能なリソースを最大限に活用できます。

28量子ビットのキックド・イジング回路は、新庄ら(参照)により研究された離散時間準結晶をシミュレートしている。 arXiv 2403.16718 および Q2B24 東京 )。 ψ0=0n| \psi_0 \rangle = | 0 \rangle ^{\otimes n} ここで用いた回路パラメータは、強磁性初期状態 (θx,θz)=(0.9π,0)(\theta_x, \theta_z) = (0.9 \pi, 0) である。測定された観測値は磁化の絶対値 M=128i=027ZiM = |\frac{1}{28} \sum_{i=0}^{27} \langle Z_i \rangle| である。実用規模のKicked Ising実験がibm_fezの136個の最良量子ビットで実行された。この特別なベンチマークはクリフォード角 (θx,θz)=(π,0)(\theta_x, \theta_z) = (\pi, 0) で実行され、回路の深さとともにアクティブ体積がゆっくり成長する。

トロッター化ハミルトニアンシミュレーション回路は、分数角での横磁場イジングモデルのためのものである: (θzz,θx)=(π/4,π/8)(\theta_{zz}, \theta_x) = (\pi / 4, \pi /8)(θzz,θx)=(π/6,π/8)(\theta_{zz}, \theta_x) = (\pi / 6, \pi / 8) に対応する( Q2B24 東京参照)。 ユーティリティ・スケールの回路はibm_brisbaneのベスト119量子ビットで実行され、40量子ビットの実験は利用可能なベスト・チェーンで実行された。 精度は磁化について報告されているが、より高重量の観測値についても高精度の結果が得られている。

VQE回路は、ドイツ電子シンクロトロン(DESY)の量子技術・応用センターの研究者とともに開発された。 ここで対象とした観測量は、多数の非共約パウリ弦からなるハミルトニアンであり、QESEMが多基底観測量に対して最適化された性能を持つことを強調している。 ミティゲーションは、古典的に最適化されたansatzに適用された。これらの結果はまだ未発表であるが、同様の構造特性を持つ異なる回路に対しても同質の結果が得られるであろう。


使用を開始する

IBM Quantum Platform のAPIキーを使用して認証を行い、次のように「QESEM Qiskit Function」を選択してください。 (このスニペットは、アカウントがすでにローカル環境に保存されていることを前提としています。)

import qiskit
from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

# verify that you have access to the function
catalog.list()
# load the function
qesem_function = catalog.load("qedma/qesem")

工数見積もりの事例

backend_name時間推定ジョブは、与えられた pub および に対して必要な QPU 時間を推定するのに役立ちます。 fake_fez``backend_name また、任意のシミュレータ・バックエンドに設定することも可能です。例えば、.

QESEMは、準確率論的かつ特性評価に基づくEM法を採用している。 この手法には、おおむね次のように比例するQPUの時間オーバーヘッドがあります:

TQPU=aeαIFVaϵ2+bT_{QPU} = a \frac{e^{\alpha IF\cdot V_a}}{\epsilon^2} + b

ここで、 VaV_a は回路の有効体積、 ϵ\epsilon は目標精度、 IFIF はネイティブゲートの不完全度である。

なお、 "estimate_time_only": "empirical" ジョブに必要な時間を推定するために数分間のQPU時間が使用されます(バックエンドが実デバイスである場合。シミュレータの場合は、QPU時間は使用されません)。 通常、これには5分ほどかかりますが、10分を超えることはありません。 実測時間推定ジョブと緩和ジョブの間で不確実性が劇的に変化した場合、QPUの所要時間も劇的に変化します。

手始めに、与えられた pub に対してQESEMを実行するために必要なQPU時間を見積もる基本的な例を試してみてください:

backend_name = "fake_fez"

circ = qiskit.QuantumCircuit(5)
circ.cx(0, 1)
circ.cx(2, 3)
circ.cx(1, 2)
circ.cx(3, 4)

avg_magnetization = qiskit.quantum_info.SparsePauliOp.from_sparse_list(
    [("Z", [q], 1 / 5) for q in range(5)], num_qubits=5
)
other_observable = qiskit.quantum_info.SparsePauliOp.from_sparse_list(
    [("ZZ", [0, 1], 1.0), ("XZ", [1, 4], 0.5)], num_qubits=5
)

time_estimation_job = qesem_function.run(
    pubs=[(circ, [avg_magnetization, other_observable])],
    options={
        "estimate_time_only": "empirical",
    },
    backend_name=backend_name,  # example: "fake_fez", "ibm_fez"
)
time_estimate_result = (
    time_estimation_job.result()
)  # a list of results per pub (circuit)

以下のコードスニペットは、時間推定ジョブからさまざまな実行メトリクスを取得する方法を示しています(estimate_time_only が設定されている場合):

pub_result = time_estimate_result[0]

print(
    f"The estimated QPU time for mitigation for this PUB is: {pub_result.metadata['time_estimation_sec']}"
)
print(
    f"The QPU time that this time estimation job took is (here it is 0 because we used fake_fez): {pub_result.metadata['total_qpu_time']}"
)
print(
    f"Gates fidelity measured during the experiment: {pub_result.metadata['gate_fidelities']}"
)
print(f"Total shots: {pub_result.metadata['total_shots']}")
print(f"Resource usage breakdown: {pub_result.metadata['resource_usage']}")

Output:

The estimated QPU time for mitigation for this PUB is: 300
The QPU time that this time estimation job took is (here it is 0 because we used fake_fez): 0
Gates fidelity measured during the experiment: {'CZ': 0.9951354916722668, 'ID1Q': 0.9991246627329172}
Total shots: 220000
Resource usage breakdown: {'RUNNING: MAPPING': {'CPU_TIME': 33.6066133165732, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU_TIME': 184.53575124032795, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: WAITING_FOR_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: EXECUTING_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: POST_PROCESSING': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}}

経験的な時間推定が有効になっている場合、QESEMは少数の回路を実行し、より正確なQPU時間の推定値を算出します。 これらの回路による緩和の結果は、ジョブの【 empirical_estimation_mitigation_results フィールド】で確認できます。

これらの結果は限られた数の回路のサンプルから導き出されたものであるため、QESEMによる緩和作業全体から得られた最終結果に比べ、精度はかなり低い。 ただし、回路が小規模である場合や、目標とする精度が低い場合には、経験的な時間推定の過程で行われる緩和措置だけで所望の精度に達することがあり、完全な緩和処理は必要ない場合もある。

この empirical_estimation_mitigation_results フィールドは、入力パラメータごとにオブジェクトの PrimitiveResult リストで構成されています。 回路がパラメータ化されていない場合、リストの長さは1になります。

empirical_estimation_mitigation_results = time_estimate_result[0].metadata[
    "empirical_estimation_mitigation_results"
][0]  # a list per parameter
print("Partial results for the observables:")

print(
    f"    Mitigated expectation values: {empirical_estimation_mitigation_results.data.evs}"
)
print(
    f"    Mitigated error bars: {empirical_estimation_mitigation_results.data.stds}"
)
print(
    f"    Number of shots used for mitigation: {empirical_estimation_mitigation_results.metadata['mitigation_shots']}"
)
transpiled_circ = empirical_estimation_mitigation_results.metadata[
    "transpiled_circ"
]
print(f"    Qubit mapping: {transpiled_circ['qubit_maps']}")
print(
    f"    Number of measurement bases: {transpiled_circ['num_measurement_bases']}\n"
)

# results per obs
emp_obs_results = empirical_estimation_mitigation_results.metadata["results"][
    0
]
# print(f"Results for each observable: {results}")
print("Results for each observable:")

for i, (obs_array, result_dict) in enumerate(emp_obs_results):
    # obs_array, result_dict = results
    print(f"Observable {i+1}: {obs_array}")
    print(
        f"    QESEM mitigated value: {result_dict['qesem']['value']} \u00b1 {result_dict['qesem']['error_bar']}"
    )

Output:

Partial results for the observables:
    Mitigated expectation values: [1.00347302 1.00693905]
    Mitigated error bars: [0.00304061 0.00714276]
    Number of shots used for mitigation: 180000
    Qubit mapping: [[[0, 136], [1, 143], [2, 142], [3, 141], [4, 140]]]
    Number of measurement bases: 2

Results for each observable:
Observable 1: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
    QESEM mitigated value: 1.003473015776871 ± 0.0030406128032204015
Observable 2: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
    QESEM mitigated value: 1.0069390542613554 ± 0.0071427606736885925

QESEMの緩和策ジョブの例

次の例では、QESEMジョブを実行します:

sample_job = qesem_function.run(
    pubs=[(circ, [avg_magnetization, other_observable])],
    backend_name=backend_name,  # example: "ibm_fez"
    # options = {
    #     "estimate_time_only": "empirical",
    #     "default_precision": 0.2,  # Default precision is applied to all pubs that don't have a precision specified, see API reference for more details
    #     "max_execution_time": 3600,  # You can specify a maximum QPU time in seconds, see API reference for more details
    #     "transpilation_level": "standard",  # "minimal_with_layout_opt" for minimal transpilation, see API reference for more details
    #     "parallel_execution": True,  # True for parallel execution, see API reference for more details
    # },
)

各入力フィールドおよびオプションの詳細については、 QESEM API リファレンスを参照してください。

使い慣れたQiskit Serverless APIを使って、Qiskit Functionのワークロードの状態をチェックしたり、結果を返したりできます:

# Print the ID so you can use it later, if necessary
print(sample_job.job_id)
print(sample_job.status())
sample_result = sample_job.result()

Output:

3ac6b2df-15b0-4dc0-8f48-cf14bd20a1c8
DONE

以下のコードスニペットは、緩和策の結果と実行メトリクスを取得する方法を示しています。 これらには、さまざまなパラメータがQESEMの実行にどのような影響を与えるかをより深く理解するために不可欠なデータが含まれています。 また、自身の研究に基づいて論文を書く際にも参考になるかもしれません。

for pub_idx, pub_result in enumerate(
    sample_result
):  # each element in the list is a result for a different pub, here we sent only one pub
    print(f"\nPUB {pub_idx}:")
    print(
        f"  The QPU time that this job took is (here it is 0 because we used fake_fez): {pub_result.metadata['total_qpu_time']}"
    )
    print(
        f"  Gates fidelity measured during the experiment: {pub_result.metadata['gate_fidelities']}"
    )
    print(f"  Total shots: {pub_result.metadata['total_shots']}")
    print(
        f"  Number of shots used for mitigation: {pub_result.metadata['mitigation_shots']}"
    )
    print(
        f"  Resource usage breakdown: {pub_result.metadata['resource_usage']}"
    )

Output:


PUB 0:
  The QPU time that this job took is (here it is 0 because we used fake_fez): 0.0
  Gates fidelity measured during the experiment: {'CZ': 0.9953704216147041, 'ID1Q': 0.9991834123567518}
  Total shots: 446000
  Number of shots used for mitigation: 194000
  Resource usage breakdown: {'RUNNING: MAPPING': {'CPU_TIME': 32.52745003718883, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU_TIME': 257.850521848537, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: WAITING_FOR_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: EXECUTING_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: POST_PROCESSING': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}}

metadata["results"]では、結果はまず回路インスタンスごとに、次に観測変数ごとにグループ化されます。

print("Full QESEM mitigation results:")

for pub_idx, pub_result in enumerate(sample_result):
    print(f"\nPUB {pub_idx}:")

    print(f"  Mitigated expectation values: {pub_result.data.evs}")
    print(f"  Mitigated error bars: {pub_result.data.stds}")
    noisy_results = pub_result.metadata.get("noisy_results")
    print(f"  Unmitigated expectation values: {noisy_results.evs}")
    print(f"  Unmitigated error bars: {noisy_results.stds}")

    print("  Transpiled circuits:")
    for circ_idx, transpiled_circ in enumerate(
        pub_result.metadata["transpiled_circs"]
    ):
        print(f"    Circuit {circ_idx}:")
        # print(f"      Circuit: \n {transpiled_circ['circuit']}") # not printing it because it's long but you can see the transpiled circuit itself
        print(f"      Qubit mapping: {transpiled_circ['qubit_maps']}")
        print(
            f"      Measurement bases: {transpiled_circ['num_measurement_bases']}"
        )

    print("  Results for each observable:")
    for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
        print(f"    Circuit {circ_idx}:")
        for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
            print(f"      Observable {obs_idx}: {obs_array}")
            print(
                f"        QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
            )
            print(
                f"        Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
            )

Output:

Full QESEM mitigation results:

PUB 0:
  Mitigated expectation values: [1.00648343 1.00636289]
  Mitigated error bars: [0.00253812 0.00693586]
  Unmitigated expectation values: [0.98031429 0.96357143]
  Unmitigated error bars: [0.00124128 0.00578812]
  Transpiled circuits:
    Circuit 0:
      Qubit mapping: [[[0, 140], [1, 141], [2, 142], [3, 143], [4, 136]]]
      Measurement bases: 2
  Results for each observable:
    Circuit 0:
      Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
        QESEM mitigated value: 1.0064834305181962 ± 0.002538119914534849
        Unmitigated value: 0.9803142857142859 ± 0.0012412835813609938
      Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
        QESEM mitigated value: 1.0063628870614818 ± 0.006935859820870656
        Unmitigated value: 0.9635714285714285 ± 0.005788121870526659

主な結果の内訳:

  • mitigated: 完全に緩和されたQESEMの期待値。
  • unmitigated: 誤差低減処理を行っていない、物理ノイズの生の結果。

QESEMによるヒューリスティック外挿の結果

単一 precision のフロートを用いた標準的なQESEM実行では、結果にはQESEMのヒューリスティックに使用される、自動的に利用可能なノイズスケーリングポイントも含まれます。 これらのポイントは、追加のQPUリソースを使用せずに計算されます。

スケール 1.0 は、読み出しノイズ低減(REM)を適用した物理デバイスのノイズレベルを表し、スケール 2.0 は、同じくREMを適用した、ノイズ増幅された相補的な点を表します。 これらの点が、結果 qesem_heuristic を生み出すために用いられます。

  • qesem_heuristic: 入手可能なノイズ補正済みデータから算出されたZNE方式の推定値。 現在、ここでは指数関数的な外挿法が用いられています。
  • noise_scaling.results_with_REM: さまざまなノイズスケールにおける期待値。いずれも読み出しノイズ低減(REM)が適用されている。

些細ではあるが重要な点として、スケ 1.0 ールの結果は、の unmitigated 結果とは同じではない。 どちらも物理的なデバイスのノイズレベルに対応していますが、スケール 1.0 ポイントには読み出し時のノイズ低減効果が含まれているのに対し unmitigated 、には含まれていません。

print("QESEM heuristic results:")

for pub_idx, pub_result in enumerate(sample_result):
    print(f"\nPUB {pub_idx}:")
    for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
        print(f"  Circuit {circ_idx}:")
        for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
            print(f"    Observable {obs_idx}: {obs_array}")
            qesem_heuristic = result_dict["qesem_heuristic"][0]
            print("      QESEM heuristic:")
            print(
                f"        Value: {qesem_heuristic['value']} ± {qesem_heuristic['error_bar']}"
            )
            print(
                f"        Extrapolation: {qesem_heuristic['extrapolation']}"
            )
            print(
                f"        Scale factors: {qesem_heuristic['scale_factors']}"
            )
            noise_scaling = result_dict["noise_scaling"]
            print("      Noise scaling results:")
            print(
                f"        Scaling method: {noise_scaling['scaling_method']}"
            )
            print("        Results with Readout mitigation (REM):")
            for rem_result in sorted(
                (
                    item
                    for item in noise_scaling["results_with_REM"]
                    if item["scale"] != 0.0
                ),
                key=lambda item: item["scale"],
            ):
                print(
                    f"          Scale factor {rem_result['scale']}: {rem_result['value']} ± {rem_result['error_bar']}"
                )

Output:

QESEM heuristic results:

PUB 0:
  Circuit 0:
    Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
      QESEM heuristic:
        Value: 1.0008161638888535 ± 0.0038859458884403964
        Extrapolation: exponential
        Scale factors: [1.0, 2.0]
      Noise scaling results:
        Scaling method: QESEM
        Results with Readout mitigation (REM):
          Scale factor 1.0: 0.9918395459270772 ± 0.0012565417579355634
          Scale factor 2.0: 0.982943441922748 ± 0.0028919278067695018
    Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
      QESEM heuristic:
        Value: 0.9960853148925298 ± 0.013811635038961175
        Extrapolation: exponential
        Scale factors: [1.0, 2.0]
      Noise scaling results:
        Scaling method: QESEM
        Results with Readout mitigation (REM):
          Scale factor 1.0: 0.9902860583785115 ± 0.005921236914723409
          Scale factor 2.0: 0.984520565414274 ± 0.006909522262347639
Note

以下の例では、特定の機能に関する入力と結果に焦点を当てているため、毎回実行メトリクスをすべて表示するわけではありません。 先ほど示した total_qpu_timegate_fidelities総ショット数緩和措置_ショットresource_usage といった最上位のメタデータは、これらのジョブでも利用可能です。

簡潔さを期すため、バックエンド、オブザーバブル、基本回路パラメータなど、前の例で使用した変数のいくつかを以下で再利用しています。

Note

以下の例はすべて、経験的な時間推定を用いて実行することも可能です。 これを有効にするには、関数のオプションに <code>"estimate_time_only": "経験的"</code> を指定してください。

パラメータ化された回路の例

多くのアルゴリズムでは、同じ回路を複数のパラメータ値で評価します。 パラメータ化された回路を1つのQESEMジョブとして送信することで、QESEMは回路インスタンス間で特性評価とキャリブレーションを共有できるようになり、個別のジョブを実行する場合に比べてQPU時間のオーバーヘッドを削減できます。

パラメータ化された回路を提出するには、トランスパイレーションレベル "minimal_with_layout_opt" を使用する必要があります。 このレベルで提出される回路は、バックエンドに応じて、すでにそのバックエンドの基底ゲートを用いて表現されている必要があります。 このレベルでは、QESEMは提出された構造を入力回路に可能な限り近づけたまま維持し、レイヤ化(操作を並列な2量子ビットゲートのレイヤーにグループ化すること)の際の障壁を考慮しつつ、高忠実度の量子ビットへのハードウェアマッピングやデバイスの接続設定も自動的に処理します。

実際には、これは、提出する前に回路をターゲットバックエンドの基本ゲートに変換しておく必要があることを意味します。 以下に、単純なベースゲート変換の例を示します。

QESEMでは現在、パラメータセットごとに1つの観測値のみをサポートしています。 other_observable``avg_magnetization以下の 2 つのパラメータ行は、2 つのオブザーバブルと結合されています。1 行目は で測定され、2 行目は で測定されています。

# Transpile to the backend basis gates only. With minimal_with_layout_opt, QESEM handles hardware mapping/connectivity and observable layout internally.
from qiskit_ibm_runtime.fake_provider import FakeFez

backend = FakeFez()
basis = backend.operation_names
print(basis)

param0 = qiskit.circuit.Parameter("param0")
param1 = qiskit.circuit.Parameter("param1")
parametrized_circ = qiskit.QuantumCircuit(5)
parametrized_circ.rx(param0, 0)
parametrized_circ.rx(param1, 1)
parametrized_circ.cx(0, 1)
parametrized_circ.cx(2, 3)
parametrized_circ.cx(1, 2)
parametrized_circ.cx(3, 4)

parametrized_circ = qiskit.transpile(
    parametrized_circ, basis_gates=basis, optimization_level=1
)
parametrized_parameter_values = [[0.5, 0.1], [0.0, 0.6]]
parametrized_observables = [avg_magnetization, other_observable]

parametrized_job = qesem_function.run(
    pubs=[
        (
            parametrized_circ,
            parametrized_observables,
            parametrized_parameter_values,
            0.1,
        )
    ],
    backend_name=backend_name,
    options={
        "max_execution_time": 300,
        "transpilation_level": "minimal_with_layout_opt",
    },
)
print(parametrized_job.job_id)
print(parametrized_job.status())

Output:

d1b0e29b-196c-4896-aec6-44a268ebd874
DONE
parametrized_result = parametrized_job.result()
print("Parameterized circuit QESEM results:")

for pub_idx, pub_result in enumerate(parametrized_result):
    print(f"\nPUB {pub_idx}:")
    print(f"  Mitigated expectation values: {pub_result.data.evs}")
    print(f"  Mitigated error bars: {pub_result.data.stds}")
    noisy_results = pub_result.metadata["noisy_results"]
    print(f"  Unmitigated expectation values: {noisy_results.evs}")
    print(f"  Unmitigated error bars: {noisy_results.stds}")
    print("  Results for each parameter value:")
    for param_idx, param_results in enumerate(pub_result.metadata["results"]):
        print(
            f"    Parameter set {param_idx}: {parametrized_parameter_values[param_idx]}"
        )
        for obs_idx, (obs_array, result_dict) in enumerate(param_results):
            print(f"      Observable {obs_idx}: {obs_array}")
            print(
                f"        QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
            )
            print(
                f"        Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
            )

Output:

Parameterized circuit QESEM results:

PUB 0:
  Mitigated expectation values: [0.92392021 0.82517653]
  Mitigated error bars: [0.00565281 0.00616016]
  Unmitigated expectation values: [0.9028     0.78771429]
  Unmitigated error bars: [0.00335142 0.00925413]
  Results for each parameter value:
    Parameter set 0: [0.5, 0.1]
      Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
        QESEM mitigated value: 0.923920210615709 ± 0.005652811570890183
        Unmitigated value: 0.9028 ± 0.0033514176105045447
    Parameter set 1: [0.0, 0.6]
      Observable 0: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
        QESEM mitigated value: 0.8251765289285893 ± 0.006160161743353999
        Unmitigated value: 0.7877142857142858 ± 0.009254130564027902

複数のパブを含む例

マルチパブ実行は、1つのQESEMジョブ内で複数の関連する回路を実行したい場合に役立ちます。 パラメータ化された実行と同様に、QESEMでは個別のジョブで繰り返し実行するのではなく、回路インスタンス間で特性評価やキャリブレーションを共有できるため、オーバーヘッドを削減できます。

これは、 トロッター型ワークロードなど、異なるサーキットが同一の固有レイヤーを再利用する、共有レイヤー構造を持つサーキットにおいて特に有用です。 その場合、これらをまとめて実行することで、個別のQESEM作業と比較して特性評価のコストを削減できます。

"transpilation_level": "minimal_with_layout_opt"複数のパブでの仕事には、以下が必要です。 パラメータ化された例と同様に、回路は提出前に、ターゲットバックエンドの基本ゲートに変換しておく必要があります。 その後、QESEMはデバイスとの接続、レイアウト、および高忠実度量子ビットへのマッピングを内部で処理します。

以下の各 PUB には、1つの回路と、このノートブックの前半で使用されたのと同じ2つの観測可能変数が含まれているため、返される PrimitiveResult 値には入力回路ごとに1つの PubResult が含まれます。

以下の例では、同じ層パターンを持つ2つの単純なトロッター回路を使用しています。 circ_a 1つはトロッター層が1つあり、もう1つは circ_b 同じ層パターンを2回繰り返しています。 これにより、共有構造が明示されます。

def make_trotter_circuit(num_qubits, num_layers, zz_angle=0.2, x_angle=0.1):
    trotter_circ = qiskit.QuantumCircuit(num_qubits)
    for _ in range(num_layers):
        for q in range(num_qubits):
            trotter_circ.rx(x_angle, q)
        trotter_circ.barrier()
        for q in range(0, num_qubits - 1, 2):
            trotter_circ.rzz(zz_angle, q, q + 1)
        trotter_circ.barrier()
        for q in range(1, num_qubits - 1, 2):
            trotter_circ.rzz(zz_angle, q, q + 1)
        trotter_circ.barrier()
    return trotter_circ


circ_a = make_trotter_circuit(num_qubits=5, num_layers=1)
circ_b = make_trotter_circuit(num_qubits=5, num_layers=2)
multi_pubs = [
    (
        qiskit.transpile(qci, basis_gates=basis, optimization_level=1),
        [avg_magnetization, other_observable],
    )
    for qci in [circ_a, circ_b]
]

multi_circ_job = qesem_function.run(
    pubs=multi_pubs,
    backend_name=backend_name,
    options={
        "max_execution_time": 300,
        "transpilation_level": "minimal_with_layout_opt",
        "default_precision": 0.1,
    },
)
print(multi_circ_job.job_id)
print(multi_circ_job.status())

Output:

e34565b8-7262-4133-a120-de42ce624a99
DONE
multi_circ_result = multi_circ_job.result()
print("Multi-pub QESEM results:")

for pub_idx, pub_result in enumerate(multi_circ_result):
    print(f"\nPUB {pub_idx}:")
    print(f"  Mitigated expectation values: {pub_result.data.evs}")
    print(f"  Mitigated error bars: {pub_result.data.stds}")
    noisy_results = pub_result.metadata["noisy_results"]
    print(f"  Unmitigated expectation values: {noisy_results.evs}")
    print(f"  Unmitigated error bars: {noisy_results.stds}")
    print("  Results for each observable:")
    for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
        print(f"    Circuit {circ_idx}:")
        for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
            print(f"      Observable {obs_idx}: {obs_array}")
            print(
                f"        QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
            )
            print(
                f"        Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
            )

Output:

Multi-pub QESEM results:

PUB 0:
  Mitigated expectation values: [0.99502406 1.02209332]
  Mitigated error bars: [0.00483819 0.00707488]
  Unmitigated expectation values: [0.96934286 0.97271429]
  Unmitigated error bars: [0.00124855 0.00617294]
  Results for each observable:
    Circuit 0:
      Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
        QESEM mitigated value: 0.9950240647925642 ± 0.004838188086259301
        Unmitigated value: 0.9693428571428573 ± 0.0012485470362492692
      Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
        QESEM mitigated value: 1.0220933230604674 ± 0.007074884384355636
        Unmitigated value: 0.9727142857142859 ± 0.006172939375512439

PUB 1:
  Mitigated expectation values: [0.98850017 1.02555188]
  Mitigated error bars: [0.0077912  0.01672652]
  Unmitigated expectation values: [0.93682857 0.95371429]
  Unmitigated error bars: [0.00156245 0.00665735]
  Results for each observable:
    Circuit 0:
      Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
        QESEM mitigated value: 0.988500171577252 ± 0.007791203181151346
        Unmitigated value: 0.9368285714285716 ± 0.001562451883089579
      Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
        QESEM mitigated value: 1.02555188098689 ± 0.016726524388086233
        Unmitigated value: 0.9537142857142858 ± 0.006657345655544263

準確率論的誤差調整(QET)の例

準確率論的誤差調整(QET)では、選択されたノイズスケール係数における期待値が求められます。 これは、カスタムノイズスケーリングの研究や、ゼロノイズ外挿のワークフローに役立ちます。 「スケール 1.0 」は物理的なノイズレベルを表します。~ 1.00.0 間の値ではノイズが部分的に低減され、~を超える 1.0 値ではノイズが増幅されます。

Qiskit FunctionでQETを使用するには、 PUB の精度として辞書を渡してください。 この辞書は、要求された各ノイズスケールを、その目標精度に対応付けます。 返されたスケール係数の結果は に noise_scaling.results_with_REM 保存され、読み出しの誤差補正が含まれています。 したがって、スケール 1.0 値は未補正値とは同一ではありません。なぜなら 1.0 、前者には読み出し補正が含まれているのに対し unmitigated 、後者には含まれていないからです。

スケールの要求があった場合、QESEMは追加のQPU使用量なしで、その周囲 1.0 の補完スケールも返します。 0.7``1.5たとえば、をリクエストすると `0.5` が返されることもあり、をリクエスト `1.3` すると が返されることもあります。 補完スケールの精度は保証されません。

noise_scale_precision = {0.5: 0.15, 1.3: 0.2}

qet_job = qesem_function.run(
    pubs=[
        (
            circ,
            [avg_magnetization, other_observable],
            None,
            noise_scale_precision,
        )
    ],
    backend_name=backend_name,
    options={"max_execution_time": 300},
)
print(qet_job.job_id)
print(qet_job.status())

Output:

8195fa58-f037-4651-8715-36ce1cdc5521
DONE
qet_result = qet_job.result()
print("QET noise-scaling results:")

for pub_idx, pub_result in enumerate(qet_result):
    print(f"\nPUB {pub_idx}:")
    noisy_results = pub_result.metadata["noisy_results"]
    print(f"  Unmitigated expectation values: {noisy_results.evs}")
    print(f"  Unmitigated error bars: {noisy_results.stds}")
    print("  Results for each observable:")
    for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
        print(f"    Circuit {circ_idx}:")
        for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
            print(f"      Observable {obs_idx}: {obs_array}")
            noise_scaling = result_dict["noise_scaling"]
            print(
                f"        Scaling method: {noise_scaling['scaling_method']}"
            )
            print("        Results with Readout mitigation (REM):")
            for rem_result in sorted(
                (
                    item
                    for item in noise_scaling["results_with_REM"]
                    if item["scale"] != 0.0
                ),
                key=lambda item: item["scale"],
            ):
                print(
                    f"          Scale factor {rem_result['scale']}: {rem_result['value']} ± {rem_result['error_bar']}"
                )

Output:

QET noise-scaling results:

PUB 0:
  Unmitigated expectation values: [0.97822857 0.96171429]
  Unmitigated error bars: [0.00123812 0.00672958]
  Results for each observable:
    Circuit 0:
      Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
        Scaling method: QESEM
        Results with Readout mitigation (REM):
          Scale factor 0.5: 0.9938730340199383 ± 0.0032116907357568275
          Scale factor 0.7: 0.9963976191853445 ± 0.00036300258869586616
          Scale factor 1.0: 0.9898115079506586 ± 0.0012525947426560995
          Scale factor 1.3: 0.9864667065580341 ± 0.002633221613518526
          Scale factor 1.5: 0.9838755527197551 ± 0.002948417797996015
      Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
        Scaling method: QESEM
        Results with Readout mitigation (REM):
          Scale factor 0.5: 1.0006538544450332 ± 0.002121742014777343
          Scale factor 0.7: 1.0004159801523036 ± 0.0021671375357823794
          Scale factor 1.0: 0.9898058846339917 ± 0.00690183710903159
          Scale factor 1.3: 0.9948946719997267 ± 0.002146532859610311
          Scale factor 1.5: 0.9927220368192772 ± 0.0020875057190323882

エラーメッセージを取得する

ワークロードのステータスが「ERROR」の場合は、次のようにしてエラーメッセージを取得してください job.result()

# Get the result and truncate for readability
result = sample_job.result()
result_str = str(result)
max_length = 500  # Adjust this value as necessary

if len(result_str) > max_length:
    truncated = (
        result_str[:max_length]
        + f"... (truncated {len(result_str) - max_length} characters)"
    )
else:
    truncated = result_str

print(truncated)

Output:

PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(2,), dtype=float64>), stds=np.ndarray(<shape=(2,), dtype=float64>), shape=(2,)), metadata={'gate_fidelities': {'CZ': 0.9979444718552628, 'ID1Q': 0.9991994239814883}, 'total_shots': 498600, 'mitigation_shots': 223400, 'transpiled_circs': [{'circuit': 'OPENQASM 3.0;\ninclude "stdgates.inc";\nbit[76] c0;\nqubit[76] q0;\nrx(0) q0[54];\nrx(0) q0[59];\nrx(0) q0[75];\nrz(pi/2) q0[54];\nrz(pi/2) q0[59];\nrz(pi/2) q0[75];\nrx(pi/2) q0[54];\nr... (truncated 3771 characters)

サポートの利用

Qedmaのサポートチームがお手伝いします! QESEM Qiskit Functionの使用に関して何か問題が発生したり、質問がある場合は、遠慮なくご連絡ください。 当社の知識豊富でフレンドリーなサポートスタッフが、技術的な問題やお問い合わせに対応いたします。

Eメールでのお問い合わせは [email protected] までご連絡ください。 迅速かつ正確な対応をさせていただくため、お困りの問題についてできるだけ詳しくご記入ください。 また、Qedma POCの専任担当者に電子メールまたは電話でご連絡いただくこともできます。

より効率的にサポートさせていただくため、お問い合わせの際は以下の情報をお知らせください:

  • 問題の詳細
  • ジョブ ID
  • 関連するエラーメッセージやコード

Qiskitの機能を最大限にご活用いただけるよう、迅速かつ効果的なサポートをお約束いたします。

私たちは常に製品の改善に努めており、皆様からのご提案をお待ちしております! サービス改善のご提案やご希望の機能などございましたら、 [email protected] までお寄せください。


次のステップ

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