QESEM: Qiskit Function od Qedmy
Viz referenci API
Verze balíčků
Kód na této stránce byl vyvinut s použitím následujících požadavků. Doporučujeme používat tyto nebo novější verze.
qiskit[all]~=2.5.0
qiskit-ibm-runtime~=0.47.0
Qiskit Functions jsou experimentální funkce dostupné pouze uživatelům plánů IBM Quantum® Premium Plan, Flex Plan a On-Prem (prostřednictvím IBM Quantum Platform API). Jsou ve stavu preview verze a mohou se měnit.
Přehled
Přestože se kvantové procesory (QPU) v posledních letech výrazně zlepšily, chyby způsobené hlukem a nedokonalostmi stávajícího hardwaru zůstávají klíčovou výzvou pro vývojáře kvantových algoritmů. Jak se obor přibližuje kvantovým výpočtům v měřítku užitečnosti, které nelze klasicky ověřit, stávají se řešení pro eliminaci šumu se zaručenou přesností čím dál důležitějšími. K překonání této výzvy vyvinula Qedma metodu Quantum Error Mitigation (QESEM), která je bezešvě integrována na IBM Quantum Platform jako Qiskit Function.
S QESEM můžeš spouštět své kvantové obvody na hlučných QPU a získávat vysoce přesné výsledky bez chyb s vysoce efektivní spotřebou QPU času, blízkou fundamentálním limitům. QESEM k tomu využívá sadu proprietárních metod vyvinutých Qedmou pro charakterizaci a redukci chyb. Techniky redukce chyb zahrnují optimalizaci Gate, transpilaci s ohledem na šum, potlačení chyb (ES) a nestrannou mitigaci chyb (EM). Díky kombinaci těchto metod založených na charakterizaci mohou uživatelé dosáhnout spolehlivých výsledků bez chyb pro obecné kvantové obvody s velkým objemem, čímž se odemykají aplikace, které by jinak nebylo možné realizovat.
Úplný popis základních komponent i demonstraci v měřítku užitečnosti najdeš v článku Reliable high-accuracy error mitigation for utility-scale quantum circuits.
Popis
Funkci QESEM od Qedmy můžeš použít ke snadnému odhadování a spouštění svých obvodů s potlačením a mitigací chyb, čímž dosáhneš větších objemů obvodů a vyšší přesnosti. Pro použití QESEM zadáš kvantový Circuit, sadu pozorovatelných veličin k měření, cílovou statistickou přesnost pro každou pozorovatelnou veličinu a zvolený QPU. Před spuštěním obvodu na cílovou přesnost můžeš odhadnout požadovaný čas QPU na základě analytického výpočtu, který nevyžaduje spuštění obvodu. Jakmile jsi spokojený s odhadem času QPU, můžeš Circuit spustit s QESEM.
Při spuštění obvodu provede QESEM protokol charakterizace zařízení přizpůsobený tvému obvodu, čímž vznikne spolehlivý šumový model pro chyby vyskytující se v obvodu. Na základě charakterizace QESEM nejprve implementuje transpilaci s ohledem na šum, která mapuje vstupní Circuit na sadu fyzických Qubitů a Gate, čímž minimalizuje šum ovlivňující cílovou pozorovatelnou veličinu. Patří sem nativně dostupné Gate (CX/CZ na zařízeních IBM®) i další Gate optimalizované QESEM, tvořící rozšířenou sadu Gate systému QESEM. Poté QESEM spustí na QPU sadu ES a EM obvodů založených na charakterizaci a shromáždí výsledky měření. Ty jsou následně klasicky post-procesovány a poskytují nestrannou střední hodnotu a chybové pásmo pro každou pozorovatelnou veličinu odpovídající požadované přesnosti.
QESEM prokázal schopnost poskytovat vysoce přesné výsledky pro různé kvantové aplikace a pro největší objemy obvodů dosažitelné dnes. QESEM nabízí následující funkce pro uživatele, demonstrované v části s benchmarky níže:
- Zaručená přesnost: QESEM poskytuje nestranné odhady středních hodnot pozorovatelných veličin. Jeho metoda EM je vybavena teoretickými zárukami, které – společně s nejmodernější charakterizací Qedmy – zajišťují, že mitigace konverguje k výstupu bezchybného obvodu s přesností specifikovanou uživatelem. Na rozdíl od mnoha heuristických metod EM, které jsou náchylné k systematickým chybám nebo zkreslení, je zaručená přesnost QESEM nezbytná pro zajištění spolehlivých výsledků u obecných kvantových obvodů a pozorovatelných veličin.
- Škálovatelnost na velké QPU: Čas QPU systému QESEM závisí na objemech obvodů, ale jinak je nezávislý na počtu Qubitů. Qedma demonstrovala QESEM na největších kvantových zařízeních dostupných dnes, včetně IBM Quantum 127-qubitového Eagle a 133-qubitového Heron zařízení.
- Nezávislost na aplikaci: QESEM byl demonstrován na různých aplikacích, včetně Hamiltonovy simulace, VQE, QAOA a amplitudového odhadování. Uživatelé mohou zadat libovolný kvantový Circuit a pozorovatelnou veličinu k měření a získat přesné výsledky bez chyb. Jediná omezení jsou dána hardwarovými specifikacemi a přiděleným časem QPU, které určují přístupné objemy obvodů a přesnosti výstupu. Naproti tomu mnohá řešení pro redukci chyb jsou specifická pro konkrétní aplikaci nebo zahrnují nekontrolované heuristiky, čímž jsou nepoužitelná pro obecné kvantové obvody a aplikace.
- Rozšířená sada Gate: QESEM podporuje Gate s frakčními úhly a poskytuje Qedmou optimalizované frakčně-úhlové Gate na zařízeních IBM Quantum Heron a Eagle. Tato rozšířená sada Gate umožňuje efektivnější kompilaci a odemyká objemy obvodů větší až o faktor 2 ve srovnání s výchozí kompilací CX/CZ.
- Multibase pozorovatelné veličiny: QESEM podporuje vstupní pozorovatelné veličiny složené z mnoha nekomutujících Pauliho řetězců, jako jsou obecné Hamiltonovy operátory. Výběr měřicích bází a optimalizace alokace QPU zdrojů (snímky a obvody) je pak prováděna automaticky systémem QESEM tak, aby minimalizovala požadovaný čas QPU pro požadovanou přesnost. Tato optimalizace, která bere v úvahu věrnosti hardwaru a rychlosti spouštění, ti umožňuje spouštět hlubší obvody a dosahovat vyšší přesnosti.
Benchmarky
QESEM byl testován na široké škále případů použití a aplikací. Následující příklady ti pomohou posoudit, jaké typy pracovních zátěží lze s QESEM spouštět.
Klíčovým ukazatelem pro kvantifikaci náročnosti jak mitigace chyb, tak klasické simulace pro daný Circuit a pozorovatelnou veličinu je aktivní objem: počet CNOT Gate ovlivňujících pozorovatelnou veličinu v obvodu. Aktivní objem závisí na hloubce a šířce obvodu, na váze pozorovatelné veličiny a na struktuře obvodu, která určuje světelný kužel pozorovatelné veličiny. Podrobnosti najdeš v přednášce z IBM Quantum Summit 2024. QESEM poskytuje zvláště velkou hodnotu v režimu vysokého objemu, kde dává spolehlivé výsledky pro obecné obvody a pozorovatelné veličiny.
| Aplikace | Počet Qubitů | Zařízení | Popis obvodu | Přesnost | Celkový čas | Využití Runtime |
|---|---|---|---|---|---|---|
| VQE Circuit | 8 | Eagle (r3) | 21 celkových vrstev, 9 měřicích bází, 1D řetězec | 98 % | 35 min | 14 min |
| Kicked Ising | 28 | Eagle (r3) | 3 jedinečné vrstvy × 3 kroky, 2D topologie heavy-hex | 97 % | 22 min | 4 min |
| Kicked Ising | 28 | Eagle (r3) | 3 jedinečné vrstvy × 8 kroků, 2D topologie heavy-hex | 97 % | 116 min | 23 min |
| Trotterizovaná Hamiltonova simulace | 40 | Eagle (r3) | 2 jedinečné vrstvy × 10 Trotterových kroků, 1D řetězec | 97 % | 3 hodiny | 25 min |
| Trotterizovaná Hamiltonova simulace | 119 | Eagle (r3) | 3 jedinečné vrstvy × 9 Trotterových kroků, 2D topologie heavy-hex | 95 % | 6,5 hodiny | 45 min |
| Kicked Ising | 136 | Heron (r2) | 3 jedinečné vrstvy × 15 kroků, 2D topologie heavy-hex | 99 % | 52 min | 9 min |
Přesnost je zde měřena relativně k ideální hodnotě pozorovatelné veličiny: , kde '' je absolutní přesnost mitigace (nastavená vstupem uživatele) a je pozorovatelná veličina bezchybného obvodu. „Využití Runtime" měří využití benchmarku v dávkovém režimu (součet využití jednotlivých úloh), zatímco „celkový čas" měří využití v session režimu (celková doba experimentu), která zahrnuje dodatečné klasické a komunikační časy. QESEM je dostupný pro spouštění v obou režimech, takže uživatelé mohou co nejlépe využít své dostupné zdroje.
28-qubitové obvody Kicked Ising simulují Diskrétní časový kvazikrystal studovaný Shinjem et al. (viz arXiv 2403.16718 a Q2B24 Tokyo) na třech propojených smyčkách ibm_kawasaki. Parametry obvodu použité zde jsou s feromagnetickým počátečním stavem . Měřená pozorovatelná veličina je absolutní hodnota magnetizace . Experiment Kicked Ising v měřítku užitečnosti byl spuštěn na 136 nejlepších Qubitech ibm_fez; tento konkrétní benchmark byl spuštěn na Cliffordově úhlu , při němž aktivní objem roste s hloubkou obvodu pomalu, což – společně s vysokou věrností zařízení – umožňuje vysokou přesnost při krátkém čase běhu.
Trotterizované obvody Hamiltonovy simulace jsou pro model Ising s příčným polem při frakčních úhlech: a (viz Q2B24 Tokyo). Obvod v měřítku užitečnosti byl spuštěn na 119 nejlepších Qubitech ibm_brisbane, zatímco experiment se 40 Qubity byl spuštěn na nejlepším dostupném řetězci. Přesnost je uváděna pro magnetizaci; vysoce přesné výsledky byly získány i pro pozorovatelné veličiny s vyšší vahou.
Obvod VQE byl vyvinut společně s výzkumníky z Centra pro kvantové technologie a aplikace Německého elektronu-synchrotronu (DESY). Cílová pozorovatelná veličina zde byl Hamiltonův operátor složený z velkého počtu nekomutujících Pauliho řetězců, což zdůrazňuje optimalizovaný výkon QESEM pro pozorovatelné veličiny ve více bázích. Mitigace byla aplikována na klasicky optimalizovaný ansatz; ačkoli tyto výsledky jsou zatím nepublikované, výsledky stejné kvality budou získány pro různé obvody s podobnými strukturálními vlastnostmi.
Začínáme
Autentizuj se pomocí svého IBM Quantum Platform API klíče a vyber Qiskit Function QESEM takto. (Tento úryvek předpokládá, že jsi již uložil svůj účet do svého lokálního prostředí.)
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-catalog qiskit-ibm-runtime
import qiskit
from qiskit_ibm_catalog import QiskitFunctionsCatalog
catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")
# verify that you have access to the function
catalog.list()
# load the function
qesem_function = catalog.load("qedma/qesem")
Příklady
Příklad úlohy odhadu času
Úloha odhadu času je užitečná pro odhad doby QPU potřebné pro daný pub a backend_name. backend_name může být nastaven i na libovolný simulátorový backend, například fake_fez.
QESEM používá kvazi-pravděpodobnostní metodu EM založenou na charakterizaci. Tato metoda má režii doby QPU, která se přibližně škáluje jako:
Kde je aktivní objem okruhu, je cílová přesnost a je infidelita nativních hradel.
Všimni si, že "estimate_time_only": "empirical" využívá několik minut doby QPU k odhadu doby potřebné pro úlohu (pokud je backendem skutečné zařízení; pokud jde o simulátor, žádná doba QPU se nepoužívá). To obvykle trvá kolem 5 minut, ale ne déle než 10 minut. Pokud se infidelita mezi empirickou úlohou odhadu času a úlohou mitigace výrazně změní, výrazně se změní i doba QPU.
Pro začátek vyzkoušej tento základní příklad odhadování požadovaného času QPU pro spuštění QESEM pro daný pub:
# This cell is hidden from users
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
backend_name = service.least_busy().name
backend_name = "fake_fez"
circ = qiskit.QuantumCircuit(5)
circ.cx(0, 1)
circ.cx(2, 3)
circ.cx(1, 2)
circ.cx(3, 4)
avg_magnetization = qiskit.quantum_info.SparsePauliOp.from_sparse_list(
[("Z", [q], 1 / 5) for q in range(5)], num_qubits=5
)
other_observable = qiskit.quantum_info.SparsePauliOp.from_sparse_list(
[("ZZ", [0, 1], 1.0), ("XZ", [1, 4], 0.5)], num_qubits=5
)
time_estimation_job = qesem_function.run(
pubs=[(circ, [avg_magnetization, other_observable])],
options={
"estimate_time_only": "empirical",
},
backend_name=backend_name, # example: "fake_fez", "ibm_fez"
)
time_estimate_result = (
time_estimation_job.result()
) # a list of results per pub (circuit)
Následující ukázka kódu popisuje, jak získat různé metriky provádění z úlohy odhadu času (je nastaveno estimate_time_only):
pub_result = time_estimate_result[0]
print(
f"The estimated QPU time for mitigation for this PUB is: {pub_result.metadata['time_estimation_sec']}"
)
print(
f"The QPU time that this time estimation job took is (here it is 0 because we used fake_fez): {pub_result.metadata['total_qpu_time']}"
)
print(
f"Gates fidelity measured during the experiment: {pub_result.metadata['gate_fidelities']}"
)
print(f"Total shots: {pub_result.metadata['total_shots']}")
print(f"Resource usage breakdown: {pub_result.metadata['resource_usage']}")
The estimated QPU time for mitigation for this PUB is: 300
The QPU time that this time estimation job took is (here it is 0 because we used fake_fez): 0
Gates fidelity measured during the experiment: {'CZ': 0.9951354916722668, 'ID1Q': 0.9991246627329172}
Total shots: 220000
Resource usage breakdown: {'RUNNING: MAPPING': {'CPU_TIME': 33.6066133165732, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU_TIME': 184.53575124032795, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: WAITING_FOR_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: EXECUTING_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: POST_PROCESSING': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}}
Když je povolen empirický odhad času, QESEM spustí malý počet okruhů, aby poskytl přesnější odhad doby QPU. Výsledky mitigace z těchto okruhů jsou dostupné v poli empirical_estimation_mitigation_results úlohy.
Protože tyto výsledky jsou odvozeny z omezeného vzorku okruhů, jsou výrazně méně přesné než konečné výsledky získané z kompletní mitigační úlohy QESEM. Nicméně pokud je okruh malý nebo je cílová přesnost nízká, mitigace provedená během empirického odhadu času může být dostatečná k dosažení požadované přesnosti a úplná mitigační úloha nemusí být nutná.
Pole empirical_estimation_mitigation_results je seznam objektů PrimitiveResult pro každý vstupní parametr. Pokud okruh není parametrizovaný, bude mít seznam délku 1.
empirical_estimation_mitigation_results = time_estimate_result[0].metadata[
"empirical_estimation_mitigation_results"
][0] # a list per parameter
print("Partial results for the observables:")
print(
f" Mitigated expectation values: {empirical_estimation_mitigation_results.data.evs}"
)
print(
f" Mitigated error bars: {empirical_estimation_mitigation_results.data.stds}"
)
print(
f" Number of shots used for mitigation: {empirical_estimation_mitigation_results.metadata['mitigation_shots']}"
)
transpiled_circ = empirical_estimation_mitigation_results.metadata[
"transpiled_circ"
]
print(f" Qubit mapping: {transpiled_circ['qubit_maps']}")
print(
f" Number of measurement bases: {transpiled_circ['num_measurement_bases']}\n"
)
# results per obs
emp_obs_results = empirical_estimation_mitigation_results.metadata["results"][
0
]
# print(f"Results for each observable: {results}")
print("Results for each observable:")
for i, (obs_array, result_dict) in enumerate(emp_obs_results):
# obs_array, result_dict = results
print(f"Observable {i+1}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} \u00b1 {result_dict['qesem']['error_bar']}"
)
Partial results for the observables:
Mitigated expectation values: [1.00347302 1.00693905]
Mitigated error bars: [0.00304061 0.00714276]
Number of shots used for mitigation: 180000
Qubit mapping: [[[0, 136], [1, 143], [2, 142], [3, 141], [4, 140]]]
Number of measurement bases: 2
Results for each observable:
Observable 1: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 1.003473015776871 ± 0.0030406128032204015
Observable 2: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.0069390542613554 ± 0.0071427606736885925
Příklad mitigační úlohy QESEM
Následující příklad spustí úlohu QESEM:
sample_job = qesem_function.run(
pubs=[(circ, [avg_magnetization, other_observable])],
backend_name=backend_name, # example: "ibm_fez"
# options = {
# "estimate_time_only": "empirical",
# "default_precision": 0.2, # Default precision is applied to all pubs that don't have a precision specified, see API reference for more details
# "max_execution_time": 3600, # You can specify a maximum QPU time in seconds, see API reference for more details
# "transpilation_level": "standard", # "minimal_with_layout_opt" for minimal transpilation, see API reference for more details
# "parallel_execution": True, # True for parallel execution, see API reference for more details
# },
)
Podrobný popis každého vstupního pole a možnosti najdeš v referenci API QESEM. Pro kontrolu stavu pracovní zátěže Qiskit Function nebo získání výsledků můžeš použít známá API Qiskit Serverless:
# Print the ID so you can use it later, if necessary
print(sample_job.job_id)
print(sample_job.status())
sample_result = sample_job.result()
3ac6b2df-15b0-4dc0-8f48-cf14bd20a1c8
DONE
Následující úryvek kódu ukazuje, jak získat výsledky mitigace a metriky provádění. Tyto obsahují základní data, která umožňují hlubší pochopení toho, jak různé parametry ovlivňují provádění QESEM. Mohou být také relevantní při psaní článku na základě tvého výzkumu.
for pub_idx, pub_result in enumerate(
sample_result
): # each element in the list is a result for a different pub, here we sent only one pub
print(f"\nPUB {pub_idx}:")
print(
f" The QPU time that this job took is (here it is 0 because we used fake_fez): {pub_result.metadata['total_qpu_time']}"
)
print(
f" Gates fidelity measured during the experiment: {pub_result.metadata['gate_fidelities']}"
)
print(f" Total shots: {pub_result.metadata['total_shots']}")
print(
f" Number of shots used for mitigation: {pub_result.metadata['mitigation_shots']}"
)
print(
f" Resource usage breakdown: {pub_result.metadata['resource_usage']}"
)
PUB 0:
The QPU time that this job took is (here it is 0 because we used fake_fez): 0.0
Gates fidelity measured during the experiment: {'CZ': 0.9953704216147041, 'ID1Q': 0.9991834123567518}
Total shots: 446000
Number of shots used for mitigation: 194000
Resource usage breakdown: {'RUNNING: MAPPING': {'CPU_TIME': 32.52745003718883, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU_TIME': 257.850521848537, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: WAITING_FOR_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: EXECUTING_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: POST_PROCESSING': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}}
V metadata["results"] jsou výsledky seskupeny nejprve podle instance okruhu a poté podle pozorovatelné veličiny.
print("Full QESEM mitigation results:")
for pub_idx, pub_result in enumerate(sample_result):
print(f"\nPUB {pub_idx}:")
print(f" Mitigated expectation values: {pub_result.data.evs}")
print(f" Mitigated error bars: {pub_result.data.stds}")
noisy_results = pub_result.metadata.get("noisy_results")
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")
print(" Transpiled circuits:")
for circ_idx, transpiled_circ in enumerate(
pub_result.metadata["transpiled_circs"]
):
print(f" Circuit {circ_idx}:")
# print(f" Circuit: \n {transpiled_circ['circuit']}") # not printing it because it's long but you can see the transpiled circuit itself
print(f" Qubit mapping: {transpiled_circ['qubit_maps']}")
print(
f" Measurement bases: {transpiled_circ['num_measurement_bases']}"
)
print(" Results for each observable:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
)
print(
f" Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
)
Full QESEM mitigation results:
PUB 0:
Mitigated expectation values: [1.00648343 1.00636289]
Mitigated error bars: [0.00253812 0.00693586]
Unmitigated expectation values: [0.98031429 0.96357143]
Unmitigated error bars: [0.00124128 0.00578812]
Transpiled circuits:
Circuit 0:
Qubit mapping: [[[0, 140], [1, 141], [2, 142], [3, 143], [4, 136]]]
Measurement bases: 2
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 1.0064834305181962 ± 0.002538119914534849
Unmitigated value: 0.9803142857142859 ± 0.0012412835813609938
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.0063628870614818 ± 0.006935859820870656
Unmitigated value: 0.9635714285714285 ± 0.005788121870526659
Přehled hlavních výsledků:
mitigated: plně mitigovaná očekávaná hodnota QESEM.unmitigated: syrový výsledek fyzického šumu bez mitigace chyb.
Výsledky heuristické extrapolace QESEM
Ve standardním běhu QESEM s jednou hodnotou precision typu float jsou ve výsledcích automaticky k dispozici i body škálování šumu použité pro heuristiku QESEM. Tyto body se vypočítávají bez dalších zdrojů QPU.
Škála 1.0 představuje úroveň šumu fyzického zařízení s mitigací výčtu (REM), zatímco škála 2.0 je komplementární bod se zesíleným šumem, rovněž s REM. Tyto body se používají k výpočtu výsledku qesem_heuristic.
-
qesem_heuristic: odhad ve stylu ZNE vypočtený z dostupných dat škálovaných podle šumu. V současnosti se k tomu používá exponenciální extrapolace. -
noise_scaling.results_with_REM: očekávané hodnoty při různých škálách šumu, vždy s mitigací výčtu (REM).
Jemný, ale důležitý detail je, že výsledek při škále 1.0 není totéž co výsledek unmitigated. Oba odpovídají úrovni šumu fyzického zařízení, ale bod se škálou 1.0 zahrnuje mitigaci výčtu, zatímco unmitigated ji nezahrnuje.
print("QESEM heuristic results:")
for pub_idx, pub_result in enumerate(sample_result):
print(f"\nPUB {pub_idx}:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
qesem_heuristic = result_dict["qesem_heuristic"][0]
print(" QESEM heuristic:")
print(
f" Value: {qesem_heuristic['value']} ± {qesem_heuristic['error_bar']}"
)
print(
f" Extrapolation: {qesem_heuristic['extrapolation']}"
)
print(
f" Scale factors: {qesem_heuristic['scale_factors']}"
)
noise_scaling = result_dict["noise_scaling"]
print(" Noise scaling results:")
print(
f" Scaling method: {noise_scaling['scaling_method']}"
)
print(" Results with Readout mitigation (REM):")
for rem_result in sorted(
(
item
for item in noise_scaling["results_with_REM"]
if item["scale"] != 0.0
),
key=lambda item: item["scale"],
):
print(
f" Scale factor {rem_result['scale']}: {rem_result['value']} ± {rem_result['error_bar']}"
)
QESEM heuristic results:
PUB 0:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM heuristic:
Value: 1.0008161638888535 ± 0.0038859458884403964
Extrapolation: exponential
Scale factors: [1.0, 2.0]
Noise scaling results:
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 1.0: 0.9918395459270772 ± 0.0012565417579355634
Scale factor 2.0: 0.982943441922748 ± 0.0028919278067695018
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM heuristic:
Value: 0.9960853148925298 ± 0.013811635038961175
Extrapolation: exponential
Scale factors: [1.0, 2.0]
Noise scaling results:
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 1.0: 0.9902860583785115 ± 0.005921236914723409
Scale factor 2.0: 0.984520565414274 ± 0.006909522262347639
Následující příklady se zaměřují na vstupy a výsledky specifické pro danou funkci, takže při každém z nich netisknou úplné metriky provedení. Metadata nejvyšší úrovně zobrazená dříve, jako total_qpu_time, gate_fidelities, total_shots, mitigation_shots a resource_usage, jsou dostupná i pro tyto úlohy.
Některé proměnné z předchozích příkladů, včetně backendu, pozorovatelných veličin a parametrů základního okruhu, jsou níže kvůli stručnosti znovu použity.
Všechny následující příklady lze také spustit s empirickým odhadem času. Chceš-li jej povolit, předej "estimate_time_only": "empirical" v možnostech funkce.
Příklad parametrizovaného okruhu
Mnoho algoritmů vyhodnocuje stejný okruh při několika hodnotách parametrů. Odeslání parametrizovaného okruhu jako jedné úlohy QESEM umožňuje QESEM sdílet charakterizaci a kalibraci napříč instancemi okruhu, což může snížit režii doby QPU ve srovnání se spouštěním samostatných úloh.
Odeslání parametrizovaného okruhu vyžaduje použití transpilační úrovně "minimal_with_layout_opt".
Okruhy odeslané na této úrovni by měly být již vyjádřeny pomocí základních hradel backendu, v závislosti na backendu. Na této úrovni QESEM zachovává odeslanou strukturu co nejblíže vstupnímu okruhu, respektuje bariéry během vrstvení (seskupování operací do vrstev paralelních dvouqubitových hradel) a stále automaticky zajišťuje mapování na hardware pro qubity s vysokou fidelitou a propojení zařízení.
V praxi to znamená, že bys měl okruhy před odesláním transpilovat na základní hradla cílového backendu. Jednoduchý příklad transpilace na základní hradla je uveden níže.
QESEM v současnosti podporuje pouze jednu pozorovatelnou veličinu na sadu parametrů. Dva níže uvedené řádky parametrů jsou spárovány se dvěma pozorovatelnými veličinami: první řádek se měří pomocí avg_magnetization a druhý řádek se měří pomocí other_observable.
# Transpile to the backend basis gates only. With minimal_with_layout_opt, QESEM handles hardware mapping/connectivity and observable layout internally.
from qiskit_ibm_runtime.fake_provider import FakeFez
backend = FakeFez()
basis = backend.operation_names
print(basis)
param0 = qiskit.circuit.Parameter("param0")
param1 = qiskit.circuit.Parameter("param1")
parametrized_circ = qiskit.QuantumCircuit(5)
parametrized_circ.rx(param0, 0)
parametrized_circ.rx(param1, 1)
parametrized_circ.cx(0, 1)
parametrized_circ.cx(2, 3)
parametrized_circ.cx(1, 2)
parametrized_circ.cx(3, 4)
parametrized_circ = qiskit.transpile(
parametrized_circ, basis_gates=basis, optimization_level=1
)
parametrized_parameter_values = [[0.5, 0.1], [0.0, 0.6]]
parametrized_observables = [avg_magnetization, other_observable]
parametrized_job = qesem_function.run(
pubs=[
(
parametrized_circ,
parametrized_observables,
parametrized_parameter_values,
0.1,
)
],
backend_name=backend_name,
options={
"max_execution_time": 300,
"transpilation_level": "minimal_with_layout_opt",
},
)
print(parametrized_job.job_id)
print(parametrized_job.status())
d1b0e29b-196c-4896-aec6-44a268ebd874
DONE
parametrized_result = parametrized_job.result()
print("Parameterized circuit QESEM results:")
for pub_idx, pub_result in enumerate(parametrized_result):
print(f"\nPUB {pub_idx}:")
print(f" Mitigated expectation values: {pub_result.data.evs}")
print(f" Mitigated error bars: {pub_result.data.stds}")
noisy_results = pub_result.metadata["noisy_results"]
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")
print(" Results for each parameter value:")
for param_idx, param_results in enumerate(pub_result.metadata["results"]):
print(
f" Parameter set {param_idx}: {parametrized_parameter_values[param_idx]}"
)
for obs_idx, (obs_array, result_dict) in enumerate(param_results):
print(f" Observable {obs_idx}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
)
print(
f" Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
)
Parameterized circuit QESEM results:
PUB 0:
Mitigated expectation values: [0.92392021 0.82517653]
Mitigated error bars: [0.00565281 0.00616016]
Unmitigated expectation values: [0.9028 0.78771429]
Unmitigated error bars: [0.00335142 0.00925413]
Results for each parameter value:
Parameter set 0: [0.5, 0.1]
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 0.923920210615709 ± 0.005652811570890183
Unmitigated value: 0.9028 ± 0.0033514176105045447
Parameter set 1: [0.0, 0.6]
Observable 0: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 0.8251765289285893 ± 0.006160161743353999
Unmitigated value: 0.7877142857142858 ± 0.009254130564027902
Příklad s více PUB
Provádění s více PUB je užitečné, když chceš spustit několik souvisejících okruhů v jedné úloze QESEM. Podobně jako u parametrizovaného provádění to může snížit režii, protože QESEM může sdílet charakterizaci a kalibraci napříč instancemi okruhu, místo aby je opakoval v samostatných úlohách.
To je zvlášť užitečné pro okruhy se sdílenou strukturou vrstev, jako jsou pracovní zátěže typu Trotter, kde různé okruhy znovu používají stejné jedinečné vrstvy. V takovém případě může jejich společné spuštění snížit náklady na charakterizaci ve srovnání s nezávislými úlohami QESEM.
Úlohy s více PUB vyžadují "transpilation_level": "minimal_with_layout_opt". Stejně jako v parametrizovaném příkladu by okruhy měly být před odesláním transpilovány na základní hradla cílového backendu. QESEM se poté interně stará o propojení zařízení, layout a mapování na qubity s vysokou fidelitou.
Každý PUB níže obsahuje jeden okruh a stejné dvě pozorovatelné veličiny použité dříve v notebooku, takže vrácený PrimitiveResult obsahuje jeden PubResult na každý vstupní okruh.
Příklad níže používá dva jednoduché Trotterovy okruhy se stejným vzorem vrstev: circ_a má jednu Trotterovu vrstvu a circ_b opakuje stejný vzorec vrstev dvakrát. Tím je sdílená struktura zřejmá.
def make_trotter_circuit(num_qubits, num_layers, zz_angle=0.2, x_angle=0.1):
trotter_circ = qiskit.QuantumCircuit(num_qubits)
for _ in range(num_layers):
for q in range(num_qubits):
trotter_circ.rx(x_angle, q)
trotter_circ.barrier()
for q in range(0, num_qubits - 1, 2):
trotter_circ.rzz(zz_angle, q, q + 1)
trotter_circ.barrier()
for q in range(1, num_qubits - 1, 2):
trotter_circ.rzz(zz_angle, q, q + 1)
trotter_circ.barrier()
return trotter_circ
circ_a = make_trotter_circuit(num_qubits=5, num_layers=1)
circ_b = make_trotter_circuit(num_qubits=5, num_layers=2)
multi_pubs = [
(
qiskit.transpile(qci, basis_gates=basis, optimization_level=1),
[avg_magnetization, other_observable],
)
for qci in [circ_a, circ_b]
]
multi_circ_job = qesem_function.run(
pubs=multi_pubs,
backend_name=backend_name,
options={
"max_execution_time": 300,
"transpilation_level": "minimal_with_layout_opt",
"default_precision": 0.1,
},
)
print(multi_circ_job.job_id)
print(multi_circ_job.status())
e34565b8-7262-4133-a120-de42ce624a99
DONE
multi_circ_result = multi_circ_job.result()
print("Multi-pub QESEM results:")
for pub_idx, pub_result in enumerate(multi_circ_result):
print(f"\nPUB {pub_idx}:")
print(f" Mitigated expectation values: {pub_result.data.evs}")
print(f" Mitigated error bars: {pub_result.data.stds}")
noisy_results = pub_result.metadata["noisy_results"]
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")
print(" Results for each observable:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
)
print(
f" Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
)
Multi-pub QESEM results:
PUB 0:
Mitigated expectation values: [0.99502406 1.02209332]
Mitigated error bars: [0.00483819 0.00707488]
Unmitigated expectation values: [0.96934286 0.97271429]
Unmitigated error bars: [0.00124855 0.00617294]
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 0.9950240647925642 ± 0.004838188086259301
Unmitigated value: 0.9693428571428573 ± 0.0012485470362492692
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.0220933230604674 ± 0.007074884384355636
Unmitigated value: 0.9727142857142859 ± 0.006172939375512439
PUB 1:
Mitigated expectation values: [0.98850017 1.02555188]
Mitigated error bars: [0.0077912 0.01672652]
Unmitigated expectation values: [0.93682857 0.95371429]
Unmitigated error bars: [0.00156245 0.00665735]
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 0.988500171577252 ± 0.007791203181151346
Unmitigated value: 0.9368285714285716 ± 0.001562451883089579
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.02555188098689 ± 0.016726524388086233
Unmitigated value: 0.9537142857142858 ± 0.006657345655544263
Příklad kvazi-pravděpodobnostního ladění chyb (QET)
Kvazi-pravděpodobnostní ladění chyb (QET) požaduje očekávané hodnoty při vybraných faktorech škálování šumu. To je užitečné pro vlastní studie škálování šumu a pracovní postupy Zero-Noise Extrapolation. Škála 1.0 je úroveň fyzického šumu, hodnoty mezi 0.0 a 1.0 šum částečně snižují a hodnoty nad 1.0 šum zesilují.
Chceš-li použít QET s Qiskit Function, předej jako přesnost PUB slovník. Slovník mapuje každou požadovanou škálu šumu na její cílovou přesnost. Vrácené výsledky pro faktory škálování jsou uloženy v noise_scaling.results_with_REM a zahrnují mitigaci výčtu. Bod se škálou 1.0 proto není totožný s nemitigovanou hodnotou, protože 1.0 zahrnuje mitigaci výčtu, zatímco unmitigated ji nezahrnuje.
Když je požadována nějaká škála, QESEM vrátí i komplementární škálu kolem 1.0, aniž by to znamenalo další využití QPU. Například požadavek na 0.5 může vrátit i 1.5 a požadavek na 1.3 může vrátit i 0.7. Přesnost na komplementární škále není zaručena.
noise_scale_precision = {0.5: 0.15, 1.3: 0.2}
qet_job = qesem_function.run(
pubs=[
(
circ,
[avg_magnetization, other_observable],
None,
noise_scale_precision,
)
],
backend_name=backend_name,
options={"max_execution_time": 300},
)
print(qet_job.job_id)
print(qet_job.status())
8195fa58-f037-4651-8715-36ce1cdc5521
DONE
qet_result = qet_job.result()
print("QET noise-scaling results:")
for pub_idx, pub_result in enumerate(qet_result):
print(f"\nPUB {pub_idx}:")
noisy_results = pub_result.metadata["noisy_results"]
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")
print(" Results for each observable:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
noise_scaling = result_dict["noise_scaling"]
print(
f" Scaling method: {noise_scaling['scaling_method']}"
)
print(" Results with Readout mitigation (REM):")
for rem_result in sorted(
(
item
for item in noise_scaling["results_with_REM"]
if item["scale"] != 0.0
),
key=lambda item: item["scale"],
):
print(
f" Scale factor {rem_result['scale']}: {rem_result['value']} ± {rem_result['error_bar']}"
)
QET noise-scaling results:
PUB 0:
Unmitigated expectation values: [0.97822857 0.96171429]
Unmitigated error bars: [0.00123812 0.00672958]
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 0.5: 0.9938730340199383 ± 0.0032116907357568275
Scale factor 0.7: 0.9963976191853445 ± 0.00036300258869586616
Scale factor 1.0: 0.9898115079506586 ± 0.0012525947426560995
Scale factor 1.3: 0.9864667065580341 ± 0.002633221613518526
Scale factor 1.5: 0.9838755527197551 ± 0.002948417797996015
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 0.5: 1.0006538544450332 ± 0.002121742014777343
Scale factor 0.7: 1.0004159801523036 ± 0.0021671375357823794
Scale factor 1.0: 0.9898058846339917 ± 0.00690183710903159
Scale factor 1.3: 0.9948946719997267 ± 0.002146532859610311
Scale factor 1.5: 0.9927220368192772 ± 0.0020875057190323882
Načtení chybových zpráv
Pokud je stav tvé pracovní zátěže ERROR, získej chybovou zprávu pomocí job.result() takto:
# Get the result and truncate for readability
result = sample_job.result()
result_str = str(result)
max_length = 500 # Adjust this value as necessary
if len(result_str) > max_length:
truncated = (
result_str[:max_length]
+ f"... (truncated {len(result_str) - max_length} characters)"
)
else:
truncated = result_str
print(truncated)
PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(2,), dtype=float64>), stds=np.ndarray(<shape=(2,), dtype=float64>), shape=(2,)), metadata={'gate_fidelities': {'CZ': 0.9979444718552628, 'ID1Q': 0.9991994239814883}, 'total_shots': 498600, 'mitigation_shots': 223400, 'transpiled_circs': [{'circuit': 'OPENQASM 3.0;\ninclude "stdgates.inc";\nbit[76] c0;\nqubit[76] q0;\nrx(0) q0[54];\nrx(0) q0[59];\nrx(0) q0[75];\nrz(pi/2) q0[54];\nrz(pi/2) q0[59];\nrz(pi/2) q0[75];\nrx(pi/2) q0[54];\nr... (truncated 3771 characters)
Získání podpory
Tým podpory Qedmy je tu, aby ti pomohl! Pokud narazíš na jakékoli problémy nebo máš otázky ohledně používání Qiskit Function QESEM, neváhej nás kontaktovat. Naši znalí a přátelští pracovníci podpory jsou připraveni ti pomoci s jakýmikoli technickými obavami nebo dotazy.
Můžeš nám napsat e-mail na support@qedma.com a požádat o pomoc. Uveď prosím co nejvíce podrobností o problému, který máš, abychom ti mohli poskytnout rychlou a přesnou odpověď. Můžeš také kontaktovat svého dedikovaného zástupce Qedmy (POC) e-mailem nebo telefonem.
Abychom ti mohli pomoci efektivněji, uveď prosím při kontaktu s námi následující informace:
-
Podrobný popis problému
-
ID úlohy
-
Všechny relevantní chybové zprávy nebo kódy
Jsme odhodláni poskytnout ti rychlou a účinnou podporu, aby tvé zkušenosti s naší Qiskit Function byly co nejlepší.
Vždy hledáme způsoby, jak náš produkt vylepšit, a vítáme tvé návrhy! Pokud máš nápady, jak bychom mohli vylepšit naše služby nebo jaké funkce bys chtěl/a vidět, pošli nám své myšlenky na support@qedma.com.
Další kroky
-
Navštiv referenci API pro tuto Qiskit Function.
-
Vyzkoušej tutoriál Simulace 2D Isingova modelu s nakloněným polem pomocí funkce QESEM.