Skip to main content
IBM Quantum Platform

Qiskit Serverless 의 컴퓨팅 및 데이터 리소스 관리

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

    qiskit[all]~=2.0.0
    qiskit-ibm-runtime~=0.37.0
    qiskit-serverless~=0.27.0
    
Tip

Qiskit Serverless 업그레이드를 진행 중이며, 기능이 빠르게 변화하고 있습니다. 이 개발 단계 동안, 릴리스 노트와 최신 문서는 Qiskit ServerlessGitHub 페이지에서 확인하실 수 있습니다.

키스킷 서버리스를 사용하면 CPU, QPU 및 기타 컴퓨팅 가속기를 포함하여 키스킷 패턴 전반에서 컴퓨팅과 데이터를 관리할 수 있습니다.


상세 상태 설정

서버리스 워크로드는 워크플로 전반에 걸쳐 여러 단계로 구성됩니다. 기본적으로 job.status() 에서 볼 수 있는 상태는 다음과 같습니다:

  • **QUEUED**워크로드가 기존 리소스에 대해 대기열에 대기 중입니다
  • **INITIALIZING**워크로드가 설정되었습니다
  • **RUNNING**워크로드가 현재 클래식 리소스에서 실행 중입니다
  • **DONE**워크로드가 성공적으로 완료되었습니다

다음과 같이 특정 워크플로 단계를 추가로 설명하는 사용자 지정 상태를 설정할 수도 있습니다.

Caution

노트북에서 코드 셀을 로컬로 실행하면 매직 %%writefile 명령어가 표시됩니다. 이 마법 같은 명령어를 사용하여 셀을 실행하면, 셀이 실제로 실행되는 대신 디스크에 저장됩니다.

./source_files/status_example.py
# If you include the preceding `%%writefile` command (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than executing the code.

from qiskit_serverless import update_status, Job

# # If your function has a mapping stage, particularly application functions, you can set the status
# to "RUNNING: MAPPING" as follows:
update_status(Job.MAPPING)

# # While handling transpilation, error suppression, and so forth, you can set the status to
# "RUNNING: OPTIMIZING_FOR_HARDWARE":
update_status(Job.OPTIMIZING_HARDWARE)

# # After you submit jobs to IBM Quantum Compute Service, the underlying quantum job will be queued. You can set
# status to "RUNNING: WAITING_FOR_QPU":
update_status(Job.WAITING_QPU)

# # When the Quantum Compute job starts running on the QPU, set the following status
# "RUNNING: EXECUTING_QPU":
update_status(Job.EXECUTING_QPU)

## Once QPU is completed and post-processing has begun, set the status "RUNNING: POST_PROCESSING":
update_status(Job.POST_PROCESSING)

이 워크로드가 성공적으로 완료되면( save_result())이 상태는 자동으로 DONE 으로 업데이트됩니다.


병렬 워크플로

병렬 처리가 가능한 일반적인 작업의 경우, @distribute_task 데코레이터를 사용하여 작업 수행에 필요한 컴퓨팅 요구 사항을 정의하십시오. 먼저 ‘첫 번째 Qiskit Serverless 프로그램 작성하기’ 주제에 나온 예제를 transpile_remote.py 떠올려 보세요. 다음 코드를 참고하세요.

다음 코드를 사용하려면 미리 인증 정보를 저장해 두어야 합니다. 해당 예시와 마찬가지로, 이 코드는 런타임 서비스를 생성하여, 이 서비스가 시작하는 모든 Qiskit Runtime 작업 및 세션이 상위 Qiskit Serverless 작업에 대해 추적되도록 합니다 get_runtime_service() . 자세한 내용은 ‘첫 번째 Qiskit Serverless 프로그램 작성하기 ’를 참조하세요.

./source_files/transpile_remote.py
# If you include the preceding `%%writefile` command (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than executing the code.

from qiskit.transpiler import generate_preset_pass_manager
from qiskit_serverless import distribute_task, get_runtime_service

service = get_runtime_service()

@distribute_task(target={"cpu": 1})
def transpile_remote(circuit, optimization_level, backend):
    """
    Transpiles an abstract circuit (or list of circuits)
    into an ISA circuit for a given backend.
    """
    pass_manager = generate_preset_pass_manager(
        optimization_level=optimization_level,
        backend=service.backend(backend)
    )
    isa_circuit = pass_manager.run(circuit)
    return isa_circuit

이 예제에서는 transpile_remote() 함수를 @distribute_task(target={"cpu": 1}) 으로 꾸몄습니다. 실행하면 단일 CPU 코어로 비동기 병렬 워커 작업을 생성하고 워커를 추적하기 위한 참조와 함께 반환합니다. 결과를 가져오려면 get() 함수에 참조를 전달합니다. 이를 사용하여 여러 병렬 작업을 실행할 수 있습니다:

./source_files/transpile_remote.py (appended)
# If you include the preceding `%%writefile` command
# (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than
# executing the code.

from time import time
from qiskit_serverless import get, get_arguments, save_result, update_status, Job

# Get arguments
arguments = get_arguments()
circuit = arguments.get("circuit")
optimization_level = arguments.get("optimization_level")
backend = arguments.get("backend")
./source_files/transpile_remote.py (appended)
# If you include the preceding `%%writefile` command
# (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than executing the code.

# Start distributed transpilation
update_status(Job.OPTIMIZING_HARDWARE)

start_time = time()
transpile_worker_references = [
    transpile_remote(circuit, optimization_level, backend)
    for circuit in arguments.get("circuit_list")
]

transpiled_circuits = get(transpile_worker_references)
end_time = time()
./source_files/transpile_remote.py (appended)
# If you include the preceding `%%writefile` command
# (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than executing the code.

# Save result, with metadata
result = {
    "circuits": transpiled_circuits,
    "metadata": {
        "resource_usage": {
            "RUNNING: OPTIMIZING_FOR_HARDWARE": {
                "CPU_TIME": end_time - start_time,
                "QPU_TIME": 0,
            },
        }
    },
}

save_result(result)

다양한 작업 구성을 탐색하세요

@distribute_task() 을 통해 작업에 필요한 CPU, GPU, 메모리를 유연하게 할당할 수 있습니다. IBM 퀀텀® 플랫폼의 키스킷 서버리스의 경우, 각 프로그램에는 필요에 따라 동적으로 할당할 수 있는 16개의 CPU 코어와 32GB RAM이 장착되어 있습니다.

CPU 코어는 다음과 같이 전체 CPU 코어 또는 부분 할당으로 할당할 수 있습니다.

메모리는 바이트 단위로 할당됩니다. 1킬로바이트에는 1024바이트, 1메가바이트에는 1024킬로바이트, 1기가바이트에는 1024메가바이트가 있다는 것을 기억하세요. 작업자에게 2GB의 메모리를 할당하려면 "mem": 2 * 1024 * 1024 * 1024 을 할당해야 합니다.

./source_files/transpile_remote.py (appended)
# If you include the preceding `%%writefile` command
# (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than executing the code.

@distribute_task(target={
    "cpu": 16,
    "mem": 2 * 1024 * 1024 * 1024
})
def transpile_remote(circuit, optimization_level, backend):
    return None

프로그램 전반에 걸쳐 데이터를 관리하세요

키스킷 서버리스를 사용하면 모든 프로그램에서 /data 디렉토리에 있는 파일을 관리할 수 있습니다. 여기에는 몇 가지 제한 사항이 포함됩니다:

  • 현재 tarh5 파일만 지원됩니다
  • 이것은 플랫 /data 저장소일 뿐이며 /data/folder/ 하위 디렉토리를 가질 수 없습니다

다음은 파일을 업로드하는 방법을 보여줍니다. IBM Quantum 계정으로 Qiskit Serverless 에 인증되었는지 반드시 확인하십시오(자세한 지침은 Qiskit Serverless 에 업로드하기를 참조하십시오).

import tarfile
from qiskit_serverless import IBMServerlessClient

# Create a tar
filename = "transpile_demo.tar"
file = tarfile.open(filename, "w")
file.add("./source_files/transpile_remote.py")
file.close()

# Get a reference to a QiskitFunction
serverless = IBMServerlessClient()
transpile_remote_demo = next(
    program
    for program in serverless.list()
    if program.title == "transpile_remote_serverless"
)

# Upload the tar to Serverless data directory
serverless.file_upload(file=filename, function=transpile_remote_demo)

Output:

'{"message":"/usr/src/app/media/5e1f442128cdf60018496a04/transpile_demo.tar"}'

다음으로 data 디렉터리에 있는 모든 파일을 나열할 수 있습니다. 이 데이터는 모든 프로그램에서 액세스할 수 있습니다.

serverless.files(function=transpile_remote_demo)

Output:

['classifier_name.pkl.tar', 'output.json.tar', 'transpile_demo.tar']

프로그램에서 file_download() 을 사용하여 파일을 프로그램 환경으로 다운로드하고 tar 의 압축을 풀면 됩니다.

./source_files/extract_tarfile.py
# If you include the preceding `%%writefile` command
# (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than executing the code.

import tarfile
from qiskit_serverless import IBMServerlessClient

# For `token`, use the 44-character API_KEY you created
# and saved from the IBM Quantum Platform Home dashboard
serverless = IBMServerlessClient(token="<YOUR_API_KEY>")
files = serverless.files()
demo_file = files[0]
downloaded_tar = serverless.file_download(demo_file)


with tarfile.open(downloaded_tar, 'r') as tar:
    tar.extractall()

이 시점에서 프로그램은 로컬 실험처럼 파일과 상호 작용할 수 있습니다. file_upload() , file_download(), file_delete() 을 로컬 실험 또는 업로드한 프로그램에서 호출하여 일관되고 유연한 데이터 관리를 할 수 있습니다.


다음 단계

권장사항
이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.