Lewati ke konten utama
Proyek ini masih dalam tahap beta. Menemukan bug? Buat isu GitHub. Punya pertanyaan atau ide? Tanya di Discussions — kami sangat menghargai masukan kamu!
Bagaimana kualitas terjemahan di halaman ini?

Buat eksperimen pembelajaran

Tutorial ini menunjukkan cara membuat eksperimen pembelajaran standar dari nol, lalu memakainya untuk mempelajari sebuah model dari data noisy hasil simulasi.

  1. Definisikan gate set pada sebuah ring qubit

  2. Pilih model Pauli-Lindblad 2-local

  3. Bangun eksperimen pembelajaran

  4. Buat circuit

  5. Siapkan simulasi lokal

  6. Jalankan programnya

  7. Analisis datanya

Menjalankan di hardware asli

Circuit di bawah ini disimulasikan secara lokal, jadi panduan ini tidak butuh kredensial IBM Quantum®. Kalau mau menjalankannya di perangkat asli:

  • Langkah 1: ganti FakeMarrakesh dengan backend asli.

  • Langkah 5: berikan backend itu sebagai mode executor, dan hapus opsi simulator.

1. Definisikan gate set pada sebuah ring qubit​

Bangun QiskitGateSet dari Target sebuah backend dan subset qubit-nya — di sini sebuah ring dua belas qubit dari FakeMarrakesh — lalu tambahkan satu gate ke dalamnya: sebuah layer berisi enam gate CZ yang mencakup ring tersebut. Secara default, gate set diinisialisasi dengan gate persiapan P dan gate pengukuran M.

from qiskit_ibm_runtime.fake_provider import FakeMarrakesh

from qiskit_noise_learning.gate_sets import QiskitGateSet

backend = FakeMarrakesh()

qubit_subset = [*range(25, 30), *range(37, 39), *range(45, 50)]
cz_pairs = [(25, 26), (27, 28), (29, 38), (37, 45), (46, 47), (48, 49)]

gate_set = QiskitGateSet(backend.num_qubits, target=backend.target, qubit_subset=qubit_subset)

with gate_set.build_new_gate("cz_gate", latex_str=r"\mathrm{CZ}") as builder:
for pair in cz_pairs:
builder.circuit.cz(*pair)

list(gate_set)
['M', 'P', 'cz_gate']
Menjalankan di hardware asli
from qiskit_ibm_runtime import QiskitRuntimeService

backend = QiskitRuntimeService().backend("ibm_marrakesh")

Panggil draw() untuk melihat gate pada topologi perangkat: ring qubit di dalam gate set, dan pasangan mana saja di antaranya yang dientangle oleh gate tersebut.

gate_set.draw()

2. Pilih model Pauli-Lindblad 2-local​

Tentukan generator Pauli-Lindblad mana saja yang boleh dimiliki noise dengan PauliLindbladModel. Bangun himpunan generator itu dari konektivitas gate set dengan k_local() — di sini setiap Pauli 2-local pada pasangan qubit terhubung dari gate unitary, dan Pauli single-qubit untuk persiapan dan pengukuran.

from qiskit_noise_learning.models import PauliLindbladModel

model = PauliLindbladModel.k_local(gate_set, gate_k={"cz_gate": 2, "M": 1, "P": 1})

Tampilkan jumlah parameter yang belum diketahui untuk model noise dari setiap gate.

{name: len(generators) for name, generators in model.generators.items()}
{'M': 12, 'P': 12, 'cz_gate': 144}

3. Bangun eksperimen pembelajaran​

Susun sebuah Experiment dengan menggabungkan tahap-tahap builder. Setiap tahap membaca apa yang ditulis tahap sebelumnya, jadi urutan itu penting:

from qiskit_noise_learning.experiment_builder import (
BindFragmentDepths,
CompleteSequences,
EvenDepthVanillaPaths,
Experiment,
GenerateInstructionSequences,
IdentifyRelations,
MergeInstructionSequences,
SPAMPaths,
VanillaInstructionSequences,
)

experiment_builder = (
# Add standard vanilla learning paths and instruction sequences, and identify relations
EvenDepthVanillaPaths()
+ VanillaInstructionSequences()
+ IdentifyRelations()
# Add paths for learning SPAM, then generate and merge instruction sequences for measuring them
+ SPAMPaths()
+ GenerateInstructionSequences()
+ MergeInstructionSequences()
# Finalize by completing the instruction sequences and setting experiment depths
+ CompleteSequences()
+ BindFragmentDepths([2, 16, 32, 64])
)

experiment = experiment_builder.run(
Experiment(fidelity_model=model, shots=20, randomizations=50)
)

print(f"Number of paths: {len(experiment.paths)}")
print(f"Number of instruction sequences: {len(experiment.instruction_sequences)}")
Number of paths: 156
Number of instruction sequences: 37

Amati rank design matrix:

print(f"Design matrix rank: {experiment.design_matrix.rank}")
Design matrix rank: 120

4. Buat circuit​

Kompilasi eksperimen dengan ExecutorCircuitGenerator, yang menghasilkan sebuah QuantumProgram — satu template circuit berparameter untuk setiap kedalaman fragmen.

from qiskit_noise_learning.circuit_generator import ExecutorCircuitGenerator

circuit_generator = ExecutorCircuitGenerator(gate_set)
quantum_program = circuit_generator.generate(experiment)

print(f"Number of template circuits: {len(quantum_program.items)}")
Number of template circuits: 5

Gambar sebuah template circuit untuk diperiksa.

quantum_program.items[0].circuit.draw("mpl", idle_wires=False, fold=False)

../_images/4088c7e98baeb5b56925c6c1f276159582c5f7040fbba76de438b919210bcc5f.png

5. Siapkan simulasi lokal​

Untuk mendefinisikan model noise bagi simulasi, kita memakai generator yang sudah ada di model dengan rate acak untuk membangun sebuah PauliLindbladMap.

import numpy as np
from qiskit.quantum_info import PauliLindbladMap

rng = np.random.default_rng(1234)

true_maps = {
name: PauliLindbladMap.from_terms(
[
PauliLindbladMap.GeneratorTerm(rate, generator)
for generator, rate in zip(generators, rng.uniform(2e-4, 1.5e-3, len(generators)))
]
)
for name, generators in model.generators.items()
if name != "P"
}
{name: noise_map.num_qubits for name, noise_map in true_maps.items()}
{'M': 156, 'cz_gate': 156}

Map-map itu selebar perangkat, karena model dinyatakan dalam pengindeksan qubit backend, padahal simulator menginginkan setiap map selebar gate yang dikenainya, dengan indeks Pauli berjalan di atas qubit gate tersebut dalam urutan fisik menaik. Persempit dengan keep_qubits(), yang men-trace out semua yang ada di luar ring:

noise_dict = {
name: noise_map.keep_qubits(qubit_subset) for name, noise_map in true_maps.items()
}
{name: noise_map.num_qubits for name, noise_map in noise_dict.items()}
{'M': 12, 'cz_gate': 12}

Simulator menamai noise sebuah layer berdasarkan instruksi box tempat layer itu dibangun, yang dikembalikan oleh to_instruction() untuk gate mana pun di gate set. Pasangkan setiap box dengan map-nya, gunakan metode simulasi stabilizer, dan atur seed_simulator agar data hasil simulasi bisa direproduksi:

from qiskit_aer import AerSimulator
from qiskit_ibm_runtime import Executor

executor = Executor(
mode=AerSimulator(method="stabilizer"),
options={
"simulator": {
"layer_noise_model": [
(gate_set[name].to_instruction(), noise_map)
for name, noise_map in noise_dict.items()
],
"seed_simulator": 42,
}
},
)
Menjalankan di hardware asli
executor = Executor(mode=backend)

6. Jalankan programnya​

Jalankan programnya, lalu format hasilnya dengan collect(), untuk menghasilkan sebuah Fit — wadah yang dibaca dan ditulis oleh tahap-tahap analisis.

Langkah ini sama saja, entah executor diarahkan ke simulator atau ke perangkat asli.

job = executor.run(quantum_program)
fit = circuit_generator.collect(job.result())

7. Analisis datanya​

Bangun pipeline analisis seputar fitting least squares nonnegatif untuk model tersebut.

from qiskit_noise_learning.analysis import (
ComputeObservables, # computes observables from raw data
CurveFitObservables, # performs exponential fitting
LeastSquaresSolve, # solves model with (nonnegative) least squares
)

analyzer = ComputeObservables() + CurveFitObservables() + LeastSquaresSolve()

fit = analyzer.run(fit)
/opt/hostedtoolcache/Python/3.15.1/x64/lib/python3.15/site-packages/qiskit_noise_learning/analysis/model_solve.py:250: UserWarning: 7 of 156 row(s) of the linear system have a non-positive or non-finite uncertainty, so they carry no usable statistical weight. Positions in LinearSystemData.row_labels: 144, 145, 148, 149, 151, 152, 154.
system = LinearSystemData.from_fit(fit)

Plot rata-rata observable hasil ukur terhadap eksponensial hasil fit-nya, satu subplot per pasangan CZ, untuk melihat apakah peluruhan yang di-fit itu memang eksponensial.

fit.plot_qubit_pair_decays(
pairs=cz_pairs,
observable_type="means",
exponential_fit=True,
)

Ganti exponential_fit dengan model_prediction untuk membandingkan data yang sama dengan peluruhan yang tersirat dari rate hasil penyelesaian non-negative least squares.

fit.plot_qubit_pair_decays(
pairs=cz_pairs,
observable_type="means",
model_prediction=True,
)