跳到主要內容

Modal Serverless Gpu

用於運行機器學習工作負載的無服務器 GPU 雲平臺。當您需要無需管理基礎設施的按需 GPU 訪問權限、將機器學習模型部署為 API,或運行具有自動伸縮功能的批處理作業時使用。

技能元數據

來源可選 — 使用 hermes skills install official/mlops/modal 安裝
路徑optional-skills/mlops/modal
版本1.0.0
作者Orchestra Research
許可證MIT
依賴項modal>=0.64.0
標籤Infrastructure, Serverless, GPU, Cloud, Deployment, Modal

參考:完整 SKILL.md

信息

以下是 Hermes 在觸發此技能時加載的完整技能定義。這是技能激活時代理看到的指令。

Modal Serverless GPU

在 Modal 的無服務器 GPU 雲平臺上運行機器學習工作負載的綜合指南。

何時使用 Modal

在以下情況使用 Modal:

  • 運行 GPU 密集型機器學習工作負載而無需管理基礎設施
  • 將機器學習模型部署為自動伸縮的 API
  • 運行批處理作業(訓練、推理、數據處理)
  • 需要按秒計費的 GPU 定價且無空閒成本
  • 快速原型化機器學習應用程序
  • 運行定時任務(類似 cron 的工作負載)

主要特性:

  • 無服務器 GPU:按需提供 T4、L4、A10G、L40S、A100、H100、H200、B200
  • Python 原生:在 Python 代碼中定義基礎設施,無需 YAML
  • 自動伸縮:縮容至零,瞬間擴容至 100+ GPU
  • 亞秒級冷啟動:基於 Rust 的基礎設施,實現快速容器啟動
  • 容器緩存:緩存鏡像層以加速迭代
  • Web 端點:將函數部署為 REST API,支持零停機更新

改用其他替代方案:

  • RunPod:適用於需要持久狀態的長時間運行 Pod
  • 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

GPU顯存最佳適用場景
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,添加檢查點機制

參考資料

資源