Skip to main content
IBM Quantum Platform

NoiseLearner から NoiseLearnerV3 への移行

このガイドでは、 IBM Quantum® から NoiseLearner へ移行する手順を順を追って説明します NoiseLearnerV3。 どちらの クラスも、 パウリ・リンドブラッドのノイズモデルに基づいてノイズ過程を特徴づける実験を行いますが、入力と 出力は若干異なります。


背景

この NoiseLearner クラスは、ユーザーが明示的なノイズ学習を行えるようにするために作成されました。 こうして得られた ノイズモデルを、 IBM Quantum に渡して、 PEA や PEC といった誤差低減手法を適用Estimatorすることができます。

NoiseLearner は と連携して動作するように設計されており Estimator、したがって、暗黙のうちに と同じレイヤー検索戦略を採用している Estimator。 この戦略を変更することはできません。変更すると、その後の 緩和措置が正しく機能しなくなります。

v0.47.0 以降、 qiskit-ibm-runtimeプリミティブExecutor実行モデルおよび 有向実行モデルと互換性のある新しい NoiseLearnerV3 クラスが導入されました。 この新しいモデルは、クライアント側で設計意図を反映するための要素を提供することでホワイトボックス型の体験を実現し、 サーバー側の単一のプリミティブ(Executor)が、それらの入力を指示通りに正確に処理します。 つまり、ユーザーに代わって暗黙的な判断を行うことはありません。 元のバージョンとは異なり NoiseLearner、 このクラスを使用NoiseLearnerV3する際は、回路の階層化方法を自分で制御でき、クラスは単にボックス化された回路の指示のリスト (例えば、固有のレイヤーなど)を入力として受け取ります。

NoiseLearnerV3 また、測定ノイズの学習にも対応しています。 入力リストの各命令について、ボックスに1クビットゲートおよび2クビットゲートが含まれている場合は パウリ・リンドブラッド学習プロトコルを、測定が含まれている場合はTRE X プロトコルを実行する。


移行すべきでしょうか?

NoiseLearner レガシーなサーバーサイドでのみ動作し Estimator、また Executor およびクライアントサイドでのみNoiseLearnerV3動作します Estimator。 以下のいずれかを使用している場合は NoiseLearnerV3 、 Executor へ移行する必要があります。またはクライアントサイド Estimator. 従来のサーバーサイド機能は非推奨となっており Estimator 、 v0.50.0 では qiskit-ibm-runtime 、これに対応するクライアントサイドの機能に置き換えられています。

Note

v0.50.0qiskit-ibm-runtime 以降をご利用の場合は、まず「 サーバーサイドからクライアントサイドへのサンプラーおよびエスティメータの移行」 ガイドを参照し、クライアントサイドプリミティブへの移行を行ってください。


マイグレーション・ステップ

手順 1:インポートを変更する

NoiseLearner:

from qiskit_ibm_runtime.noise_learner import NoiseLearner

NoiseLearnerV3:

from qiskit_ibm_runtime import NoiseLearnerV3

ステップ 2:入力内容を更新する

このメソッド NoiseLearner``run() は回路またはPUBのリストを受け取るのに対し、このメソッド NoiseLearnerV3``run() は命令のリストを受け取ります。各命令は、ISAオペレーションを含む BoxOp 、twirling注釈が付けられたものでなければなりません。 使用するプリミティブに応じて、アノテーション付きボックスを生成するための便利な方法が用意されています

NoiseLearner:

from qiskit_ibm_runtime.noise_learner import NoiseLearner

learner = NoiseLearner(mode=backend)
# `circuits_to_learn` is a list of ISA QuantumCircuit
learner_job = learner.run(circuits_to_learn)

NoiseLearnerV3, クライアントサイドのEstimatorを使用する場合:

回路の実行にクライアントサイドのEstimatorを使用する予定の場合は、Estimatorの メソッド find_unique_layers を使用して、アノテーション付きボックス(レイヤー)を作成できます:

from qiskit_ibm_runtime.executor_estimator import Estimator
from qiskit_ibm_runtime import NoiseLearnerV3

pubs = [...]  # Your PUBs
estimator = Estimator(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(backend)
learner_job = learner.run(layers)

NoiseLearnerV3, Executor を使用する際は:

回路の実行にExecutorを使用する予定の場合は、 Samplomaticの generate_boxing_pass_manager 関数を使用して、アノテーション付きボックスを作成することを検討してください:

from qiskit_ibm_runtime.noise_learner_v3 import NoiseLearnerV3
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic.utils import find_unique_box_instructions

# Run the boxing pass manager to group instructions into annotated boxes.
# `isa_circuit` is an ISA QuantumCircuit.
boxing_pm = generate_boxing_pass_manager(
    enable_gates=True,
    enable_measures=False,
    inject_noise_targets="gates",  # no measurement mitigation
    inject_noise_strategy="uniform_modification",
)
boxed_circuit = boxing_pm.run(isa_circuit)

# Find unique boxed instructions.
unique_box_instructions = find_unique_box_instructions(boxed_circuit.data)

# Instantiate a NoiseLearnerV3 object and execute the noise learning program.
learner = NoiseLearnerV3(backend)
learner_job = learner.run(unique_box_instructions)

ステップ3:オプションを変換する

以下の例外を除き NoiseLearnerV3Options、ほとんどのフィールド NoiseLearnerOptions は に直接対応しています:

  • max_layers_to_learn: の場合 NoiseLearnerV3、学習対象となる層の数は、渡された層の数に基づいて決定されます。
  • twirling_strategy: では NoiseLearnerV3、ツイリング戦略は、命令のボックス化や注釈の付け方(例えば、を使用する場合など generate_boxing_pass_manager())によって定義されます。

NoiseLearner:

from qiskit_ibm_runtime.noise_learner import NoiseLearner
from qiskit_ibm_runtime.options import NoiseLearnerOptions

# Instantiate a NoiseLearnerOptions object
learner_options = NoiseLearnerOptions(
    max_layers_to_learn=3, num_randomizations=32, twirling_strategy="all"
)

learner = NoiseLearner(mode=backend, options=learner_options)
learner_job = learner.run(circuits_to_learn)

NoiseLearnerV3, クライアントサイドのEstimatorを使用する場合:

回路の実行にクライアントサイドのEstimatorを使用する予定の場合は、 Estimator twirling.strategy オプションを次のように設定できます:

from qiskit_ibm_runtime.executor_estimator import Estimator
from qiskit_ibm_runtime import NoiseLearnerV3
from qiskit_ibm_runtime.options_models import NoiseLearnerV3Options

pubs = [...]  # Your PUBs
estimator = Estimator(backend)
estimator.options.resilience.pec_mitigation = True  # or zne_mitigation + pea amplifier
estimator.options.twirling.strategy = "all"  # set twirling strategy here

# Identify the unique layers to learn.
layers = estimator.find_unique_layers(pubs)

# Instantiate a NoiseLearnerV3 object and execute the noise learning program
learner_options = NoiseLearnerV3Options(num_randomizations=32)
learner = NoiseLearnerV3(backend, options=learner_options)

# Learn just the first 3 layers.
learner_job = learner.run(layers[:3])

NoiseLearnerV3, Executor を使用する際は:

回路の実行にExecutorを使用する予定の場合は、 generate_boxing_pass_manager 関数にこの twirling_strategy オプションを渡すことができます。

なお、の場合 generate_boxing_pass_manager()、の値 twirling_strategy にはアンダースコア ("active_accum", "active_circuit") が使用されるのに対し、の NoiseLearnerOptions.twirling_strategy 値にはハイフン ("active-accum", "active-circuit") が使用されることに注意してください。

from qiskit_ibm_runtime.noise_learner_v3 import NoiseLearnerV3
from qiskit_ibm_runtime.options_models import NoiseLearnerV3Options
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic.utils import find_unique_box_instructions

# Run the boxing pass manager to group instructions into annotated boxes
# `isa_circuit` is an ISA QuantumCircuit
boxing_pm = generate_boxing_pass_manager(
    enable_gates=True,
    enable_measures=False,
    twirling_strategy="all",  # twirling strategy can be specified here
    inject_noise_targets="gates",
    inject_noise_strategy="uniform_modification",
)
boxed_circuit = boxing_pm.run(isa_circuit)

# Find unique boxed instructions
unique_box_instructions = find_unique_box_instructions(boxed_circuit.data)

learner_options = NoiseLearnerV3Options(num_randomizations=32)

# Instantiate a NoiseLearnerV3 object and execute the noise learning program
learner = NoiseLearnerV3(backend, options=learner_options)
# Learn just the first 3 layers.
learner_job = learner.run(unique_box_instructions[:3])

ステップ4:結果を確認する

と NoiseLearner の出力には同様の情報が含まれて NoiseLearnerV3 いますが、形式が異なります。 出力内容を明示的に確認している場合は、コードを更新してください。

Result属性のマッピング:

(learner_result は学習ジョブの出力です)

属性
NoiseLearner
NoiseLearnerV3
結果のタイプNoiseLearnerResultNoiseLearnerV3Results は、 NoiseLearnerV3Result のシーケンスのようなコンテナです
学習済み層の数len( learner_result.data )len(learner_result)
第1層のデータlayer_error = learner_result.data[0]noise_map = learner_result[0].to_pauli_lindblad_map()
各レイヤーの結果タイプLayerError (type(layer_error))PauliLindbladMap (type(noise_map))
エラーチャネル用のジェネレータlayer_error.error.generatorsnoise_map.generators()
エラー率layer_error.error.ratesnoise_map.rates

ステップ 5:プリミティブにノイズモデルを入力する

NoiseLearner レガシーなサーバーサイドでのみ動作し Estimator、また Executor 、クライアントサイドでのみ NoiseLearnerV3 動作します Estimator。 ノイズモデルの指定方法は、使用するプリミティブによって若干異なります。

NoiseLearner、レガシーなサーバーサイドのEstimatorを使用する場合:

from qiskit_ibm_runtime import Estimator as LegacyEstimator

learner_result = learner_job.result()

# Pass the noise model to the `estimator.options` attribute directly
estimator = LegacyEstimator(mode=backend)
estimator.options.resilience.layer_noise_model = learner_result
job = estimator.run(pubs)

NoiseLearnerV3, クライアントサイドのEstimatorを使用する場合:

手順 2 で layers 生成した Estimator ものを再利用してください。 学習器によって返されるノイズマップは、 それらのレイヤーと位置的に一致しているため、それらは元の推定器に 割り当てる必要があります。 手順 2 で、そのデバイスではすでに PEA/PEC が有効化されていました。

なお、はパウリ・リンドブラッドプロトコルとTREXプロトコルの両方をサポート NoiseLearnerV3 していますが、はパウリ・リンドブラッドプロトコルを用いて学習された2量子ビット層のノイズ Estimator モデルのみを受け入れます。

learner_result = learner_job.result()

# Convert results to Pauli-Lindblad noise maps.
pauli_lindblad_maps = learner_result.to_pauli_lindblad_maps()

# Assign the learned noise maps so PEA/PEC uses them.
estimator.options.resilience.layer_noise_model = zip(layers, pauli_lindblad_maps)

# Now execute the target PUBs.
job = estimator.run(pubs)

NoiseLearnerV3, Executor を使用する際は:

from qiskit_ibm_runtime import Executor
from qiskit_ibm_runtime.quantum_program import QuantumProgram

# Generate a quantum program
program = QuantumProgram(shots=1000)

# Convert the NoiseLearnerV3 result to a dictionary
learner_result = learner_job.result()
noise_maps = learner_result.to_dict(
    instructions=unique_box_instructions, require_refs=False
)

# Append the samplex item and execute
program.append_samplex_item(
    template_circuit,
    samplex=samplex,
    samplex_arguments={
        "pauli_lindblad_maps": noise_maps,
    },
)

executor = Executor(backend)
executor_job = executor.run(program)

完全な例

NoiseLearnerV3 およびクライアントサイドの推定器

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, NoiseLearnerV3
from qiskit_ibm_runtime.executor_estimator import Estimator


# 1. Account + backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

# 2. Circuit + observable
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)

observable = SparsePauliOp("ZZ")

# 3. Transpile to ISA
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)
pubs = [(isa_circuit, isa_observable)]

# 4. Initialize Estimator with options
estimator = Estimator(backend)
estimator.options.resilience.pec_mitigation = True

# 5. Extract the unique boxed layers from PUBs
layers = estimator.find_unique_layers(pubs)

# 6. Learn the noise model for those layers
learner = NoiseLearnerV3(backend)
learner_job = learner.run(layers)
learner_result = learner_job.result()

# 7. Convert the result to Pauli-Lindblad maps and pass them to Estimator
pauli_lindblad_maps = learner_result.to_pauli_lindblad_maps()
estimator.options.resilience.layer_noise_model = zip(layers, pauli_lindblad_maps)

# 8. Execute the target PUBs
job = estimator.run(pubs)
result = job.result()

NoiseLearnerV3 および遺言執行者

from qiskit import QuantumCircuit
from qiskit.transpiler import generate_preset_pass_manager

from qiskit_ibm_runtime import QiskitRuntimeService, Executor, NoiseLearnerV3
from qiskit_ibm_runtime.quantum_program import QuantumProgram

from samplomatic import build
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic.utils import find_unique_box_instructions


# 1. Account + backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

# 2. Circuit + observable
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()

# 3. Transpile to ISA
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)

# 4. Run the boxing pass manager to group instructions into annotated boxes
boxing_pm = generate_boxing_pass_manager(
    enable_gates=True,
    enable_measures=False,
    inject_noise_targets="gates",  # no measurement mitigation
    inject_noise_strategy="uniform_modification",
)
boxed_circuit = boxing_pm.run(isa_circuit)

# 5. Find unique boxed instructions (layers)
unique_box_instructions = find_unique_box_instructions(boxed_circuit.data)

# 6. Learn the noise model for those layers
learner = NoiseLearnerV3(backend)
learner_job = learner.run(unique_box_instructions)
learner_result = learner_job.result()

# 7. Convert the NoiseLearnerV3 result to a dictionary
noise_maps = learner_result.to_dict(
    instructions=unique_box_instructions, require_refs=False
)

# 8. Build the template circuit and samplex pair
template_circuit, samplex = build(boxed_circuit)

# 9. Prepare a quantum program
program = QuantumProgram(shots=1000)
program.append_samplex_item(
    template_circuit,
    samplex=samplex,
    samplex_arguments={
        "pauli_lindblad_maps": noise_maps,
    },
)

executor = Executor(backend)
job = executor.run(program)
result = job.result()

参照

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