modal-compute-knowledge について
modal-compute-knowledgeは、Modalを利用するユーザー向けのリファレンスガイドです。Pythonのサーバーレス計算基盤におけるGPU関数、コンテナ、ストレージ、スケジュール、並列処理、CLI、料金を扱います。
主な機能
- 01Python関数とコンテナの設定
- 02GPUとイメージ構築設定の参照
- 03ボリューム・シークレット・分散ストレージの管理
- 04Webエンドポイントと定期実行の設定
- 05並列処理とCLIコマンドの利用
- 06料金とデプロイ手順の確認
活用シーン
- 01GPUアクセラレーション推論のデプロイ
- 02Web APIや定期実行ジョブの作成
- 03データのバッチ並列処理
- 04アプリのデプロイ・ストレージ・シークレットの管理
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill modal-compute-knowledgeインストール後、Claude Code で/modal-compute-knowledgeを入力して読み込まれたか確認します。
同梱ファイルreferences/batched-dynamic-batching.mdreferences/scaling-autoscaler.md
詳細
Modal のナレッジスキル
Modal.com プラットフォームのすべての機能、料金、ベストプラクティスを網羅しています。Modal のサーバーレスクラウドプラットフォームに関する詳細な情報が必要なユーザーに対して、このスキルを有効にします。
有効化のトリガー
ユーザーが次の内容について質問した場合、このスキルを有効にします。
- Modal.com プラットフォームの機能と性能
- GPU で高速化された Python 関数
- サーバーレスコンテナの構成
- Modal の料金と請求
- Modal CLI コマンド
- Modal 上の Web エンドポイントと API
- Modal 上のスケジュール済みジョブ/cron ジョブ
- Modal のボリューム、シークレット、ストレージ
- Modal による並列処理
- Modal のデプロイと CI/CD
プラットフォームの概要
Modal は、次の特徴を備えた、Python コードの実行に特化したサーバーレスクラウドプラットフォームです。AI/ML ワークロードに最適化されています。
- 構成不要:すべて Python コードで定義します
- GPU の高速起動:コンテナの起動は約 1 秒です
- 自動スケーリング:ゼロから数千までスケールします
- 秒単位の課金:アクティブなコンピューティングに対してのみ課金されます
- マルチクラウド:AWS、GCP、Oracle Cloud Infrastructure
コアコンポーネントのリファレンス
アプリと関数
import modal
app = modal.App("app-name")
@app.function()
def basic_function(arg: str) -> str:
return f"Result: {arg}"
@app.local_entrypoint()
def main():
result = basic_function.remote("test")
print(result)
関数デコレーターのパラメーター
| パラメーター | 型 | 説明 |
|---|---|---|
image | Image | コンテナイメージの構成 |
gpu | str/list | GPU の種類:「T4」、「A100」、「H100」、「A100」など |
cpu | float | CPU コア数(0.125 ~ 64) |
memory | int | メモリ(MB、128 ~ 262144) |
timeout | int | 実行時間の上限(秒) |
retries | int | 失敗時の再試行回数 |
secrets | list | 注入するシークレット |
volumes | dict | ボリュームのマウントポイント |
schedule | Cron/Period | スケジュール実行 |
concurrency_limit | int | 同時実行数の上限 |
container_idle_timeout | int | コンテナをウォーム状態に保つ秒数 |
include_source | bool | ソースコードを自動同期 |
GPU リファレンス
利用可能な GPU
| GPU | メモリ | 用途 | 時間あたりの概算コスト |
|---|---|---|---|
| T4 | 16 GB | 小規模な推論 | $0.59 |
| L4 | 24 GB | 中規模の推論 | $0.80 |
| A10G | 24 GB | 推論/ファインチューニング | $1.10 |
| L40S | 48 GB | 高負荷の推論 | $1.50 |
| A100-40GB | 40 GB | トレーニング | $2.00 |
| A100-80GB | 80 GB | 大規模モデル | $3.00 |
| H100 | 80 GB | 最先端 | $5.00 |
| H200 | 141 GB | 最大規模のモデル | $5.00 |
| B200 | 180+ GB | 最新世代 | $6.25 |
GPU の構成
# Single GPU
@app.function(gpu="A100")
# Specific memory variant
@app.function(gpu="A100-80GB")
# Multi-GPU
@app.function(gpu="H100:4")
# Fallbacks (tries in order)
@app.function(gpu=["H100", "A100", "any"])
# "any" = L4, A10G, or T4
@app.function(gpu="any")
イメージのビルド
ベースイメージ
# Debian slim (recommended)
modal.Image.debian_slim(python_version="3.11")
# From Dockerfile
modal.Image.from_dockerfile("./Dockerfile")
# From Docker registry
modal.Image.from_registry("nvidia/cuda:12.1.0-base-ubuntu22.04")
パッケージのインストール
# pip (standard)
image.pip_install("torch", "transformers")
# uv (FASTER - 10-100x)
image.uv_pip_install("torch", "transformers")
# System packages
image.apt_install("ffmpeg", "libsm6")
# Shell commands
image.run_commands("apt-get update", "make install")
ファイルの追加
# Single file
image.add_local_file("./config.json", "/app/config.json")
# Directory
image.add_local_dir("./models", "/app/models")
# Python source
image.add_local_python_source("my_module")
# Environment variables
image.env({"VAR": "value"})
ビルド時関数
def download_model():
from huggingface_hub import snapshot_download
snapshot_download("model-name")
image.run_function(download_model, secrets=[...])
ストレージ
ボリューム
# Create/reference volume
vol = modal.Volume.from_name("my-vol", create_if_missing=True)
# Mount in function
@app.function(volumes={"/data": vol})
def func():
# Read/write to /data
vol.commit() # Persist changes
シークレット
# From dashboard (recommended)
modal.Secret.from_name("secret-name")
# From dictionary
modal.Secret.from_dict({"KEY": "value"})
# From local env
modal.Secret.from_local_environ(["KEY1", "KEY2"])
# From .env file
modal.Secret.from_dotenv()
# Usage
@app.function(secrets=[modal.Secret.from_name("api-keys")])
def func():
import os
key = os.environ["API_KEY"]
Dict と Queue
# Distributed dict
d = modal.Dict.from_name("cache", create_if_missing=True)
d["key"] = "value"
d.put("key", "value", ttl=3600)
# Distributed queue
q = modal.Queue.from_name("jobs", create_if_missing=True)
q.put("task")
item = q.get()
Web エンドポイント
FastAPI エンドポイント(シンプル)
@app.function()
@modal.fastapi_endpoint()
def hello(name: str = "World"):
return {"message": f"Hello, {name}!"}
ASGI アプリ(完全な FastAPI)
from fastapi import FastAPI
web_app = FastAPI()
@web_app.post("/predict")
def predict(text: str):
return {"result": process(text)}
@app.function()
@modal.asgi_app()
def fastapi_app():
return web_app
WSGI アプリ(Flask)
from flask import Flask
flask_app = Flask(__name__)
@app.function()
@modal.wsgi_app()
def flask_endpoint():
return flask_app
カスタム Web サーバー
@app.function()
@modal.web_server(port=8000)
def custom_server():
subprocess.run(["python", "-m", "http.server", "8000"])
カスタムドメイン
@modal.asgi_app(custom_domains=["api.example.com"])
スケジュール設定
Cron
# Daily at 8 AM UTC
@app.function(schedule=modal.Cron("0 8 * * *"))
# With timezone
@app.function(schedule=modal.Cron("0 6 * * *", timezone="America/New_York"))
Period
@app.function(schedule=modal.Period(hours=5))
@app.function(schedule=modal.Period(days=1))
注: スケジュール済み関数は modal run ではなく、modal deploy でのみ実行されます。
並列処理
Map
# Parallel execution (up to 1000 concurrent)
results = list(func.map(items))
# Unordered (faster)
results = list(func.map(items, order_outputs=False))
Starmap
# Spread args
pairs = [(1, 2), (3, 4)]
results = list(add.starmap(pairs))
Spawn
# Async job (returns immediately)
call = func.spawn(data)
result = call.get() # Get result later
# Spawn many
calls = [func.spawn(item) for item in items]
results = [call.get() for call in calls]
コンテナのライフサイクル(クラス)
@app.cls(gpu="A100", container_idle_timeout=300)
class Server:
@modal.enter()
def load(self):
self.model = load_model()
@modal.method()
def predict(self, text):
return self.model(text)
@modal.exit()
def cleanup(self):
del self.model
同時実行
@modal.concurrent(max_inputs=100, target_inputs=80)
@modal.method()
def batched(self, item):
pass
CLI コマンド
開発
modal run app.py # Run function
modal serve app.py # Hot-reload dev server
modal shell app.py # Interactive shell
modal shell app.py --gpu A100 # Shell with GPU
デプロイ
modal deploy app.py # Deploy
modal app list # List apps
modal app logs app-name # View logs
modal app stop app-name # Stop app
リソース
# Volumes
modal volume create name
modal volume list
modal volume put name local remote
modal volume get name remote local
# Secrets
modal secret create name KEY=value
modal secret list
# Environments
modal environment create staging
料金(2025 年)
プラン
| プラン | 料金 | コンテナ数 | GPU 同時実行数 |
|---|---|---|---|
| Starter | 無料($30 分のクレジット) | 100 | 10 |
| Team | $250/月 | 1000 | 50 |
| Enterprise | カスタム | 無制限 | カスタム |
コンピューティング
- CPU:$0.0000131/コア/秒
- メモリ:$0.00000222/GiB/秒
- GPU:上記の GPU 表を参照してください
特別プログラム
- スタートアップ:最大 $25k 分のクレジット
- 研究者:最大 $10k 分のクレジット
ベストプラクティス
- モデルの読み込みには
@modal.enter()を使用します - ビルドを高速化するには
uv_pip_installを使用します - 可用性を確保するために GPU のフォールバックを使用します
- 適切なタイムアウトと再試行を設定します
- 環境(dev/staging/prod)を使用します
- モデルは実行時ではなく、ビルド時にダウンロードします
- 順序が重要でない場合は
order_outputs=Falseを使用します - コストとレイテンシのバランスを取るために
container_idle_timeoutを設定します - Modal ダッシュボードでコストを監視します
modal deployの前にmodal runでテストします
一般的なパターン
LLM 推論
@app.cls(gpu="A100", container_idle_timeout=300)
class LLM:
@modal.enter()
def load(self):
from vllm import LLM
self.llm = LLM(model="...")
@modal.method()
def generate(self, prompt):
return self.llm.generate([prompt])
バッチ処理
@app.function(volumes={"/data": vol})
def process(file):
# Process file
vol.commit()
# Parallel
results = list(process.map(files))
スケジュールされた ETL
@app.function(
schedule=modal.Cron("0 6 * * *"),
secrets=[modal.Secret.from_name("db")]
)
def daily_etl():
extract()
transform()
load()
クイックリファレンス
| タスク | コード |
|---|---|
| アプリを作成 | app = modal.App("name") |
| 基本的な関数 | @app.function() |
| GPU を使用 | @app.function(gpu="A100") |
| イメージを使用 | @app.function(image=img) |
| Web エンドポイント | @modal.asgi_app() |
| スケジュール設定 | schedule=modal.Cron("...") |
| ボリュームをマウント | volumes={"/path": vol} |
| シークレットを使用 | secrets=[modal.Secret.from_name("x")] |
| 並列マップ | func.map(items) |
| 非同期で起動 | func.spawn(arg) |
| クラスパターン | @app.cls() と @modal.enter() |
コメント
Markdown 対応