关于 modal-serverless-gpu
Modal Serverless GPU 是一份介绍如何在 Modal 无服务器 GPU 云平台运行机器学习任务的指南,涵盖 Python 基础设施定义、GPU 作业、自动扩缩 API 及常见部署模式。
主要功能
- 01按需无服务器 GPU
- 02用 Python 定义基础设施
- 03自动扩缩至零
- 04REST API 端点
- 05模型与数据持久存储
- 06定时任务与并行处理
适用场景
- 01运行 GPU 密集型机器学习任务
- 02部署可自动扩缩的模型 API
- 03批量处理训练或推理任务
- 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 云平台上运行机器学习工作负载的综合指南。
何时使用 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 | 显存 | 最适合 |
|---|---|---|
T4 | 16GB | 低成本推理、小型模型 |
L4 | 24GB | 推理、Ada Lovelace 架构 |
A10G | 24GB | 训练/推理,比 T4 快 3.3 倍 |
L40S | 48GB | 推荐用于推理(最佳性价比) |
A100-40GB | 40GB | 大型模型训练 |
A100-80GB | 80GB | 超大型模型 |
H100 | 80GB | 最快,FP8 + Transformer Engine |
H200 | 141GB | 从 H100 自动升级,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 显存不足 | 使用更大的 GPU(A100-80GB),启用梯度检查点 |
| 镜像构建失败 | 固定依赖版本,检查 CUDA 兼容性 |
| 超时错误 | 增加 timeout,添加检查点 |
参考资料
资源
- 文档:https://modal.com/docs
- 示例:https://github.com/modal-labs/modal-examples
- 定价:https://modal.com/pricing
- Discord:https://discord.gg/modal
Agent 操作流程
- 检查环境。 确认硬件、框架和服务版本、模型格式以及预期负载。
- 明确输入。 从数据或用户处确认格式、标识符和参数。任何会改变结果的值都应询问,而不是猜测。
- 先运行小规模版本。 扩大规模前,先处理或记录单个请求,或端到端运行一次。
- 使用上述说明和参考资料执行完整任务。
- 验证结果。 参照基准测量延迟、吞吐量和输出正确性;检查资源使用情况和成本。
- 汇报。 说明运行了什么(版本、命令、参数)、检查了什么,以及哪些内容仍不确定。
| 如果发生这种情况 | 请这样做 |
|---|---|
| 服务无法启动或发生 OOM | 检查模型大小与内存是否匹配,并检查量化和并行度设置。 |
| 这些说明中的函数、标志或端点在已安装版本中不存在 | 查阅已安装版本自己的文档(help()、--help、官方文档),进行适配并告知用户。切勿编造 API。 |
| 必需的输入、标识符或参数含义不明确 | 询问用户,或在运行前明确说明所作的假设。 |
诚信规则
- 切勿捏造结果、参数、标识符、引用或统计数据。如果无法运行或验证某项内容,请明确说明。
- 不要公开服务或凭据;配置资源前先确认云端费用。
- 请将此处与特定版本相关的细节视为可能已过时,并根据已安装版本的官方文档进行确认。
- 对于会产生费用、占用共享 GPU 或云配额、涉及个人或患者数据,或无法撤销的操作,请先征得同意。
相关技能
modal:Modal 是一个无服务器云平台,可按需运行 Python,包括按需使用 GPU。skypilot-multi-cloud-orchestration:用于 ML 工作负载的多云编排,可自动优化成本。lambda-labs-gpu-cloud:用于 ML 训练和推理的预留和按需 GPU 云实例。
评论
支持 Markdown