Migrace ze serverového na klientský Sampler a Estimator
Tento průvodce popisuje, jak migrovat ze serverových implementací IBM Quantum®
Sampler a Estimator na jejich nové klientské implementace v
qiskit-ibm-runtime. Rozhraní a možnosti zůstávají z velké části beze změny, takže většina kódu
funguje beze změn, ale je třeba porozumět některým rozdílům v chování.
Kontext
Sampler a Estimator jsou primitivní rozhraní definovaná v Qiskit. Služba IBM Quantum
Compute Service (dříve Qiskit Runtime) historicky poskytovala implementaci
těchto primitiv uvnitř svého runtime prostředí. Když zavoláš sampler.run() nebo
estimator.run(), požadavek je odeslán službě a veškeré výpočty — včetně
potlačení a zmírnění chyb — probíhají na straně serveru.
Tato zkušenost typu black-box je pohodlná: nemusíš se starat o detaily implementace. Ale zároveň to ztěžuje ladění, přizpůsobení nebo učení se z primitiv, protože nevidíš, co se děje během zpracování.
Nově zavedený model řízeného spouštění zaujímá opačný přístup a poskytuje zkušenost typu white-box. Veškeré záměry návrhu jsou zachyceny na straně klienta, a jediné serverové primitivum Executor zpracovává tyto vstupy přesně tak, jak je nasměrováno — nedělá za tebe žádná implicitní rozhodnutí.
Počínaje qiskit-ibm-runtime v0.50.0 jsou Sampler a Estimator znovu implementovány
na straně klienta nad Executorem. Poskytují stejné pohodlí a
abstrakci jako dříve, a nyní si můžeš prohlédnout detaily implementace, když je potřebuješ.
Protože rozhraní a možnosti zůstávají z velké části stejné, migrace by měla být
bezproblémová.
Poznámka: IBM Quantum podporuje pouze verzi 2 rozhraní Sampler a Estimator (BaseSamplerV2 a BaseEstimatorV2). Proto jsou v tomto průvodci jednoduše označovány jako Sampler a Estimator.
Aktualizace importů
Dnes musíš explicitně importovat nové implementace z jejich vyhrazených modulů:
from qiskit_ibm_runtime.executor_sampler import Sampler
from qiskit_ibm_runtime.executor_estimator import Estimator
V blízké budoucnosti se importy nejvyšší úrovně budou přesměrovávat na nové klientské implementace a nebude potřeba žádná změna kódu:
# Coming soon — the following code will import the new client-side implementations.
from qiskit_ibm_runtime import Sampler, Estimator
Podobně, pokud vytváříš typované objekty možností, musíš je importovat z
qiskit_ibm_runtime.options_models, nebo jednoduše předat obyčejný vnořený slovník:
from qiskit_ibm_runtime.options_models import SamplerOptions, EstimatorOptions
Co zůstává stejné
-
Vytváření primitiv pomocí
modeaoptions. -
Signatura
run()a formát PUB. -
Strom možností (
options.twirling,options.resilience,options.default_shots, a tak dále). -
Struktura dat výsledku vrácená
job.result().
Nekompatibilní změny v novém Sampleru
| Změna | Akce při migraci |
|---|---|
Základním primitivem je nyní Executor. Uživatelské rozhraní IBM Quantum Platform i job.primitive_id nyní zobrazí executor místo sampler. | Aktualizujte veškerý kód, který odkazuje na job.primitive_id. |
Nová implementace mapuje vstupy Sampleru na vstupy Executoru, takže job.inputs vrací vstupy Executoru. | Aktualizujte veškerý kód, který odkazuje na job.inputs. Viz Vstupy úlohy. |
Na straně klienta nyní probíhá více předzpracování a následného zpracování, takže sampler.run() a job.result() mohou trvat déle než dříve. | Povolte protokolování na úrovni INFO, abyste mohli sledovat průběh zpracování na straně klienta. Viz Povolení protokolování INFO. |
Metadata obvodu se kopírují do metadat výsledku. Typy dat povolené v metadatech výsledku jsou nyní omezeny na str, float, int, bool a seznamy nebo slovníky těchto typů. | Pokud potřebujete jiné datové typy, nejprve je zakódujte jako řetězec (například pomocí base64). |
Třídy možností (options_models.SamplerOptions a podobné) jsou nyní modely Pydantic místo dataclasses, takže je již nelze převést na slovníky Pythonu pomocí asdict(). | Místo toho použijte options.model_dump(). |
Třídy možností, které dříve měly příponu V2 (ExecutionOptionsV2 a podobné), ji již nemají, protože primitivy V1 již nejsou podporovány. | Odstraňte příponu V2 u těchto tříd možností: nahraďte ExecutionOptionsV2 za ExecutionOptions, ResilienceOptionsV2 za ResilienceOptions a SamplerExecutionOptionsV2 za SamplerExecutionOptions. |
Pokud je povoleno twirling a jsou zároveň zadány shots (v PUBech nebo v run()), shots_per_randomization a num_randomizations, má num_randomizations * shots_per_randomization přednost před shots. | Vynechte num_randomizations a shots_per_randomization, pokud chcete použít hodnotu shots. |
Některá validace vstupů se přesunula na stranu serveru a nyní vyvolává RuntimeError místo IBMInputValueError. | Aktualizujte typy výjimek, které váš kód zachytává. |
| Smíšené hodnoty shots v jedné úloze již nejsou podporovány. | Odešlete samostatnou úlohu pro každou hodnotu shots. Úvahy k tomuto tématu najdete v části Rozdělení úloh. |
Nekompatibilní změny v novém Estimatoru
| Změna | Akce při migraci |
|---|---|
Základním primitivem je nyní Executor. Uživatelské rozhraní IBM Quantum Platform i job.primitive_id nyní zobrazí executor místo estimator. | Aktualizujte veškerý kód, který odkazuje na job.primitive_id. |
Nová implementace mapuje vstupy Estimatoru na vstupy Executoru, takže job.inputs vrací vstupy Executoru. | Aktualizujte veškerý kód, který odkazuje na job.inputs. Viz Vstupy úlohy. |
Na straně klienta nyní probíhá více předzpracování a následného zpracování, takže estimator.run() a job.result() mohou trvat déle než dříve. | Povolte protokolování na úrovni INFO, abyste mohli sledovat průběh zpracování na straně klienta. Viz Povolení protokolování INFO. |
Metadata obvodu se kopírují do metadat výsledku. Typy dat povolené v metadatech výsledku jsou nyní omezeny na str, float, int, bool a seznamy nebo slovníky těchto typů. | Pokud potřebujete jiné datové typy, nejprve je zakódujte jako řetězec (například pomocí base64). |
Třídy možností (options_models.EstimatorOptions a podobné) jsou nyní modely Pydantic místo dataclasses, takže je již nelze převést na slovníky Pythonu pomocí asdict(). | Místo toho použijte options.model_dump(). |
Třídy možností, které dříve měly příponu V2 (ExecutionOptionsV2 a podobné), ji již nemají, protože primitivy V1 již nejsou podporovány. | Odstraňte příponu V2 u těchto tříd možností: nahraďte ExecutionOptionsV2 za ExecutionOptions a ResilienceOptionsV2 za ResilienceOptions. |
| Všechny vstupní možnosti se nyní vracejí v metadatech výsledku, nikoli jen vybraná podmnožina. | Žádná akce — jedná se pouze o informaci. |
Některá validace vstupů se přesunula na stranu serveru a nyní vyvolává RuntimeError místo IBMInputValueError. | Aktualizujte typy výjimek, které váš kód zachytává. |
| Již se neprovádí implicitní učení šumu pro PEA a PEC. Učení šumu měření pro TREX je stále podporováno. | Naučte modely šumu samostatně a předejte je Estimatoru. Viz Provedení explicitního učení šumu pro PEA a PEC. |
Vstupní typ ResilienceOptions.layer_noise_model je jiný a lze jej sestavit z výsledků NoiseLearnerV3. | Viz Provedení explicitního učení šumu pro PEA a PEC, kde se dozvíte, jak naučit modely šumu pomocí NoiseLearnerV3 a předat je Estimatoru. |
MeasureNoiseLearningOptions.shots_per_randomization již není podporováno. | Pro všechny obvody v úloze, včetně obvodů pro učení šumu měření, se používá jedna hodnota shots. Pokud musíte použít jinou hodnotu shots, použijte TREX pomocí qiskit-mitigation mimo Estimator. |
| Smíšené hodnoty přesnosti v jedné úloze již nejsou podporovány. | Odešlete samostatnou úlohu pro každou požadovanou přesnost. Úvahy k tomuto tématu najdete v části Rozdělení úloh. |
Možnost seed_estimator již není podporována. | Odstraňte jakékoli přiřazení options.seed_estimator (jeho nastavení vyvolá ValidationError). Neexistuje žádný ekvivalent na straně klienta, takže výsledky již nejsou reprodukovatelné pomocí tohoto seedu. |
Povolení protokolování INFO
Protože nyní více práce probíhá na straně klienta, je užitečné vidět postup tohoto
zpracování. Povol protokolování na úrovni INFO pro logger qiskit_ibm_runtime:
import logging
logger = logging.getLogger("qiskit_ibm_runtime")
logger.setLevel(logging.INFO)
Provedení explicitního učení šumu pro PEA a PEC
Nový Estimator již neprovádí implicitní učení šumu, když je vybrána metoda zmírnění chyb
PEA nebo PEC. Musíš modely šumu naučit explicitně a předat je.
Použij nový NoiseLearnerV3 k řízení toho, jak jsou obvody
rozvrstveny do vrstev. Přijímá seznam zabalených instrukcí obvodu (například
jedinečných vrstev) jako vstup.
PEA a PEC nyní tento explicitní postup vyžadují. Nevynechávej krok učení šumu, jinak tvůj kód selže. Učení šumu měření pro TREX není ovlivněno a funguje jako dříve.
Podobně, pokud tvůj kód používá NoiseLearner a předává výsledný model šumu serverovému Estimatoru, potřebuješ migrovat na NoiseLearnerV3. NEPOUŽÍVEJ starší NoiseLearner, který není kompatibilní s novým Estimatorem.
Všechny možnosti učení šumu v serverovém Estimatoru (LayerNoiseLearningOptions) se mapují přímo na možnost NoiseLearnerV3 (NoiseLearnerV3Options), s výjimkou max_layers_to_learn. Počet vrstev k naučení je místo toho založen na počtu vrstev předaných do NoiseLearnerV3.
Například:
Serverový Estimator (s povoleným PEC):
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)
Klientský Estimator (s povoleným PEC):
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)
Migrace z NoiseLearner na NoiseLearnerV3
NoiseLearner funguje pouze se serverovou implementací Estimator. Pokud tedy tvůj kód používá NoiseLearner k naučení modelu šumu a jeho předání Estimator, potřebuješ aktualizovat kód tak, aby používal NoiseLearnerV3.
Podrobnosti najdeš v průvodci Migrace z NoiseLearner na NoiseLearnerV3.
Rozdělení úloh
Když musíš rozdělit jednu úlohu na několik, protože smíšené hodnoty shots nebo precision v jedné úloze již nejsou podporovány, zvaž následující:
-
Seskup PUB podle jejich cílové hodnoty — jedna úloha na každou odlišnou hodnotu, ne jedna úloha na každý PUB. Rozdělení je přeskupení, takže celkový počet PUB, které odesíláš, se nemění. Například při
[A@0.01, B@0.05, C@0.01]odešli dvě úlohy:[A, C]sprecision=0.01a[B]sprecision=0.05. OdesláníAaCjako samostatných úloh je méně efektivní, protože každá úloha má pevnou režii. -
Nauč se model jednou a použij modely šumu ve všech rozdělených úlohách. Je efektivnější spustit jedinou úlohu
NoiseLearnerV3nad sjednocením všech vrstev. Výsledek úlohy learneru šumu obsahuje seznam objektůNoiseLearnerV3Result, po jednom pro každou vstupní instrukci, a je ve stejném pořadí jako vstupní seznam. Výstup této úlohy learneru šumu můžeš použít ve všech rozdělených (Estimator) úlohách a modely šumu pro vrstvy, které nejsou v PUB rozdělené úlohy, jsou ignorovány. -
Odešli nejprve všechny rozdělené úlohy v
Batch, poté shromáždi jejich výsledky. Režim spouštěníBatchposkytuje efektivní paralelní spouštění, když existuje více úloh. Nicménějob.result()je blokující, takže jeho volání uvnitř smyčky odesílání serializuje úlohy a ruší výhody použitíBatch. Ujisti se, že používáš vzor „odeslat vše, pak shromáždit“ (ukázaný níže).
V následujícím příkladu pub1 a pub2 vyžadují precision=0.5, zatímco pub3 vyžaduje 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]
Struktura vstupů úlohy
Nová implementace mapuje vstupy Sampleru nebo Estimatoru na vstupy Executoru, takže job.inputs vrací slovník obsahující vstupy Executoru. Tento slovník má následující klíče:
-
options: VstupníExecutorOption. -
quantum_program: VstupníQuantumProgram -
schema_version: Použitá verze schématu na straně serveru.
Pokud tvůj kód používal job.inputs['options'] k vyhledání možností specifikovaných pro úlohu, nyní můžeš místo toho použít job.result().metadata['options'].
Testování lokálně s falešným backendem
Před odesláním na hardware můžeš ověřit migrovaný kód proti backendu Fake*,
aby ses včas zachytil případné syntaktické chyby. Všimni si následujících podrobností o lokálním testovacím režimu:
-
Nereprodukuje výsledky hardwaru. Lokální simulace se šumem dokonale nereplikuje šum skutečného zařízení, a proto se výstupy mohou lišit. Spuštění ověřuje, že cesty možností a typy hodnot jsou správné.
-
NoiseLearnerV3nemá žádný lokální testovací režim: jehomodepřijímá pouze skutečnýBackend,SessionneboBatch, takže krok učení šumu nemůžeš vyzkoušet proti falešnému backendu. Ověř tuto část svého kódu proti referenční dokumentaci APINoiseLearnerV3. Potvrď, že konstruktor, tvar vstupurun(instructions)a jakýkoli pomocník (například pomocník pro jedinečné vrstvy) jsou používány tak, jak je zdokumentováno.
Cliffordizace obvodu pro efektivní lokální simulaci
Falešný backend používá simulátor statevector (se šumem), jehož náklady rostou exponenciálně s
počtem qubitů a hloubkou. Realistický pracovní obvod tedy může zamrznout nebo vyčerpat paměť. Protože
lokální testování potřebuje pouze vyzkoušet cesty možností (nikoli reprodukovat fyzikální výsledky),
nejprve zredukuj obvod na Cliffordův pomocí
ConvertISAToClifford,
který zaokrouhlí každý úhel RZ/RZZ/RX na nejbližší násobek π/2. Cliffordovy obvody
se simulují efektivně (stabilizátorová simulace) bez ohledu na velikost.
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 vyžaduje jako vstup ISA obvod (výstup
generate_preset_pass_manager(...).run(...) cílený na backend). Při vytváření lokálního PUB musíš
zohlednit následující důsledky:
-
Atribut
.layoutje zahozen. Cliffordizovaný obvod si zachovává stejný počet qubitů, aleclifford.layoutjeNone, takžeobservable.apply_layout(clifford.layout)selže. Místo toho rozvrhni observable z před-Cliffordova ISA obvodu:isa_obs = observable.apply_layout(isa_circuit.layout), poté spusť(clifford, isa_obs). -
Parametry jsou svázány pryč. Zaokrouhlení úhlů rotace mění parametrický ISA obvod na konkrétní Cliffordův, takže
clifford.num_parametersse stane0. PUB, který stále nese pole hodnot parametrů, selže při vynucení typu. Pro lokální spuštění odstraň pole parametrů z PUB; spuštění na hardwaru si ponechá původní parametrický obvod a jeho hodnoty.