メインコンテンツへスキップ

オプションの指定

Package versions

このページのコードは、以下の要件を使用して開発されました。 これらのバージョン以降の使用を推奨します。

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1

オプションを使用して、Estimator および Sampler プリミティブをカスタマイズできます。このセクションでは、Qiskit Runtime プリミティブのオプションを指定する方法に焦点を当てます。プリミティブの run() メソッドのインターフェースはすべての実装で共通ですが、オプションは共通ではありません。qiskit.primitives および qiskit_aer.primitives のオプションについては、対応する API リファレンスを参照してください。

プリミティブのオプション指定に関する注意事項:

  • SamplerV2EstimatorV2 はそれぞれ独立したオプションクラスを持っています。プリミティブの初期化中または初期化後に、利用可能なオプションを確認し、オプション値を更新できます。
  • update() メソッドを使用して、options 属性への変更を適用します。
  • オプションの値を指定しない場合、Unset という特別な値が与えられ、サーバーのデフォルト値が使用されます。
  • options 属性は Python の dataclass 型です。組み込みの asdict メソッドを使用して辞書に変換できます。

プリミティブオプションの設定

オプションは、プリミティブの初期化時、初期化後、または run() メソッド内で設定できます。同じオプションが複数の場所で指定された場合の動作については、優先順位ルールのセクションを参照してください。

プリミティブの初期化

プリミティブを初期化する際に、オプションクラスのインスタンスまたは辞書を渡すことができます。その場合、それらのオプションのコピーが作成されます。したがって、元の辞書またはオプションインスタンスを変更しても、プリミティブが所有するオプションには影響しません。

オプションクラス

EstimatorV2 または SamplerV2 クラスのインスタンスを作成する際に、オプションクラスのインスタンスを渡すことができます。それらのオプションは、run() を使用して計算を実行する際に適用されます。オプションは次の形式で指定します:options.option.sub-option.sub-sub-option = choice。例:options.dynamical_decoupling.enable = True

例:

SamplerV2EstimatorV2 はそれぞれ独立したオプションクラスを持っています(EstimatorOptions および SamplerOptions)。

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator
from qiskit_ibm_runtime.options import EstimatorOptions

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

options = EstimatorOptions(
resilience_level=2,
resilience={"zne_mitigation": True, "zne": {"noise_factors": [1, 3, 5]}},
)

# or...
options = EstimatorOptions()
options.resilience_level = 2
options.resilience.zne_mitigation = True
options.resilience.zne.noise_factors = [1, 3, 5]

estimator = Estimator(mode=backend, options=options)

辞書

プリミティブを初期化する際に、オプションを辞書として指定できます。

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

# Setting options during primitive initialization
estimator = Estimator(
backend,
options={
"resilience_level": 2,
"resilience": {
"zne_mitigation": True,
"zne": {"noise_factors": [1, 3, 5]},
},
},
)

初期化後のオプション更新

オートコンプリートを活用するために、primitive.options.option.sub-option.sub-sub-option = choice の形式でオプションを指定するか、update() メソッドを使用して一括更新を行うことができます。

プリミティブの初期化後にオプションを設定する場合、SamplerV2 および EstimatorV2 のオプションクラス(EstimatorOptions および SamplerOptions)をインスタンス化する必要はありません。

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

estimator = Estimator(mode=backend)

# Setting options after primitive initialization
# This uses auto-complete.
estimator.options.default_shots = 4000
# This does bulk update.
estimator.options.update(
default_shots=4000, resilience={"zne_mitigation": True}
)

Run() メソッド

run() に渡すことができる値は、インターフェースで定義されているものだけです。つまり、Sampler の場合は shots、Estimator の場合は precision です。これにより、現在の実行における default_shots または default_precision に設定された値が上書きされます。

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit.circuit.library import random_iqp
from qiskit.transpiler import generate_preset_pass_manager

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

circuit1 = random_iqp(3)
circuit1.measure_all()
circuit2 = random_iqp(3)
circuit2.measure_all()

pass_manager = generate_preset_pass_manager(
optimization_level=3, backend=backend
)

transpiled1 = pass_manager.run(circuit1)
transpiled2 = pass_manager.run(circuit2)

sampler = Sampler(mode=backend)
# Default shots to use if not specified in run()
sampler.options.default_shots = 500
# Sample two circuits at 128 shots each.
sampler.run([transpiled1, transpiled2], shots=128)

# Sample two circuits with different numbers of shots.
# 100 shots is used for transpiled1 and 200 for transpiled.
sampler.run([(transpiled1, None, 100), (transpiled2, None, 200)])
<RuntimeJobV2('d5k96cn853es738djikg', 'sampler')>

特殊なケース

レジリエンスレベル(Estimator のみ)

レジリエンスレベルは、プリミティブのクエリに直接影響するオプションではなく、基盤となる厳選されたオプションセットを指定するものです。一般的に、レベル 0 はすべてのエラー緩和をオフにし、レベル 1 は測定エラー緩和のオプションをオンにし、レベル 2 はゲートおよび測定エラー緩和のオプションをオンにします。

レジリエンスレベルに加えて手動で指定したオプションは、レジリエンスレベルによって定義された基本オプションセットの上に適用されます。したがって、原則として、レジリエンスレベルを 1 に設定した後に測定緩和をオフにすることも可能ですが、これは推奨されません。

以下の例では、レジリエンスレベルを 0 に設定すると最初は zne_mitigation がオフになりますが、estimator.options.resilience.zne_mitigation = True により estimator.options.resilience_level = 0 からの関連設定が上書きされます。

from qiskit_ibm_runtime import EstimatorV2, QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

estimator = EstimatorV2(backend)

estimator.options.default_shots = 100
estimator.options.resilience_level = 0
estimator.options.resilience.zne_mitigation = True

ショット数(Sampler のみ)

SamplerV2.run メソッドは 2 つの引数を受け付けます。1 つは PUB のリスト(各 PUB は PUB 固有のショット数を指定可能)で、もう 1 つは shots キーワード引数です。これらのショット値は Sampler 実行インターフェースの一部であり、Runtime Sampler のオプションとは独立しています。Sampler の抽象化に準拠するため、オプションとして指定された値よりも優先されます。

ただし、shots がいずれの PUB でも run キーワード引数でも指定されていない場合(またはすべてが None の場合)、オプションのショット値、特に default_shots が使用されます。

まとめると、Sampler の特定の PUB に対してショット数を指定する際の優先順位は次のとおりです:

  1. PUB でショット数が指定されている場合、その値を使用します。
  2. run 内で shots キーワード引数が指定されている場合、その値を使用します。
  3. num_randomizationsshots_per_randomizationtwirling オプションとして指定されている場合、ショット数はそれらの積になります。
  4. sampler.options.default_shots が指定されている場合、その値を使用します。

したがって、すべての場所でショット数が指定されている場合、最も優先度の高いもの(PUB で指定されたショット数)が使用されます。

精度(Estimator のみ)

精度は前のセクションで説明したショット数に類似していますが、Estimator のオプションには default_shotsdefault_precision の両方が含まれる点が異なります。また、ゲートトワーリングがデフォルトで有効になっているため、num_randomizationsshots_per_randomization の積はこれら 2 つのオプションよりも優先されます。

具体的には、特定の Estimator PUB に対して:

  1. PUB で精度が指定されている場合、その値を使用します。
  2. run 内で precision キーワード引数が指定されている場合、その値を使用します。
  3. twirling オプションとして num_randomizationsshots_per_randomization が指定されている場合(デフォルトで有効)、データ量の制御にそれらの積を使用します。
  4. estimator.options.default_shots が指定されている場合、その値をデータ量の制御に使用します。
  5. estimator.options.default_precision が指定されている場合、その値を使用します。

例えば、4 か所すべてで精度が指定されている場合、最も優先度の高いもの(PUB で指定された精度)が使用されます。

備考

精度は使用量と反比例します。つまり、精度が低いほど、実行に必要な QPU 時間が長くなります。

よく使われるオプション

利用可能なオプションは多数ありますが、以下が最もよく使われるものです:

ショット数

一部のアルゴリズムでは、特定のショット数を設定することがルーティンの核心部分です。ショット数(または精度)は複数の場所で指定できます。優先順位は次のとおりです:

Sampler の任意の PUB に対して:

  1. PUB に含まれる整数値のショット数
  2. run(...,shots=val) の値
  3. options.default_shots の値

Estimator の任意の PUB に対して:

  1. PUB に含まれる浮動小数点値の精度
  2. run(...,precision=val) の値
  3. options.default_shots の値
  4. options.default_precision の値

例:

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit.circuit.library import random_iqp
from qiskit.transpiler import generate_preset_pass_manager

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

circuit1 = random_iqp(3)
circuit1.measure_all()
circuit2 = random_iqp(3)
circuit2.measure_all()

pass_manager = generate_preset_pass_manager(
optimization_level=3, backend=backend
)

transpiled1 = pass_manager.run(circuit1)
transpiled2 = pass_manager.run(circuit2)

# Setting shots during primitive initialization
sampler = Sampler(mode=backend, options={"default_shots": 4096})

# Setting options after primitive initialization
# This uses auto-complete.
sampler.options.default_shots = 2000

# This does bulk update. The value for default_shots is overridden if you specify shots with run() or in the PUB.
sampler.options.update(
default_shots=1024, dynamical_decoupling={"sequence_type": "XpXm"}
)

# Sample two circuits at 128 shots each.
sampler.run([transpiled1, transpiled2], shots=128)
<RuntimeJobV2('d5k96icjt3vs73ds5t0g', 'sampler')>

最大実行時間

最大実行時間(max_execution_time)は、ジョブの実行時間の上限を制限します。ジョブがこの時間制限を超えた場合、強制的にキャンセルされます。この値は、ジョブ、セッション、バッチモードのいずれで実行されるかに関わらず、単一のジョブに適用されます。

値は秒単位で設定され、量子時間(ウォールクロック時間ではなく)に基づいています。量子時間とは、QPU がジョブの処理に専念している時間のことです。このモードは量子時間を使用しないため、ローカルテストモードを使用する場合は無視されます。

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

estimator = Estimator(mode=backend)

estimator.options.max_execution_time = 2500

すべてのエラー緩和とエラー抑制をオフにする

例えば、独自の緩和技術に関する研究を行っている場合など、すべてのエラー緩和と抑制をオフにすることができます。これを実現するには、EstimatorV2 の場合は resilience_level = 0 を設定します。SamplerV2 の場合は、デフォルトでエラー緩和または抑制のオプションが有効になっていないため、変更は必要ありません。

例:

Estimator のすべてのエラー緩和と抑制をオフにします。

from qiskit_ibm_runtime import EstimatorV2 as Estimator, QiskitRuntimeService

# Define the service. This allows you to access IBM QPU.
service = QiskitRuntimeService()

# Get a backend
backend = service.least_busy(operational=True, simulator=False)

# Define Estimator
estimator = Estimator(backend)

options = estimator.options

# Turn off all error mitigation and suppression
options.resilience_level = 0

次のステップ

推奨事項