양자컴퓨터 실험 : 똑같은 양자회로를 서로 다른 양자컴퓨터에서 돌리면 결과가 같을까? 실제 QPU 2대 비교

양자컴퓨터가 다르다면 같은 양자회로라도 실행결과가 달라질까요? 이번 글에서는 Bell State 회로 하나를 서로 다른 실제 QPU 두 대에서 동일한 조건으로 실행하고 측정값, 오류 비율, 회로 변환 결과까지 직접 비교합니다. 아래 글을 함께 보시죠.

동일한 Bell State 양자회로를 서로 다른 실제 QPU 두 대에서 실행해 결과를 비교하는 실험
동일한 Bell State 회로를 서로 다른 실제 양자컴퓨터 두 대에서 실행해 측정 결과가 얼마나 달라지는지 비교합니다.

코드는 하나인데 실행하는 양자컴퓨터가 달라지면 결과도 달라질까요? 이번 실험에서는 똑같은 2큐비트 Bell State 회로를 서로 다른 실제 양자 프로세서 두 대에서 실행합니다. 단순히 0과 1의 비율만 비교하지 않고, 실제 QPU에 맞게 변환된 회로의 깊이와 측정 오류까지 함께 확인해보겠습니다.

1. 오늘의 대결: 회로 하나, 실제 QPU 두 대

이번 실험의 조건은 최대한 단순하게 맞춥니다. 두 양자컴퓨터에 서로 다른 문제를 주는 것이 아니라 완전히 동일한 논리 회로와 동일한 측정 횟수를 사용합니다.

비교 조건설정
논리 회로2큐비트 Bell State
측정 횟수각 QPU 2,000 shots
QPU 수서로 다른 실제 QPU 2대
Transpile 최적화 수준optimization_level=1
비교 대상00·01·10·11 비율, 상관 성공률, 회로 깊이

이번 실험의 질문은 단순합니다. 같은 명령을 줬을 때 두 실제 양자컴퓨터가 얼마나 비슷한 결과를 보여줄까? 입니다.

2. 먼저 정답지를 만든다: 이상적인 Bell State

비교 기준이 없으면 두 QPU 중 어떤 결과가 이상적인 값에 더 가까운지 판단하기 어렵습니다. 그래서 실제 장치를 실행하기 전에 이상적인 시뮬레이터에서 같은 회로를 먼저 확인합니다.

Hadamard와 CNOT 게이트로 만든 Bell State의 이상적인 00과 11 측정 결과
이상적인 Bell State에서는 00과 11이 각각 약 절반씩 측정되고 01과 10은 나타나지 않습니다.
from qiskit import QuantumCircuit
from qiskit.primitives import StatevectorSampler

shots = 2000

bell = QuantumCircuit(2)
bell.h(0)
bell.cx(0, 1)
bell.measure_all()

ideal_sampler = StatevectorSampler()
ideal_result = ideal_sampler.run(
    [bell],
    shots=shots
).result()

ideal_counts = ideal_result[0].data.meas.get_counts()

print(ideal_counts)

이상적인 Bell State에서는 주로 00과 11이 측정됩니다. 두 결과의 비율은 각각 약 50%에 가까워지며, 이상적인 회로에서는 01과 10이 나타날 확률은 0입니다.

다만 shots를 이용해 실제로 표본을 뽑기 때문에 00과 11이 정확히 1,000회씩 나올 필요는 없습니다.

3. 이번 실험에 출전할 QPU 두 대 고르기

특정 QPU 이름을 코드에 고정하면 시간이 지난 뒤 장치가 변경되거나 현재 계정에서 사용할 수 없는 문제가 생길 수 있습니다. 그래서 현재 계정에서 접근 가능한 실제 QPU 중 정상 작동 중인 장치를 찾고, 대기 작업이 적은 순서대로 두 대를 선택합니다.

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()

backends = service.backends(
    simulator=False,
    operational=True,
    min_num_qubits=2
)

available = []

for backend in backends:
    status = backend.status()

    if status.operational and status.status_msg == "active":
        available.append(
            (status.pending_jobs, backend)
        )

available.sort(key=lambda x: x[0])

if len(available) < 2:
    raise RuntimeError(
        "현재 접근 가능한 실제 QPU가 2대 미만입니다."
    )

backend_a = available[0][1]
backend_b = available[1][1]

print("QPU A:", backend_a.name)
print("QPU B:", backend_b.name)
print("A qubits:", backend_a.num_qubits)
print("B qubits:", backend_b.num_qubits)

이번 실행에서 선택된 두 장치는 QPU A와 QPU B입니다. 실제 장치명과 실행 당시 상태는 아래 결과표에 함께 기록합니다. 이렇게 해야 나중에 같은 실험을 다시 했을 때 조건을 비교할 수 있습니다.

4. 여기서 중요한 반전: 같은 회로가 그대로 들어가는 것은 아니다

동일한 논리 양자회로가 서로 다른 QPU에서 다른 물리 회로로 변환되는 과정
QPU별 양자회로 Transpile 비교

우리가 작성한 Bell 회로는 두 QPU에 똑같이 전달됩니다. 하지만 실제 하드웨어에서 실행되는 물리적 회로까지 완전히 같다는 뜻은 아닙니다.

양자 프로세서마다 지원하는 명령과 물리적 큐비트 연결 구조가 다를 수 있기 때문에 Qiskit은 각 QPU에 맞는 ISA 회로로 다시 변환합니다. 따라서 논리적으로는 같은 Bell State 회로라도 실제 QPU A와 QPU B에서 실행되는 회로의 깊이와 게이트 구성이 달라질 수 있습니다.

from qiskit.transpiler import generate_preset_pass_manager

def compile_for_backend(circuit, backend):

    pm = generate_preset_pass_manager(
        backend=backend,
        optimization_level=1,
        seed_transpiler=42
    )

    isa = pm.run(circuit)

    return isa

isa_a = compile_for_backend(bell, backend_a)
isa_b = compile_for_backend(bell, backend_b)

print("QPU A depth:", isa_a.depth())
print("QPU B depth:", isa_b.depth())

print("QPU A operations:")
print(isa_a.count_ops())

print("QPU B operations:")
print(isa_b.count_ops())

이번 글에서는 이 부분도 중요한 결과로 봅니다. 단순히 최종 측정값만 비교하는 것이 아니라 같은 논리 회로가 서로 다른 하드웨어에서 어떻게 변환됐는가도 확인할 수 있기 때문입니다.

5. 이제 실제 QPU 두 대에 같은 문제를 준다

from qiskit_ibm_runtime import SamplerV2 as Sampler

def run_qpu(backend, isa_circuit, shots=2000):

    sampler = Sampler(mode=backend)

    job = sampler.run(
        [isa_circuit],
        shots=shots
    )

    result = job.result()
    counts = result[0].data.meas.get_counts()

    return job, counts


job_a, counts_a = run_qpu(
    backend_a,
    isa_a,
    shots
)

job_b, counts_b = run_qpu(
    backend_b,
    isa_b,
    shots
)

print("QPU A:", backend_a.name)
print("Job A:", job_a.job_id())
print(counts_a)

print()

print("QPU B:", backend_b.name)
print("Job B:", job_b.job_id())
print(counts_b)

두 작업은 같은 논리 회로와 같은 shots를 사용합니다. 달라지는 핵심 변수는 실제로 회로를 처리하는 양자 하드웨어입니다.

6. 단순한 50:50 대신 세 가지 점수를 비교한다

Bell State 실험에서는 단순히 00과 11이 각각 몇 번 나왔는지만 보는 것보다 다음 세 가지 값을 함께 보는 편이 좋습니다.

  • Bell 상관 성공률: 00 또는 11이 측정된 비율
  • 비정상 결과 비율: 이상적으로 나오지 않아야 하는 01 또는 10의 비율
  • 00·11 균형: 두 정상 결과가 얼마나 50:50에 가깝게 나타났는지
def analyze_counts(counts, shots):

    c00 = counts.get("00", 0)
    c01 = counts.get("01", 0)
    c10 = counts.get("10", 0)
    c11 = counts.get("11", 0)

    correlation = (
        (c00 + c11) / shots * 100
    )

    unwanted = (
        (c01 + c10) / shots * 100
    )

    balance_gap = (
        abs(c00 - c11) / shots * 100
    )

    return {
        "00": c00,
        "01": c01,
        "10": c10,
        "11": c11,
        "Bell 상관률(%)": correlation,
        "비정상 결과(%)": unwanted,
        "00-11 차이(%p)": balance_gap
    }

stats_a = analyze_counts(counts_a, shots)
stats_b = analyze_counts(counts_b, shots)

print(stats_a)
print(stats_b)

7. 결과 점수판: QPU A와 QPU B는 얼마나 달랐을까?

동일한 Bell State 회로를 실제 QPU 두 대에서 실행한 00 01 10 11 측정 결과 비교
같은 Bell State 회로와 동일한 shots를 사용한 두 실제 QPU의 측정 분포를 비교한 결과입니다.

비교 항목QPU AQPU B
실제 장치명ibm_pittsburghibm_fez
00992회 (49.6%)962회 (48.1%)
0124회 (1.2%)32회 (1.6%)
1020회 (1.0%)28회 (1.4%)
11964회 (48.2%)978회 (48.9%)
Bell 상관 성공률97.8%97.0%
비정상 결과(01+10)2.2%3.0%
Transpiled circuit depth45

결과를 보면 같은 Bell 회로를 실행했음에도 두 QPU의 측정 분포가 완전히 일치하지 않았습니다. 특히 이상적으로는 나타나지 않아야 하는 01과 10의 비율을 비교하면 각 실제 하드웨어에서 Bell 상관관계가 얼마나 잘 유지됐는지 확인할 수 있습니다.

8. 결과를 읽는 세 가지 관점

① 어느 QPU가 이상적인 분포에 더 가까웠나?

가장 먼저 00과 11을 합친 Bell 상관 성공률을 비교합니다. 이 값이 높을수록 이번 실험에서는 이상적인 Bell State 측정 결과에 더 가까웠다고 볼 수 있습니다.

② 01과 10은 얼마나 나타났나?

이상적인 Bell State에서 01과 10은 나타나지 않아야 합니다. 실제 QPU에서 이 값이 측정됐다면 실제 하드웨어의 게이트 오류, 판독 오류, decoherence 등 여러 요인이 결과에 영향을 줬을 가능성이 있습니다.

③ 같은 코드가 얼마나 다른 물리 회로로 바뀌었나?

두 QPU에서 최종 측정값뿐 아니라 transpile 이후의 circuit depth와 gate 구성도 비교합니다. 같은 논리 회로라도 장치별 Target에 맞춰 변환되기 때문에 실제 실행 경로는 달라질 수 있습니다.

9. 결과가 더 좋았다고 그 QPU가 무조건 더 좋은 것은 아니다

이번 실험에서 특정 QPU의 Bell 상관률이 더 높게 나왔다고 해서 그 장치가 모든 양자 연산에서 더 뛰어나다고 결론 내릴 수는 없습니다.

  • 실험에 사용된 물리적 큐비트가 달라질 수 있습니다.
  • 각 장치의 캘리브레이션 상태는 시간에 따라 변할 수 있습니다.
  • 큐비트별 게이트 오류와 판독 오류도 서로 다릅니다.
  • Transpile 결과와 물리적 큐비트 배치가 결과에 영향을 줄 수 있습니다.
  • 한 번의 실험만으로 장치 전체 성능을 평가할 수는 없습니다.

따라서 이번 실험은 QPU의 종합 성능 순위를 매기는 시험이라기보다 동일한 논리 회로가 서로 다른 실제 양자 하드웨어에서 어떤 차이를 보이는지 직접 관찰하는 실험으로 보는 것이 적절합니다.

10. 이번 실험이 보여준 것

똑같은 Bell State 회로와 동일한 shots를 사용해도 서로 다른 실제 QPU에서 얻은 결과가 완전히 같지는 않았습니다. 두 장치는 모두 Bell State의 기본적인 00·11 상관관계를 보여줬지만, 비정상 결과의 비율과 00·11의 균형, 그리고 실제 하드웨어용으로 변환된 회로 구조에서 차이가 나타났습니다.

특히 이번 비교에서 중요한 점은 우리가 작성한 코드는 같아도 실제 하드웨어에서 실행되는 과정까지 완전히 동일한 것은 아니라는 점입니다. 양자컴퓨팅 프로그램을 이해할 때 알고리즘뿐 아니라 어떤 실제 QPU에서 실행하는지도 중요한 이유를 직접 확인할 수 있습니다.

다음 실험

이번에는 서로 다른 QPU 두 대를 비교했습니다. 다음에는 한 QPU를 서로 다른 시간대에 반복 실행해 하드웨어의 상태 변화가 결과에 얼마나 영향을 주는지 비교해볼 수 있습니다.

관련 실험

참고자료

Andrew Shin

양자컴퓨팅을 처음 접하는 사람도 이해할 수 있도록 복잡한 개념과 기술을 쉽게 풀어 설명합니다. 기초 원리부터 큐비트, 양자게이트, 하드웨어, 실제 활용 분야와 최신 기술 흐름까지 신뢰할 수 있는 자료를 바탕으로 정리합니다.

문의: jyamee01@gmail.com

댓글 남기기