Serverless Sandboxes はパブリックプレビューです。
このページでは、Serverless Sandbox のライフサイクルについて説明します。これにより、状態変化の待機方法、サンドボックスの停止方法、ライフタイムを考慮したコード構成について適切な方法を選択できます。ライフサイクルを理解することで、競合状態を回避し、起動時の失敗と実行時エラーを区別し、リソースを意図したとおりにクリーンアップできるようになります。
W&B Serverless Sandbox は、ライフサイクルの中でいくつかの状態を経ます。サンドボックスの状態によって、利用できる操作が決まります。
通常、サンドボックスは PENDING 状態で開始され、コンテナーのプロビジョニング中に CREATING に移行し、使用可能になると RUNNING に入ります。
サンドボックスを メインコマンド とともに開始すると、そのコマンドがサンドボックスのメインプロセスになります。メインプロセスが終了すると、サンドボックスは COMPLETED (終了コード 0) や FAILED (起動時または実行中のエラー) などの終端状態に入ります。サンドボックスは、外部から停止された場合や最大ライフタイムを超えた場合にも TERMINATED に入ることがあります。
PENDING -> CREATING -> RUNNING -> COMPLETED
-> FAILED
-> TERMINATED
以下のセクションでは、サンドボックスの状態、準備完了または処理完了まで待機する方法、そしてサンドボックスを停止する方法について説明します。サンドボックスの作成方法やコマンドの実行方法について詳しくは、サンドボックスを作成する および コマンドを実行する を参照してください。
次の表は、サンドボックスの状態をまとめたものです。
| 状態 | 説明 |
|---|
PENDING | サンドボックスのリクエストは受理され、スケジュールされるのを待っている状態です。 |
CREATING | コンテナーをプロビジョニング中です。 |
RUNNING | サンドボックスは操作を実行できる状態です。 |
COMPLETED | メインプロセスが終了コード 0 で正常終了しました。 |
FAILED | サンドボックスまたはそのメインプロセスで、起動時または実行中にエラーが発生しました。 |
TERMINATED | 外部プロセスによってサンドボックスが停止されたか、最大ライフタイムを超えたため終了しました。 |
ほとんどの操作では、サンドボックスが RUNNING 状態である必要があります。ただし、多くの操作では、サンドボックスの準備が完了するまで待機してから処理が続行されます。
サンドボックスが終端状態に入ると、追加の作業には使用できなくなります。
以下のセクションでは、サンドボックスの状態変化を待機するための 2 つのメソッドと、それぞれをいつ使用するかについて説明します。必要に応じて、以下の待機メソッドを使い分けてください。
Sandbox.wait() を使用すると、サンドボックスが RUNNING 状態になるまで明示的に待機できます。このメソッドは、起動時の問題をデバッグする場合や、起動の失敗と後続のコマンドで発生するエラーを区別したい場合に役立ちます。
たとえば、次のコードでは、サンドボックスを作成し、準備完了になるまで待機してからコマンドを実行します。
import wandb
from wandb.sandbox import Sandbox
with Sandbox.run() as sandbox:
sandbox.wait() # サンドボックスが実行中になるまでブロックする
result = sandbox.exec(["python", "-c", "print('hello from sandbox')"]).result()
print(result.stdout)
サンドボックスのメインプロセスがワークロード全体に相当し、そのジョブの完了まで待機したい場合は、Sandbox.wait_until_complete() を使用します。
from wandb.sandbox import Sandbox
sandbox = Sandbox.run("python", "train.py")
sandbox.wait_until_complete(timeout=3600.0).result() # メインプロセスが終了するかタイムアウトになるまで待機
print(f"Exit code: {sandbox.returncode}")
このパターンは、Sandbox.run("python", "train.py") のようなメインコマンドでサンドボックスを開始し、そのサンドボックスのライフサイクルをそのコマンドの実行に合わせたい場合に便利です。
メインプロセスが終了すると、サンドボックスは終端状態に入ります。成功した run は通常 COMPLETED で終了します。プロセスが失敗した場合、サンドボックスは FAILED に入ることがあります。
代わりにコマンドをインタラクティブに実行する必要がある場合は、Sandbox.exec() とともにコンテキストマネージャーを使用します:
from wandb.sandbox import Sandbox
with Sandbox.run() as sandbox:
result = sandbox.exec(["python", "train.py"]).result()
print(result.stdout)
# 終了時にサンドボックスは自動的に停止
サンドボックスのライフサイクルを明示的に制御する必要がある場合は、Sandbox.wait() や Sandbox.stop() などのメソッドを使用します。
通常、これらのメソッドを直接呼び出す必要はありません。Sandbox.exec()、Sandbox.read_file()、Sandbox.write_file() などの操作では、準備が整うまで待機します。また、コンテキストマネージャー (with Sandbox.run() as sandbox:) は、ブロックを抜けるとサンドボックスを停止します。
サンドボックス が不要になった場合、長時間実行中のプロセスを終了したい場合、または サンドボックス が最大ライフタイムに達する前にリソースをクリーンアップする必要がある場合は、Sandbox.stop() を使用します。
from wandb.sandbox import Sandbox
sandbox = Sandbox.run("sleep", "infinity")
# ... サンドボックスを使用する ...
sandbox.stop().result()
追加オプションを使用して、シャットダウン時の動作を制御することもできます。
from wandb.sandbox import Sandbox
with Sandbox.run("sleep", "infinity") as sandbox:
sandbox.stop(
graceful_shutdown_seconds=30.0, # 強制終了前の待機時間(秒)。
missing_ok=True, # すでに停止済みの場合もエラーを発生させない。
).result()