mcpField
M
modal

modal

github.com/crazymsn云与 DevOps2335 次安装22 周前更新
代码仓库

关于 modal

modal 是一项指导如何使用 Modal 在云端运行 Python 工作负载的技能,适用于 AI/ML 任务。内容涵盖 GPU 函数、存储、端点、定时任务和扩缩容,并通过 Python 定义应用。

主要功能

  1. 01运行无服务器 Python 函数
  2. 02按需使用 GPU 计算
  3. 03用 Python 定义容器镜像
  4. 04持久化卷与密钥
  5. 05Web 端点和定时任务
  6. 06自动扩缩容与并行执行

适用场景

  1. 01部署 AI/ML 推理或训练
  2. 02并行运行批处理
  3. 03提供 API 或模型端点
  4. 04安排定期数据管道

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/crazymsn/academic-skills --skill modal

安装后在 Claude Code 中输入/modal确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
api_reference.md
examples.md
functions.md
getting-started.md
gpu.md
images.md
resources.md
scaling.md
scheduled-jobs.md
secrets.md
volumes.md
web-endpoints.md

详细介绍

Modal

概述

Modal 是一个用于无服务器运行 Python 代码的云平台,专注于 AI/ML 工作负载。主要功能:

  • 按需 GPU 计算(T4、L4、A10、L40S、A100、H100、H200、B200)
  • 无服务器函数,可自动扩缩容,从零扩展到数千个容器
  • 自定义容器映像,完全通过 Python 代码构建
  • 通过 Volumes 实现持久化存储,用于存放模型权重和数据集
  • 用于提供模型和 API 服务的Web 端点
  • 通过 cron 或固定间隔运行定时任务
  • 亚秒级冷启动,实现低延迟推理

Modal 中的一切都通过代码定义——无需 YAML 或 Dockerfiles(但两者都受支持)。

何时使用此技能

在以下情况下使用此技能:

  • 在云端部署或提供 AI/ML 模型服务
  • 运行 GPU 加速计算(训练、推理、微调)
  • 创建无服务器 Web API 或端点
  • 并行扩展批处理任务
  • 安排定期任务(数据管道、重新训练、抓取)
  • 需要用于模型权重或数据集的持久云存储
  • 想要在自定义容器环境中运行代码
  • 构建作业队列或异步任务处理系统

安装和身份验证

安装
uv pip install modal
身份验证

创建新凭据前,优先使用现有凭据:

  1. 检查当前环境中是否已存在 MODAL_TOKEN_ID 和 MODAL_TOKEN_SECRET。
  2. 如果不存在,请检查本地 .env 文件中是否包含这些值,并在适合当前工作流时加载。
  3. 只有在这两个来源都没有提供凭据时,才使用交互式 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() — 在构建期间运行 shell 命令
  • .run_function() — 在构建期间运行 Python(例如,下载模型权重)
  • .add_local_python_source() — 添加本地模块
  • .env() — 设置环境变量

参考:Dockerfiles、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+

  • 每个容器最多可使用 8 个 GPU(A10 除外:最多 4 个)
  • 推荐将 L40S 用于推理(成本与性能均衡,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)和 WebSockets
  • 请求正文最大支持 4 GiB,响应大小不受限制

参考:请参阅 references/web-endpoints.md,了解 ASGI/WSGI 应用、流式传输、身份验证和 WebSockets。

定时作业

按计划运行函数:

@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 仪表板中监控运行情况

参考:请参阅 references/scheduled-jobs.md,了解 cron 语法和管理方式。

扩缩容与并发

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):
    ...

参考:请参阅 references/scaling.md,了解 .map()、.starmap()、.spawn() 和相关限制。

资源配置
@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():
    ...

默认值:0.125 个 CPU 核心、128 MiB 内存。按 max(request, usage) 计费。

参考:请参阅 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 — 凭据、环境变量、dotenv
  • references/web-endpoints.md — FastAPI、ASGI/WSGI、流式传输、身份验证、WebSockets
  • references/scheduled-jobs.md — Cron、周期计划、管理方式
  • references/scaling.md — 自动扩缩容、并发、.map()、限制
  • references/resources.md — CPU、内存、磁盘、超时配置
  • references/examples.md — 常见用例和模式
  • references/api_reference.md — 主要 API 类和方法

需要了解本概览之外的详细信息时,请阅读这些文件。

评论

支持 Markdown