주 콘텐츠로 건너뛰기

Session에서 작업 실행하기

패키지 버전

이 페이지의 코드는 다음 요구 사항을 사용하여 개발되었습니다. 해당 버전 이상을 사용하는 것을 권장합니다.

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
scipy~=1.16.3
참고

Open Plan 사용자는 Session 작업을 제출할 수 없습니다. 워크로드는 작업 모드 또는 배치 모드에서 실행해야 합니다.

QPU에 대한 전용 독점 액세스가 필요할 때 Session을 사용하세요.

Session 사용 설정

Session을 시작하기 전에 Qiskit Runtime을 설정하고 서비스로 초기화해야 합니다:

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime scipy
from qiskit_ibm_runtime import (
QiskitRuntimeService,
Session,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)

service = QiskitRuntimeService()

Session 열기

컨텍스트 매니저 with Session(...)을 사용하거나 Session 클래스를 초기화하여 런타임 Session을 열 수 있습니다. Session을 시작할 때는 backend 객체를 전달하여 QPU를 지정해야 합니다. Session은 첫 번째 작업이 실행을 시작할 때 시작됩니다.

참고

Session을 열었지만 30분 동안 작업을 제출하지 않으면 Session이 자동으로 닫힙니다.

Session 클래스

주의

다음 코드 블록은 Session을 사용하기 때문에 Open Plan 사용자에게 오류를 반환합니다. Open Plan의 워크로드는 작업 모드 또는 배치 모드에서만 실행할 수 있습니다.

backend = service.least_busy(operational=True, simulator=False)
session = Session(backend=backend)
estimator = Estimator(mode=session)
sampler = Sampler(mode=session)
# Close the session because no context manager was used.
session.close()

컨텍스트 매니저

컨텍스트 매니저는 Session을 자동으로 열고 닫습니다.

주의

다음 코드 블록은 Session을 사용하기 때문에 Open Plan 사용자에게 오류를 반환합니다. Open Plan의 워크로드는 작업 모드 또는 배치 모드에서만 실행할 수 있습니다.

from qiskit_ibm_runtime import (
Session,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)

backend = service.least_busy(operational=True, simulator=False)
with Session(backend=backend):
estimator = Estimator()
sampler = Sampler()

Session 길이

최대 Session 유효 시간(TTL)은 Session이 실행될 수 있는 기간을 결정합니다. max_time 파라미터를 사용하여 이 값을 설정할 수 있습니다. 이 값은 가장 긴 작업의 실행 시간을 초과해야 합니다.

이 타이머는 Session이 시작될 때 시작됩니다. 값에 도달하면 Session이 닫힙니다. 실행 중인 작업은 완료되지만, 아직 대기 중인 작업은 실패 처리됩니다.

주의

다음 코드 블록은 Session을 사용하기 때문에 Open Plan 사용자에게 오류를 반환합니다. Open Plan의 워크로드는 작업 모드 또는 배치 모드에서만 실행할 수 있습니다.

with Session(backend=backend, max_time="25m"):
...

또한 구성할 수 없는 대화형 유효 시간(interactive TTL) 값도 있습니다. 해당 시간 내에 Session 작업이 대기열에 추가되지 않으면 Session이 일시적으로 비활성화됩니다.

기본값:

인스턴스 유형 (Open 또는 Premium Plan)대화형 TTL최대 TTL
Premium Plan60초*8시간*
* 일부 Premium Plan 인스턴스는 다른 값으로 구성될 수 있습니다.

Session의 최대 TTL 또는 대화형 TTL을 확인하려면 Session 세부 정보 확인의 지침을 따르고 각각 max_time 또는 interactive_timeout 값을 확인하세요.

Session 종료

Session은 다음과 같은 상황에서 종료됩니다:

  • 최대 타임아웃(TTL) 값에 도달하면 대기 중인 모든 작업이 취소됩니다.
  • Session이 수동으로 취소되면 대기 중인 모든 작업이 취소됩니다.
  • Session이 수동으로 닫힙니다. Session은 새 작업 수락을 중단하지만 대기 중인 작업은 우선순위로 계속 실행됩니다.
  • Session을 컨텍스트 매니저로 사용하는 경우, 즉 with Session()을 사용하면, 컨텍스트가 종료될 때 Session이 자동으로 닫힙니다(session.close() 사용과 동일한 동작).

Session 닫기

Session은 컨텍스트 매니저를 종료할 때 자동으로 닫힙니다. Session 컨텍스트 매니저가 종료되면 Session은 "진행 중, 새 작업 미수락" 상태로 전환됩니다. 이는 Session이 최대 타임아웃 값에 도달할 때까지 실행 중이거나 대기 중인 모든 작업의 처리를 완료한다는 것을 의미합니다. 모든 작업이 완료되면 Session이 즉시 닫힙니다. 이를 통해 스케줄러가 Session 대화형 타임아웃을 기다리지 않고 다음 작업을 실행할 수 있어 평균 작업 대기 시간이 줄어듭니다. 닫힌 Session에는 작업을 제출할 수 없습니다.

주의

다음 코드 블록은 Session을 사용하기 때문에 Open Plan 사용자에게 오류를 반환합니다. Open Plan의 워크로드는 작업 모드 또는 배치 모드에서만 실행할 수 있습니다.

from qiskit.quantum_info import SparsePauliOp
from qiskit.circuit import QuantumCircuit, Parameter
from qiskit.transpiler import generate_preset_pass_manager
import numpy as np

# This cell is hidden from users
service = QiskitRuntimeService()
backend = service.least_busy()

# Define two circuits, each with one parameter with two parameters.
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.ry(Parameter("a"), 0)
circuit.cx(0, 1)
circuit.h(0)
circuit.measure_all()

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
transpiled_circuit = pm.run(circuit)
transpiled_circuit_sampler = transpiled_circuit
transpiled_circuit_sampler.measure_all()

# Create parameters and mapped observables to submit
params = np.random.uniform(size=(2, 3)).T
observables = [
SparsePauliOp(["XX", "IY"], [0.5, 0.5]),
SparsePauliOp("XX"),
SparsePauliOp("IY"),
]
mapped_observables = [
[observable.apply_layout(transpiled_circuit.layout)]
for observable in observables
]

sampler_pub = (transpiled_circuit_sampler, params)
estimator_pub = (transpiled_circuit_sampler, mapped_observables, params)
with Session(backend=backend) as session:
estimator = Estimator()
sampler = Sampler()
job1 = estimator.run([estimator_pub])
job2 = sampler.run([sampler_pub])

# The session is no longer accepting jobs but the submitted job will run to completion.
result = job1.result()
result2 = job2.result()

컨텍스트 매니저를 사용하지 않는 경우, 원치 않는 비용을 방지하기 위해 수동으로 Session을 닫으세요. Session에 작업 제출을 완료하는 즉시 닫을 수 있습니다. session.close()로 Session을 닫으면 더 이상 새 작업을 수락하지 않지만, 이미 제출된 작업은 완료될 때까지 계속 실행되며 결과를 가져올 수 있습니다.

주의

다음 코드 블록은 Session을 사용하기 때문에 Open Plan 사용자에게 오류를 반환합니다. Open Plan의 워크로드는 작업 모드 또는 배치 모드에서만 실행할 수 있습니다.

session = Session(backend=backend)

# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `session=`
estimator = Estimator(mode=session)
sampler = Sampler(mode=session)
job1 = estimator.run([estimator_pub])
job2 = sampler.run([sampler_pub])
print(f"Result1: {job1.result()}")
print(f"Result2: {job2.result()}")

# Manually close the session. Running and queued jobs will run to completion.
session.close()
Result1: PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(3, 2), dtype=float64>), stds=np.ndarray(<shape=(3, 2), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 2), dtype=float64>), shape=(3, 2)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})
Result2: PrimitiveResult([SamplerPubResult(data=DataBin(meas=BitArray(<shape=(3, 2), num_shots=4096, num_bits=2>), meas0=BitArray(<shape=(3, 2), num_shots=4096, num_bits=133>), shape=(3, 2)), metadata={'circuit_metadata': {}})], metadata={'execution': {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-01-15 07:53:15', stop='2026-01-15 07:53:21', size=24576>)])}, 'version': 2})

Session 상태 확인

session.status()를 사용하거나 워크로드 페이지를 확인하여 Session의 현재 상태를 조회할 수 있습니다.

Session 상태는 다음 중 하나일 수 있습니다:

  • Pending: Session이 시작되지 않았거나 비활성화되었습니다. 다음 Session 작업은 다른 작업처럼 대기열에서 기다려야 합니다.
  • In progress, accepting new jobs: Session이 활성 상태이며 새 작업을 수락하고 있습니다.
  • In progress, not accepting new jobs: Session이 활성 상태이지만 새 작업을 수락하지 않습니다. Session에 대한 작업 제출은 거부되지만 미처리 Session 작업은 완료될 때까지 실행됩니다. 모든 작업이 완료되면 Session이 자동으로 닫힙니다.
  • Closed: Session의 최대 타임아웃 값에 도달했거나 Session이 명시적으로 닫혔습니다.

Session 세부 정보 확인

Session의 구성 및 상태에 대한 포괄적인 개요를 보려면 session.details() 메서드를 사용하세요.

주의

다음 코드 블록은 Session을 사용하기 때문에 Open Plan 사용자에게 오류를 반환합니다. Open Plan의 워크로드는 작업 모드 또는 배치 모드에서만 실행할 수 있습니다.

from qiskit_ibm_runtime import (
QiskitRuntimeService,
Session,
EstimatorV2 as Estimator,
)

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

with Session(backend=backend) as session:
print(session.details())
{'id': 'be84569d-86b5-4a7f-be5e-7d33e80dc220', 'backend_name': 'ibm_torino', 'interactive_timeout': 60, 'max_time': 28800, 'active_timeout': 28800, 'state': 'open', 'accepting_jobs': True, 'last_job_started': None, 'last_job_completed': None, 'started_at': None, 'closed_at': None, 'activated_at': None, 'mode': 'dedicated', 'usage_time': None}

사용 패턴

Session은 클래식 리소스와 양자 리소스 간의 빈번한 통신이 필요한 알고리즘에 특히 유용합니다.

예시: 클래식 SciPy 최적화 도구를 사용하여 비용 함수를 최소화하는 반복 워크로드를 실행합니다. 이 모델에서 SciPy는 비용 함수의 출력을 사용하여 다음 입력을 계산합니다.

주의

다음 코드 블록은 Session을 사용하기 때문에 Open Plan 사용자에게 오류를 반환합니다. Open Plan의 워크로드는 작업 모드 또는 배치 모드에서만 실행할 수 있습니다.

from scipy.optimize import minimize
from qiskit.circuit.library import efficient_su2

def cost_func(params, ansatz, hamiltonian, estimator):
# Return estimate of energy from estimator

energy = sum(
estimator.run([(ansatz, hamiltonian, params)]).result()[0].data.evs
)
return energy

hamiltonian = SparsePauliOp.from_list(
[("YZ", 0.3980), ("ZI", -0.3980), ("ZZ", -0.0113), ("XX", 0.1810)]
)
su2_ansatz = efficient_su2(hamiltonian.num_qubits)
pm = generate_preset_pass_manager(backend=backend, optimization_level=3)
ansatz = pm.run(su2_ansatz)
mapped_hamiltonian = [
operator.apply_layout(ansatz.layout) for operator in hamiltonian
]

num_params = ansatz.num_parameters
x0 = 2 * np.pi * np.random.random(num_params)

session = Session(backend=backend)

# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `session=`
estimator = Estimator(mode=session, options={"default_shots": int(1e4)})
res = minimize(
cost_func,
x0,
args=(ansatz, mapped_hamiltonian, estimator),
method="cobyla",
options={"maxiter": 25},
)

# Close the session because no context manager was used.
session.close()

스레딩을 사용하여 Session에서 두 개의 VQE 알고리즘 실행하기

단일 Session 내에서 여러 워크로드를 동시에 실행하여 Session을 더 효율적으로 활용할 수 있습니다. 다음 예시는 서로 다른 클래식 최적화 도구를 사용하는 두 개의 VQE 알고리즘을 단일 Session 내에서 동시에 실행하는 방법을 보여줍니다. 각 워크로드의 작업을 구분하기 위해 작업 태그도 사용됩니다.

주의

다음 코드 블록은 Session을 사용하기 때문에 Open Plan 사용자에게 오류를 반환합니다. Open Plan의 워크로드는 작업 모드 또는 배치 모드에서만 실행할 수 있습니다.

from concurrent.futures import ThreadPoolExecutor
from qiskit_ibm_runtime import EstimatorV2 as Estimator

def minimize_thread(estimator, method):
return minimize(
cost_func,
x0,
args=(ansatz, mapped_hamiltonian, estimator),
method=method,
options={"maxiter": 25},
)

with Session(backend=backend), ThreadPoolExecutor() as executor:
estimator1 = Estimator()
estimator2 = Estimator()

# Use different tags to differentiate the jobs.
estimator1.options.environment.job_tags = ["cobyla"]
estimator2.options.environment.job_tags = ["nelder-mead"]

# Submit the two workloads.
cobyla_future = executor.submit(minimize_thread, estimator1, "cobyla")
nelder_mead_future = executor.submit(
minimize_thread, estimator2, "nelder-mead"
)

# Get workload results.
cobyla_result = cobyla_future.result()
nelder_mead_result = nelder_mead_future.result()

다음 단계

권장 사항