Skip to main content
IBM Quantum Platform

Qiskit Serverless のコンピューティングリソースとデータリソースを管理する

  • このページのコードは、以下の要件に基づいて開発された。 これらのバージョンまたは新しいバージョンの使用をお勧めします。

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

Qiskit Serverless アップグレードが行われており、その機能は急速に変化しています。 この開発フェーズでは、リリースノートと最新のドキュメントは Qiskit Serverless GitHub ページでご覧いただけます。

Qiskit Serverlessでは、CPU、QPU、その他のコンピュートアクセラレータを含む Qiskitパターン全体でコンピュートとデータを管理できます。


詳細なステータスを設定する

サーバーレス・ワークロードには、ワークフロー全体でいくつかの段階がある。 デフォルトでは、以下のステータスが 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 decorator を使用して、タスクの実行に必要な計算要件を定義してください。 まず、 「最初の Qiskit Serverless プログラムを作成する」 というトピックで紹介された例 transpile_remote.py を思い出してください。その例では、次のようなコードが使用されていました。

以下のコードでは、すでに認証情報を保存している必要があります。

./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_ibm_runtime import QiskitRuntimeService
from qiskit_serverless import distribute_task

service = QiskitRuntimeService()

@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、メモリをタスクに柔軟に割り当てることができる。 Qiskit Serverless on IBM Quantum® Platformでは、各プログラムに16個のCPUコアと32GBのRAMが搭載され、必要に応じて動的に割り当てることができる。

CPUコアはフルCPUコアとして割り当てることもできるし、以下に示すように端数割り当てることもできる。

メモリはバイト数で割り当てられる。 キロバイトには1024バイト、メガバイトには1024キロバイト、ギガバイトには1024メガバイトがあることを思い出してほしい。 ワーカーに 2 GB のメモリを割り当てるには、 "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

プログラム全体でデータを管理する

Qiskit Serverlessでは、すべてのプログラムで /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で行ってください。