クライアントサイドの推定ツール
qiskit_ibm_runtime.executor_estimator
概要
qiskit_ibm_runtime.executor_estimator.Estimator これは、 Executor プリミティブを基盤として構築されたQiskit EstimatorV2 インターフェースの実装です。 IBM Quantum バックエンド上でISA回路を実行することにより、量子観測量の期待値を推定します。
従来のサーバーサイドの実装と Estimator この新しい実装との主な違いは、 すべての前処理および後処理がクライアントマシン上で実行されるという点です。 これには、回路の準備(ツイリング、ゲートフォールディング、動的デカップリング、ノイズ注入)に加え、結果の後処理(TREXによる再スケーリング、ZNEによる外挿、PECによる準確率重み付け)が含まれます。 これらの手順をローカルで実行することで、デバッグのフィードバックがより迅速に得られ、ユーザーによる制御も強化されます。
ユーザーが を通じてジョブを送信すると run()、その背後で行われる処理は以下の通りです:
- プリミティブ統合ブロック(PUB)の強制生成、回復力レベルのデフォルト値の設定、およびショット数の決定。
- PUBをに変換し
QuantumProgram、指定されたオプションに従って回路変換(ツイリング、ゲートフォールディング、DD、ノイズ注入)を適用します。 - 量子プログラムをバックエンドに送信するために
Executor呼び出します。 - 作業完了後、生データから期待値を推定し、必要に応じて誤差低減のための後処理を適用する。
大規模または複雑なワークロードの場合、クライアント側での前処理および後処理のステップには多大なリソースを要するため、ジョブの送信までに遅延が生じる可能性があります。 クライアント側の処理を監視 INFO するには、ロガー qiskit_ibm_runtime を に設定します:
import logging
logger = logging.getLogger("qiskit_ibm_runtime")
logger.setLevel(logging.INFO)基本使用
例 1 — 最小構成(エラー緩和なし)
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime.executor_estimator import Estimator
# Select a backend.
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
observable = SparsePauliOp("ZZ")
# Transform the circuit and observable into ISA format.
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)
isa_obs = observable.apply_layout(isa_qc.layout)
estimator = Estimator(mode=backend)
estimator.options.resilience_level = 0
job = estimator.run([(isa_qc, isa_obs)])
result = job.result()
print(result[0].data.evs) # expectation value例 2 — レジリエンスレベル 2(測定誤差の低減+ゲートフォールディング ZNE)
estimator = Estimator(mode=backend)
estimator.options.resilience_level = 2 # TREX + ZNE (gate folding)
job = estimator.run([(isa_qc, isa_obs)])
result = job.result()
print(result[0].data.evs) # zero-noise extrapolated expectation value
print(result[0].data.evs_noise_factors) # raw values at each noise amplification level例 3 — PEC(明示的なノイズ学習が必要)
従来のサーバーサイドの実装とは異なり、このクライアントサイドの実装では、ノイズモデルを必要とする誤差低減手法(PECおよびPEA)に対して、明示的なノイズ学習が必要 Estimator となる。
を使用してPUBから一意のゲート層を抽 find_unique_layers() 出し、それらの層を に渡して別のジョブでノイズを学習させ NoiseLearnerV3 、学習されたノイズマップを に割り当てます layer_noise_model。
from qiskit_ibm_runtime.noise_learner_v3 import NoiseLearnerV3
pubs = [(isa_qc, isa_obs)]
estimator = Estimator(mode=backend)
estimator.options.resilience.pec_mitigation = True
# Step 1. Extract the unique boxed gate layers from your PUBs.
layers = estimator.find_unique_layers(pubs)
# Step 2. Learn the noise model for those layers.
nl_result = NoiseLearnerV3(mode=backend).run(layers).result()
# Step 3. Convert the NoiseLearnerV3 result to Pauli-Lindblad maps and pass them
# to the Estimator. The maps follow the same order as the input layers, so they can
# be zipped positionally.
pauli_lindblad_maps = nl_result.to_pauli_lindblad_maps()
estimator.options.resilience.layer_noise_model = zip(layers, pauli_lindblad_maps)
job = estimator.run(pubs)
result = job.result()
print(result[0].data.evs)入力
この関数の各呼び出しでは、PUBのリストが引数として run() 渡されます。 各 PUB は、以下の形式になっています:
(<single circuit>, <one or more observables>, <optional parameter values>, <optional precision>)エスティメータの入力および出力に関する詳細については、「エスティメータの入力および出力」を参照してください。
オブザーバブルおよびパラメータ値からの要素は、「 プリミティブ入力および出力」 で説明されている NumPy のブロードキャスティング規則に従って結合されます。
オプション
をインスタンス化する際 Estimator、 EstimatorOptions または辞書を使用してオプションを渡すことができます。 や など resilience_level、よく使われるオプションは第1レベルに配置されています。 その他のオプションは、次のようなカテゴリに分類されています execution。 オプションは次の形式で指定してください: options.<category>.<option> = <value>. 例えば: options.dynamical_decoupling.enable = True。
プリミティブ・オプションの指定に関する概要については、 「オプションの概要」を参照してください。 Estimator のオプションに関する詳細については、「 Estimator オプションの指定」 および「 Estimator によるノイズ管理の設定」 を参照してください。
出力
run() を返します RuntimeJobV2。 Calling は、 PUB オブジェクト EstimatorPubResult を 1 つ PrimitiveResult ずつ、入力ごとに 1 つずつ job.result() 返します:
result = job.result()
pub_result = result[0] # EstimatorPubResult for the first PUB
pub_result.data # DataBin holding numerical arrays
pub_result.metadata # dictionary with per-PUB metadata
result.metadata # dictionary with job-level metadataの内容は、指定された緩和策によって異なります pub_result.data 。
緩和策なし/測定による緩和のみ(レジリエンスレベル0および1)
以下のすべてのフィールドは、形状が であり pub_shape、これは である broadcast(param_shape, obs_shape)。
data.evs— 期待値。data.stds— 標準偏差。 「トゥイリング」が有効になっている場合の、トゥイリングによるランダム化のばらつきを反映します。トゥイリングが無効になっているensemble_standard_error場合は となります。data.ensemble_standard_error— 独立同分布のショットノイズの仮定(ドリフトの寄与がない)に基づく標準誤差。
測定誤差低減機能(TREX)が作動している場合、メイン回路と並行して自動的に動作する較正回路を用いて、読み出し誤差に対して値 evs が補正されます。
PEC
PECは、緩和策を講じない場合と同じ3つのフィールド、すなわち evs、 stds、を生成する ensemble_standard_error。 ガンマ準確率係数は、後処理の過程で内部的に適用されるものであり、個別の出力フィールドとして表示されることはありません。
これらの値 stds はガンマ係数によってスケーリングされるため、ショット数が同じ場合、通常は緩和策を講じていない場合よりも大きくなります。 これがPECの根本的なコストである。つまり、バイアスのない推定値を得るには、サンプリングのオーバーヘッドに比例して分散が増大する(gamma^2)。
ZNE(ゲートフォールディング)とPEA
このとき resilience.zne_mitigation=True、推定器は複数のノイズ増幅レベルで回路を動作させ、曲線を当てはめてノイズゼロの状態まで外挿します。 結果には、各ノイズレベルにおける外挿推定値と生データの両方が含まれています。
data.evs— ノイズゼロの外挿期待値(最良の異種データ適合 — 多項観測量の場合、各項ごとに外挿関数が選択される)。 形状:pub_shape.data.stds— 外挿値の標準偏差。 と同じ形ですevs。 「トゥイリング」がオンになっている場合の、トゥイリングによるランダム化のスプレッドから導出されたものです。data.evs_noise_factors— 各ノイズ増幅レベルにおける(外挿を行っていない)期待値。 形状:(*pub_shape, num_noise_factors).data.stds_noise_factors— 各ノイズ係数における標準偏差。 と同じ形ですevs_noise_factors。 「トゥイリング」がオンの場合、ランダム化によるばらつきを反映します。「トゥイリング」がオフの場合はensemble_stds_noise_factors、に等しくなります。data.ensemble_stds_noise_factors— 独立同分布のショットノイズを仮定した場合、各ノイズ係数におけるアンサンブル標準誤差。 形状:(*pub_shape, num_noise_factors).data.evs_extrapolated— 要求された各外挿関数による期待値。は、の各点で評価されるresilience.zne.extrapolated_noise_factors。 これらは強制均質フィッティングです。つまり、多項観測量のすべての項に同じ外挿関数が適用され、外挿関数ごとに1回のフィッティングが行われます。 形状:(*pub_shape, num_extrapolators, num_eval_points).data.stds_extrapolated— に対応する標準偏差evs_extrapolated。 同じ形。
多項の観測量(例えば、 {"XX": 0.5, "XY": 0.5})については、および evs は不均一フィッティング stds を用いる:各パウリ項ごとに、最適な外挿関数が個別に選択される。 evs_extrapolated また、各外挿器ごとに同次近似を用いる stds_extrapolated ことで、モデルの比較に役立ちます。 分析において、単一の外挿関数を一貫して適用する必要がある場合は、多項の観測量を単項の観測量に分割し、各項を個別に推定するようにしてください。
ZNEの結果は、 および draw_zne_evs() を使用して可視化できます draw_zne_extrapolators() ( が必要です plotly)。
ジョブレベルのメタデータ
result.metadata は、以下の内容を含む dict ものです:
"options"— 完成版をEstimatorOptions、辞書として。 使用されていないレジリエンスのサブオプションは削除され(たとえば、の場合、サブzne辞書は省略されますzne_mitigation=False)、ノイズモデル(指定されている場合)も削除されます。"target_precision"— PUBs から算出された精度と、の引数precisionrun()、あるいはどちらも指定されていないNone場合は。 その場合、ショット数は から算出されdefault_shots、それが へと切り替わりますdefault_precision。"shots"— 実行に使用されたショットの総数。"executor"— 基になるExecutorの結果のメタデータ。
マイグレーション・ガイド
このクライアントサイドのEstimatorの実装は、旧来のものにほぼそのまま置き換えることができます。 以下の手順に従って新しい実装へ移行してください。その際、以下の動作の変更点に留意してください:
- 前処理と後処理はクライアント側で行われます。 従来のEstimatorでは、すべての回路変換(ツイリング、ゲートフォールディング、ノイズ注入)および結果のポストプロセッシング(ZNE外挿、TREX再スケーリング、PEC重み付け)が、サーバー側で実行されます。 このクライアントサイドの実装では、これらの手順はすべてクライアントマシン上で実行されます。
- ノイズ学習は、これとは別のステップです。 従来のEstimatorでは、PECおよびPEAのノイズ学習はEstimatorジョブ自体に組み込まれており、サーバー側で暗黙的に処理されます。 この新しい実装では、ノイズ学習は独立したワークフローとなっており、明示的に実行する必要があります。
- 実行ジョブが送信されました。 クライアント側のEstimatorは、Executorを使用してジョブを送信するため、それらはEstimatorジョブではなくExecutorジョブとなります。 や
primitive_idなどのジョブ属性はinputs、Executor ジョブに関する情報を返します。
ステップ 1 — インポートを更新します。
前:
from qiskit_ibm_runtime import Estimator
from qiskit_ibm_runtime.options import EstimatorOptions後:
from qiskit_ibm_runtime.executor_estimator import Estimator
from qiskit_ibm_runtime.options_models import EstimatorOptionsステップ 2 — ノイズ学習を明示的に実行する(PEC または PEA を使用する場合)。
コードで PEC (pec_mitigation=True) または PEA (zne.amplifier="pea") を伴う ZNE を使用している場合は、を使用してノイズ学習を明示的に実行する必要があります NoiseLearnerV3。
前:
from qiskit_ibm_runtime import Estimator
pubs = [...] # Your PUBs
estimator = Estimator(mode=backend)
estimator.options.resilience.pec_mitigation = True # or zne_mitigation + pea amplifier
job = estimator.run(pubs)後:
from qiskit_ibm_runtime.executor_estimator import Estimator
from qiskit_ibm_runtime import NoiseLearnerV3
pubs = [...] # Your PUBs
estimator = Estimator(mode=backend)
estimator.options.resilience.pec_mitigation = True # or zne_mitigation + pea amplifier
# Identify the unique layers to learn.
layers = estimator.find_unique_layers(pubs)
# Learn the noise model for those layers (runs as a separate job).
learner = NoiseLearnerV3(mode=backend)
learner_job = learner.run(layers)
learner_result = learner_job.result()
# Convert the result to Pauli-Lindblad noise maps.
pauli_lindblad_maps = learner_result.to_pauli_lindblad_maps()
# Assign the learned noise maps so PEA/PEC uses them.
# The result objects returned by NoiseLearnerV3 follow the same order as the input
# layers, so the positional zip can be used here.
estimator.options.resilience.layer_noise_model = zip(layers, pauli_lindblad_maps)
# Now execute the target PUBs.
job = estimator.run(pubs)ステップ 3 — 1 つのジョブを複数のジョブに分割する(PUB が異なる精度値を使用している場合)。
混合精度のサポートは終了しました。ジョブ内に、異なる精度値を要求するPUBを含めることはできなくなり、含めた IBMInputValueError 場合は 例外が発生 run() します。 PUBを精度ごとにグループ分けし、各グループごとに1つのジョブを送信します。この際、グループ内のジョブがまとめて実行されるように Batch します。
前:
from qiskit_ibm_runtime import Estimator
# PUBs with different precision values.
pubs = [(isa_circuit, isa_obs, None, 0.1), (isa_circuit1, isa_obs1, None, 0.5)]
estimator = Estimator(mode=backend)
job = estimator.run(pubs)後:
from qiskit_ibm_runtime.executor_estimator import Estimator
from qiskit_ibm_runtime import Batch
# Group the PUBs by precision, one group per job.
with Batch(backend=backend) as batch:
estimator = Estimator(mode=batch)
jobs = [
estimator.run([(isa_circuit, isa_obs)], precision=0.1),
estimator.run([(isa_circuit1, isa_obs1)], precision=0.5),
]
results = [job.result() for job in jobs]クラス
コラム「 1 」 | コラム「 2 」 |
|---|---|
Estimator | IBM Quantum Compute (旧称: Qiskit Runtime )用のクライアントサイド・エスティメータプリミティブ。 |
EstimatorV2 | 別名 Estimator |