Debug kerja Qiskit Runtime
Versi pakej
Kod pada halaman ini dibangunkan menggunakan keperluan berikut. Kami mengesyorkan menggunakan versi ini atau yang lebih baharu.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
qiskit-aer~=0.17
Sebelum menghantar beban kerja Qiskit Runtime yang memerlukan sumber intensif untuk dilaksanakan pada perkakasan, anda boleh menggunakan kelas Qiskit Runtime Neat (Noisy Estimator Analyzer Tool) untuk mengesahkan bahawa beban kerja Estimator anda disediakan dengan betul, berkemungkinan mengembalikan keputusan yang tepat, menggunakan pilihan yang paling sesuai untuk masalah yang ditentukan, dan banyak lagi.
Neat melakukan proses Cliffordize ke atas Circuit input untuk simulasi yang lebih cekap, sambil mengekalkan struktur dan kedalamannya. Circuit Clifford mengalami tahap hingar yang serupa dan merupakan proksi yang baik untuk mengkaji Circuit asal yang diminati.
Contoh-contoh berikut menggambarkan situasi di mana Neat boleh menjadi sumber yang berguna.
Mula-mula, import pakej yang berkaitan dan sahkan diri kepada perkhidmatan Qiskit Runtime.
Sediakan persekitaranβ
# Added by doQumentation β required packages for this notebook
!pip install -q numpy qiskit qiskit-aer qiskit-ibm-runtime
import numpy as np
import random
from qiskit.circuit import QuantumCircuit
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp
from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator
from qiskit_ibm_runtime.debug_tools import Neat
from qiskit_aer.noise import NoiseModel, depolarizing_error
# Choose the least busy backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# Generate a preset pass manager
# This will be used to convert the abstract circuit to an equivalent Instruction Set Architecture (ISA) circuit.
pm = generate_preset_pass_manager(backend=backend, optimization_level=0)
# Set the random seed
random.seed(10)
Mulakan Circuit sasaranβ
Pertimbangkan Circuit enam-Qubit yang mempunyai sifat-sifat berikut:
- Berselang-seli antara putaran
RZrawak dan lapisan GateCNOT. - Mempunyai struktur cermin, iaitu, ia menggunakan unitary
Udiikuti dengan inversnya.
def generate_circuit(n_qubits, n_layers):
r"""
A function to generate a pseudo-random a circuit with ``n_qubits`` qubits and
``2*n_layers`` entangling layers of the type used in this notebook.
"""
# An array of random angles
angles = [
[random.random() for q in range(n_qubits)] for s in range(n_layers)
]
qc = QuantumCircuit(n_qubits)
qubits = list(range(n_qubits))
# do random circuit
for layer in range(n_layers):
# rotations
for q_idx, qubit in enumerate(qubits):
qc.rz(angles[layer][q_idx], qubit)
# cx gates
control_qubits = (
qubits[::2] if layer % 2 == 0 else qubits[1 : n_qubits - 1 : 2]
)
for qubit in control_qubits:
qc.cx(qubit, qubit + 1)
# undo random circuit
for layer in range(n_layers)[::-1]:
# cx gates
control_qubits = (
qubits[::2] if layer % 2 == 0 else qubits[1 : n_qubits - 1 : 2]
)
for qubit in control_qubits:
qc.cx(qubit, qubit + 1)
# rotations
for q_idx, qubit in enumerate(qubits):
qc.rz(-angles[layer][q_idx], qubit)
return qc
# Generate a random circuit
qc = generate_circuit(6, 3)
# Convert the abstract circuit to an equivalent ISA circuit.
isa_qc = pm.run(qc)
qc.draw("mpl", idle_wires=0)
Pilih operator Z Pauli tunggal sebagai observable dan gunakannya untuk memulakan blok kesatuan primitif (PUB).
# Initialize the observables
obs = ["ZIIIII", "IZIIII", "IIZIII", "IIIZII", "IIIIZI", "IIIIIZ"]
print(f"Observables: {obs}")
# Map the observables to the backend's layout
isa_obs = [SparsePauliOp(o).apply_layout(isa_qc.layout) for o in obs]
# Initialize the PUBs, which consist of six-qubit circuits with `n_layers` 1, ..., 6
all_n_layers = [1, 2, 3, 4, 5, 6]
pubs = [(pm.run(generate_circuit(6, n)), isa_obs) for n in all_n_layers]
Observables: ['ZIIIII', 'IZIIII', 'IIZIII', 'IIIZII', 'IIIIZI', 'IIIIIZ']
Cliffordize Circuitβ
Circuit PUB yang ditakrifkan sebelum ini bukan Clifford, yang menjadikannya sukar untuk disimulasikan secara klasik. Walau bagaimanapun, anda boleh menggunakan kaedah Neat to_clifford untuk memetakannya ke Circuit Clifford bagi simulasi yang lebih cekap. Kaedah to_clifford adalah pembungkus sekitar laluan Transpiler ConvertISAToClifford, yang juga boleh digunakan secara bebas. Khususnya, ia menggantikan Gate satu-Qubit bukan-Clifford dalam Circuit asal dengan Gate satu-Qubit Clifford, tetapi tidak mengubah Gate dua-Qubit, bilangan Qubit, atau kedalaman Circuit.
Lihat Simulasi cekap Circuit stabilizer dengan primitif Qiskit Aer untuk maklumat lanjut tentang simulasi Circuit Clifford.
Mula-mula, mulakan Neat.
# You could specify a custom `NoiseModel` here. If `None`, `Neat`
# pulls the noise model from the given backend
noise_model = None
# Initialize `Neat`
analyzer = Neat(backend, noise_model)
Seterusnya, Cliffordize PUB.
clifford_pubs = analyzer.to_clifford(pubs)
clifford_pubs[0].circuit.draw("mpl", idle_wires=0)
Aplikasi 1: Analisis kesan hingar ke atas output Circuitβ
Contoh ini menunjukkan cara menggunakan Neat untuk mengkaji kesan model hingar yang berbeza ke atas PUB sebagai fungsi kedalaman Circuit dengan menjalankan simulasi dalam keadaan ideal (ideal_sim) dan berhingar (noisy_sim). Ini boleh berguna untuk menetapkan jangkaan terhadap kualiti keputusan eksperimen sebelum menjalankan kerja pada QPU. Untuk mengetahui lebih lanjut tentang model hingar, lihat Simulasi tepat dan berhingar dengan primitif Qiskit Aer.
Keputusan yang disimulasikan menyokong operasi matematik, dan oleh itu boleh dibandingkan antara satu sama lain (atau dengan keputusan eksperimen) untuk mengira angka merit.
QPU boleh dipengaruhi oleh pelbagai jenis hingar. Model hingar Qiskit Aer yang digunakan di sini hanya mensimulasikan sebahagian daripadanya dan oleh itu berkemungkinan kurang teruk berbanding hingar pada QPU sebenar.
Untuk butiran tentang ralat yang disertakan apabila memulakan model hingar dari QPU, lihat rujukan API Aer NoiseModel.
Mulakan dengan menjalankan simulasi klasik yang ideal dan berhingar.
# Perform a noiseless simulation
ideal_results = analyzer.ideal_sim(clifford_pubs)
print(f"Ideal results:\n {ideal_results}\n")
# Perform a noisy simulation with the backend's noise model
noisy_results = analyzer.noisy_sim(clifford_pubs)
print(f"Noisy results:\n {noisy_results}\n")
Ideal results:
NeatResult([NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.]))])
Noisy results:
NeatResult([NeatPubResult(vals=array([0.99023438, 0.99609375, 0.9921875 , 0.99023438, 0.99414062,
0.99414062])), NeatPubResult(vals=array([0.984375 , 0.99414062, 0.98242188, 0.98828125, 0.98632812,
0.99414062])), NeatPubResult(vals=array([0.96679688, 0.97070312, 0.95898438, 0.97851562, 0.98046875,
0.98828125])), NeatPubResult(vals=array([0.9453125 , 0.953125 , 0.97070312, 0.96875 , 0.98242188,
0.99023438])), NeatPubResult(vals=array([0.93164062, 0.9375 , 0.953125 , 0.96875 , 0.96484375,
0.98046875])), NeatPubResult(vals=array([0.92578125, 0.921875 , 0.93359375, 0.953125 , 0.95898438,
0.9765625 ]))])
Seterusnya, gunakan operasi matematik untuk mengira perbezaan mutlak. Selebihnya panduan ini menggunakan perbezaan mutlak sebagai angka merit untuk membandingkan keputusan ideal dengan keputusan berhingar atau eksperimen, tetapi angka merit yang serupa boleh disediakan.
Perbezaan mutlak menunjukkan bahawa kesan hingar meningkat seiring dengan saiz Circuit.
# Figure of merit: Absolute difference
def rdiff(res1, re2):
r"""The absolute difference between `res1` and re2`.
--> The closer to `0`, the better.
"""
d = abs(res1 - re2)
return np.round(d.vals * 100, 2)
for idx, (ideal_res, noisy_res) in enumerate(
zip(ideal_results, noisy_results)
):
vals = rdiff(ideal_res, noisy_res)
# Print the mean absolute difference for the observables
mean_vals = np.round(np.mean(vals), 2)
print(
f"Mean absolute difference between ideal and noisy results for circuits with {all_n_layers[idx]} layers:\n {mean_vals}%\n"
)
Mean absolute difference between ideal and noisy results for circuits with 1 layers:
0.72%
Mean absolute difference between ideal and noisy results for circuits with 2 layers:
1.17%
Mean absolute difference between ideal and noisy results for circuits with 3 layers:
2.6%
Mean absolute difference between ideal and noisy results for circuits with 4 layers:
3.16%
Mean absolute difference between ideal and noisy results for circuits with 5 layers:
4.4%
Mean absolute difference between ideal and noisy results for circuits with 6 layers:
5.5%
Anda boleh mengikuti garis panduan kasar dan ringkas ini untuk menambah baik Circuit jenis ini:
- Jika perbezaan mutlak min melebihi 90%, mitigasi berkemungkinan tidak akan membantu.
- Jika perbezaan mutlak min kurang daripada 90%, Probabilistic Error Amplification (PEA) berkemungkinan dapat meningkatkan keputusan.
- Jika perbezaan mutlak min kurang daripada 80%, ZNE dengan pelipatan Gate juga berkemungkinan dapat meningkatkan keputusan.
Oleh kerana semua perbezaan mutlak di atas kurang daripada 90%, menggunakan PEA pada Circuit asal diharapkan dapat meningkatkan kualiti keputusannya. Anda boleh menentukan model hingar yang berbeza dalam analyzer. Contoh berikut menjalankan ujian yang sama tetapi menambah model hingar tersuai.
# Set up a noise model with strength 0.02 on every two-qubit gate
noise_model = NoiseModel()
for qubits in backend.coupling_map:
noise_model.add_quantum_error(
depolarizing_error(0.02, 2), ["ecr", "cx"], qubits
)
# Update the analyzer's noise model
analyzer.noise_model = noise_model
# Perform a noiseless simulation
ideal_results = analyzer.ideal_sim(clifford_pubs)
# Perform a noisy simulation with the backend's noise model
noisy_results = analyzer.noisy_sim(clifford_pubs)
# Compare the results
for idx, (ideal_res, noisy_res) in enumerate(
zip(ideal_results, noisy_results)
):
values = rdiff(ideal_res, noisy_res)
# Print the mean absolute difference for the observables
mean_values = np.round(np.mean(values), 2)
print(
f"Mean absolute difference between ideal and noisy results for circuits with {all_n_layers[idx]} layers:\n {mean_values}%\n"
)
Mean absolute difference between ideal and noisy results for circuits with 1 layers:
0.0%
Mean absolute difference between ideal and noisy results for circuits with 2 layers:
0.0%
Mean absolute difference between ideal and noisy results for circuits with 3 layers:
0.0%
Mean absolute difference between ideal and noisy results for circuits with 4 layers:
0.0%
Mean absolute difference between ideal and noisy results for circuits with 5 layers:
0.0%
Mean absolute difference between ideal and noisy results for circuits with 6 layers:
0.0%
Seperti yang ditunjukkan, dengan model hingar yang diberikan, anda boleh cuba mengukur kesan hingar ke atas PUB (versi yang telah di-Cliffordize) yang diminati sebelum menjalankannya pada QPU.
Aplikasi 2: Bandingkan strategi yang berbezaβ
Contoh ini menggunakan Neat untuk membantu mengenal pasti pilihan terbaik untuk PUB anda. Untuk berbuat demikian, pertimbangkan untuk menjalankan masalah anggaran dengan PEA, yang tidak boleh disimulasikan dengan qiskit_aer. Anda boleh menggunakan Neat untuk membantu menentukan faktor amplifikasi hingar yang paling sesuai, kemudian gunakan faktor tersebut apabila menjalankan eksperimen asal pada QPU.
# Generate a circuit with six qubits and six layers
isa_qc = pm.run(generate_circuit(6, 3))
# Use the same observables as previously
pubs = [(isa_qc, isa_obs)]
clifford_pubs = analyzer.to_clifford(pubs)
noise_factors = [
[1, 1.1],
[1, 1.1, 1.2],
[1, 1.5, 2],
[1, 1.5, 2, 2.5, 3],
[1, 4],
]
# Run the PUBs on a QPU
estimator = Estimator(backend)
estimator.options.default_shots = 100000
estimator.options.twirling.enable_gates = True
estimator.options.twirling.enable_measure = True
estimator.options.twirling.shots_per_randomization = 100
estimator.options.resilience.measure_mitigation = True
estimator.options.resilience.zne_mitigation = True
estimator.options.resilience.zne.amplifier = "pea"
jobs = []
for factors in noise_factors:
estimator.options.resilience.zne.noise_factors = factors
jobs.append(estimator.run(clifford_pubs))
results = [job.result() for job in jobs]
# Perform a noiseless simulation
ideal_results = analyzer.ideal_sim(clifford_pubs)
# Look at the mean absolute difference to quickly tell the best choice for your options
for factors, res in zip(noise_factors, results):
d = rdiff(ideal_results[0], res[0])
print(
f"Mean absolute difference for factors {factors}:\n {np.round(np.mean(d), 2)}%\n"
)
Mean absolute difference for factors [1, 1.1]:
6.83%
Mean absolute difference for factors [1, 1.1, 1.2]:
8.76%
Mean absolute difference for factors [1, 1.5, 2]:
8.03%
Mean absolute difference for factors [1, 1.5, 2, 2.5, 3]:
10.17%
Mean absolute difference for factors [1, 4]:
8.02%
Keputusan dengan perbezaan terkecil mencadangkan pilihan mana yang perlu dipilih.
Langkah seterusnyaβ
- Ketahui tentang Simulasi tepat dan berhingar dengan primitif Qiskit Aer.
- Ketahui tentang pilihan Qiskit Runtime yang tersedia.
- Ketahui tentang teknik mitigasi dan penindasan ralat.
- Lawati topik Transpile dengan pengurus laluan.
- Ketahui cara mentranspile Circuit sebagai sebahagian daripada aliran kerja corak Qiskit menggunakan Qiskit Runtime.
- Semak dokumentasi API alat Penyahpepijatan.