Skip to main content
IBM Quantum Platform

TEM 함수를 사용하여 차동 이징 모델을 시뮬레이션합니다

알고리즘의 텐서 네트워크 오류 완화(TEM) 방법은 양자-고전 하이브리드 알고리즘으로, 노이즈 완화를 전적으로 고전적 후처리 단계 내에서 수행하도록 설계되었습니다. TEM을 통해 사용자는 관측 가능한 양자의 기대값을 계산할 수 있으며, 이는 양자 하드웨어에서 발생하는 불가피한 잡음 유발 오류를 정확도와 비용 효율성을 높여 완화시켜 양자 연구자와 산업 실무자 모두에게 매우 매력적인 선택지로 자리매김하고 있습니다.

이 튜토리얼은 TEM이 양자 시스템의 역학에 대해 의미 있는 결과를 얻을 수 있는 방법을 보여줍니다. 이는 오류 완화 없이는 접근할 수 없으며, PEC 및 ZNE와 같은 다른 오류 완화 방법을 사용할 경우 훨씬 더 많은 양자 자원이 필요합니다.

사용량 추정치: 이 노트북은 Heron r3 장치에서 약 10 QPU 분을 사용합니다. 실행 시간은 선택한 장치에 따라 크게 달라질 수 있습니다. 섹션별 사용량 추정치는 아래에서 확인할 수 있습니다.


TEM 기능을 사용하여 오류 완화 다체 물리 실험을 실행하십시오

이 튜토리얼은 다음 참고 문헌을 기반으로 합니다: L. E. Fischer 외, Nat. 실제 (2026). 이 참고문헌은 최대 91 큐비트 규모의 양자 하드웨어에서 수행된 실제 시뮬레이션에 대해 논의합니다. 이 튜토리얼에서는 더 작은 회로 크기로 유사한 시뮬레이션을 재현합니다.

킥드 아이징 모델은 일반적인 아이징 모델에 대응한다:

H^I=Jn=0N2Z^nZ^n+1+hn=0N1Z^n\hat{H}_{\text{I}} = J \sum_{n=0}^{N-2} \hat{Z}_n \hat{Z}_{n+1} + h \sum_{n=0}^{N-1} \hat{Z}_n

가로차기가 가해지는 대상:

H^K=bn=0N1X^n\hat{H}_{K} = b \sum_{n=0}^{N-1} \hat{X}_n

목표는 횡방향 킥 이징 해밀토니언 하에서 상태의 역학을 시뮬레이션하는 것이며, 그 시간 진화는 플로케 유니터리 U^KI=eiH^KeiH^I\hat{U}_{\text{KI}} = e^{-i \hat{H}_K} e^{-i \hat{H}_I} 로 구현될 수 있다. 진화시킬 초기 상태는 첫 번째 큐비트가 상태 +|+\rangle 에 있고, 나머지 큐비트들은 쌍을 이루어 벨 상태 (00+11)/2(|00\rangle + |11\rangle)/\sqrt{2} 로 설정된 상태이다.

우리가 관찰하고자 하는 양은 상관 함수이다. 참고 논문은 이 양을 양자 큐비트( nthn^{th} )에 대한 양자 파울리 연산자( X^\hat{X} )로 어떻게 재표현할 수 있는지 논의한다. 일정 수의 물리적 시간 단계 tt 가 지난 후, 우리는 파울리 연산자 X^n=t\hat{X}_{n=t} 의 값을 계산한다. 시스템의 매개변수에 따라, 이 관측가능량의 값은 정확히 계산 가능한 값과 같거나, 근사적 방법으로만 시뮬레이션될 수 있다. 구체적으로, J=b=π/4|J|=|b|=\pi/4 의 경우 [cos(2h)]t[\cos(2h)]^t 와 동일하며, 이는 본 튜토리얼 결과 벤치마킹에 사용할 값입니다. 또한, 주어진 시간 단계 tt 에서, X^nt\langle\hat{X}_{n\neq t}\rangle 는 0이다. 이러한 값을 얻는 방법과, 이러한 매개변수 범위를 벗어난 근사적 고전적 시뮬레이션 결과와의 비교에 대한 자세한 내용은 L. E. Fischer 외, Nat. 실제 (2026).

TEM은 먼저 회로 내 2-큐비트 게이트의 각 고유 레이어에 대한 노이즈를 특성화하고, 판독 오류를 특성화함으로써 작동합니다. 그런 다음, 회로가 양자 기계에서 실행됩니다. 마지막으로, 텐서 네트워크 오류 완화 처리가 IBM Cloud® 의 클래식 리소스에서 수행되며, 완화된 값이 반환됩니다. 이 예시에서 회로는 특성화할 두 개의 고유한 레이어를 가지고 있습니다.


설정

필수 조건으로, 필요한 종속성들이 설치되어 있는지 확인하십시오.

%pip install numpy matplotlib qiskit qiskit-ibm-catalog qiskit-ibm-runtime pylatexenc qiskit_qasm3_import
import os
from matplotlib import pyplot as plt
import numpy as np

from qiskit.quantum_info import SparsePauliOp
from qiskit.qasm3 import load

from qiskit_ibm_catalog import QiskitFunctionsCatalog

TEM을 통한 오류 완화

여기서 우리는 앞서 설명한 킥드 아이징 모델을 구현하는 회로를 제시한다. 회로는 다음과 같이 준비된다. 먼저, 상태 준비 단계가 있습니다. 이 단계에서 첫 번째 큐비트는 상태 +|+\rangle 에 있으며, 나머지 큐비트들은 벨 쌍 (00+11)/2(|00\rangle + |11\rangle)/\sqrt{2} 상태에 있습니다. 이어서 단위 진화 U^KI\hat{U}_{\text{KI}} 를 구현하는 벽돌 구조가 적용됩니다. 물리적 시간 단계 수는 t/2t/2 회로 레이어 수에 해당합니다.

다음 코드는 이 튜토리얼에 필요한 두 개의 QASM 파일을 다운로드합니다.

# Download required QASM files
import urllib

urllib.request.urlretrieve(
    "https://ibm.box.com/shared/static/swy5jtq309b0xpzluzlmsmj908yphes8.qasm",
    "ki_30q.qasm",
)
urllib.request.urlretrieve(
    "https://ibm.box.com/shared/static/et3gkodonw6gsp2trs43lzaozrdtiu7s.qasm",
    "ki_12q.qasm",
)

12개의 큐비트와 6개의 시간 단계로 구성된 회로의 축소 버전을 시각화할 수 있습니다:

# Parameters of the kicked Ising model
h = 0.0
num_qubits = 12
t_steps = 6

# Load the circuit for the kicked Ising model
small_circuit = load("ki_12q.qasm")

# Draw the circuit
small_circuit.draw("mpl", scale=0.25, fold=-1)

Output:

Output of the previous code cell

다음으로 관측 가능 객체( X^n=t\hat{X}_{n=t} )를 생성합니다. 이는 Qiskit에서 사용하는 순서와 일치하는 단순한 파울리 문자열로 구성됩니다:

def xt_observable(n_qubits, t_steps):
    pauli_str = "".join(["I" * t_steps, "X", "I" * (n_qubits - t_steps - 1)])
    pauli_str = pauli_str[::-1]  # Reverse the string to match qiskit order
    return SparsePauliOp(data=pauli_str, coeffs=1.0)

우리의 작은 12큐비트 예시에서 관측 가능량은 다음과 같습니다:

# Build the observable for the kicked Ising model
small_observable = xt_observable(n_qubits=12, t_steps=6)
print(small_observable)

Output:

SparsePauliOp(['IIIIIXIIIIII'],
              coeffs=[1.+0.j])

Qiskit Functions PUB을 입력 수집 수단으로 사용하십시오. 우리의 경우, 단일 회로와 관측 가능량을 우리의 관측 가능 계량( PUB )으로 고려해 보자:

# Collect the input PUBs, in this case composed of a
# single circuit and observable
pubs = [(small_circuit, [small_observable])]

다음으로, TEM 기능에 접근할 수 있게 됩니다. 먼저 IBM Cloud 에 필요한 인증을 설정하고 사용 가능한 장치 중에서 백엔드를 선택합니다. 토큰, 사용 가능한 백엔드 및 해당 클라우드 리소스 이름(CRN) IBM Quantum Platform 대시보드에서 계정에 로그인하여 확인할 수 있습니다.

# Set IBM Quantum credentials and backend configuration
personal_token = os.environ.get(
    "QISKIT_IBM_TOKEN", "<API-KEY>"
)  # Replace with your personal token or set the environment variable
channel = "ibm_quantum_platform"
crn = "your_crn"  # Replace with the Cloud Resource Name (CRN)

# Select the QPU backend
backend_name = "ibm_qpu_name"  # Replace with your desired backend's name

Qiskit Functions Catalog 에서 TEM 함수를 불러옵니다:

# Load the TEM function from the Qiskit Functions Catalog
catalog = QiskitFunctionsCatalog(
    channel=channel,
    token=personal_token,
    instance=crn,
)
tem = catalog.load("algorithmiq/tem")

이제 TEM이 제공하는 오류 완화 기능을 적용하여 킥된 아이징 회로에 대한 실험을 수행할 수 있습니다. 기본 설정으로 TEM을 실행하면 QPU에 따라 예상 QPU 실행 시간이 약 2.5 분 정도로 간단하게 실행할 수 있습니다:

tem_job = tem.run(pubs=pubs, backend_name=backend_name)

기본 옵션으로 TEM 함수는 양자 컴퓨터에서 세 가지 작업을 실행합니다: 잡음 학습, 판독 완화, 회로 샘플링. 이들 각각이 사용하는 샷 수는 함수에 전달되는 옵션에서 변경할 수 있습니다. 기본적으로 이러한 매개변수는 완화된 기대값에서 0.05 의 정밀도를 달성하도록 설정됩니다.

작업 상태는 IBM Quantum Platform 대시보드 에서 확인하거나 다음 명령어로 확인할 수 있습니다:

print(tem_job.status())

Output:

QUEUED

상태가 일 때 DONE, 원시 결과와 완화된 결과를 확인할 수 있습니다. 아래에 정의된 tem_evs 는 요청된 관측량들의 기대값이며, 이 경우 단일 관측량인 X^n=t\langle \hat X_{n=t}\rangle 에 해당하며, 와 tem_std 는 각각 대응하는 표준편차이다.

# Get the results of the TEM job
tem_results = tem_job.result()[
    0
]  # Get the first and only result from the job
tem_evs = tem_results.data.evs[0]
tem_std = tem_results.data.stds[0]

print(f"TEM Result: {tem_evs:.3f} ± {tem_std:.3f}")

Output:

TEM Result: 1.031 ± 0.046

각 호출에 사용된 양자 런타임의 양은 IBM Quantum Platform 에서 확인하거나, Python 코드의 결과 메타데이터를 검사하여 확인할 수 있습니다.

# Get the TEM job runtime
tem_runtime = tem_job.result().metadata["resource_usage"][
    "RUNNING: EXECUTING_QPU"
]["QPU_TIME"]

print(f"TEM Runtime: {tem_runtime} seconds")

Output:

TEM Runtime: 155.0 seconds

TEM 매개변수 및 고급 옵션 사용자 지정

TEM 기능은 오류 완화 워크플로를 사용자 정의할 수 있는 여러 고급 옵션을 제공합니다. 이러한 옵션을 통해 정밀도, 샷 수, 잡음 학습 전략 및 기타 매개변수를 제어하여 실험 요구사항과 사용 가능한 양자 자원에 더 잘 맞출 수 있습니다.

일반적인 고급 옵션은 다음과 같습니다:

  • **precision**완화된 기대값에 대한 목표 정밀도를 지정하십시오.
  • **default_shots**대신 측정 작업에서 사용되는 샷 precision 수를 지정할 수 있습니다.
  • **tem_max_bond_dimension**텐서 네트워크에서 사용되는 최대 결합 차원.
  • **tem_compression_cutoff**텐서 네트워크에 사용할 컷오프 값.
  • 노이즈 학습 옵션 : 노이즈 특성화 방식을 구성합니다. 예를 들어 반복 횟수나 특정 교정 회로 등을 설정할 수 있습니다.
  • **private**회로 및 실험 결과가 본인에게만 비공개로 유지되도록 하고, 작업 결과의 다중 다운로드를 비활성화하십시오.

지원되는 옵션의 전체 목록과 설명은 TEM 문서 또는 Qiskit Functions Catalog 를 참조하십시오. 이러한 매개변수를 조정하여 실행 시간, 리소스 사용량 및 결과 정확도 간의 균형을 맞출 수 있습니다.

TEM 함수를 실행할 때 다음 옵션을 사전(dictionary) 형태로 인수로 options 전달할 수 있습니다:

options = {
    "default_shots": 10_000,
    "tem_max_bond_dimension": 512,
    "tem_compression_cutoff": 1e-16,
    # This option helps optimizing the measurement
    # stage since the observable is strongly biased
    # toward the X operator for all the qubits.
    "compute_shadows_bias_from_observable": True,
    # set to True to keep experiment results private,
    # recommended for confidential circuits
    "private": False,
}

노이즈 학습기를 위한 사용자 지정 옵션도 전달할 수 있습니다. 이 정의들은 에서 사용된 정의를 따릅니다: qiskit-ibm-runtimeNoiseLearnerOptions

nl_options = {
    "num_randomizations": 32,
    "max_layers_to_learn": 2,
    "shots_per_randomization": 128,
    "layer_pair_depths": [0, 1, 2, 4, 16, 32],
}

# add noise learning options to the overall options
options |= nl_options

이 회로에 맞춰 조정된 사용자 지정 옵션으로 실험을 다시 실행하십시오. 예상 실행 시간은 약 4 QPU 분입니다.

tem_job_custom = tem.run(
    pubs=pubs, backend_name=backend_name, options=options
)

작업이 비공개로 설정되지 않은 경우, 나중에 결과를 복구할 수 있습니다. 이를 위해 여기에 출력된 작업 ID를 저장하고 사용하십시오 tem_job_custom = catalog.get_job_by_id("your-job-id").

job_id = tem_job_custom.job_id
print(f"Job ID: {job_id}")

Output:

Job ID: 1ba10094-a541-457a-9287-dbd49306d12d
results_custom = tem_job_custom.result()
tem_evs = results_custom[0].data.evs[0]
tem_std = results_custom[0].data.stds[0]

print(f"TEM Result: {tem_evs:.3f} ± {tem_std:.3f}")

Output:

TEM Result: 0.956 ± 0.018

이제 실험에 대한 통찰력을 얻기 위해 결과와 메타데이터를 확인할 수 있습니다:

metadata_custom = results_custom[0].metadata

unmitigated_evs = metadata_custom["evs_non_mitigated"][0]
unmitigated_stds = metadata_custom["stds_non_mitigated"][0]
print(f"Unmitigated Result: {unmitigated_evs:.3f} ± {unmitigated_stds:.3f}")

# Exact result for the kicked Ising model from the reference paper
exact_evs = np.cos(2 * h) ** t_steps
print("Exact Result:", exact_evs)

Output:

Unmitigated Result: 0.894 ± 0.015
Exact Result: 1.0
# Plot comparing the different expectation values
plt.bar(
    ["Unmitigated", "TEM"],
    [unmitigated_evs, tem_evs],
    yerr=[unmitigated_stds, tem_std],
    color=["grey", "c"],
)
plt.hlines(y=exact_evs, xmin=-0.5, xmax=1.5, colors="r", linestyles="dashed")
plt.ylabel("Expectation Value")
plt.ylim(0, 1.1)
plt.show()

Output:

Output of the previous code cell

마지막으로, 사용자 정의 옵션이 QPU 및 클래식 런타임에 미치는 영향을 확인할 수 있습니다:

# Get the metadata of the TEM job
job_metadata = results_custom.metadata

# Get the runtime of the TEM job
qpu_runtime = job_metadata["resource_usage"]["RUNNING: EXECUTING_QPU"][
    "QPU_TIME"
]
classical_runtime = (
    job_metadata["resource_usage"]["RUNNING: OPTIMIZING_FOR_HARDWARE"][
        "CPU_TIME"
    ]
    + job_metadata["resource_usage"]["RUNNING: POST_PROCESSING"]["CPU_TIME"]
)

print(f"QPU Runtime: {qpu_runtime} seconds")
print(f"Classical Runtime: {classical_runtime} seconds")

Output:

QPU Runtime: 342.0 seconds
Classical Runtime: 107.632604 seconds

대형 회로에 적용 가능한 TEM

대형 회로는 원칙적으로 TEM 기능으로 실행될 수 있다. 그러나 TEM이 실행 시간이 매우 길 수 있는 IBM Cloud 러너에서 실행된다는 점을 고려할 때, 고전적 자원의 한계를 인지하는 것이 중요합니다. 매우 큰 회로의 경우, qiskit\ [email protected] 으로 TEM 지원팀에 문의하십시오.

여기서는 더 큰 유틸리티 규모인 30큐비트 회로로 예시를 실행하며, 정확도보다는 속도를 위해 TEM 매개변수를 최적화합니다.

# Kicked Ising model parameters
n_qubits = 30
t_steps = 15
h = 0.0

# Load the circuit for the kicked Ising model
circuit = load("ki_30q.qasm")


# Build the observable for the kicked Ising model
observable = xt_observable(n_qubits=n_qubits, t_steps=t_steps)

# Collect the input PUBs, in this case composed of a
# single circuit and observable
pubs = [(circuit, [observable])]

성능 중심의 옵션을 정의해 보겠습니다:

options = {
    "num_randomizations": 32,
    "max_layers_to_learn": 2,
    "shots_per_randomization": 128,
    "layer_pair_depths": [0, 1, 2, 4, 16, 32, 64],
    "default_shots": 5_000,
    "tem_max_bond_dimension": 128,
    "tem_compression_cutoff": 1e-10,
    "compute_shadows_bias_from_observable": True,
    "private": False,
}

마지막으로 실험을 실행하고 결과를 얻은 후 시각화합니다. 이 작업에는 약 3.5 QPU 분이 소요될 것입니다.

tem_job_large = tem.run(pubs=pubs, backend_name=backend_name, options=options)
job_id = tem_job_large.job_id
print(f"Job ID: {job_id}")

Output:

Job ID: 9f3f190f-f4b0-4dcb-bb83-5f71f37d0d77
results_large = tem_job_large.result()
tem_evs = results_large[0].data.evs[0]
tem_std = results_large[0].data.stds[0]

print(f"TEM Result: {tem_evs:.3f} ± {tem_std:.3f}")


# Get the metadata of the TEM job
job_metadata = tem_job_large.result().metadata

# Get the runtime of the TEM job
qpu_runtime = job_metadata["resource_usage"]["RUNNING: EXECUTING_QPU"][
    "QPU_TIME"
]
classical_runtime = (
    job_metadata["resource_usage"]["RUNNING: OPTIMIZING_FOR_HARDWARE"][
        "CPU_TIME"
    ]
    + job_metadata["resource_usage"]["RUNNING: POST_PROCESSING"]["CPU_TIME"]
)

print(f"QPU Runtime: {qpu_runtime} seconds")
print(f"Classical Runtime: {classical_runtime} seconds")

Output:

TEM Result: 0.794 ± 0.026
QPU Runtime: 203.0 seconds
Classical Runtime: 251.71805499999996 seconds
# Plot comparing the different expectation values
metadata_large = results_large[0].metadata
unmitigated_evs = metadata_large["evs_non_mitigated"][0]
unmitigated_stds = metadata_large["stds_non_mitigated"][0]

exact_evs = np.cos(2 * h) ** t_steps

plt.bar(
    ["Unmitigated", "TEM"],
    [unmitigated_evs, tem_evs],
    yerr=[unmitigated_stds, tem_std],
    color=["grey", "c"],
)
plt.hlines(y=exact_evs, xmin=-0.5, xmax=1.5, colors="r", linestyles="dashed")
plt.ylabel("Expectation Value")
plt.ylim(0, 1.1)
plt.show()

Output:

Output of the previous code cell
이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.