Langkau ke kandungan utama

Eksperimen berskala utiliti I

nota

Tamiya Onodera (5 Julai 2024)

Muat turun pdf kuliah asal. Perlu diingat bahawa beberapa petikan kod mungkin telah lapuk kerana ia adalah imej statik.

Anggaran masa QPU untuk menjalankan eksperimen ini ialah 45 saat.

1. Pengenalan kepada kertas utiliti

Dalam pelajaran ini, kita jalankan litar berskala utiliti yang muncul dalam apa yang kami panggil secara tidak rasmi "kertas utiliti" yang diterbitkan dalam Nature Vol 618, 15 Jun 2023. Kertas ini membahas evolusi masa model Ising medan melintang 2D. Secara khususnya, mereka mengkaji dinamik masa Hamiltonian,

H=HZZ+HX=J(i,j)ZiZj+hiXiH = H_{ZZ} + H_X = - J \sum_{(i,j)} Z_i Z_j + h \sum_{i} X_i

di mana J>0J > 0 ialah gandingan spin jiran terdekat dengan i<ji < j dan hh ialah medan melintang global. Mereka mensimulasikan dinamik spin daripada keadaan awal menggunakan penguraian Trotter peringkat pertama bagi operator evolusi masa,

exp(iHZZδt)=(i,j)exp(iJδtZiZj)=(i,j)RZiZj(2Jδt)exp(iHXδt)=iexp(ihδtXi)=iRXi(2hδt)\begin{aligned} \exp(-i H_{ZZ} \delta t) &= \prod_{(i,j)} \exp (i J \delta t Z_i Z_j) = \prod_{(i,j)} \mathrm{R}_{Z_i Z_j} ( - 2 J \delta t) \\ \exp(-i H_X \delta t) &= \prod_{i} \exp (-i h \delta t X_i ) = \prod_{i} \mathrm{R}_{X_i} ( 2 h \delta t) \end{aligned}

di mana masa evolusi TT dipecahkan kepada T/δtT / \delta t langkah Trotter dan RZiZj(θJ)\mathrm{R}_{Z_i Z_j}(\theta_J) serta RXi(θh)\mathrm{R}_{X_i}(\theta_h) masing-masing ialah Gate putaran ZZZZ dan XX.

Mereka menjalankan eksperimen pada pemproses IBM Quantum® Eagle, iaitu peranti 127-Qubit dengan ketersambungan heks berat, menggunakan interaksi XX pada semua Qubit dan interaksi ZZZZ untuk semua tepi peta gandingan. Perlu diingat bahawa semua interaksi ZZZZ tidak boleh digunakan serentak kerana "ketergantungan data". Oleh itu, mereka mewarnakan peta gandingan untuk mengumpulkan interaksi ke dalam lapisan. Interaksi dalam satu lapisan diberi warna yang sama dan boleh digunakan secara selari.

Selain itu, untuk memudahkan eksperimen, mereka menumpukan pada kes θJ=π/2\theta_J=-\pi /2.

Sumbangan baharu dalam kertas ini ialah mereka membina litar kuantum pada skala melebihi simulasi vektor keadaan, menjalankannya pada komputer kuantum yang bising, dan berjaya mengekstrak keputusan yang boleh dipercayai. Iaitu, mereka menunjukkan kegunaan komputer kuantum yang bising. Dalam proses itu, mereka menggunakan extrapolasi sifar hingar (ZNE) dengan amplifikasi ralat kebarangkalian (PEA) untuk mengurangkan ralat daripada peranti yang bising.

Sejak itu, kami memanggil eksperimen dan litar sedemikian sebagai "berskala utiliti".

1.1 Matlamat anda

Matlamat kamu dalam pelajaran ini ialah membina litar berskala utiliti dan menjalankannya pada pemproses Eagle. Adalah di luar skop buku nota ini untuk mengekstrak keputusan yang boleh dipercayai, sebahagiannya kerana PEA ialah ciri eksperimental Qiskit pada masa penulisan ini dan sebahagiannya kerana menggunakan ZNE dengan PEA memerlukan masa yang agak lama.

Secara konkrit, kamu diminta untuk membina dan menjalankan litar yang sepadan dengan Rajah 4b dalam kertas tersebut, dan memplot titik "tanpa mitigasi" sendiri. Seperti yang dapat dilihat, ia adalah litar 127-Qubit ×\times 60-lapisan (20 langkah Trotter) dengan Z62\langle Z_{62} \rangle sebagai boleh cerapan. image.png Kedengaran besar?   Jangan risau. Tiga pelajaran terakhir kursus ini menyediakan batu loncatan. Untuk bermula, kita akan menunjukkan eksperimen berskala lebih kecil iaitu membina dan menjalankan pada peranti palsu litar 27-Qubit ×\times 6-lapisan (2 langkah Trotter) dengan Z13\langle Z_{13} \rangle sebagai boleh cerapan.

Itu sahaja untuk pengenalan. Jom kita mulakan pengembaraan berskala utiliti!

# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-aer qiskit-ibm-runtime rustworkx
import qiskit

qiskit.__version__
'2.0.2'
#!pip install qiskit_ibm_runtime
#!pip install qiskit_aer
import matplotlib.pyplot as plt
import numpy as np
import rustworkx as rx

from qiskit import QuantumCircuit, transpile
from qiskit.circuit import Parameter
from qiskit.circuit.library import YGate
from qiskit.quantum_info import SparsePauliOp
from qiskit_ibm_runtime import (
QiskitRuntimeService,
fake_provider,
EstimatorV2 as Estimator,
)
from qiskit_aer import AerSimulator
service = QiskitRuntimeService()

2. Persediaan

2.1 Bina RZZ(-π\pi / 2)

Pertama, perhatikan bahawa Gate RZZ secara umum memerlukan dua Gate CXCX.

from qiskit.circuit.library import RZZGate

θ_h = Parameter("$\\theta_h$")
qc1 = QuantumCircuit(2)
qc1.append(RZZGate(θ_h), [0, 1])
qc1.decompose(reps=1).draw("mpl")

Output of the previous code cell

Seperti yang disebutkan di atas, kita menumpukan pada Gate RZZ dengan sudut tertentu, -π\pi / 2, untuk eksperimen ini. Seperti yang ditunjukkan dalam kertas tersebut, ia boleh direalisasikan dengan hanya satu Gate CXCX.

qc2 = QuantumCircuit(2)

qc2.sdg([0, 1])
qc2.append(YGate().power(1 / 2), [1])
qc2.cx(0, 1)
qc2.append(YGate().power(1 / 2).adjoint(), [1])

qc2.draw("mpl")

Output of the previous code cell

Kita takrifkan sebuah Gate berdasarkan Circuit ini untuk rujukan masa hadapan.

rzz = qc2.to_gate(label="RZZ")

Jom kita cuba gunakan rzz yang baru ditakrifkan ini.

qc3 = QuantumCircuit(3)
qc3.append(rzz, [0, 1])
qc3.append(rzz, [0, 2])
display(qc3.draw("mpl"))
# display(qc.decompose(reps=1).draw("mpl"))

Output of the previous code cell

Sebelum menggunakannya lebih lanjut, mari kita sahkan kesetaraan logik qc1 (Gate RZZ) untuk -pi/2 dan Gate rzz atau qc2 yang baru ditakrifkan:

from qiskit.quantum_info import Operator

op1 = Operator(qc1.assign_parameters([-np.pi / 2]))
op2 = Operator(qc2)

op1.equiv(op2)
True

2.2 Warnakan peta gandingan

Jom kita kaji cara mewarnakan peta gandingan sebuah Backend. Ini diperlukan untuk mengumpulkan interaksi ZZZZ ke dalam lapisan.

Untuk memulakan, jom kita visualkan peta gandingan sebuah Backend. Perhatikan bahawa peta gandingan adalah berbentuk heks berat untuk semua peranti IBM Quantum semasa.

backend = service.least_busy(operational=True, simulator=False)

backend.coupling_map.draw()

Output of the previous code cell

Untuk mewarnakan peta gandingan, kita gunakan rustworkx, iaitu pakej Python untuk bekerja dengan graf dan rangkaian kompleks. Ia menyediakan pelbagai algoritma pewarnaan, yang semuanya bersifat heuristik dan oleh itu tidak dijamin untuk mencari pewarnaan minimum.

Walau bagaimanapun, memandangkan graf heks berat adalah dwi-bahagian, kita pilih graph_bipartite_edge_color, yang sepatutnya mencari pewarnaan minimum untuk graf-graf ini.

def color_coupling_map(backend):
graph = backend.coupling_map.graph
undirected_graph = graph.to_undirected(multigraph=False)
edge_color_map = rx.graph_bipartite_edge_color(undirected_graph)
if edge_color_map is None:
edge_color_map = rx.graph_greedy_edge_color(undirected_graph)
# build a map from color to a list of edges
edge_index_map = undirected_graph.edge_index_map()
color_edges_map = {color: [] for color in edge_color_map.values()}
for edge_index, color in edge_color_map.items():
color_edges_map[color].append(
(edge_index_map[edge_index][0], edge_index_map[edge_index][1])
)
return edge_color_map, color_edges_map

Graf heks berat sepatutnya diwarnakan dengan tiga warna. Jom kita semak ini untuk peta gandingan di atas.

edge_color_map, color_edges_map = color_coupling_map(backend)
print(
f"{backend.name}, {backend.num_qubits}-qubit device, {len(color_edges_map.keys())} colors assigned."
)
ibm_strasbourg, 127-qubit device, 3 colors assigned.

Ya, betul!

Untuk keseronokan, jom kita warnakan peta gandingan mengikut pewarnaan yang diperoleh, menggunakan ciri visualisasi rustworkx.

color_str_map = {0: "green", 1: "red", 2: "blue"}

undirected_graph = backend.coupling_map.graph.to_undirected(multigraph=False)
for i in undirected_graph.edge_indices():
undirected_graph.get_edge_data_by_index(i)["color"] = color_str_map[
edge_color_map[i]
]

rx.visualization.graphviz_draw(
undirected_graph, method="neato", edge_attr_fn=lambda edge: {"color": edge["color"]}
)

Output of the previous code cell

3. Selesaikan evolusi masa Trotterized bagi model Ising 2D.

Mari kita definisikan satu rutin untuk membina Circuit bagi kertas utility bagi evolusi masa model Ising 2D. Rutin ini mengambil tiga parameter: sebuah backend, integer yang menunjukkan bilangan langkah Trotter, dan Boolean yang mengawal penyisipan halangan.

def get_utility_circuit(backend, num_steps: int, barrier: bool = False):
num_qubits = backend.num_qubits
_, color_edges_map = color_coupling_map(backend)
θ_h = Parameter("$\\theta_h$")
qc = QuantumCircuit(num_qubits)

for i in range(num_steps):
qc.rx(θ_h, range(num_qubits))

for _, edge_list in color_edges_map.items():
for edge in edge_list:
qc.append(rzz, edge)

if barrier:
qc.barrier()
return qc

Sila ambil perhatian bahawa kita telah melakukan pemetaan dan penghalaan Qubit secara manual untuk Circuit yang dibina. Oleh itu, semasa kita mentranspil Circuit nanti, kita tidak (tidak sepatutnya) meminta Transpiler melakukan pemetaan dan penghalaan Qubit. Seperti yang akan anda lihat tidak lama lagi, kita memanggilnya dengan tahap pengoptimuman 1 dan kaedah susun atur sebagai "trivial".

Seterusnya kita definisikan satu rutin mudah untuk mendapatkan maklumat tentang Circuit yang dibina bagi semakan pantas.

def get_circuit_info(qc: QuantumCircuit, reps: int = 0):
qc0 = qc.decompose(reps=reps)
return (
f"{qc0.num_qubits} qubits × {qc0.depth(lambda x: x.operation.num_qubits == 2)} layers ({qc0.depth()}-depth)"
+ ", "
+ f"""Gate breakdown: {", ".join([f"{k.upper()} {v}" for k, v in qc0.count_ops().items()])}"""
)

Mari kita latih rutin-rutin ini. Anda seharusnya melihat Circuit 27 Qubit ×\times 15 lapisan (5 langkah Trotter). Memandangkan peranti palsu mempunyai 28 tepi, sepatutnya ada 28*5 Gate pembelit.

backend = fake_provider.FakeTorontoV2()
num_steps = 5
qc = get_utility_circuit(backend, num_steps, True)

display(qc.draw(output="mpl", fold=-1))
print(get_circuit_info(qc, reps=0))
print(get_circuit_info(qc, reps=1))

Output of the previous code cell

27 qubits × 15 layers (20-depth),  Gate breakdown: CIRCUIT-165 140, RX 135, BARRIER 5
27 qubits × 15 layers (60-depth), Gate breakdown: SDG 280, UNITARY 280, CX 140, R 135, BARRIER 5

4. Selesaikan versi 27-Qubit bagi masalah ini.

Kita kini menunjukkan versi berskala lebih kecil bagi eksperimen utility. Kita membina Circuit 27 Qubit ×\times 6 lapisan (2 langkah Trotter) dengan Z13\langle Z_{13} \rangle sebagai observable, dan menjalankannya pada AerSimulator dan peranti palsu.

Tentu saja, kita mengikuti aliran kerja empat langkah kita, "corak Qiskit", yang terdiri daripada Peta, Optima, Laksana, dan Pasca-Proses. Lebih konkrit:

  • Petakan input klasik kepada pengiraan kuantum.
  • Optimumkan Circuit untuk pengiraan kuantum.
  • Laksanakan Circuit menggunakan primitif.
  • Pasca-proses dan pulangkan hasil dalam format klasik.

Dalam bahagian berikut, kita ada langkah Peta untuk mencipta Circuit bagi eksperimen berskala lebih kecil. Kemudian kita ada satu set Optima dan Laksana untuk AerSimulator dan satu lagi untuk peranti palsu. Akhirnya, kita ada langkah Pasca-Proses untuk memplot hasil.

4.1 Langkah 1: Peta

backend = fake_provider.FakeTorontoV2()  # a 27 qubit fake device.
num_steps = 2
qc = get_utility_circuit(backend, num_steps)
obs = SparsePauliOp.from_sparse_list(
[("Z", [13], 1)], num_qubits=backend.num_qubits
) # Falcon
angles = [
0,
0.1,
0.2,
0.3,
0.4,
0.5,
0.6,
0.7,
0.8,
1.0,
np.pi / 2,
] # We try 11 angles for theta_h.

4.2 Langkah 2 dan 3: Optimumkan dan Laksana (Simulator)

backend_sim = AerSimulator()
transpiled_qc_sim = transpile(
qc, backend_sim, optimization_level=1, layout_method="trivial"
)
transpiled_obs_sim = obs.apply_layout(layout=transpiled_qc_sim.layout)

print(get_circuit_info(qc, reps=1))
print(get_circuit_info(transpiled_qc_sim, reps=1))
27 qubits × 6 layers (23-depth),  Gate breakdown: SDG 112, UNITARY 112, CX 56, R 54
27 qubits × 6 layers (16-depth), Gate breakdown: U3 80, CX 56, R 54, U1 32, U 28

Seorang pengguna menjalankan sel seterusnya menggunakan MacBook Pro dengan pemproses Intel Core i7 2.3 GHz quad-core dilengkapi RAM 32GB 3LPDDR4X, yang menjalankan macOS 14.5. Ia mengambil masa 161ms dalam masa dinding. Setiap laptop akan sedikit berbeza.

%%time
params = [[p] for p in angles]
estimator = Estimator(mode=backend_sim)
pub = (transpiled_qc_sim, transpiled_obs_sim, params)
result_sim = estimator.run([pub]).result()
CPU times: user 231 ms, sys: 186 ms, total: 417 ms
Wall time: 111 ms

4.3 Langkah 2 dan 3: Optimumkan dan laksana (peranti palsu)

backend_fake = fake_provider.FakeTorontoV2()
transpiled_qc_fake = transpile(
qc, backend_fake, optimization_level=1, layout_method="trivial"
)
transpiled_obs_fake = obs.apply_layout(layout=transpiled_qc_fake.layout)

print(get_circuit_info(qc, reps=1))
print(get_circuit_info(transpiled_qc_fake, reps=1))
27 qubits × 6 layers (23-depth),  Gate breakdown: SDG 112, UNITARY 112, CX 56, R 54
27 qubits × 6 layers (49-depth), Gate breakdown: SDG 324, U1 274, H 162, CX 56, U3 14

Apabila pengguna yang sama menjalankan sel seterusnya dengan persekitaran yang sama seperti di atas, ia mengambil masa 2 minit 19 saat dalam Masa Dinding. Melaksanakan Circuit pada peranti palsu menggunakan simulasi berbising yang mengambil masa jauh lebih lama daripada simulasi tepat. Kami mengesyorkan anda tidak melaksanakan Circuit yang lebih besar (seperti Circuit 27-Qubit ×\times 9 lapisan dengan 3 langkah Trotter) pada peranti palsu.

%%time
params = [[p] for p in angles]
estimator = Estimator(mode=backend_fake)
pub = (transpiled_qc_fake, transpiled_obs_fake, params)
result_fake = estimator.run([pub]).result()
CPU times: user 4min 42s, sys: 9.35 s, total: 4min 51s
Wall time: 38.3 s

4.4 Langkah 4: Pasca-proses

Kita memplot hasil daripada simulasi tepat dan berbising. Anda dapat melihat kesan teruk bunyi pada FakeToronto.

plt.plot(angles, result_fake[0].data.evs, "o", label="Fake Device")
plt.plot(angles, result_sim[0].data.evs, "o", label="AerSimulator")
plt.xlabel("$\\mathrm{R_x}$ angle $\\theta_h$")
plt.title("$\\langle Z_{13} \\rangle$")
plt.legend()
plt.show()

Output of the previous code cell

5. Selesaikan versi 127-Qubit bagi masalah ini

Matlamat anda adalah untuk menjalankan eksperimen berskala utility seperti yang disebutkan pada awalnya. Anda akan mencipta dan melaksanakan Circuit 127 Qubit dan 60 lapisan (20 langkah Trotter) dengan Z62\langle Z_{62} \rangle sebagai observable. Kami mengesyorkan anda cuba melakukan ini sendiri, menggunakan kod untuk versi 27-Qubit apabila sesuai. Tetapi penyelesaiannya disediakan di sini.

Penyelesaian:

5.1 Langkah 1: Peta

# backend_map = service.backend("ibm_brisbane")
backend_map = service.least_busy(operational=True, simulator=False)

num_steps = 20
qc = get_utility_circuit(backend_map, num_steps)
obs = SparsePauliOp.from_sparse_list(
[("Z", [62], 1)], num_qubits=backend_map.num_qubits
) # Eagle
angles = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1.0, np.pi / 2]

5.2 Langkah 2 dan 3: Optimumkan dan laksana

Kita perhatikan bahawa peta gandingan pemproses Eagle mempunyai 144 tepi.

# backend = service.backend("ibm_brisbane")
backend = backend_map

transpiled_qc = transpile(qc, backend, optimization_level=1, layout_method="trivial")
transpiled_obs = obs.apply_layout(layout=transpiled_qc.layout)

print(get_circuit_info(qc, reps=1))
print(get_circuit_info(transpiled_qc))
156 qubits × 60 layers (221-depth),  Gate breakdown: SDG 7040, UNITARY 7040, CX 3520, R 3120
156 qubits × 60 layers (201-depth), Gate breakdown: RZ 11933, SX 6240, CZ 3520
params = [[p] for p in angles]
estimator = Estimator(mode=backend)
pub = (transpiled_qc, transpiled_obs, params)
job = estimator.run([pub])

job_id = job.job_id()
print(f"job id={job_id}")
job id=d1479n6qf56g0081sxa0

5.3 Pasca-proses

Kita menyediakan nilai untuk titik "yang telah dikurangkan kesalahannya" dalam Rajah 4b kertas utility. Plot nilai-nilai ini bersama hasil anda.

result_paper = [
1.0171,
1.0044,
0.9563,
0.9602,
0.8394,
0.8120,
0.5466,
0.4556,
0.1953,
0.0141,
0.0117,
]

# REPLACE WITH YOUR OWN JOB ID
job = service.job(job_id)

plt.plot(angles, job.result()[0].data.evs, "o", label=f"{job.backend().name}")
plt.plot(angles, result_paper, "o", label="Utility Paper")
plt.xlabel("$\\mathrm{R_x}$ angle $\\theta_h$")
plt.title("$\\langle Z_{62} \\rangle$")
plt.legend()
plt.show()

Output of the previous code cell

Adakah hasil anda serupa dengan "yang tidak dikurangkan kesalahannya" dalam Rajah 4b?   Ia mungkin sangat berbeza, bergantung pada peranti dan keadaannya semasa eksperimen. Jangan bimbang tentang hasil itu sendiri. Apa yang akan kita semak ialah sama ada anda telah melakukan pengekodan dengan betul. Jika anda telah melakukannya, tahniah, anda telah mencapai garis permulaan era utility.

Seperti dalam kertas Utility, para saintis di seluruh dunia telah menunjukkan kreativiti yang luar biasa untuk mengekstrak hasil yang bermakna walaupun dalam kehadiran bunyi. Matlamat akhir usaha bersama ini ialah kelebihan kuantum: suatu keadaan di mana komputer kuantum dapat menyelesaikan beberapa masalah yang berguna dalam industri dengan lebih pantas, dengan ketepatan lebih tinggi, atau lebih murah berbanding komputer klasik. Ini berkemungkinan bukan peristiwa tunggal, tetapi lebih kepada suatu era di mana penghasilan semula klasik bagi hasil kuantum mengambil masa yang semakin lama, sehingga pada satu ketika masa unggul kuantum itu menjadi sangat penting. Satu perkara yang jelas tentang kelebihan kuantum: kita hanya boleh sampai ke sana melalui eksperimen berskala utility. Jika kursus ini mengakibatkan anda menyertai pencarian ini, yang penuh cabaran dan keseronokan, kami akan sangat gembira.

Rujukan

Source: IBM Quantum docs — updated 15 Jan 2026
English version on doQumentation — updated 7 Mei 2026
This translation based on the English version of approx. 27 Mac 2026