NoiseLearner 에서 NoiseLearnerV3 로 이전하기
이 가이드에서는 IBM Quantum® 에서 로 NoiseLearner 마이그레이션하는 과정을 단계별로 안내합니다 NoiseLearnerV3. 두
강좌 모두
파울리-린드블라드 잡음 모델을 바탕으로 잡음 과정을 규명하는 실험을 수행하지만, 입력과
출력은 약간 다릅니다.
배경
이 NoiseLearner
클래스는 사용자가 명시적인 노이즈 학습을 수행할 수 있도록 만들어졌습니다. 이렇게 도출된
노이즈 모델은 이후 IBM Quantum 로 전달되어 PEA 및 PEC와 같은
오류 완화 기법을 적용할Estimator 수 있습니다.
NoiseLearner 는 과 함께 작동하도록 설계되었으므로 Estimator, 암묵적으로
와 동일한 레이어 검색 전략을 사용합니다 Estimator. 이 전략은 변경할 수 없습니다. 그렇지 않으면 이후의
완화 조치가 제대로 작동하지 않을 수 있습니다.
v0.47.0qiskit-ibm-runtime 부터, 기본Executor 실행 모델 및
방향성 실행 모델과 호환되는 새로운
NoiseLearnerV3
클래스가 도입되었습니다.
이 새로운 모델은 클라이언트 측에서 설계 의도를 반영할 수 있는 구성 요소를 제공함으로써 화이트박스 경험을 구현하며,
단일 서버 측 기본 요소(Executor)가 해당 입력을 지시된 대로 정확히 처리합니다.
즉, 사용자를 대신해 암묵적인 결정을 내리지 않습니다. 원본과 달리 NoiseLearner,
사용NoiseLearnerV3 시 회로를 어떻게 계층화할지 직접 제어할 수 있으며, 이 클래스는 단순히 박스화된 회로 지시문 목록
(예: 고유 레이어)을 입력으로 받습니다.
NoiseLearnerV3 또한 측정 잡음 학습을 지원합니다. 입력 목록에 있는 각 명령에 대해, 상자에 1큐비트 및 2큐비트 게이트가 포함되어 있으면
파울리-린드블라드 학습 프로토콜을 실행하고, 상자에 측정 명령이 포함되어 있으면
TREX
프로토콜을 실행합니다.
이주해야 할까요?
NoiseLearner 레거시 서버 측에서만 작동하며 Estimator,
Executor 클라이언트 측에서만NoiseLearnerV3 작동합니다 Estimator. 다음 중 하나를 사용하고 있다면 NoiseLearnerV3 반드시 로 마이그레이션해야 합니다.
Executor 또는 클라이언트 측 Estimator. 기존의 서버 측 기능은 더 이상 사용되지 Estimator 않으며, v0.50.0qiskit-ibm-runtime 에서 클라이언트 측에 해당하는 기능으로 대체되었습니다.
v0.50.0 qiskit-ibm-runtime 이상을 사용 중인 경우, 먼저 ‘서버 측에서 클라이언트 측 샘플러 및 추정기로 마이그레이션’ 가이드를 참고하여 클라이언트 측 프리미티브로 마이그레이션하십시오.
마이그레이션 단계
1단계: 임포트 설정 변경하기
NoiseLearner:
from qiskit_ibm_runtime.noise_learner import NoiseLearnerNoiseLearnerV3:
from qiskit_ibm_runtime import NoiseLearnerV32단계: 입력값 업데이트
이 NoiseLearner``run() 메서드는 회로 또는 PUB 목록을 인수로 받는 반면, 이 메서드는 NoiseLearnerV3``run() 명령어 목록을 인수로 받으며, 각 명령어는 ISA 연산을 포함하는 BoxOp 트위를링 주석이 달린 객체여야 합니다.
사용하려는 기본 도형에 따라, 주석이 달린 상자를 생성하는 데 사용할 수 있는
편리한 방법들이 제공됩니다.
NoiseLearner:
from qiskit_ibm_runtime.noise_learner import NoiseLearner
learner = NoiseLearner(mode=backend)
# `circuits_to_learn` is a list of ISA QuantumCircuit
learner_job = learner.run(circuits_to_learn)NoiseLearnerV3, 클라이언트 측 Estimator를 사용할 때는:
회로 실행을 위해 클라이언트 측 Estimator를 사용할 계획이라면, Estimator의 메서드를 find_unique_layers 사용하여 어노테이션이 지정된 박스(레이어)를 생성할 수 있습니다:
from qiskit_ibm_runtime.executor_estimator import Estimator
from qiskit_ibm_runtime import NoiseLearnerV3
pubs = [...] # Your PUBs
estimator = Estimator(backend)
estimator.options.resilience.pec_mitigation = True # or zne_mitigation + pea amplifier
# Identify the unique layers to learn.
layers = estimator.find_unique_layers(pubs)
# Learn the noise model for those layers (runs as a separate job).
learner = NoiseLearnerV3(backend)
learner_job = learner.run(layers)NoiseLearnerV3, Executor를 사용할 때는:
회로 실행을 위해 Executor를 사용할 계획이라면, Samplomatic의 generate_boxing_pass_manager 함수를 사용하여 어노테이션이 추가된 박스를 생성하는 것을 고려해 보세요:
from qiskit_ibm_runtime.noise_learner_v3 import NoiseLearnerV3
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic.utils import find_unique_box_instructions
# Run the boxing pass manager to group instructions into annotated boxes.
# `isa_circuit` is an ISA QuantumCircuit.
boxing_pm = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=False,
inject_noise_targets="gates", # no measurement mitigation
inject_noise_strategy="uniform_modification",
)
boxed_circuit = boxing_pm.run(isa_circuit)
# Find unique boxed instructions.
unique_box_instructions = find_unique_box_instructions(boxed_circuit.data)
# Instantiate a NoiseLearnerV3 object and execute the noise learning program.
learner = NoiseLearnerV3(backend)
learner_job = learner.run(unique_box_instructions)3단계: 옵션 변환하기
다음 항목을 제외하고 대부분의 NoiseLearnerOptions 필드는 에 직접 매핑됩니다 NoiseLearnerV3Options:
max_layers_to_learn: 의 경우NoiseLearnerV3, 학습할 레이어 수는 전달된 레이어 수에 따라 결정됩니다.twirling_strategy: 의 경우NoiseLearnerV3, 회전 전략은 명령어가 어떻게 그룹화되고 주석이 달리는지에 따라 결정됩니다(예: 를 사용할 때generate_boxing_pass_manager()).
NoiseLearner:
from qiskit_ibm_runtime.noise_learner import NoiseLearner
from qiskit_ibm_runtime.options import NoiseLearnerOptions
# Instantiate a NoiseLearnerOptions object
learner_options = NoiseLearnerOptions(
max_layers_to_learn=3, num_randomizations=32, twirling_strategy="all"
)
learner = NoiseLearner(mode=backend, options=learner_options)
learner_job = learner.run(circuits_to_learn)NoiseLearnerV3, 클라이언트 측 Estimator를 사용할 때는:
회로 실행을 위해 클라이언트 측 에스티메이터를 사용할 계획이라면,
다음과 같이 에스티메이터 twirling.strategy 옵션을 설정할 수 있습니다:
from qiskit_ibm_runtime.executor_estimator import Estimator
from qiskit_ibm_runtime import NoiseLearnerV3
from qiskit_ibm_runtime.options_models import NoiseLearnerV3Options
pubs = [...] # Your PUBs
estimator = Estimator(backend)
estimator.options.resilience.pec_mitigation = True # or zne_mitigation + pea amplifier
estimator.options.twirling.strategy = "all" # set twirling strategy here
# Identify the unique layers to learn.
layers = estimator.find_unique_layers(pubs)
# Instantiate a NoiseLearnerV3 object and execute the noise learning program
learner_options = NoiseLearnerV3Options(num_randomizations=32)
learner = NoiseLearnerV3(backend, options=learner_options)
# Learn just the first 3 layers.
learner_job = learner.run(layers[:3])NoiseLearnerV3, Executor를 사용할 때는:
회로 실행을 위해 Executor를 사용할 계획이라면, generate_boxing_pass_manager 함수에 해당 옵션을 twirling_strategy 전달할 수 있습니다.
참고로 generate_boxing_pass_manager(), 의 경우 twirling_strategy 값에는 밑줄("active_accum"
, "active_circuit")이 사용되는 반면, 의 NoiseLearnerOptions.twirling_strategy 값에는 하이픈("active-accum", "active-circuit")이 사용됩니다.
from qiskit_ibm_runtime.noise_learner_v3 import NoiseLearnerV3
from qiskit_ibm_runtime.options_models import NoiseLearnerV3Options
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic.utils import find_unique_box_instructions
# Run the boxing pass manager to group instructions into annotated boxes
# `isa_circuit` is an ISA QuantumCircuit
boxing_pm = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=False,
twirling_strategy="all", # twirling strategy can be specified here
inject_noise_targets="gates",
inject_noise_strategy="uniform_modification",
)
boxed_circuit = boxing_pm.run(isa_circuit)
# Find unique boxed instructions
unique_box_instructions = find_unique_box_instructions(boxed_circuit.data)
learner_options = NoiseLearnerV3Options(num_randomizations=32)
# Instantiate a NoiseLearnerV3 object and execute the noise learning program
learner = NoiseLearnerV3(backend, options=learner_options)
# Learn just the first 3 layers.
learner_job = learner.run(unique_box_instructions[:3])4단계: 결과 확인
와 NoiseLearner 의 출력값은 비슷한 정보를 담고 NoiseLearnerV3 있지만 형식이 다릅니다. 출력을 명시적으로 확인하는 코드가 있다면 해당 코드를 수정하십시오.
결과 속성 매핑:
(learner_result 는 학습자 작업의 출력입니다)
속성 | NoiseLearner | NoiseLearnerV3 |
|---|---|---|
| 결과 유형 | NoiseLearnerResult | NoiseLearnerV3Results 는 NoiseLearnerV3Result 의 시퀀스형 컨테이너입니다 |
| 학습된 층의 수 | len( learner_result.data ) | len(learner_result) |
| 첫 번째 계층에 대한 데이터 | layer_error = learner_result.data[0] | noise_map = learner_result[0].to_pauli_lindblad_map() |
| 각 레이어의 결과 유형 | LayerError (type(layer_error)) | PauliLindbladMap (type(noise_map)) |
| 오류 채널용 생성기 | layer_error.error.generators | noise_map.generators() |
| 오류 비율 | layer_error.error.rates | noise_map.rates |
5단계: 노이즈 모델을 프리미티브에 입력하기
NoiseLearner 레거시 서버 측에서만 작동하며 Estimator, Executor 및 클라이언트 측에서만 NoiseLearnerV3 작동합니다 Estimator. 소음 모델의 지정 방식은 사용되는 기본 요소에 따라 약간씩 다릅니다.
NoiseLearner, 구형 서버 측 Estimator를 사용할 때는:
from qiskit_ibm_runtime import Estimator as LegacyEstimator
learner_result = learner_job.result()
# Pass the noise model to the `estimator.options` attribute directly
estimator = LegacyEstimator(mode=backend)
estimator.options.resilience.layer_noise_model = learner_result
job = estimator.run(pubs)NoiseLearnerV3, 클라이언트 측 Estimator를 사용할 때는:
2단계에서 layers 를 생성했던 것과 Estimator 동일한 것을 다시 사용하십시오. 학습기가 반환한 노이즈 맵은
해당 레이어와 위치가 일치하므로, 이 맵들은 원래 출처가 된 추정기에
할당되어야 합니다. 2단계에서 이미 해당 장치에 PEA/PEC가 활성화되었습니다.
는 파울리-린드블라드(Pauli-Lindblad) 및 TREX 프로토콜을 모두 NoiseLearnerV3 지원하지만, 파울리-린드블라드 프로토콜로 학습된 2-큐비트 레이어의 노이즈 모델만 Estimator 허용한다는 점에 유의하십시오.
learner_result = learner_job.result()
# Convert results to Pauli-Lindblad noise maps.
pauli_lindblad_maps = learner_result.to_pauli_lindblad_maps()
# Assign the learned noise maps so PEA/PEC uses them.
estimator.options.resilience.layer_noise_model = zip(layers, pauli_lindblad_maps)
# Now execute the target PUBs.
job = estimator.run(pubs)NoiseLearnerV3, Executor를 사용할 때는:
from qiskit_ibm_runtime import Executor
from qiskit_ibm_runtime.quantum_program import QuantumProgram
# Generate a quantum program
program = QuantumProgram(shots=1000)
# Convert the NoiseLearnerV3 result to a dictionary
learner_result = learner_job.result()
noise_maps = learner_result.to_dict(
instructions=unique_box_instructions, require_refs=False
)
# Append the samplex item and execute
program.append_samplex_item(
template_circuit,
samplex=samplex,
samplex_arguments={
"pauli_lindblad_maps": noise_maps,
},
)
executor = Executor(backend)
executor_job = executor.run(program)전체 예시
NoiseLearnerV3 및 클라이언트 측 추정기
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService, NoiseLearnerV3
from qiskit_ibm_runtime.executor_estimator import Estimator
# 1. Account + backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# 2. Circuit + observable
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
observable = SparsePauliOp("ZZ")
# 3. Transpile to ISA
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)
pubs = [(isa_circuit, isa_observable)]
# 4. Initialize Estimator with options
estimator = Estimator(backend)
estimator.options.resilience.pec_mitigation = True
# 5. Extract the unique boxed layers from PUBs
layers = estimator.find_unique_layers(pubs)
# 6. Learn the noise model for those layers
learner = NoiseLearnerV3(backend)
learner_job = learner.run(layers)
learner_result = learner_job.result()
# 7. Convert the result to Pauli-Lindblad maps and pass them to Estimator
pauli_lindblad_maps = learner_result.to_pauli_lindblad_maps()
estimator.options.resilience.layer_noise_model = zip(layers, pauli_lindblad_maps)
# 8. Execute the target PUBs
job = estimator.run(pubs)
result = job.result()NoiseLearnerV3 및 유언집행자
from qiskit import QuantumCircuit
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService, Executor, NoiseLearnerV3
from qiskit_ibm_runtime.quantum_program import QuantumProgram
from samplomatic import build
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic.utils import find_unique_box_instructions
# 1. Account + backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# 2. Circuit + observable
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
# 3. Transpile to ISA
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)
# 4. Run the boxing pass manager to group instructions into annotated boxes
boxing_pm = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=False,
inject_noise_targets="gates", # no measurement mitigation
inject_noise_strategy="uniform_modification",
)
boxed_circuit = boxing_pm.run(isa_circuit)
# 5. Find unique boxed instructions (layers)
unique_box_instructions = find_unique_box_instructions(boxed_circuit.data)
# 6. Learn the noise model for those layers
learner = NoiseLearnerV3(backend)
learner_job = learner.run(unique_box_instructions)
learner_result = learner_job.result()
# 7. Convert the NoiseLearnerV3 result to a dictionary
noise_maps = learner_result.to_dict(
instructions=unique_box_instructions, require_refs=False
)
# 8. Build the template circuit and samplex pair
template_circuit, samplex = build(boxed_circuit)
# 9. Prepare a quantum program
program = QuantumProgram(shots=1000)
program.append_samplex_item(
template_circuit,
samplex=samplex,
samplex_arguments={
"pauli_lindblad_maps": noise_maps,
},
)
executor = Executor(backend)
job = executor.run(program)
result = job.result()