Qiskit Runtimeのノイズのあるシミュレーター¶
このノートブックは、 ibmq_qasm_simulator
をセットアップし、Qiskit Runtime でIBM Quantumハードウェア・デバイス用の基本的なノイズモデルをマッピングする方法を示します。 実際のデバイスで発生するエラーの影響を調べるために、このノイズモデルを使用して、 Sampler
と Estimator
上で QuantumCircuits
のノイズ・シミュレーションを行います。
ローカル開発環境のセットアップ¶
このチュートリアルでは、Qiskit Runtime サービス・インスタンスが必要です。まだ実行していない場合は、これらの手順 に従ってセットアップしてください。
# load necessary Runtime libraries
from qiskit_ibm_runtime import QiskitRuntimeService, Sampler, Estimator, Session, Options
service = QiskitRuntimeService(channel="ibm_quantum")
環境の準備¶
デモンストレーションをするために、サンプル・ルーチンを実行していきましょう。 primitiveを使用する主な利点の 1 つは、パラメーター化された回路で、複数のパラメーターの結合を単純化することです。 これを確認するために、制御 P ゲート を持つ回路の例を以下のコードに示します。 ここでは、P-gate
を回転パラメーター theta
でパラメーター化します。 Qiskitを使用して回路作成しパラメーターを結合する方法を学習するには、 Qiskit ドキュメンテーションの 回路の基本 および 回路の応用 を参照してください。
from qiskit.circuit import Parameter
from qiskit import QuantumCircuit
theta = Parameter('theta')
qc = QuantumCircuit(2,1)
qc.x(1)
qc.h(0)
qc.cp(theta,0,1)
qc.h(0)
qc.measure(0,0)
qc.draw('mpl')

前のセルで示した回路は、測定する量子ビット0にキックバックされる固有値でパラメーター化されます。 キックバックの量はパラメーター thetaによって決定されます。 以下のセルでは、上記の回路のパラメーターをリストとして定義します。 ここでのパラメーターは、 \(0\) から \(2\pi\) までで、50個の均等な間隔の点に分けられます。
import numpy as np
phases = np.linspace(0, 2*np.pi, 50)
# phases need to be expressed as a list of lists in order to work
individual_phases = [[phase] for phase in phases]
理想的なシミュレーターでの実行¶
使用するバックエンドとオプションの設定¶
最初に、Sampler と Estimator の両方で noise_model
、optimization_level
または reverence_level
がない理想的なケースを使用して実行することを示します。 以下のコードではオプションの設定に進みます。
backend = "ibmq_qasm_simulator" # use the simulator
options = Options()
options.simulator.seed_simulator = 42
options.execution.shots = 1000
options.optimization_level = 0 # no optimization
options.resilience_level = 0 # no error mitigation
Samplerでの回路の実行¶
ここで、 Sampler primitive を使用して回路をサンプリングし、結果の確率分布を取得します。 Sampler
primitive の使用方法および Qiskit Runtime Sessionの使用開始方法については、次のチュートリアルで確認することができます: `Sampler primitive 入門<https://qiskit.org/documentation/partners/qiskit_ibm_runtime/tutorials/how-to-getting-started-with-sampler.html>`__
with Session(service=service, backend=backend):
sampler = Sampler(options=options)
job = sampler.run(
circuits=[qc]*len(phases),
parameter_values=individual_phases
)
result = job.result()
import matplotlib.pyplot as plt
# the probablity of being in the 1 state for each of these values
prob_values = [dist.get(1, 0) for dist in result.quasi_dists]
plt.plot(phases, prob_values, 'o', label='Simulator')
plt.plot(phases, np.sin(phases/2,)**2, label='Theory')
plt.xlabel('Phase')
plt.ylabel('Probability')
plt.legend()
<matplotlib.legend.Legend at 0x7f7fd233b6d0>

Estimatorでの回路の実行¶
Estimator のためのセッションを開始する方法を学ぶには、次のチュートリアルの確認してください: Estimator primitive 入門
このEstimatorは、量子演算子の期待値を返す前に、単一量子ビット回転を結合してハミルトニアンを得ます。 したがって、回路は測定を必要としません。現在の回路 qc
には測定がありますので、remove_final_measurements
でこれを削除します。
qc_no_meas = qc.remove_final_measurements(inplace=False)
qc_no_meas.draw('mpl')

from qiskit.quantum_info import SparsePauliOp
ZZ = SparsePauliOp.from_list([("ZZ", 1)])
print(f" > Observable: {ZZ.paulis}")
> Observable: ['ZZ']
この観測量を使用すると、期待値は以下の式で計算されます。
次のセルは、ここで示したものを実装します。
with Session(service=service, backend=backend):
estimator = Estimator(options=options)
job = estimator.run(
circuits=[qc_no_meas]*len(phases),
parameter_values=individual_phases,
observables=[ZZ]*len(phases)
)
result = job.result()
exp_values = result.values
plt.plot(phases, exp_values, 'o', label='Simulator')
plt.plot(phases, 2*np.sin(phases/2)**2-1, label='Theory')
plt.xlabel('Phase')
plt.ylabel('Expectation')
plt.legend()
<matplotlib.legend.Legend at 0x7f7fd0ed8820>

ノイズのあるシミュレーションの実行¶
次に、理想的なシミュレーションではなく、ノイズのあるシミュレーションを実行するためのシミュレーターを設定します。 Options
パラメーターに指定することで、Runtime のシミュレーターにカスタムの noise_model
を渡すことができます。 ここでは実際のバックエンドを模倣し、FakeBackend
クラスから noise_model
をマップします。 ノイズモデルは FakeBackend
から抽出し、オプションの simulator
パラメーターとして渡すことができます。 fake_provider
についてもっと知りたい場合は、Qiskit ドキュメンテーションの Fake Provider を参照してください。
本物のバックエンドを模倣しようとしているので、より現実的なノイズ・シミュレーションをサポートするための、バックエンドのトポロジーを表す coupling_map
と、バックエンドがサポートする ``basis_gates``を渡すこともできます。
from qiskit.providers.fake_provider import FakeManila
from qiskit_aer.noise import NoiseModel
# Make a noise model
fake_backend = FakeManila()
noise_model = NoiseModel.from_backend(fake_backend)
# Set options to include the noise model
options = Options()
options.simulator = {
"noise_model": noise_model,
"basis_gates": fake_backend.configuration().basis_gates,
"coupling_map": fake_backend.configuration().coupling_map,
"seed_simulator": 42
}
# Set number of shots, optimization_level and resilience_level
options.execution.shots = 1000
options.optimization_level = 0
options.resilience_level = 0
ibmq_qasm_simulator
は、Qiskit Runtime Service が提供する resilience_levels
を有効にします。 シミュレーターでこれらのレベルを使用することで、以前のようなノイズのあるシミュレーションが最もよくデモンストレーションされます。
比較を見るには、Options
の2つのセットを定義します。 ibmq_qasm_simulator
シミュレーターは、Qiskit Runtimeによって提供されるresilienceレベルを有効化します。シミュレーターでのこれらのレベルを使うには我々が構築したノイズのあるシミュレーションを使ってデモを行うことが最適です。 ここで、options
はエラー緩和なしの通常の実行を表すために resilience level
= 0
に設定されます。 そして options with em
は resilience level
= 1
に設定され、エラー緩和が有効になっている実行を表します。
# Set options to include the noise model with error mitigation
options_with_em = Options()
options_with_em.simulator = {
"noise_model": noise_model,
"basis_gates": fake_backend.configuration().basis_gates,
"coupling_map": fake_backend.configuration().coupling_map,
"seed_simulator": 42
}
# Set number of shots, optimization_level and resilience_level
options_with_em.execution.shots = 1000
options_with_em.optimization_level = 0 # no optimization
options_with_em.resilience_level = 1 # M3 for Sampler and T-REx for Estimator
resilience_level
を 1 に設定すると、SamplerでM3が有効になります。利用可能なすべてのresilienceレベルの設定は、 ここ で確認できます。
with Session(service=service, backend=backend):
# include the noise model without M3
sampler = Sampler(options=options)
job = sampler.run(
circuits=[qc]*len(phases),
parameter_values=individual_phases
)
result = job.result()
prob_values = [1-dist[0] for dist in result.quasi_dists]
# include the noise model with M3
sampler = Sampler(options=options_with_em)
job = sampler.run(
circuits=[qc]*len(phases),
parameter_values=individual_phases
)
result = job.result()
prob_values_with_em = [1-dist[0] for dist in result.quasi_dists]
plt.plot(phases, prob_values, 'o', label='Noisy')
plt.plot(phases, prob_values_with_em, 'o', label='Mitigated')
plt.plot(phases, np.sin(phases/2,)**2, label='Theory')
plt.xlabel('Phase')
plt.ylabel('Probability')
plt.legend()
<matplotlib.legend.Legend at 0x7f7fb4230700>

T-REx
はresilienceレベルが 1 に設定されている場合に、Estimator で起動されます。
with Session(service=service, backend=backend):
# include the noise model without T-REx
estimator = Estimator(options=options)
job = estimator.run(
circuits=[qc_no_meas]*len(phases),
parameter_values=individual_phases,
observables=[ZZ]*len(phases)
)
result = job.result()
exp_values = result.values
# include the noise model with T-REx
estimator = Estimator(options=options_with_em)
job = estimator.run(
circuits=[qc_no_meas]*len(phases),
parameter_values=individual_phases,
observables=[ZZ]*len(phases))
result = job.result()
exp_values_with_em = result.values
plt.plot(phases, exp_values, 'o', label='Noisy')
plt.plot(phases, exp_values_with_em, 'o', label='Mitigated')
plt.plot(phases, 2*np.sin(phases/2)**2-1, label='Theory')
plt.xlabel('Phase')
plt.ylabel('Expectation')
plt.legend()
<matplotlib.legend.Legend at 0x7f7f7006ca00>

Resilience レベルは現在ベータ版のため、サンプリングのオーバーヘッドとソリューションの品質は回路によって異なります。 新機能、高度なオプションおよび管理ツールは、順次リリースされます。 またより高いレベルのresilienceを設定し、それらによって提供される追加オプションを探索することもできます。 上記の例で示した M3 や T-REx に加えて、 Digital-ZNE や PEC のような機能の有効化についてもっと知りたい場合は、次のチュートリアルを確認してください: Qiskit Runtimeによるエラーの抑制とエラーの軽減
import qiskit_ibm_runtime
qiskit_ibm_runtime.version.get_version_info()
'0.8.0'
from qiskit.tools.jupyter import *
%qiskit_version_table
Version Information
Qiskit Software | Version |
---|---|
qiskit-terra | 0.22.2 |
qiskit-aer | 0.11.1 |
qiskit-ibmq-provider | 0.19.2 |
qiskit | 0.39.2 |
qiskit-nature | 0.5.0 |
qiskit-finance | 0.3.4 |
qiskit-optimization | 0.4.0 |
qiskit-machine-learning | 0.5.0 |
System information | |
Python version | 3.8.13 |
Python compiler | GCC 10.3.0 |
Python build | default, Mar 25 2022 06:04:10 |
OS | Linux |
CPUs | 8 |
Memory (Gb) | 31.211326599121094 |
Wed Nov 30 02:43:41 2022 UTC |