게이트의 노이즈 모델 학습하기
이 튜토리얼은 고수준 프로토콜 함수 prepare_vanilla_program()과 process_vanilla_result()로 사용할 수 있는 표준 학습 프로토콜을 통해 유니터리 게이트의 노이즈 모델을 학습하는 방법을 보여 줍니다.
-
게이트 정의하기
-
로컬 시뮬레이션 설정하기
-
양자 프로그램 준비하기
-
양자 프로그램 실행하기
-
결과 읽기
아래 회로는 로컬에서 시뮬레이션되므로 이 안내를 따라 하는 데 IBM Quantum® 자격 증명이 필요하지 않습니다. 대신 실제 장치에서 실행하려면 다음과 같이 합니다.
-
1단계:
FakeMarrakesh를 실제 백엔드로 교체합니다. -
2단계: 해당 백엔드를 실행기(executor)의 모드로 전달하고 시뮬레이터 옵션은 제거합니다.
1. 게이트 정의하기
이 게이트는 서로 겹치지 않는 CZ 게이트 6개로 이루어진 트윌링된 층을 담고 있는 BoxOp입니다.
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 인덱스는 Gate에 대해 국소적이며, 물리 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}
각 CZ 쌍에 상관된 ZZ 항과 더 약한 XX 항을 두고, 모든 곳에 단일 Qubit Z 항을 추가하여 노이즈를 정의합니다. 측정에는 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
)
측정이 학습할 박스를 만듭니다.
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의 각 항목은 이러한 박스 중 하나와 그 박스에 적용할 맵을 짝지어 줍니다. 스태빌라이저 시뮬레이션 방법을 사용하고, 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가 시뮬레이터를 가리키든 실제 장치를 가리키든 동일합니다.
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)
Qubit 쌍별 충실도 감쇠를 플롯합니다. 데이터와 지수 피팅을 모두 표시합니다.
fit.plot_qubit_pair_decays(
pairs=cz_pairs,
observable_type="means",
exponential_fit=True,
)