Migrasi dari Sampler dan Estimator sisi server ke sisi klien
Panduan ini menjelaskan cara migrasi dari implementasi sisi server dari IBM Quantum®
Sampler dan Estimator ke implementasi sisi klien yang baru di
qiskit-ibm-runtime. Interface dan opsi sebagian besar tidak berubah, sehingga sebagian besar kode
berjalan apa adanya, tetapi ada beberapa perbedaan perilaku yang perlu dipahami.
Latar Belakang
Sampler dan Estimator adalah interface primitif yang didefinisikan dalam Qiskit. IBM Quantum
Compute Service (sebelumnya Qiskit Runtime) secara historis telah menyediakan implementasi
dari primitif ini di dalam lingkungan runtime-nya. Ketika kamu memanggil sampler.run() atau
estimator.run(), permintaan tersebut dikirim ke layanan, dan semua komputasi — termasuk
penekanan dan mitigasi error — terjadi di sisi server.
Pengalaman black-box ini memberikan kenyamanan: kamu tidak perlu khawatir tentang detail implementasi. Namun, ini juga membuat primitif sulit untuk di-debug, dikustomisasi, atau dipelajari, karena kamu tidak bisa melihat apa yang terjadi selama pemrosesan.
Directed execution model yang baru diperkenalkan mengambil pendekatan yang berlawanan dan memberikan pengalaman white-box. Semua maksud desain ditangkap di sisi klien, dan satu primitif sisi server Executor memproses input tersebut persis seperti yang diarahkan — ia tidak membuat keputusan implisit atas namamu.
Mulai dari qiskit-ibm-runtime v0.50.0, Sampler dan Estimator diimplementasikan ulang
di sisi klien di atas Executor. Keduanya memberikan kenyamanan dan
abstraksi yang sama seperti sebelumnya, dan sekarang kamu bisa memeriksa detail implementasi saat kamu
perlu. Karena interface dan opsi sebagian besar tetap sama, migrasi seharusnya
berjalan mulus.
Catatan: IBM Quantum hanya mendukung versi 2 dari interface Sampler dan Estimator (BaseSamplerV2 dan BaseEstimatorV2). Oleh karena itu, keduanya cukup disebut sebagai Sampler dan Estimator dalam panduan ini.
Perbarui import
Saat ini, kamu harus secara eksplisit mengimpor implementasi baru dari modul khususnya:
from qiskit_ibm_runtime.executor_sampler import Sampler
from qiskit_ibm_runtime.executor_estimator import Estimator
Dalam waktu dekat, import tingkat atas akan mengarah ke implementasi sisi klien yang baru, dan tidak akan diperlukan perubahan kode:
# Coming soon — the following code will import the new client-side implementations.
from qiskit_ibm_runtime import Sampler, Estimator
Begitu juga, jika kamu membuat objek options bertipe, kamu harus mengimpornya dari
qiskit_ibm_runtime.options_models, atau cukup mengoper dict bersarang biasa:
from qiskit_ibm_runtime.options_models import SamplerOptions, EstimatorOptions
Apa yang tetap sama
-
Konstruksi primitif dengan
modedanoptions. -
Signature
run()dan format PUB. -
Pohon options (
options.twirling,options.resilience,options.default_shots, dan sebagainya). -
Struktur data hasil yang dikembalikan oleh
job.result().
Perubahan yang tidak kompatibel di Sampler baru
| Perubahan | Tindakan migrasi |
|---|---|
Primitif yang mendasarinya sekarang adalah Executor. Baik antarmuka pengguna IBM Quantum Platform maupun job.primitive_id akan menampilkan executor, bukan sampler. | Perbarui kode apa pun yang mereferensikan job.primitive_id. |
Implementasi baru memetakan input Sampler ke input Executor, sehingga job.inputs mengembalikan input Executor. | Perbarui kode apa pun yang mereferensikan job.inputs. Lihat Struktur input job. |
Lebih banyak pra-pemrosesan dan pasca-pemrosesan sekarang terjadi di sisi klien, sehingga sampler.run() dan job.result() mungkin memakan waktu lebih lama dari sebelumnya. | Aktifkan logging INFO untuk mengikuti progres pemrosesan sisi klien. Lihat Aktifkan logging INFO. |
Metadata circuit disalin ke metadata hasil. Tipe data yang diizinkan dalam metadata hasil sekarang dibatasi menjadi str, float, int, bool, dan list atau dictionary dari tipe-tipe tersebut. | Jika kamu memerlukan tipe data lain, encode terlebih dahulu sebagai string (misalnya, dengan base64). |
Kelas options (options_models.SamplerOptions dan sebagainya) sekarang adalah model Pydantic, bukan dataclass, sehingga tidak bisa lagi dikonversi menjadi dictionary Python menggunakan asdict(). | Gunakan options.model_dump() sebagai gantinya. |
Kelas options yang sebelumnya memiliki akhiran V2 (ExecutionOptionsV2 dan sebagainya) tidak lagi memilikinya, karena primitif V1 tidak lagi didukung. | Hapus akhiran V2 dari kelas options ini: ganti ExecutionOptionsV2 dengan ExecutionOptions, ResilienceOptionsV2 dengan ResilienceOptions, dan SamplerExecutionOptionsV2 dengan SamplerExecutionOptions. |
Jika twirling diaktifkan dan shots (di PUB atau di run()), shots_per_randomization, dan num_randomizations semuanya ditentukan, maka num_randomizations * shots_per_randomization lebih diutamakan daripada shots. | Hilangkan num_randomizations dan shots_per_randomization jika kamu ingin nilai shots digunakan. |
Beberapa validasi input telah dipindahkan ke sisi server dan sekarang memunculkan RuntimeError alih-alih IBMInputValueError. | Perbarui tipe exception yang ditangkap oleh kodemu. |
| Nilai shot campuran dalam satu job tidak lagi didukung. | Kirim job terpisah untuk setiap nilai shot. Lihat Pembagian job untuk pertimbangan. |
Perubahan yang tidak kompatibel di Estimator baru
| Perubahan | Tindakan migrasi |
|---|---|
Primitif yang mendasarinya sekarang adalah Executor. Baik antarmuka pengguna IBM Quantum Platform maupun job.primitive_id akan menampilkan executor, bukan estimator. | Perbarui kode apa pun yang mereferensikan job.primitive_id. |
Implementasi baru memetakan input Estimator ke input Executor, sehingga job.inputs mengembalikan input Executor. | Perbarui kode apa pun yang mereferensikan job.inputs. Lihat Struktur input job. |
Lebih banyak pra-pemrosesan dan pasca-pemrosesan sekarang terjadi di sisi klien, sehingga estimator.run() dan job.result() mungkin memakan waktu lebih lama dari sebelumnya. | Aktifkan logging INFO untuk mengikuti progres pemrosesan sisi klien. Lihat Aktifkan logging INFO. |
Metadata circuit disalin ke metadata hasil. Tipe data yang diizinkan dalam metadata hasil sekarang dibatasi menjadi str, float, int, bool, dan list atau dictionary dari tipe-tipe tersebut. | Jika kamu memerlukan tipe data lain, encode terlebih dahulu sebagai string (misalnya, dengan base64). |
Kelas options (options_models.EstimatorOptions dan sebagainya) sekarang adalah model Pydantic, bukan dataclass, sehingga tidak bisa lagi dikonversi menjadi dictionary Python menggunakan asdict(). | Gunakan options.model_dump() sebagai gantinya. |
Kelas options yang sebelumnya memiliki akhiran V2 (ExecutionOptionsV2 dan sebagainya) tidak lagi memilikinya, karena primitif V1 tidak lagi didukung. | Hapus akhiran V2 dari kelas options ini: ganti ExecutionOptionsV2 dengan ExecutionOptions dan ResilienceOptionsV2 dengan ResilienceOptions. |
| Semua opsi input dikembalikan dalam metadata hasil, bukan hanya sebagian yang dipilih. | Tidak ada — ini hanya informasional. |
Beberapa validasi input telah dipindahkan ke sisi server dan sekarang memunculkan RuntimeError alih-alih IBMInputValueError. | Perbarui tipe exception yang ditangkap oleh kodemu. |
| Tidak ada lagi pembelajaran noise implisit untuk PEA dan PEC. Pembelajaran noise pengukuran untuk TREX masih didukung. | Pelajari model noise secara terpisah dan berikan ke Estimator. Lihat Lakukan pembelajaran noise eksplisit untuk PEA dan PEC. |
Tipe input dari ResilienceOptions.layer_noise_model berbeda dan bisa dibuat dari hasil NoiseLearnerV3. | Lihat Lakukan pembelajaran noise eksplisit untuk PEA dan PEC tentang cara mempelajari model noise menggunakan NoiseLearnerV3 dan memberikannya ke Estimator. |
MeasureNoiseLearningOptions.shots_per_randomization tidak lagi didukung. | Satu nilai shot digunakan untuk semua circuit dalam job, termasuk circuit pembelajaran noise pengukuran. Jika kamu harus menggunakan nilai shot yang berbeda, terapkan TREX dengan qiskit-mitigation di luar Estimator. |
| Nilai precision campuran dalam satu job tidak lagi didukung. | Kirim job terpisah untuk setiap precision yang diinginkan. Lihat Pembagian job untuk pertimbangan. |
Opsi seed_estimator tidak lagi didukung. | Hapus penetapan options.seed_estimator mana pun (menetapkannya akan memunculkan ValidationError). Tidak ada padanan sisi klien, sehingga hasil tidak lagi dapat direproduksi melalui seed ini. |
Aktifkan logging INFO
Karena lebih banyak pekerjaan sekarang terjadi di sisi klien, akan berguna untuk melihat progres dari pemrosesan
tersebut. Aktifkan logging level INFO untuk logger qiskit_ibm_runtime:
import logging
logger = logging.getLogger("qiskit_ibm_runtime")
logger.setLevel(logging.INFO)
Lakukan pembelajaran noise eksplisit untuk PEA dan PEC
Estimator baru tidak lagi melakukan pembelajaran noise implisit ketika metode mitigasi error PEA atau PEC
dipilih. Kamu harus mempelajari model noise secara eksplisit dan memberikannya.
Gunakan NoiseLearnerV3 yang baru untuk mengontrol bagaimana circuit
distratifikasi menjadi layer. Ia menerima daftar instruksi circuit yang di-box (misalnya,
layer unik) sebagai input.
PEA dan PEC sekarang mengharuskan pola eksplisit ini. Jangan lewati langkah pembelajaran noise atau kodemu akan gagal. Pembelajaran noise pengukuran untuk TREX tidak terpengaruh dan terus bekerja seperti sebelumnya.
Begitu juga, jika kodemu menggunakan NoiseLearner dan memberikan model noise hasilnya ke Estimator sisi server, kamu perlu migrasi ke NoiseLearnerV3. JANGAN gunakan NoiseLearner versi lama, yang tidak kompatibel dengan Estimator baru.
Semua opsi pembelajaran noise di Estimator sisi server (LayerNoiseLearningOptions) dipetakan langsung ke opsi NoiseLearnerV3 (NoiseLearnerV3Options), kecuali max_layers_to_learn. Jumlah layer yang dipelajari sebagai gantinya didasarkan pada jumlah layer yang diberikan ke NoiseLearnerV3.
Sebagai contoh:
Estimator sisi server (dengan PEC diaktifkan):
from qiskit_ibm_runtime import Estimator
pubs = [...] # Your PUBs
estimator = Estimator(mode, options)
estimator.options.resilience.pec_mitigation = True # or zne_mitigation + pea amplifier
estimator.options.resilience.layer_noise_learning.num_randomizations = 64
job = estimator.run(pubs)
Estimator sisi klien (dengan PEC diaktifkan):
from qiskit_ibm_runtime.executor_estimator import Estimator
from qiskit_ibm_runtime import NoiseLearnerV3
pubs = [...] # Your PUBs
estimator = Estimator(mode, options)
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(mode)
learner.options.num_randomizations = 64 # Same as layer_noise_learning.num_randomizations
learner_job = learner.run(layers)
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)
Migrasi dari NoiseLearner ke NoiseLearnerV3
NoiseLearner hanya bekerja dengan implementasi sisi server dari Estimator. Oleh karena itu, jika kodemu menggunakan NoiseLearner untuk mempelajari model noise dan memberikannya ke Estimator, kamu perlu memperbarui kodemu untuk menggunakan NoiseLearnerV3.
Lihat panduan Migrasi dari NoiseLearner ke NoiseLearnerV3 untuk detailnya.
Pembagian job
Ketika kamu harus membagi satu job menjadi beberapa job karena nilai shot atau precision campuran dalam satu job tidak lagi didukung, pertimbangkan hal berikut:
-
Kelompokkan PUB berdasarkan nilai targetnya — satu job per nilai yang berbeda, bukan satu job per PUB. Pembagian adalah pengelompokan ulang, sehingga jumlah total PUB yang kamu kirim tidak berubah. Sebagai contoh, dengan
[A@0.01, B@0.05, C@0.01], kirim dua job:[A, C]padaprecision=0.01dan[B]padaprecision=0.05. MengirimAdanCsebagai job terpisah kurang efisien, karena setiap job memiliki overhead tetap. -
Pelajari sekali dan gunakan model noise di semua job hasil pembagian. Lebih efisien untuk menjalankan satu job
NoiseLearnerV3atas gabungan semua layer. Hasil dari job noise learner berisi daftar objekNoiseLearnerV3Result, satu untuk setiap instruksi input, dan berada dalam urutan yang sama dengan daftar input. Kamu bisa menggunakan output dari job noise learner ini di semua job (Estimator) hasil pembagian, dan model noise untuk layer yang tidak ada di PUB job hasil pembagian akan diabaikan. -
Kirim semua job hasil pembagian dalam
Batchterlebih dahulu, lalu kumpulkan hasilnya. Mode eksekusiBatchmenyediakan eksekusi paralel yang efisien ketika ada banyak job. Namun,job.result()bersifat blocking, sehingga memanggilnya di dalam loop pengiriman akan menyerialisasi job dan menghilangkan manfaat penggunaanBatch. Pastikan kamu menggunakan pola kirim-semua-lalu-kumpulkan (ditunjukkan di bawah).
Dalam contoh berikut, pub1 dan pub2 memerlukan precision=0.5, sedangkan pub3 memerlukan precision=0.1:
group1_pubs = [pub1, pub2]
group2_pubs = [pub3]
with Batch(backend=backend) as batch:
estimator = Estimator(mode=batch)
estimator.options.resilience.pec_mitigation = True
# Learn once, over the union of every job's layers.
all_layers = estimator.find_unique_layers(group1_pubs + group2_pubs)
learner_job = NoiseLearnerV3(mode=batch).run(all_layers)
learner_result = learner_job.result()
pauli_lindblad_maps = learner_result.to_pauli_lindblad_maps()
# Assign the learned noise maps. Any layers not found in the input PUBs are ignored.
estimator.options.resilience.layer_noise_model = zip(all_layers, pauli_lindblad_maps)
# Submit every split job with different precision values.
jobs = []
jobs.append(estimator.run(group1_pubs, precision=0.5))
jobs.append(estimator.run(group2_pubs, precision=0.1))
# Block once, at the end — the jobs run in parallel.
results = [job.result() for job in jobs]
Struktur input job
Implementasi baru memetakan input Sampler atau Estimator ke input Executor, sehingga job.inputs mengembalikan dictionary yang berisi input Executor. Dictionary ini memiliki key berikut:
-
options: InputExecutorOption. -
quantum_program: InputQuantumProgram -
schema_version: Versi schema sisi server yang digunakan.
Jika kodemu menggunakan job.inputs['options'] untuk menemukan opsi yang ditentukan untuk job, kamu sekarang bisa menggunakan job.result().metadata['options'] sebagai gantinya.
Uji secara lokal dengan fake backend
Sebelum mengirim ke hardware, kamu bisa memvalidasi kode hasil migrasi terhadap backend Fake*
untuk menangkap error sintaks lebih awal. Perhatikan detail berikut tentang mode pengujian lokal:
-
Ini tidak mereproduksi hasil hardware. Simulasi noisy lokal tidak sepenuhnya mereplikasi noise perangkat nyata, sehingga output mungkin berbeda. Menjalankannya tetap memvalidasi bahwa jalur opsi dan tipe nilai sudah benar.
-
NoiseLearnerV3tidak memiliki mode pengujian lokal:mode-nya hanya menerimaBackend,Session, atauBatchyang asli, sehingga kamu tidak bisa menjalankan langkah pembelajaran noise terhadap fake backend. Sebagai gantinya, verifikasi bagian kode tersebut terhadap referensi APINoiseLearnerV3. Pastikan bahwa constructor, bentuk inputrun(instructions), dan helper apa pun (seperti helper unique-layer) digunakan sesuai dokumentasi.
Cliffordisasi circuit untuk simulasi lokal yang efisien
Fake backend menggunakan simulator statevector (noisy), yang biayanya tumbuh secara eksponensial seiring dengan
jumlah qubit dan depth. Karena itu, circuit workload yang realistis bisa hang atau menghabiskan memori. Karena
pengujian lokal hanya perlu menjalankan jalur opsi (bukan mereproduksi hasil fisik),
kurangi circuit menjadi circuit Clifford terlebih dahulu dengan
ConvertISAToClifford,
yang membulatkan setiap sudut RZ/RZZ/RX ke kelipatan terdekat dari π/2. Circuit Clifford
bersimulasi secara efisien (simulasi stabilizer) terlepas dari ukurannya.
from qiskit.transpiler import PassManager
from qiskit_ibm_runtime.transpiler.passes import ConvertISAToClifford
clifford = PassManager([ConvertISAToClifford()]).run(isa_circuit)
# run `clifford` (not the original) through the fake-backend primitive
ConvertISAToClifford memerlukan circuit ISA sebagai input (output dari
generate_preset_pass_manager(...).run(...) yang menargetkan backend). Kamu harus memperhitungkan konsekuensi berikut
saat membuat PUB lokal:
-
Atribut
.layoutdihilangkan. Circuit yang telah di-Cliffordisasi mempertahankan jumlah qubit yang sama, tetapiclifford.layoutbernilaiNone, sehinggaobservable.apply_layout(clifford.layout)gagal. Sebagai gantinya, tata letakkan observable dari circuit ISA sebelum-Clifford:isa_obs = observable.apply_layout(isa_circuit.layout), lalu jalankan(clifford, isa_obs). -
Parameter di-bind sepenuhnya. Pembulatan sudut rotasi mengubah circuit ISA parametrik menjadi circuit Clifford konkret, sehingga
clifford.num_parametersmenjadi0. PUB yang masih membawa array nilai parameter akan gagal saat coercion. Untuk run lokal, hilangkan array parameter dari PUB; run hardware tetap menggunakan circuit parametrik asli dan nilainya.