Skip to main content
IBM Quantum Platform

빠른 시작

이 가이드에서는 해당 qiskit-addon-pna 패키지의 최소 실행 가능한 예제를 보여줍니다. 우리는 소음 완화 관측량을 구축하기 위해 전파형 소음 흡수(PNA)를 사용합니다. 주어진 회로와 파울리-린드블라드 잡음 모델이 있을 때, PNA는 고전적으로 관측량을 역잡음 채널을 통해 전파합니다. 노이즈가 있는 QPU에서 결과 관측량을 측정하면 학습된 게이트 노이즈가 완화됩니다.

NoiseLearnerV3지시형 실행 모델을 활용해 현실적인 워크플로를 구축하고 양자 하드웨어에서 실행하는 방법, 그리고 를 이용한 노이즈 모델 학습 방법을 알아보려면, IBM Quantum Platform 의 PNA 튜토리얼을 확인해 보세요.


1. PNA에 필요한 입력 데이터를 준비합니다

PNA는 회로, 잡음 모델 및 관측량을 입력으로 받습니다. 여기서는 1D 사슬을 기반으로 10-큐비트 트로터화 횡자장 이징 모델을 구축합니다. 각 얽힘 게이트에 대해 무작위 2-로컬 파울리-린드블라드 노이즈 모델을 생성하고, 해당 게이트 바로 앞에 Qiskit Aer PauliLindbladError 명령어로 삽입합니다. 우리는 측정 대상으로 ‘ weight-4 ’ 파울리-Z 관측량을 선택한다.

import numpy as np
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp, pauli_basis
from qiskit_aer.noise import PauliLindbladError


def random_pauli_lindblad_noise(generators, seed, noise_scale=2e-3):
    rates = np.random.default_rng(seed).random(len(generators)) * noise_scale
    return PauliLindbladError(generators, rates)


def ising_circuit(
    num_qubits,
    layers,
    edge_noise=None,
    *,
    num_steps=3,
    rx_angle=np.pi / 8,
    rzz_angle=-np.pi / 2,
):
    """Trotterized transverse-field Ising model; edge_noise=None gives the noiseless circuit."""
    qc = QuantumCircuit(num_qubits)
    for _ in range(num_steps):
        qc.rx(rx_angle, range(num_qubits))
        for layer in layers:
            for edge in layer:
                if edge_noise is not None:
                    qc.append(
                        edge_noise[edge], edge
                    )  # inject synthetic gate noise
                qc.rzz(rzz_angle, *edge)
    return qc


num_qubits = 10

# Two entangling layers per Trotter step: even and odd bonds of a 1D chain
layers = [
    [(i, i + 1) for i in range(0, num_qubits - 1, 2)],
    [(i, i + 1) for i in range(1, num_qubits - 1, 2)],
]
edges = [edge for layer in layers for edge in layer]

# Random 2-local Pauli-Lindblad noise, one instance per entangling gate
two_qubit_paulis = SparsePauliOp(
    [p for p in pauli_basis(2) if np.sum(p.x + p.z)]
).paulis
edge_noise = {
    edge: random_pauli_lindblad_noise(two_qubit_paulis, seed=1234 + j)
    for j, edge in enumerate(edges)
}

noisy_circuit = ising_circuit(num_qubits, layers, edge_noise)

# A single weight-4 observable: <Z3 Z4 Z5 Z6>
observable = SparsePauliOp.from_sparse_list(
    [("ZZZZ", [3, 4, 5, 6], 1.0)], num_qubits=num_qubits
)

noisy_circuit.draw("mpl", fold=-1, scale=0.6)

Output:

Output of the previous code cell

2. 잡음 완화 관측량을 생성한다

generate_noise_mitigating_observable은 역잡음 채널의 각 파울리 생성자를 회로 끝까지 전방으로 전파합니다. 그런 다음 관측값은 역 잡음 채널을 통해 역전파되어 새로운 관측값 O~\tilde{O} 을 반환합니다. 계산 비용에는 다음 세 가지 주요 매개변수가 영향을 미칩니다:

  • max_err_terms: 전방 전파 과정에서 각 항잡음 생성기에 유지되는 항의 수.
  • max_obs_terms: O~\tilde{O} 에 저장된 용어의 수.
  • atol: 계수의 크기가 이 임계값보다 작은 항은 제외됩니다.

atol클리포드 회로에 가까운 이 작은 회로의 경우, 항의 차수를 높게 설정하고 적당한 값을 사용하므로, O~\tilde{O} 의 크기는 작게 유지되며 모든 항을 측정할 수 있습니다.

참고: 이 함수는 Python multiprocessing를 사용합니다. 스크립트로 실행할 때는 guard 블록 if __name__ == "__main__": 내에서 호출하십시오.

from qiskit_addon_pna import generate_noise_mitigating_observable

mitigating_observable = generate_noise_mitigating_observable(
    noisy_circuit,
    observable,
    max_err_terms=100_000,
    max_obs_terms=100_000,
    atol=1e-5,
    num_processes=4,
)

print(f"Original observable:         {len(observable)} term")
print(f"Noise-mitigating observable: {len(mitigating_observable)} terms")

Output:

Original observable:         1 term
Noise-mitigating observable: 207 terms

3. 잡음 완화 관측량을 측정하여 게이트 오류를 완화한다

여기서 우리는 새로운 관측량이 실험에 영향을 미치는 게이트 노이즈를 효과적으로 완화한다는 것을 알 수 있다.

import matplotlib.pyplot as plt
from qiskit_aer.primitives import EstimatorV2

noiseless_circuit = ising_circuit(num_qubits, layers)

# density_matrix method at zero precision -> exact expectation values (no shot noise)
estimator = EstimatorV2(
    options={
        "backend_options": {"method": "density_matrix"},
        "default_precision": 0.0,
    }
)

ideal, noisy, mitigated = (
    result.data.evs
    for result in estimator.run(
        [
            (noiseless_circuit, observable),
            (noisy_circuit, observable),
            (noisy_circuit, mitigating_observable),
        ]
    ).result()
)

print(f"Ideal (noiseless):   {ideal:.4f}")
print(f"Noisy (unmitigated): {noisy:.4f}")
print(f"Mitigated (PNA):     {mitigated:.4f}")

fig, ax = plt.subplots()
ax.bar(
    ["Noisy", "Mitigated"],
    [noisy, mitigated],
    width=0.6,
    color=["#b0b0b0", "#4c4c4c"],
)
ax.axhline(ideal, color="green", linestyle="--", label="Ideal (noiseless)")
ax.set_ylabel(r"$\langle Z_3 Z_4 Z_5 Z_6 \rangle$")
ax.legend()
plt.show()

Output:

Ideal (noiseless):   0.8073
Noisy (unmitigated): 0.6431
Mitigated (PNA):     0.8071
Output of the previous code cell
이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.