ข้ามไปยังเนื้อหาหลัก
โครงการนี้อยู่ในช่วงเบต้า พบข้อผิดพลาด? สร้าง GitHub Issue มีคำถามหรือไอเดีย? ถามใน Discussions — ยินดีรับฟังความคิดเห็น!
คุณภาพการแปลในหน้านี้เป็นอย่างไร?

เรียนรู้โมเดลสัญญาณรบกวนของ gate

บทแนะนำนี้สาธิตการเรียนรู้โมเดลสัญญาณรบกวนสำหรับ gate แบบ unitary ด้วยโปรโตคอลการเรียนรู้มาตรฐานที่เข้าถึงได้ผ่านฟังก์ชันโปรโตคอลระดับสูง prepare_vanilla_program() และ process_vanilla_result()

  1. กำหนด gate

  2. ตั้งค่าการจำลองในเครื่อง

  3. เตรียมโปรแกรมควอนตัม

  4. รันโปรแกรมควอนตัม

  5. อ่านผลลัพธ์

การรันบนฮาร์ดแวร์จริง

circuit ด้านล่างจำลองในเครื่อง ดังนั้นการทดลองตามนี้ไม่ต้องใช้ข้อมูลรับรอง IBM Quantum® หากต้องการรันบนอุปกรณ์จริงแทน:

  • ขั้นที่ 1: แทนที่ FakeMarrakesh ด้วย backend จริง

  • ขั้นที่ 2: ส่ง backend นั้นเป็นโหมดของ executor และเอาตัวเลือกของ simulator ออก

1. กำหนด gate​

Gate นี้คือ BoxOp ที่บรรจุชั้นที่ผ่านการ twirl ของ CZ gate หกตัวที่ไม่ซ้อนทับกัน

from qiskit.circuit import QuantumCircuit
from qiskit_ibm_runtime.fake_provider import FakeMarrakesh
from samplomatic import InjectNoise, Tag, Twirl

backend = FakeMarrakesh()

cz_pairs = [(91, 92), (93, 94), (95, 99), (98, 111), (112, 113), (114, 115)]

circuit = QuantumCircuit(backend.num_qubits)
with circuit.box([Twirl(), Tag("cz_gate"), InjectNoise("cz_gate")]):
for pair in cz_pairs:
circuit.cz(*pair)
การรันบนฮาร์ดแวร์จริง
from qiskit_ibm_runtime import QiskitRuntimeService

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

2. ตั้งค่าการจำลองในเครื่อง​

ดัชนี Pauli ภายในแต่ละ map เป็นดัชนีเฉพาะของ gate เรียงตามลำดับ physical qubit จากน้อยไปมาก:

cz_qubits = sorted({qubit for pair in cz_pairs for qubit in pair})
local = {qubit: index for index, qubit in enumerate(cz_qubits)}
local
{91: 0,
92: 1,
93: 2,
94: 3,
95: 4,
98: 5,
99: 6,
111: 7,
112: 8,
113: 9,
114: 10,
115: 11}

กำหนดสัญญาณรบกวนด้วยพจน์ ZZ ที่มีสหสัมพันธ์กับพจน์ XX ที่อ่อนกว่าบนแต่ละคู่ CZ บวกพจน์ Z แบบ single-qubit ทุกที่ ส่วนการวัดจะได้พจน์ bit-flip ต่อ qubit

from qiskit.quantum_info import PauliLindbladMap

num_qubits = len(cz_qubits)

cz_noise = PauliLindbladMap.from_sparse_list(
[("ZZ", [local[a], local[b]], 8e-4) for a, b in cz_pairs]
+ [("XX", [local[a], local[b]], 4e-4) for a, b in cz_pairs]
+ [("Z", [index], 3e-4) for index in range(num_qubits)],
num_qubits=num_qubits,
)

readout_noise = PauliLindbladMap.from_sparse_list(
[("X", [index], 5e-3) for index in range(num_qubits)], num_qubits=num_qubits
)

สร้าง box สำหรับให้การวัดเรียนรู้

measurement = QuantumCircuit(backend.num_qubits, num_qubits)
with measurement.box([Twirl(), Tag("readout"), InjectNoise("readout")]):
for clbit, qubit in enumerate(cz_qubits):
measurement.measure(qubit, clbit)

แต่ละรายการของ layer_noise_model จับคู่ box หนึ่งใบกับ map ที่จะใช้กับ box นั้น ใช้วิธีจำลองแบบ stabilizer และตั้งค่า seed_simulator เพื่อให้ข้อมูลจำลองทำซ้ำได้

from qiskit_aer import AerSimulator
from qiskit_ibm_runtime import Executor

executor = Executor(
mode=AerSimulator(method="stabilizer"),
options={
"simulator": {
"layer_noise_model": [
(circuit[0], cz_noise),
(measurement[0], readout_noise),
],
"seed_simulator": 1234,
}
},
)
การรันบนฮาร์ดแวร์จริง
executor = Executor(mode=backend)

3. เตรียมโปรแกรมควอนตัม​

ใช้ prepare_vanilla_program() เพื่อสร้างโปรแกรมควอนตัมที่มีการทดลองเรียนรู้

from qiskit_noise_learning.protocols import prepare_vanilla_program

program = prepare_vanilla_program(
backend,
[circuit[0], measurement[0]],
fragment_depths=[2, 16, 64, 128],
num_randomizations=50,
shots_per_randomization=20,
)

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

4. รันโปรแกรมควอนตัม​

ส่งโปรแกรมควอนตัม ขั้นตอนนี้เหมือนกันไม่ว่า executor จะชี้ไปที่ simulator หรืออุปกรณ์จริง

result = executor.run(program).result()

5. อ่านผลลัพธ์​

ประมวลผลลัพธ์ด้วย process_vanilla_result()

from qiskit_noise_learning.protocols import process_vanilla_result

noise_maps, gate_names, fit = process_vanilla_result(result)

พล็อตการสลายของ fidelity ต่อคู่ qubit ทั้งข้อมูลและการ fit แบบเอกซ์โพเนนเชียล

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