Skip to main content
IBM Quantum Platform

실시간 벤치마킹을 통해 백엔드 속성을 갱신하기

예상 소요 시간: 선택적 예제를 포함하여 4분 (참고: 이는 단지 예상 시간일 뿐입니다 ibm_boston.) (실행 시간은 다를 수 있습니다.)


학습 성과

  • QPU가 보고하는 속성이 장치의 실제 동작과 다를 수 있는 이유와, 언제 직접 다시 측정해야 하는지
  • 5가지 표준 특성 분석 실험(리드아웃, 단일 큐비트 무작위 벤치마킹, 계층적 2-큐비트 무작위 벤치마킹, T1T_1, T2T_2 ) 각각이 측정하는 내용
  • 단일 호출로 전체 특성 분석 모음을 실행하거나 단계별로 실행하고, 속성이 갱신된 백엔드 객체를 얻는 방법
  • 측정된 특성을 보고된 특성과 비교하는 방법, 그리고 왜 일부 차이가 소자의 드리프트가 아니라 측정 방법론에 기인하는지
  • 갱신된 속성을 큐비트 선택에 활용하는 방법과, 이를 통해 GHZ 상태 회로의 결과가 개선되는지 확인하는 방법

전제조건


배경

모든 IBM Quantum® QPU는 큐비트의 현재 성능을 설명하는 일련의 속성, 즉 이완 시간( T1T_1 ), 코히어런스 시간( T2T_2 ), 판독 오류, 1큐비트 및 2큐비트 게이트 오류를 보고합니다. 이러한 수치는 실제 상황에서 중요한 의미를 지닙니다. 트랜스파일러는 이를 활용하여 회로에 사용할 물리적 큐비트를 선택하며, 오류 완화 기법도 이에 의존합니다. 또한 실험을 진행하기에 장치가 충분히 잘 작동하는지 판단하는 데 이를 활용할 수도 있습니다.

보고된 측정값은 일반적으로 하루에 한 번 정도 수행되는 교정 절차에서 도출된 것입니다. 그러나 초전도 큐비트는 더 짧은 시간 규모에서 드리프트 현상이 발생할 수 있으며, 과도적 결함(이중 수준 시스템으로 알려진)으로 인해 보정 시점에 정상적으로 작동하던 큐비트의 성능이 일시적으로 저하될 수 있다. 게다가, 작업은 실행되기 훨씬 전에 트랜스파일되는 경우가 많기 때문에, 보고된 속성을 바탕으로 내린 결정은 오래된 정보에 근거할 수 있습니다.

이 튜토리얼에서는 실험 구성, 작업 제출, 곡선 피팅을 몇 번의 호출로 통합해 주는 Qiskit Device Benchmarking의 BackendCharacterization 유틸리티를 사용합니다. 약 70초 분량의 QPU 시간을 사용하면, 기기의 현재 상태를 반영하는 속성을 가진 백엔드 객체를 받게 됩니다. 이러한 속성을 보고된 값과 비교하거나, 백엔드를 다른 도구로 전달할 수 있습니다. 마지막 예제에서는 갱신된 값을 사용하여 GHZ 상태 회로에 필요한 물리적 큐비트를 선택하고, 그 결과를 보고된 특성을 바탕으로 컴파일된 동일한 회로의 결과와 비교합니다.

성질 규명 실험

이 제품군에는 5가지 모델이 포함되어 있으며, 각 모델마다 표준 실험이 하나씩 있습니다:

  • 판독 오류 (readout): 이 실험에서는 각 큐비트를 ∣0⟩|0\rangle 또는 ∣1⟩|1\rangle 상태로 준비한 후 즉시 측정합니다. 잘못된 측정값이 나올 확률은 상태 준비 및 측정(SPAM) 오차를 나타낸다.
  • 단일 큐비트 게이트 오류 (rb_1q): 무작위 벤치마킹(RB)은 이상적으로 항등 게이트로 합성되는 무작위 단일 큐비트 클리포드 게이트 시퀀스를 실행합니다. 서열 길이에 따른 생존 확률의 감소는 SPAM 오류와 무관하게 게이트당 평균 오류를 나타냅니다.
  • 2-큐비트 게이트 오류 (rb_2q): 이 실험에서는 레이어 충실도 실험과 마찬가지로, 동시에 실행되는 중첩되지 않은 2-큐비트 게이트로 구성된 전체 레이어에 동일한 RB 방법을 적용한다. 많은 게이트가 동시에 작동하기 때문에, 그 결과로 발생하는 오류율에는 크로스톡 효과가 포함되어 있으며, 이는 심층 회로의 오류율에 더 가깝습니다.
  • T1T_1 (t1): 이 실험은 각 큐비트를 여기시킨 후, 지연 시간을 점차 늘려가며 측정합니다. 여기 상태의 개체 수 감소에 따라 이완 시간이 결정된다.
  • T2T_2 (t2): 한 에코(Hahn echo) 실험에서는 각 큐비트를 중첩 상태에 놓은 뒤, 지연 시간의 절반 지점에서 에코 펄스를 가하고, 큐비트가 위상 일관성을 잃는 속도를 측정합니다. 기본적으로 이 실험에서는 하나의 에코를 사용합니다. 이 튜토리얼의 뒷부분에서는 다중 에코(CPMG 방식) 변형에 대해 설명합니다.

갱신된 속성의 적용 범위 및 제한 사항

이 워크플로를 사용할 때는 다음 사항을 유의하시기 바랍니다:

  • 업데이트된 속성은 유틸리티가 사용자에게 반환하는 백엔드 객체에만 존재합니다. 장치 자체나 IBM Quantum 가 다른 사용자에게 보고하는 보정 데이터에는 아무런 변화가 없습니다.
  • 측정값은 특정 방법론을 통해 포착한 순간의 모습입니다. 그중 일부, 특히 중첩된 2-큐비트 오류와 병렬 단일 에코 T2T_2 값의 경우, 보고된 보정 데이터와 측정 방식이 다르기 때문에, 관찰되는 편차의 일부는 드리프트가 아닌 측정 방법론에서 비롯된 것입니다. 이 튜토리얼에서는 이러한 사례들을 살펴봅니다.
  • 특성 분석 자체에 QPU 시간이 소요되며(156 큐비트 헤론 프로세서에서 전체 테스트 스위트를 실행하는 데 약 70초), 이것이 바로 현재 정보의 비용입니다.

이 워크플로는 Qiskit 패턴의 네 단계를 따릅니다:

  • 1단계: 고전적 입력을 양자 문제에 매핑한다. 측정할 장치와 속성 집합을 선택하십시오.
  • 2단계: 양자 하드웨어에서 실행할 수 있도록 문제를 최적화한다. 이 유틸리티는 실험용 회로를 디바이스의 기본 게이트에 직접 구축하고, 디바이스 전체에 걸쳐 이를 병렬화합니다.
  • 3단계: Qiskit primitives 을 사용하여 실행합니다. 이 실험들은 배치 내에서 샘플러 작업으로 실행됩니다.
  • 4단계: 후처리를 수행하고 원하는 기존 형식으로 결과를 반환합니다. 측정 데이터를 큐비트별 오류 맵에 대입하고, 백엔드를 갱신한 다음, 측정된 특성과 보고된 특성을 비교합니다.

요구사항

이 튜토리얼을 시작하기 전에 다음 항목이 설치되어 있는지 확인하십시오:

  • Qiskit SDK v2.0 또는 그 이후 버전이며, 시각화 기능을 지원합니다
  • qiskit-ibm-runtime v0.40 이상 (pip install qiskit-ibm-runtime)
  • Qiskit Device Benchmarking ( Qiskit Experiments 도 함께 설치됨) (pip install git+https://github.com/qiskit-community/qiskit-device-benchmarking.git)

설정

필요한 라이브러리를 불러옵니다.

from copy import deepcopy

import logging
import sys

import matplotlib.pyplot as plt
import numpy as np
from qiskit import QuantumCircuit
from qiskit.quantum_info import hellinger_fidelity
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import Batch, QiskitRuntimeService, SamplerV2

from qiskit_device_benchmarking.utilities.characterization_utils import (
    BackendCharacterization,
    plot_characterization_comparison,
)

특성 분석 스위트는 여러 실험을 구성하고, 여러 작업을 제출하며, 결과를 분석합니다. 이 과정은 총 몇 분 정도 걸릴 수 있습니다. 각 단계가 실행되는 동안 진행 상황을 출력하도록 INFO 수준 로깅을 활성화하십시오.

logger = logging.getLogger("qiskit_device_benchmarking")
logger.setLevel(logging.INFO)
logger.addHandler(logging.StreamHandler(stream=sys.stdout))

소규모 시뮬레이터 예시

이 튜토리얼에는 시뮬레이터 예제가 포함되어 있지 않습니다. 이 워크플로는 특정 장치의 물리적 결함을 측정합니다. 즉, 큐비트가 이완되고 위상이 어긋나는 속도, 그리고 게이트와 판독이 실패하는 빈도를 측정합니다. 이상적인 시뮬레이터에는 이러한 결함이 전혀 없으므로, 특성화할 대상이 없습니다. 가짜 백엔드에 합성 노이즈 모델을 적용하면, 실험 결과에서는 모델에 입력한 값들만 복원됩니다. 이러한 이유로, 이 튜토리얼은 Qiskit 패턴의 네 단계에 따라 바로 하드웨어 부분으로 넘어갑니다.


대규모 하드웨어 예시

1단계: 고전적 입력을 양자 문제에 매핑하기

이 워크플로우에서 “문제”는 바로 장치 그 자체입니다. 일반적인 입력값은 특성 분석을 수행하려는 QPU와 측정할 속성 목록입니다. 양자 실험이란 유틸리티가 이러한 입력값을 바탕으로 생성하는 특성 분석 회로를 말합니다.

먼저, 최소 120 큐비트를 갖추고 있으며 사용 가능한 QPU 중에서 가장 부하가 적은 것을 선택하십시오. 이 튜토리얼의 결과는 2026년 10월 6일 ibm_boston, Heron r3 프로세서에서 수집되었습니다.

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

다음으로, 측정할 속성을 선택하십시오. 다음 실험 중 원하는 부분 집합을 선택하여 응시할 수 있습니다:

  • readout: SPAM(상태 준비 및 측정) 실험
  • rb_1q: 고립된 단일 큐비트에 대한 무작위 벤치마킹
  • rb_2q: 레이어 충실도 실험을 통한 2-큐비트 동시 무작위 벤치마킹
  • t2: T2T_2 한(Hahn) 에코 실험 (기본값은 단일 에코)
  • t1: T1T_1 이완 실험

디바이스의 특성을 완전히 파악하려면 전체 테스트 모음을 실행하십시오. QPU 시간을 절약하려면 필요하지 않은 속성에 대한 항목을 제거하십시오.

experiments = ["readout", "rb_1q", "rb_2q", "t1", "t2"]

2단계: 양자 하드웨어 실행을 위해 문제를 최적화한다

대부분의 튜토리얼에서 이 단계는 회로를 트랜스파일하는 단계입니다. 이 튜토리얼에서는 가 내부적으로 트랜스파일링을 처리합니다 BackendCharacterization . 이 방법은 실험 회로를 디바이스의 기본 게이트에 직접 구축하고, 모든 큐비트에 대해 단일 큐비트 실험을 병렬로 수행하며, 결합 맵의 서로 겹치지 않는 레이어에 걸쳐 2-큐비트 벤치마킹을 스케줄링함으로써, 소수의 작업만으로 디바이스 전체를 커버할 수 있도록 합니다. 이러한 병렬화 덕분에 전체 테스트 스위트는 QPU 시간을 약 70초 정도만 소요합니다.

워크플로를 관리하는 클래스를 초기화합니다:

# Initialize the class used to run the experiments
characterizer = BackendCharacterization(backend)

3단계: Qiskit primitives 을 사용하여 실행하기

이 run_experiments 메서드는 회로를 구성하고 이를 샘플러 작업으로 제출합니다. 작업들이 QPU에서 함께 스케줄링되도록 Batch 컨텍스트 내에서 실행하십시오. 이 메서드는 모든 작업을 제출한 후에 반환됩니다. 이 메서드는 외부나 Batch 내부에서 실행할 수도 있습니다 Session.

Note

세션 컨텍스트 관리자가 열려 있는 상태에서 백엔드가 전달되었다는 경고 메시지가 표시될 수 있습니다. 이 경고는 예상되는 것이므로 안심하고 무시해도 됩니다. 레이어 충실도 실험은 선택적 xslow 게이트를 사용하지 않는다는 점을 경고할 수도 있습니다. 이 실험에서는 지원되는 표준 단일 큐비트 게이트를 사용하므로 이 경고도 무시해도 됩니다.

# Run the characterization experiments inside a Batch
with Batch(backend=backend):
    jobs = characterizer.run_experiments(experiments=experiments)

Output:

base_primitive.get_mode_service_backend:WARNING:2026-10-06 12:30:28,757: A backend was passed in as the mode but a session context manager is open so this job will run inside this session/batch instead of in job mode.
Building readout experiments
Building 1Q RB experiments
Building 2Q RB experiments
Building T1 experiments
Building T2 experiments
layer_fidelity.py:258: UserWarning: Not using single qubit gate "xslow". Please open an issue if support for using gates outside of Qiskit's standard gates is needed for layer fidelity.
  warnings.warn(
Layered two-qubit RB submitted: ['db2i4sk2ljfc73d4h54g', 'db2i52nr11fs7396pqe0', 'db2i5hc7f06c73apso10', 'db2i5ks2ljfc73d4h5u0']
Readout job submitted: db2i5l42ljfc73d4h5ug
T1 experiment submitted: ['db2i5le8v0ts73c2sc6g']
T2 (Hahn) experiment submitted: ['db2i5ls2ljfc73d4h5vg']
Single-qubit RB submitted: ['db2i6fs7f06c73apsp9g', 'db2i6lnr11fs7396psa0']

이 메서드는 제출된 작업을 실험별로 하나의 항목이 포함된 사전 형태로 반환합니다. 이 사전을 사용하여 IBM Quantum Platform 대시보드에서 작업을 추적하거나 디버깅할 수 있습니다.

# Print all the job IDs for debugging purposes
jobs

Output:

{'rb_2q': [<RuntimeJobV2('db2i4sk2ljfc73d4h54g', 'sampler')>,
  <RuntimeJobV2('db2i52nr11fs7396pqe0', 'sampler')>,
  <RuntimeJobV2('db2i5hc7f06c73apso10', 'sampler')>,
  <RuntimeJobV2('db2i5ks2ljfc73d4h5u0', 'sampler')>],
 'readout': [<RuntimeJobV2('db2i5l42ljfc73d4h5ug', 'sampler')>],
 't1': [<RuntimeJobV2('db2i5le8v0ts73c2sc6g', 'sampler')>],
 't2': [<RuntimeJobV2('db2i5ls2ljfc73d4h5vg', 'sampler')>],
 'rb_1q': [<RuntimeJobV2('db2i6fs7f06c73apsp9g', 'sampler')>,
  <RuntimeJobV2('db2i6lnr11fs7396psa0', 'sampler')>]}

4단계: 후처리를 수행하고 원하는 기존 형식으로 결과를 반환합니다

결과를 분석하십시오

이 analyze_results 메서드는 작업이 완료될 때까지 기다린 다음 측정 데이터를 처리합니다. T1T_1 및 T2T_2 데이터에는 지수적 감쇠 곡선을, RB 데이터에는 생존 확률 감쇠 곡선을 각각 적합시키고, 판독을 위한 할당 행렬을 계산합니다. 측정된 각 속성마다 하나의 항목이 포함된 오류 맵 의 사전(dictionary)을 반환합니다. 각 오류 맵은 각 큐비트(또는 큐비트 쌍)에 측정값을 할당합니다.

error_maps = characterizer.analyze_results()
print(f"The following error maps are available: {list(error_maps.keys())}")
readout_q0 = error_maps["readout_error"][0]
print(f"For example, readout error for qubit 0 is {readout_q0}")

Output:

The following error maps are available: ['readout_error', 'oneq_error_x', 'oneq_error_sx', 'lf_error_map', 't1_map', 't2_map']
For example, readout error for qubit 0 is 0.0023999999999999577

이 지도에는 판독 오류, 단일 큐비트 x 및 sx 게이트 오류, 계층적 2큐비트 오류(lf_error_map계층 충실도 실험에서 도출된 ), 그리고 T1T_1 와 T2T_2 의 시간(단위: 초)이 포함되어 있습니다.

백엔드 속성을 업데이트합니다

이 update_backend 메서드는 측정된 값을 백엔드의 복사본 속성에 기록하고, 해당 복사본을 반환합니다. 원본 backend 객체에는 보고된 보정 데이터가 유지되므로, 다음 섹션에서 보여드리듯이 두 속성 집합을 비교할 수 있습니다. 이 업데이트는 현재 Python 세션에만 적용됩니다. 이는 기기나 다른 사용자에게 아무런 영향을 미치지 않습니다.

backend_updated = characterizer.update_backend()

Output:

Updating readout error
Updating single-qubit X error
Updating single-qubit SX error
Updating two-qubit error
Updating T1
Updating T2

측정된 특성을 보고된 특성과 비교하십시오

마지막으로, 측정된 실시간 속성을 백엔드가 보고하는 값과 비교하여 그래프로 표시합니다. 각 패널에서 큐비트(또는 큐비트 쌍)는 측정값에 따라 정렬되어 있으므로, 구조상 측정 곡선은 매끄럽게 나타납니다. 이 곡선 주변에 보고된 값들이 흩어져 있는 양상은 두 데이터 세트가 일치하지 않는 부분을 보여줍니다. 단일 큐비트 RB 결과는 하나의 그래프에 표시되는데, 이는 유틸리티가 게이트와 x sx 게이트 모두에 게이트당 동일한 측정 오차를 할당하기 때문이다. 축의 범위는 대부분의 데이터를 기준으로 설정되어 있으므로, 소수의 극단적인 이상값이 그래프를 압축하지 않도록 합니다. 각 그래프의 주석에는 해당 범위 밖으로 벗어난 모든 점이 집계됩니다. 한도를 직접 설정하려면 ylim 인수를 전달하십시오.

plot_characterization_comparison(
    old_props=backend.properties().to_dict(),
    new_props=backend_updated.properties().to_dict(),
    plots=["readout", "rb_1q", "rb_2q", "t1", "t2"],
)

Output:

Output of the previous code cell Output of the previous code cell Output of the previous code cell Output of the previous code cell Output of the previous code cell

이 그래프들을 주의 깊게 살펴보십시오. 두 곡선 사이의 모든 간격이 장치의 드리프트가 발생했다는 것을 의미하는 것은 아니기 때문입니다:

  • 판독값과 단일 큐비트 오류 : 대부분의 큐비트에 대해서는 측정값이 보고된 값과 일치하지만, 일부 큐비트의 경우 보고된 값이 측정 곡선과 크게 어긋납니다. 이러한 국부적인 불일치는 이 워크플로가 감지하도록 설계된 편차를 반영할 수 있습니다.
  • T1T_1 : 두 데이터 세트는 체계적인 편차 없이 서로 주변에 흩어져 있으며, 이는 T1T_1 의 시간 경과에 따른 자연스러운 변동과 일치한다.
  • 2-큐비트 오류 : 측정된 값이 보고된 값보다 체계적으로 높게 나타난다. 이러한 차이는 예상되는 바입니다. 보고된 값들은 개별 게이트에서 측정된 반면, 레이어 충실도 실험은 여러 게이트를 동시에 실행하므로 크로스톡이 포함되기 때문입니다. 계층별 값은 심층 회로와 더 관련이 깊지만, 보고된 보정 데이터와는 직접적으로 비교할 수는 없다.
  • T2T_2 : 대부분의 큐비트에 대해 측정값이 보고된 값보다 훨씬 낮게 나타났다. 2큐비트 오류의 경우와 마찬가지로, 방법론이 큰 역할을 하는데, 이에 대해서는 다음 절에서 살펴보겠습니다.

개별 실험 결과 확인하기

또한 experiment_data 속성을 통해 개별 특성 분석 실험의 원시 결과를 확인할 수 있으며, 이 속성은 해당 실험의 기반이 되는 Qiskit Experiments 객체를 ExperimentData 반환합니다. 예를 들어, 다음 코드는 단일 큐비트의 측정된 T1T_1 감쇠 곡선을 표시합니다. 적합 분석 결과로 도출된 값을 신뢰하기 전에, 이와 같은 곡선을 활용하여 적합도의 품질을 확인하십시오.

t1_data = characterizer.experiment_data["t1"]

# Each qubit has its own fit figure
n_figs = len(t1_data.figure_names)
print(f"{n_figs} figures available, e.g. {t1_data.figure_names[0]}")

# Show the T1 decay curve of the first qubit
t1_data.figure(0)

Output:

156 figures available, e.g. T1_Q0_ee504947.svg
Output of the previous code cell

동적 분리 기법을 이용한 T2 측정

기본적으로 T2T_2 실험은 단일 한(Hahn) 에코를 적용하고 모든 큐비트를 병렬로 측정합니다. 앞서 제시된 비교 그래프에서 볼 수 있듯이, 이 방법은 백엔드에서 보고하는 값보다 눈에 띄게 낮은 T2T_2 값을 산출할 수 있습니다. 한 가지 가능한 원인은 에코의 수입니다. 보고된 값은 저주파 잡음을 억제하는 동적 디커플링을 사용한 보정 과정에서 도출된 것일 수 있습니다. 이 가설을 검증하기 위해, 더 큰 값의 를 사용하여 T2T_2 만 포함된 특성 분석을 실행해 보십시오 t2_num_echoes. 이 분석에서는 CPMG 방식의 에코 펄스 열이 적용됩니다. 두 경우 모두, 이 지연 시간은 자유 진화 시간의 총합을 나타내므로, 추정된 T2T_2 값은 단일 에코 결과와 직접 비교할 수 있습니다.

# Run a T2-only characterization using a CPMG-style train of 8 echoes
characterizer_dd = BackendCharacterization(backend)
backend_updated_dd = characterizer_dd.run_and_update(
    experiments=["t2"], t2_num_echoes=8
)

Output:

Building T2 experiments
T2 (Hahn) experiment submitted: ['db2i7uc2ljfc73d4h8mg']
Updating T2
# Compare the multi-echo T2 against the backend-reported values
plot_characterization_comparison(
    old_props=backend.properties().to_dict(),
    new_props=backend_updated_dd.properties().to_dict(),
    plots=["t2"],
    title_prefix="8-echo CPMG",
)

# Compare medians across the reported values, the single-echo run,
# and the 8-echo run
reported_t2s = [
    prop["value"]
    for qubit in backend.properties().to_dict()["qubits"]
    for prop in qubit
    if prop["name"] == "T2"
]
t2_reported = np.median(reported_t2s)
t2_single = np.median(list(error_maps["t2_map"].values())) * 1e6
t2_dd = (
    np.median(list(characterizer_dd.analyze_results()["t2_map"].values()))
    * 1e6
)
print(
    f"Median T2 — reported: {t2_reported:.0f} us | "
    f"single echo: {t2_single:.0f} us | 8-echo CPMG: {t2_dd:.0f} us"
)

Output:

Output of the previous code cell
Median T2 — reported: 300 us | single echo: 75 us | 8-echo CPMG: 77 us

이번 실행에서는 추가된 에코가 결과에 거의 영향을 미치지 않았습니다. 8회 에코의 중앙값(77 µs)은 단일 에코의 중앙값(75 µs)과 비슷하며, 두 값 모두 보고된 중앙값(300 µs)보다 훨씬 낮습니다. 반향의 수만으로는 이러한 차이를 설명할 수 없다. 교정 절차의 세부 사항이나, 큐비트를 개별적으로 측정하는 대신 병렬로 측정하는 방식 등 다른 방법론적 차이점들도 영향을 미칩니다.

따라서, 각 방법론 간에 T2T_2 값(및 중첩된 2-큐비트 오류)을 비교할 때는 신중을 기해야 합니다. 갱신된 값들은 실제 워크로드와 유사한 조건에서 측정된, 내부적으로 일관성이 있는 스냅샷입니다. 이러한 값들은 큐비트끼리 서로 비교하거나, 시간이 지남에 따라 장치의 상태를 추적하는 데 매우 적합합니다. 그러나 보고된 교정 데이터와 비교했을 때 차이가 있다고 해서, 그것이 반드시 드리프트의 증거는 아니다.

단일 호출로 1~4단계를 실행합니다

일상적인 사용에서는 중간 결과를 거의 필요로 하지 않습니다. 이 run_and_update 메서드는 이전 단계들(빌드, 제출, 피팅, 업데이트)을 하나의 호출로 통합하여, 갱신된 백엔드를 반환합니다. 이 기능은 동일한 experiments 목록을 받아들이며, 다음과 같은 옵션을 전달합니다 t2_num_echoes. 또한 이를 또는 Batch Session 컨텍스트로 감쌀 수도 있습니다.

Note

다음 셀은 모든 작업과 후처리가 완료될 때까지 결과를 반환하지 않습니다.

# Initialize a fresh characterizer
characterizer = BackendCharacterization(backend)

# Run all of the experiments and update the backend in a single call
backend_updated = characterizer.run_and_update(experiments=experiments)

Output:

Building readout experiments
Building 1Q RB experiments
Building 2Q RB experiments
Building T1 experiments
Building T2 experiments
layer_fidelity.py:258: UserWarning: Not using single qubit gate "xslow". Please open an issue if support for using gates outside of Qiskit's standard gates is needed for layer fidelity.
  warnings.warn(
Layered two-qubit RB submitted: ['db2i8fe8v0ts73c2sfsg', 'db2i8j42ljfc73d4h9qg', 'db2i91k7f06c73apsstg', 'db2i95e8v0ts73c2sgsg']
Readout job submitted: db2i95m8v0ts73c2sgtg
T1 experiment submitted: ['db2i9647f06c73apst40']
T2 (Hahn) experiment submitted: ['db2i96nr11fs7396pvpg']
Single-qubit RB submitted: ['db2ia3e8v0ts73c2si90', 'db2ia8c2ljfc73d4hc00']
Updating readout error
Updating single-qubit X error
Updating single-qubit SX error
Updating two-qubit error
Updating T1
Updating T2

업데이트된 backend_updated 객체는 다음 섹션에서 진행될 GHZ 비교를 위한 준비가 완료되었습니다. 실행 시점에 가까워지면 속성을 새로 고침으로써 향후 장치 드리프트의 영향을 줄이십시오.


큐비트 선택에 새로 고침된 속성을 사용하십시오

이 선택적 예제는 워크플로를 완성합니다. 이 기능은 업데이트된 속성이 회로 결과를 개선하는지 여부를 확인합니다. 동일한 회로를 두 번 컴파일하는데, 한 번은 보고된 속성을 사용하여, 다른 한 번은 갱신된 속성을 사용하여 컴파일합니다. 그런 다음 두 버전을 모두 실행하고 그 결과를 비교합니다. 이 예제는 앞선 섹션에서 다룬 및 backend backend_updated 객체를 사용하며, QPU에 추가 작업을 제출합니다.

비교 회로를 제작하십시오

nn 큐비트 그린버거-혼-자일링거(GHZ) 상태를 하다마르 게이트와 이어지는 일련의 CNOT 게이트를 통해 생성한 다음, 각 큐비트를 측정한다. 이상적으로는 결과 ∣0⋯0⟩|0\cdots0\rangle 와 ∣1⋯1⟩|1\cdots1\rangle 의 확률이 각각 0.5 가 되어야 합니다. 모든 큐비트를 측정하기 때문에, 판독 오류를 포함하여 체인 내의 어느 큐비트에서든 오류가 발생하면 이상적인 결과가 나올 확률이 낮아집니다. 따라서 측정된 출력은 트랜스파일러가 선택하는 물리적 큐비트에 민감합니다.

갱신된 속성은 트랜스파일러가 여러 후보 큐비트 사슬 중에서 선택할 수 있는 중간 규모의 경우에서 가장 중요한 역할을 하는 경향이 있습니다. 매우 큰 회로는 소자의 대부분을 차지하기 때문에, 트랜스파일러는 성능이 저조한 큐비트를 배제할 여지가 거의 없습니다. QPU 시간을 절약하려면 회로 크기 목록을 줄이십시오.

num_qubits_list = list(range(5, 41, 5))
circuits = []
for num_qubits in num_qubits_list:
    circuit = QuantumCircuit(num_qubits)
    circuit.h(0)
    for qubit in range(num_qubits - 1):
        circuit.cx(qubit, qubit + 1)
    circuit.measure_all()
    circuits.append(circuit)

circuits[1].draw(output="mpl", style="clifford", fold=-1)

Output:

Output of the previous code cell

보고된 속성과 갱신된 속성을 사용하여 트랜스파일하기

트랜스파일러는 를 사용하여 물리적 큐비트와 네이티브 명령어를 Target 선택합니다. 백엔드 속성만 업데이트하면 기존 타깃은 변경되지 않은 상태로 유지될 수 있습니다. 대신, 원래 대상을 복사한 다음, 갱신된 오류 및 일관성 시간을 복사본에 명시적으로 적용하십시오. 이 복사본은 원본의 지시 사항의 지속 시간과 연결 관계를 그대로 유지합니다. 쿼빗에 대한 코히어런스 시간을 확인할 수 없는 경우, 기존 목표값을 유지한다.

오류 값이 1로 보고된 경우, 해당 큐비트나 게이트에 대한 벤치마킹이 며칠 동안 성공하지 못해 오류가 정의되지 않았으며, 해당 값이 오래된 것임을 의미합니다( QPU 정보 참조). 이 수치가 반드시 게이트가 작동하지 않는다는 것을 의미하는 것은 아니지만, 게이트를 다룰 때는 주의를 기울여야 합니다. 이러한 게이트의 경우, 단 한 번의 특성 분석 결과만으로도 오차 범위가 작게 나올 수 있으므로, 이 게이트는 해당 소자에서 가장 우수한 게이트 중 하나로 보일 수 있다. 안전을 기하기 위해, 해당 항목들의 값을 보고된 그대로 유지하여 트랜스파일러가 계속해서 이를 건너뛰도록 하십시오.

두 컴파일 작업 모두에 동일한 최적화 수준과 난수 시드를 사용하여, 비교 시 트랜스파일러의 난수성을 통제할 수 있도록 하십시오.

target_updated = deepcopy(backend.target)
properties_updated = backend_updated.properties()

for gate in properties_updated.gates:
    if not any(
        parameter.name == "gate_error" for parameter in gate.parameters
    ):
        continue
    qargs = tuple(gate.qubits)
    if gate.gate not in target_updated.operation_names:
        continue
    if qargs not in target_updated[gate.gate]:
        continue
    instruction_properties = deepcopy(target_updated[gate.gate][qargs])
    # Keep gates whose reported error is undefined (error of 1)
    if (
        instruction_properties is not None
        and instruction_properties.error < 1
    ):
        instruction_properties.error = properties_updated.gate_error(
            gate.gate, qargs
        )
        target_updated.update_instruction_properties(
            gate.gate, qargs, instruction_properties
        )

for qubit in range(backend.num_qubits):
    measurement_properties = deepcopy(target_updated["measure"][(qubit,)])
    if measurement_properties.error < 1:
        measurement_properties.error = properties_updated.readout_error(qubit)
        target_updated.update_instruction_properties(
            "measure", (qubit,), measurement_properties
        )
    qubit_properties = properties_updated.qubit_property(qubit)
    if "T1" in qubit_properties:
        target_updated.qubit_properties[qubit].t1 = qubit_properties["T1"][0]
    if "T2" in qubit_properties:
        target_updated.qubit_properties[qubit].t2 = qubit_properties["T2"][0]

pm_reported = generate_preset_pass_manager(
    target=backend.target, optimization_level=3, seed_transpiler=42
)
pm_refreshed = generate_preset_pass_manager(
    target=target_updated, optimization_level=3, seed_transpiler=42
)
isa_reported = pm_reported.run(circuits)
isa_refreshed = pm_refreshed.run(circuits)

회로를 실행하기 전에, 새로 고침된 각 레이아웃이 물리적 큐비트를 몇 개나 변경하는지 확인하십시오. 두 개의 컴파일레이션이 동일한 큐비트를 선택한다면, 갱신된 속성은 해당 회로에 아무런 영향을 미치지 못합니다.

for num_qubits, circuit_reported, circuit_refreshed in zip(
    num_qubits_list, isa_reported, isa_refreshed
):
    qubits_reported = set(circuit_reported.layout.final_index_layout())
    qubits_refreshed = set(circuit_refreshed.layout.final_index_layout())
    num_changed = len(qubits_refreshed - qubits_reported)
    print(f"GHZ-{num_qubits}: {num_changed} of {num_qubits} qubits changed")

Output:

GHZ-5: 5 of 5 qubits changed
GHZ-10: 10 of 10 qubits changed
GHZ-15: 15 of 15 qubits changed
GHZ-20: 20 of 20 qubits changed
GHZ-25: 15 of 25 qubits changed
GHZ-30: 11 of 30 qubits changed
GHZ-35: 18 of 35 qubits changed
GHZ-40: 18 of 40 qubits changed

두 세트의 서킷 운동을 모두 수행하십시오

동일한 QPU에서 두 버전을 모두 실행하되, 샷 수와 오류 억제 설정은 동일하게 유지하십시오. 제출물에서 보고된 버전과 갱신된 버전을 번갈아 배치하고, 시험 간 변동을 관찰하기 위해 이 비교를 세 번 반복하십시오. 제출 순서가 실행 순서를 보장하지는 않으며, 인터리빙을 한다고 해서 드리프트가 사라지는 것은 아닙니다.

n_trials = 3
shots = 4096
interleaved_circuits = [
    circuit for pair in zip(isa_reported, isa_refreshed) for circuit in pair
]
sampler = SamplerV2(mode=backend)
sampler.options.environment.job_tags = ["TUT_RTBQS"]
sampler.options.dynamical_decoupling.enable = True
sampler.options.dynamical_decoupling.sequence_type = "XY4"
comparison_job = sampler.run(interleaved_circuits * n_trials, shots=shots)
print(f"Comparison job ID: {comparison_job.job_id()}")

Output:

Comparison job ID: db2ici47f06c73apt1j0

출력 분포를 비교해 보세요

각 측정된 분포와 이상적인 GHZ 분포 간의 헬링거 충실도를 계산하십시오. 값이 1이면 분포가 일치함을 의미합니다. 이 지표는 계산 기저에서만 일치도를 측정합니다. 이 방법은 ∣0⋯0⟩|0\cdots0\rangle 와 ∣1⋯1⟩|1\cdots1\rangle 사이의 일관성을 측정하지 않으므로, GHZ 상태의 충실도에 대한 상한값일 뿐, 얽힘을 증명하는 것은 아닙니다.

이 그래프는 여러 실험에 걸친 평균값을 나타냅니다. 오차 막대는 1 표준편차를 나타냅니다.

comparison_results = comparison_job.result()
fidelities = np.empty((n_trials, len(num_qubits_list), 2))
for trial in range(n_trials):
    for chain_index in range(len(num_qubits_list)):
        for variant in range(2):
            result_index = (
                trial * 2 * len(num_qubits_list) + 2 * chain_index + variant
            )
            counts = comparison_results[result_index].data.meas.get_counts()
            num_qubits = num_qubits_list[chain_index]
            ideal_dist = {"0" * num_qubits: 0.5, "1" * num_qubits: 0.5}
            fidelities[trial, chain_index, variant] = hellinger_fidelity(
                ideal_dist, counts
            )

fig, ax = plt.subplots(figsize=(8, 5))
for variant, label in enumerate(
    ["Reported properties", "Refreshed properties"]
):
    ax.errorbar(
        num_qubits_list,
        fidelities[:, :, variant].mean(axis=0),
        yerr=fidelities[:, :, variant].std(axis=0),
        fmt="o-",
        label=label,
    )
ax.set_xlabel("Number of qubits in GHZ state")
ax.set_ylabel("Hellinger fidelity")
ax.set_xticks(num_qubits_list, labels=num_qubits_list, rotation=45)
ax.legend()
ax.grid(True)
fig.tight_layout()
plt.show()

for num_qubits, (reported, refreshed) in zip(
    num_qubits_list, fidelities.mean(axis=0)
):
    print(
        f"GHZ-{num_qubits}: reported {reported:.3f} | refreshed {refreshed:.3f}"
    )

Output:

Output of the previous code cell
GHZ-5: reported 0.958 | refreshed 0.962
GHZ-10: reported 0.895 | refreshed 0.915
GHZ-15: reported 0.821 | refreshed 0.813
GHZ-20: reported 0.725 | refreshed 0.753
GHZ-25: reported 0.629 | refreshed 0.694
GHZ-30: reported 0.591 | refreshed 0.596
GHZ-35: reported 0.492 | refreshed 0.529
GHZ-40: reported 0.379 | refreshed 0.406

이번 실행에서, 갱신된 속성은 모든 크기에서 선택된 큐비트의 일부 또는 전부를 변경했으며, 갱신된 레이아웃은 8개의 GHZ 상태 중 7개에서 더 높은 평균 충실도를 나타냈다. 가장 큰 향상을 보인 것은 25 큐비트 상태로, 이 상태의 평균 충실도가 0.629 에서 0.694 로 증가했다. 새롭게 개선된 레이아웃은 5, 10, 20, 25, 35, 40 큐비트 상태에 대한 모든 실험에서 더 높은 점수를 기록했다. 모든 사이즈에서 개선된 것은 아닙니다. 15 큐비트 상태의 경우, 갱신된 레이아웃의 성능이 약간 떨어졌다( 0.813 대 0.821 ). 30 큐비트 상태의 경우, 그 차이( 0.596 대 0.591 )는 실험 간 변동 범위 내에 있습니다.

업데이트된 속성이 더 나은 결과를 보장하는 것은 아닙니다. 이 이점은 기기가 마지막 보정 이후 얼마나 많이 편차를 보였는지에 따라 달라집니다. 또한, 캐릭터 묘사 그 자체가 잡음이 섞인 순간적인 단면일 뿐입니다. 트랜스파일러는 특정 큐비트나 게이트의 성능이 더 뛰어나지 않더라도, 우연히 측정 결과가 좋은 큐비트나 게이트를 선택할 수 있다. 샷 노이즈, 특성 분석 단계와 실행 단계 간의 추가적인 편차, 그리고 특성 분석 방법론의 차이 또한 비교 결과에 영향을 미칩니다. 측정된 변화량과 그 변동 범위를 바탕으로, 갱신된 속성이 해당 워크로드에 유용한지 여부를 판단하십시오.


다음 단계

권장사항
  • 자신이 설계한 회로에 큐비트 선택 비교 방법을 적용하고, 그 이점이 특성 분석에 드는 비용을 상쇄할 만큼 충분한지 평가해 보십시오
  • QPU 정보 가이드에서 보고된 교정 데이터에 액세스하는 방법을 알아보세요
  • Qiskit Experiments 문서를 통해 개별 특성 분석 실험을 살펴보세요
  • Qiskit Device Benchmarking 저장소에서 추가적인 기기 수준 벤치마크를 살펴보세요
이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.