modal について
modalは、Modalを使ってクラウド上でPythonワークロードを実行するためのスキルです。AI/ML向けのGPU関数、ストレージ、エンドポイント、スケジュール実行、スケーリングをPythonで定義する方法を扱います。
主な機能
- 01サーバーレスPython関数の実行
- 02オンデマンドGPU計算
- 03Pythonによるコンテナイメージ定義
- 04永続ボリュームとシークレット
- 05Webエンドポイントとスケジュール実行
- 06自動スケーリングと並列実行
活用シーン
- 01AI/MLの推論や学習のデプロイ
- 02バッチ処理の並列実行
- 03APIやモデルエンドポイントの提供
- 04定期データパイプラインの実行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ crazymsn/ academic-skills --skill modalインストール後、Claude Code で/modalを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/api_reference.mdexamples.mdfunctions.mdgetting-started.mdgpu.mdimages.mdresources.mdscaling.mdscheduled-jobs.mdsecrets.mdvolumes.mdweb-endpoints.md詳細
Modal
概要
Modal は、AI/ML ワークロードに重点を置いた、Python コードをサーバーレスで実行するためのクラウドプラットフォームです。主な機能は以下のとおりです。
- オンデマンドの GPU コンピューティング(T4、L4、A10、L40S、A100、H100、H200、B200)
- サーバーレス関数。コンテナをゼロから数千個まで自動スケーリングします
- カスタムコンテナイメージ。すべて Python コードで構築します
- モデルの重みやデータセット向けの Volumes による永続ストレージ
- モデルや API を提供するための ウェブエンドポイント
- cron または固定間隔による スケジュール済みジョブ
- 低レイテンシー推論を実現する 1 秒未満のコールドスタート
Modal ではすべてをコードで定義するため、YAML や Dockerfile は不要です(どちらもサポートされています)。
このスキルを使用する場面
以下の場合にこのスキルを使用します。
- クラウドで AI/ML モデルをデプロイまたは提供する
- GPU アクセラレーションによる計算(トレーニング、推論、ファインチューニング)を実行する
- サーバーレスのウェブ API やエンドポイントを作成する
- バッチ処理ジョブを並列にスケーリングする
- 定期的なタスク(データパイプライン、再トレーニング、スクレイピング)をスケジュールする
- モデルの重みやデータセット用の永続的なクラウドストレージが必要
- カスタムコンテナ環境でコードを実行したい
- ジョブキューや非同期タスク処理システムを構築する
インストールと認証
インストール
uv pip install modal
認証
新しい認証情報を作成する前に、既存の認証情報を優先してください。
- 現在の環境に
MODAL_TOKEN_IDとMODAL_TOKEN_SECRETがすでに存在するか確認します。 - 存在しない場合は、ローカルの
.envファイルにそれらの値があるか確認し、ワークフローに適切であれば読み込みます。 - どちらの場所にも認証情報がない場合に限り、対話形式の
modal setupを実行するか、新しいトークンを生成します。
modal setup
ブラウザーが開き、認証が行われます。CI/CD やヘッドレス環境では、環境変数を使用してください。
export MODAL_TOKEN_ID=<your-token-id>
export MODAL_TOKEN_SECRET=<your-token-secret>
トークンが環境または .env にまだない場合は、https://modal.com/settings で生成してください。
Modal では、月額 30 ドル分のクレジットが付与される無料プランを利用できます。
参考:詳細なセットアップと初めてのアプリの手順については、references/getting-started.md を参照してください。
主な概念
アプリと関数
Modal の App は、関連する関数をまとめます。@app.function() でデコレートされた関数は、クラウド上でリモート実行されます。
import modal
app = modal.App("my-app")
@app.function()
def square(x):
return x ** 2
@app.local_entrypoint()
def main():
# .remote() runs in the cloud
print(square.remote(42))
modal run script.py で実行します。modal deploy script.py でデプロイします。
参考:ライフサイクルフック、クラス、.map()、.spawn() などについては、references/functions.md を参照してください。
コンテナイメージ
Modal は Python コードからコンテナイメージを構築します。推奨されるパッケージインストーラーは uv です。
image = (
modal.Image.debian_slim(python_version="3.11")
.uv_pip_install("torch==2.8.0", "transformers", "accelerate")
.apt_install("git")
)
@app.function(image=image)
def inference(prompt):
from transformers import pipeline
pipe = pipeline("text-generation", model="meta-llama/Llama-3-8B")
return pipe(prompt)
主なイメージメソッド:
.uv_pip_install()— uv を使用して Python パッケージをインストールします(推奨).pip_install()— pip を使用してインストールします(代替手段).apt_install()— システムパッケージをインストールします.run_commands()— ビルド中にシェルコマンドを実行します.run_function()— ビルド中に Python を実行します(例:モデルの重みをダウンロード).add_local_python_source()— ローカルモジュールを追加します.env()— 環境変数を設定します
参考:Dockerfile、micromamba、キャッシュ、GPU ビルド手順については、references/images.md を参照してください。
GPU コンピューティング
gpu パラメーターで GPU を指定します。
@app.function(gpu="H100")
def train_model():
import torch
device = torch.device("cuda")
# GPU training code here
# Multiple GPUs
@app.function(gpu="H100:4")
def distributed_training():
...
# GPU fallback chain
@app.function(gpu=["H100", "A100-80GB", "A100-40GB"])
def flexible_inference():
...
利用可能な GPU:T4、L4、A10、L40S、A100-40GB、A100-80GB、H100、H200、B200、B200+
- 1 コンテナあたり最大 8 GPU(A10 は最大 4 GPU)
- 推論には L40S を推奨します(コストと性能のバランスに優れ、VRAM は 48 GB)
- H100/A100 は追加料金なしで H200/A100-80GB に自動アップグレードできます
- 自動アップグレードを無効にするには、
gpu="H100!"を使用します
参考:GPU の選択方法とマルチ GPU トレーニングについては、references/gpu.md を参照してください。
Volumes(永続ストレージ)
Volumes は、分散型の永続ファイルストレージを提供します。
vol = modal.Volume.from_name("model-weights", create_if_missing=True)
@app.function(volumes={"/data": vol})
def save_model():
# Write to the mounted path
with open("/data/model.pt", "wb") as f:
torch.save(model.state_dict(), f)
@app.function(volumes={"/data": vol})
def load_model():
model.load_state_dict(torch.load("/data/model.pt"))
- 一度書き込み、何度も読み取るワークロード(モデルの重み、データセット)向けに最適化されています
- CLI からの操作:
modal volume ls、modal volume put、modal volume get - 数秒ごとにバックグラウンドで自動コミットされます
参考:v2 volumes、並行書き込み、ベストプラクティスについては、references/volumes.md を参照してください。
シークレット
認証情報を関数に安全に渡します。
@app.function(secrets=[modal.Secret.from_name("my-api-keys")])
def call_api():
import os
api_key = os.environ["API_KEY"]
# Use the key
CLI でシークレットを作成します:modal secret create my-api-keys API_KEY=sk-xxx
または .env ファイルから作成します:modal.Secret.from_dotenv()
リファレンス:ダッシュボードの設定、複数のシークレット、テンプレートについては references/secrets.md を参照してください。
Web エンドポイント
モデルや API を Web エンドポイントとして提供します。
@app.function()
@modal.fastapi_endpoint()
def predict(text: str):
return {"result": model.predict(text)}
modal serve script.py— ホットリロードと一時 URL を使った開発modal deploy script.py— 固定 URL を使った本番環境へのデプロイ- FastAPI、ASGI(Starlette、FastHTML)、WSGI(Flask、Django)、WebSocket に対応しています
- リクエストボディは最大 4 GiB、レスポンスサイズは無制限です
リファレンス:ASGI/WSGI アプリ、ストリーミング、認証、WebSocket については references/web-endpoints.md を参照してください。
スケジュール済みジョブ
関数をスケジュールに従って実行します。
@app.function(schedule=modal.Cron("0 9 * * *")) # Daily at 9 AM UTC
def daily_pipeline():
# ETL, retraining, scraping, etc.
...
@app.function(schedule=modal.Period(hours=6))
def periodic_check():
...
スケジュールを有効にするには、modal deploy script.py でデプロイします。
modal.Cron("...")— 標準の cron 構文で、デプロイ後も安定して動作しますmodal.Period(hours=N)— 固定間隔で、再デプロイ時にリセットされます- 実行状況は Modal ダッシュボードで監視できます
リファレンス:cron 構文と管理については references/scheduled-jobs.md を参照してください。
スケーリングと並行処理
Modal はコンテナを自動的にスケールします。上限を設定できます。
@app.function(
max_containers=100, # Upper limit
min_containers=2, # Keep warm for low latency
buffer_containers=5, # Reserve capacity
scaledown_window=300, # Idle seconds before shutdown
)
def process(data):
...
.map() を使って入力を並列処理します。
results = list(process.map([item1, item2, item3, ...]))
コンテナごとの同時リクエスト処理を有効にします。
@app.function()
@modal.concurrent(max_inputs=10)
async def handle_request(req):
...
リファレンス:.map()、.starmap()、.spawn()、上限については references/scaling.md を参照してください。
リソースの設定
@app.function(
cpu=4.0, # Physical cores (not vCPUs)
memory=16384, # MiB
ephemeral_disk=51200, # MiB (up to 3 TiB)
timeout=3600, # Seconds
)
def heavy_computation():
...
デフォルト:CPU コア 0.125 個、メモリ 128 MiB。課金額は、リクエストされた量と使用量のうち大きい方に基づきます。
リファレンス:上限と課金の詳細については references/resources.md を参照してください。
ライフサイクルフック付きクラス
状態を保持するワークロード(例:モデルを一度読み込み、多数のリクエストに応答する)の場合:
@app.cls(gpu="L40S", image=image)
class Predictor:
@modal.enter()
def load_model(self):
self.model = load_heavy_model() # Runs once on container start
@modal.method()
def predict(self, text: str):
return self.model(text)
@modal.exit()
def cleanup(self):
... # Runs on container shutdown
次のように呼び出します:Predictor().predict.remote("hello")
よくあるワークフローパターン
GPU モデル推論サービス
import modal
app = modal.App("llm-service")
image = (
modal.Image.debian_slim(python_version="3.11")
.uv_pip_install("vllm")
)
@app.cls(gpu="H100", image=image, min_containers=1)
class LLMService:
@modal.enter()
def load(self):
from vllm import LLM
self.llm = LLM(model="meta-llama/Llama-3-70B")
@modal.method()
@modal.fastapi_endpoint(method="POST")
def generate(self, prompt: str, max_tokens: int = 256):
outputs = self.llm.generate([prompt], max_tokens=max_tokens)
return {"text": outputs[0].outputs[0].text}
バッチ処理パイプライン
app = modal.App("batch-pipeline")
vol = modal.Volume.from_name("pipeline-data", create_if_missing=True)
@app.function(volumes={"/data": vol}, cpu=4.0, memory=8192)
def process_chunk(chunk_id: int):
import pandas as pd
df = pd.read_parquet(f"/data/input/chunk_{chunk_id}.parquet")
result = heavy_transform(df)
result.to_parquet(f"/data/output/chunk_{chunk_id}.parquet")
return len(result)
@app.local_entrypoint()
def main():
chunk_ids = list(range(100))
results = list(process_chunk.map(chunk_ids))
print(f"Processed {sum(results)} total rows")
スケジュール済みデータパイプライン
app = modal.App("etl-pipeline")
@app.function(
schedule=modal.Cron("0 */6 * * *"), # Every 6 hours
secrets=[modal.Secret.from_name("db-credentials")],
)
def etl_job():
import os
db_url = os.environ["DATABASE_URL"]
# Extract, transform, load
...
CLI リファレンス
| コマンド | 説明 |
|---|---|
modal setup | Modal で認証します |
modal run script.py | スクリプトのローカルエントリーポイントを実行します |
modal serve script.py | ホットリロード対応の開発サーバーを起動します |
modal deploy script.py | 本番環境にデプロイします |
modal volume ls <name> | ボリューム内のファイルを一覧表示します |
modal volume put <name> <file> | ファイルをボリュームにアップロードします |
modal volume get <name> <file> | ボリュームからファイルをダウンロードします |
modal secret create <name> K=V | シークレットを作成します |
modal secret list | シークレットを一覧表示します |
modal app list | デプロイ済みのアプリを一覧表示します |
modal app stop <name> | デプロイ済みのアプリを停止します |
リファレンスファイル
各トピックの詳細なドキュメント:
references/getting-started.md— インストール、認証、最初のアプリreferences/functions.md— 関数、クラス、ライフサイクルフック、リモート実行references/images.md— コンテナイメージ、パッケージのインストール、キャッシュreferences/gpu.md— GPU の種類、選択、マルチ GPU、トレーニングreferences/volumes.md— 永続ストレージ、ファイル管理、v2 ボリュームreferences/secrets.md— 認証情報、環境変数、dotenvreferences/web-endpoints.md— FastAPI、ASGI/WSGI、ストリーミング、認証、WebSocketreferences/scheduled-jobs.md— cron、定期スケジュール、管理references/scaling.md— オートスケーリング、並行処理、.map()、上限references/resources.md— CPU、メモリ、ディスク、タイムアウトの設定references/examples.md— よくあるユースケースとパターンreferences/api_reference.md— 主要な API クラスとメソッド
この概要を超える詳細情報が必要な場合は、これらのファイルを参照してください。