mcpField
M
modal-serverless-gpu

modal-serverless-gpu

github.com/kalarislabsその他7343 回インストール4 日前に更新
リポジトリ

modal-serverless-gpu について

Modal Serverless GPUは、ModalのサーバーレスGPUクラウドで機械学習ワークロードを実行するためのガイドです。Pythonによるインフラ定義、GPUジョブ、自動スケーリングAPI、一般的なデプロイ手法を扱います。

主な機能

  1. 01オンデマンドのサーバーレスGPU
  2. 02Pythonによるインフラ定義
  3. 03ゼロまでの自動スケーリング
  4. 04REST APIエンドポイント
  5. 05モデルとデータの永続ストレージ
  6. 06定期実行と並列処理

活用シーン

  1. 01GPU負荷の高い機械学習処理
  2. 02自動スケーリングするモデルAPIのデプロイ
  3. 03学習や推論バッチの処理
  4. 04機械学習ジョブの定期実行

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/kalarislabs/research-agent-skills --skill modal-serverless-gpu

インストール後、Claude Code で/modal-serverless-gpuを入力して読み込まれたか確認します。

同梱ファイルreferences/advanced-usage.mdreferences/troubleshooting.md

詳細

Modal サーバーレス GPU

Modal のサーバーレス GPU クラウドプラットフォームで ML ワークロードを実行するための包括的なガイドです。

Modal を使うタイミング

Modal を使うとよい場合:

  • インフラを管理せずに GPU を多用する ML ワークロードを実行したいとき
  • ML モデルを自動スケーリングする API としてデプロイしたいとき
  • バッチ処理ジョブ(トレーニング、推論、データ処理)を実行したいとき
  • アイドル時のコストをかけず、秒単位の従量課金で GPU を利用したいとき
  • ML アプリケーションのプロトタイピングを素早く行いたいとき
  • スケジュールジョブ(cron のようなワークロード)を実行したいとき

主な機能:

  • サーバーレス GPU: T4、L4、A10G、L40S、A100、H100、H200、B200 をオンデマンドで利用可能
  • Python ネイティブ: インフラを YAML ではなく Python コードで定義
  • 自動スケーリング: ゼロまでスケールダウンし、100 基以上の GPU へ即座にスケールアップ
  • 1 秒未満のコールドスタート: Rust ベースのインフラにより、コンテナを高速に起動
  • コンテナキャッシュ: イメージレイヤーをキャッシュし、迅速な反復開発を実現
  • Web エンドポイント: 関数を、ダウンタイムなしで更新できる REST API としてデプロイ

代わりに検討できるサービス:

  • RunPod: 永続的な状態を持つ、長時間稼働するポッド向け
  • Lambda Labs: 予約制の GPU インスタンス向け
  • SkyPilot: マルチクラウドのオーケストレーションとコスト最適化向け
  • Kubernetes: 複雑なマルチサービスアーキテクチャ向け

クイックスタート

インストール
pip install modal
modal setup  # Opens browser for authentication
GPU を使った Hello World
import modal

app = modal.App("hello-gpu")

@app.function(gpu="T4")
def gpu_info():
    import subprocess
    return subprocess.run(["nvidia-smi"], capture_output=True, text=True).stdout

@app.local_entrypoint()
def main():
    print(gpu_info.remote())

実行: modal run hello_gpu.py

基本的な推論エンドポイント
import modal

app = modal.App("text-generation")
image = modal.Image.debian_slim().pip_install("transformers", "torch", "accelerate")

@app.cls(gpu="A10G", image=image)
class TextGenerator:
    @modal.enter()
    def load_model(self):
        from transformers import pipeline
        self.pipe = pipeline("text-generation", model="gpt2", device=0)

    @modal.method()
    def generate(self, prompt: str) -> str:
        return self.pipe(prompt, max_length=100)[0]["generated_text"]

@app.local_entrypoint()
def main():
    print(TextGenerator().generate.remote("Hello, world"))

コアコンセプト

主要コンポーネント
コンポーネント用途
App関数とリソースのコンテナ
Functionコンピュートスペックを持つサーバーレス関数
Clsライフサイクルフックを持つクラスベースの関数
Imageコンテナイメージの定義
Volumeモデルやデータを保存する永続ストレージ
Secret認証情報を安全に保存する仕組み
実行モード
コマンド説明
modal run script.py実行して終了
modal serve script.pyライブリロードを使った開発
modal deploy script.py永続的なクラウドへのデプロイ

GPU の設定

利用可能な GPU
GPUVRAM適した用途
T416GB低コストの推論、小規模モデル
L424GB推論、Ada Lovelace アーキテクチャ
A10G24GBトレーニング/推論、T4 比で 3.3 倍高速
L40S48GB推論に推奨(コストパフォーマンスが最良)
A100-40GB40GB大規模モデルのトレーニング
A100-80GB80GB非常に大規模なモデル
H10080GB最速、FP8 + Transformer Engine
H200141GBH100 から自動アップグレード、4.8TB/s の帯域幅
B200最新Blackwell アーキテクチャ
GPU 指定のパターン
# Single GPU
@app.function(gpu="A100")

# Specific memory variant
@app.function(gpu="A100-80GB")

# Multiple GPUs (up to 8)
@app.function(gpu="H100:4")

# GPU with fallbacks
@app.function(gpu=["H100", "A100", "L40S"])

# Any available GPU
@app.function(gpu="any")

コンテナイメージ

# Basic image with pip
image = modal.Image.debian_slim(python_version="3.11").pip_install(
    "torch==2.1.0", "transformers==4.36.0", "accelerate"
)

# From CUDA base
image = modal.Image.from_registry(
    "nvidia/cuda:12.1.0-cudnn8-devel-ubuntu22.04",
    add_python="3.11"
).pip_install("torch", "transformers")

# With system packages
image = modal.Image.debian_slim().apt_install("git", "ffmpeg").pip_install("whisper")

永続ストレージ

volume = modal.Volume.from_name("model-cache", create_if_missing=True)

@app.function(gpu="A10G", volumes={"/models": volume})
def load_model():
    import os
    model_path = "/models/llama-7b"
    if not os.path.exists(model_path):
        model = download_model()
        model.save_pretrained(model_path)
        volume.commit()  # Persist changes
    return load_from_path(model_path)

Web エンドポイント

FastAPI エンドポイントのデコレーター
@app.function()
@modal.fastapi_endpoint(method="POST")
def predict(text: str) -> dict:
    return {"result": model.predict(text)}
フル ASGI アプリ
from fastapi import FastAPI
web_app = FastAPI()

@web_app.post("/predict")
async def predict(text: str):
    return {"result": await model.predict.remote.aio(text)}

@app.function()
@modal.asgi_app()
def fastapi_app():
    return web_app
Web エンドポイントの種類
デコレーターユースケース
@modal.fastapi_endpoint()単純な関数を API 化
@modal.asgi_app()フルな FastAPI/Starlette アプリ
@modal.wsgi_app()Django/Flask アプリ
@modal.web_server(port)任意の HTTP サーバー

動的バッチ処理

@app.function()
@modal.batched(max_batch_size=32, wait_ms=100)
async def batch_predict(inputs: list[str]) -> list[dict]:
    # Inputs automatically batched
    return model.batch_predict(inputs)

シークレット管理

# Create secret
modal secret create huggingface HF_TOKEN=hf_xxx
@app.function(secrets=[modal.Secret.from_name("huggingface")])
def download_model():
    import os
    token = os.environ["HF_TOKEN"]

スケジューリング

@app.function(schedule=modal.Cron("0 0 * * *"))  # Daily midnight
def daily_job():
    pass

@app.function(schedule=modal.Period(hours=1))
def hourly_job():
    pass

パフォーマンス最適化

コールドスタートの軽減
@app.function(
    container_idle_timeout=300,  # Keep warm 5 min
    allow_concurrent_inputs=10,  # Handle concurrent requests
)
def inference():
    pass
モデル読み込みのベストプラクティス
@app.cls(gpu="A100")
class Model:
    @modal.enter()  # Run once at container start
    def load(self):
        self.model = load_model()  # Load during warm-up

    @modal.method()
    def predict(self, x):
        return self.model(x)

並列処理

@app.function()
def process_item(item):
    return expensive_computation(item)

@app.function()
def run_parallel():
    items = list(range(1000))
    # Fan out to parallel containers
    results = list(process_item.map(items))
    return results

共通の設定

@app.function(
    gpu="A100",
    memory=32768,              # 32GB RAM
    cpu=4,                     # 4 CPU cores
    timeout=3600,              # 1 hour max
    container_idle_timeout=120,# Keep warm 2 min
    retries=3,                 # Retry on failure
    concurrency_limit=10,      # Max concurrent containers
)
def my_function():
    pass

デバッグ

# Test locally
if __name__ == "__main__":
    result = my_function.local()

# View logs
# modal app logs my-app

よくある問題

問題解決策
コールドスタートの遅延container_idle_timeout を増やし、@modal.enter() を使用
GPU の OOMより大きな GPU(A100-80GB)を使用し、勾配チェックポイントを有効化
イメージのビルド失敗依存関係のバージョンを固定し、CUDA の互換性を確認
タイムアウトエラーtimeout を増やし、チェックポイントを追加

参考資料

リソース

エージェントの作業手順

  1. 環境を確認します。 ハードウェア、フレームワークとサーバーのバージョン、モデル形式、想定負荷を確認します。
  2. 入力を明確にします。 データまたはユーザーから、形式、識別子、パラメーターを確認します。結果に影響する値は推測せず、質問します。
  3. まず小規模に実行します。 スケールアップする前に、単一のリクエストを処理またはログに記録するか、エンドツーエンドで実行します。
  4. 上記の手順と参考情報に従って、タスク全体を実行します。
  5. 結果を検証します。 レイテンシ、スループット、出力の正確性を参照値と照らし合わせて測定し、リソース使用量とコストを確認します。
  6. 報告します。 実行した内容(バージョン、コマンド、パラメーター)、確認した内容、未確定の点を明記します。
このような場合対応方法
サーバーの起動に失敗するか、OOM が発生するモデルサイズとメモリ、量子化、並列処理の設定を確認します。
これらの手順に記載された関数、フラグ、エンドポイントがインストール済みバージョンに存在しないインストール済みバージョンのドキュメント(help()、--help、公式ドキュメント)を確認して調整し、ユーザーに伝えます。API を捏造してはいけません。
必須の入力、識別子、パラメーターが曖昧であるユーザーに質問するか、実行前に仮定を明示します。

誠実性に関するルール

  • 結果、パラメーター、識別子、引用、統計を捏造してはいけません。実行または検証できないことは、明確にその旨を伝えます。
  • サービスや認証情報を公開してはいけません。プロビジョニングする前にクラウドのコストを確認します。
  • ここに記載されたバージョン固有の詳細は古くなっている可能性があるため、インストール済みバージョンの公式ドキュメントで確認します。
  • 費用が発生する、共有 GPU またはクラウドのクォータを消費する、個人データや患者データを扱う、または取り消せない操作を行う前に、ユーザーに確認します。

関連スキル

  • modal: Modal は、オンデマンド GPU を含む、オンデマンドで Python を実行するためのサーバーレスクラウドプラットフォームです。
  • skypilot-multi-cloud-orchestration: コストを自動最適化する、ML ワークロード向けのマルチクラウドオーケストレーションです。
  • lambda-labs-gpu-cloud: ML のトレーニングと推論向けの、予約制およびオンデマンドの GPU クラウドインスタンスです。

コメント