mcpField
M
modal

modal

github.com/davila7云与 DevOps33.0k884 次安装1 天前更新
代码仓库

关于 modal

面向 Python 开发者的 Modal 云端运行平台使用指南,介绍如何配置容器化函数、GPU、存储与自动扩缩,并部署 API 或定时任务。

主要功能

  1. 01定义云端 Python 函数
  2. 02配置容器镜像与依赖
  3. 03申请 GPU 和计算资源
  4. 04自动扩缩与并行处理
  5. 05持久化存储和管理密钥
  6. 06部署端点及定时任务

适用场景

  1. 01部署机器学习模型推理
  2. 02并行处理大型数据集
  3. 03运行 GPU 训练任务
  4. 04创建自动扩缩的 API
  5. 05安排周期性计算任务

安装

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

$npx skills add https://github.com/davila7/claude-code-templates --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 代码。在强大的 GPU 上执行函数,自动扩展至数千个容器,并且只为实际使用的算力付费。

Modal 特别适合 AI/ML 工作负载、高性能批处理、定时任务、GPU 推理和无服务器 API。在 https://modal.com 免费注册,即可获得每月 $30 的额度。

何时使用此 Skill

在以下场景使用 Modal:

  • 部署和提供 ML 模型服务(大模型、图像生成、嵌入模型)
  • 运行 GPU 加速计算(训练、推理、渲染)
  • 并行批处理大型数据集
  • 调度计算密集型任务(每日数据处理、模型训练)
  • 构建需要自动扩缩的无服务器 API
  • 需要分布式计算或专用硬件的科学计算

身份验证与设置

Modal 需要通过 API 令牌进行身份验证。

初始设置
# Install Modal
uv uv pip install modal

# Authenticate (opens browser for login)
modal token new

这会创建一个存储在 ~/.modal.toml 中的令牌。该令牌用于验证所有 Modal 操作。

验证设置
import modal

app = modal.App("test-app")

@app.function()
def hello():
    print("Modal is working!")

使用以下命令运行:modal run script.py

核心能力

Modal 通过运行在容器中的 Function 提供无服务器 Python 执行能力。以声明式方式定义算力需求、依赖项和扩缩行为。

1. 定义容器镜像

使用 Modal Image 为函数指定依赖项和运行环境。

import modal

# Basic image with Python packages
image = (
    modal.Image.debian_slim(python_version="3.12")
    .uv_pip_install("torch", "transformers", "numpy")
)

app = modal.App("ml-app", image=image)

常见模式:

  • 安装 Python 包:.uv_pip_install("pandas", "scikit-learn")
  • 安装系统包:.apt_install("ffmpeg", "git")
  • 使用现有 Docker 镜像:modal.Image.from_registry("nvidia/cuda:12.1.0-base")
  • 添加本地代码:.add_local_python_source("my_module")

有关镜像构建的完整文档,请参见 references/images.md。

2. 创建函数

使用 @app.function() 装饰器定义在云端运行的函数。

@app.function()
def process_data(file_path: str):
    import pandas as pd
    df = pd.read_csv(file_path)
    return df.describe()

调用函数:

# From local entrypoint
@app.local_entrypoint()
def main():
    result = process_data.remote("data.csv")
    print(result)

使用以下命令运行:modal run script.py

有关函数模式、部署和参数处理,请参见 references/functions.md。

3. 请求 GPU

将 GPU 挂载到函数上以加速计算。

@app.function(gpu="H100")
def train_model():
    import torch
    assert torch.cuda.is_available()
    # GPU-accelerated code here

可用 GPU 类型:

  • T4、L4 - 高性价比推理
  • A10、A100、A100-80GB - 标准训练/推理
  • L40S - 出色的性价比平衡(48GB)
  • H100、H200 - 高性能训练
  • B200 - 旗舰性能(最强大)

请求多个 GPU:

@app.function(gpu="H100:8")  # 8x H100 GPUs
def train_large_model():
    pass

有关 GPU 选择指南、CUDA 设置和多 GPU 配置,请参见 references/gpu.md。

4. 配置资源

为函数请求 CPU 核心、内存和磁盘。

@app.function(
    cpu=8.0,           # 8 physical cores
    memory=32768,      # 32 GiB RAM
    ephemeral_disk=10240  # 10 GiB disk
)
def memory_intensive_task():
    pass

默认分配:0.125 个 CPU 核心,128 MiB 内存。按预留量或实际用量中较高者计费。

有关资源限制和计费详情,请参见 references/resources.md。

5. 自动扩缩

Modal 会根据需求将函数从零自动扩展至数千个容器。

并行处理输入:

@app.function()
def analyze_sample(sample_id: int):
    # Process single sample
    return result

@app.local_entrypoint()
def main():
    sample_ids = range(1000)
    # Automatically parallelized across containers
    results = list(analyze_sample.map(sample_ids))

配置自动扩缩:

@app.function(
    max_containers=100,      # Upper limit
    min_containers=2,        # Keep warm
    buffer_containers=5      # Idle buffer for bursts
)
def inference():
    pass

有关自动扩缩配置、并发和扩缩限制,请参见 references/scaling.md。

6. 持久化存储数据

使用 Volume 在多次函数调用之间实现持久化存储。

volume = modal.Volume.from_name("my-data", create_if_missing=True)

@app.function(volumes={"/data": volume})
def save_results(data):
    with open("/data/results.txt", "w") as f:
        f.write(data)
    volume.commit()  # Persist changes

Volume 可在多次运行之间持久保存数据、存储模型权重、缓存数据集,并在函数之间共享数据。

有关 Volume 管理、提交和缓存模式,请参见 references/volumes.md。

7. 管理密钥

使用 Modal Secret 安全地存储 API 密钥和凭据。

@app.function(secrets=[modal.Secret.from_name("huggingface")])
def download_model():
    import os
    token = os.environ["HF_TOKEN"]
    # Use token for authentication

在 Modal 控制面板中或通过命令行创建密钥:

modal secret create my-secret KEY=value API_TOKEN=xyz

有关密钥管理和身份验证模式,请参见 references/secrets.md。

8. 部署 Web 端点

使用 @modal.web_endpoint() 提供 HTTP 端点、API 和 webhook。

@app.function()
@modal.web_endpoint(method="POST")
def predict(data: dict):
    # Process request
    result = model.predict(data["input"])
    return {"prediction": result}

使用以下命令部署:

modal deploy script.py

Modal 会为该端点提供 HTTPS URL。

有关 FastAPI 集成、流式传输、身份验证和 WebSocket 支持,请参见 references/web-endpoints.md。

9. 调度任务

使用 cron 表达式按计划运行函数。

@app.function(schedule=modal.Cron("0 2 * * *"))  # Daily at 2 AM
def daily_backup():
    # Backup data
    pass

@app.function(schedule=modal.Period(hours=4))  # Every 4 hours
def refresh_cache():
    # Update cache
    pass

已调度的函数会自动运行,无需手动调用。

有关 cron 语法、时区配置和监控,请参阅 references/scheduled-jobs.md。

常见工作流

部署 ML 模型用于推理
import modal

# Define dependencies
image = modal.Image.debian_slim().uv_pip_install("torch", "transformers")
app = modal.App("llm-inference", image=image)

# Download model at build time
@app.function()
def download_model():
    from transformers import AutoModel
    AutoModel.from_pretrained("bert-base-uncased")

# Serve model
@app.cls(gpu="L40S")
class Model:
    @modal.enter()
    def load_model(self):
        from transformers import pipeline
        self.pipe = pipeline("text-classification", device="cuda")

    @modal.method()
    def predict(self, text: str):
        return self.pipe(text)

@app.local_entrypoint()
def main():
    model = Model()
    result = model.predict.remote("Modal is great!")
    print(result)
批量处理大型数据集
@app.function(cpu=2.0, memory=4096)
def process_file(file_path: str):
    import pandas as pd
    df = pd.read_csv(file_path)
    # Process data
    return df.shape[0]

@app.local_entrypoint()
def main():
    files = ["file1.csv", "file2.csv", ...]  # 1000s of files
    # Automatically parallelized across containers
    for count in process_file.map(files):
        print(f"Processed {count} rows")
在 GPU 上训练模型
@app.function(
    gpu="A100:2",      # 2x A100 GPUs
    timeout=3600       # 1 hour timeout
)
def train_model(config: dict):
    import torch
    # Multi-GPU training code
    model = create_model(config)
    train(model)
    return metrics

参考文档

特定功能的详细文档:

  • references/getting-started.md - 身份验证、设置、基本概念
  • references/images.md - 镜像构建、依赖项、Dockerfile
  • references/functions.md - 函数模式、部署、参数
  • references/gpu.md - GPU 类型、CUDA、多 GPU 配置
  • references/resources.md - CPU、内存、磁盘管理
  • references/scaling.md - 自动扩缩容、并行执行、并发
  • references/volumes.md - 持久化存储、数据管理
  • references/secrets.md - 环境变量、身份验证
  • references/web-endpoints.md - API、webhook、端点
  • references/scheduled-jobs.md - Cron 任务、周期性任务
  • references/examples.md - 科学计算的常见模式

最佳实践

  1. 在 .uv_pip_install() 中固定依赖版本,以实现可复现的构建
  2. 使用合适的 GPU 类型 - 推理用 L40S,训练用 H100/A100
  3. 利用缓存 - 使用 Volume 存储模型权重和数据集
  4. 配置自动扩缩容 - 根据工作负载设置 max_containers 和 min_containers
  5. 在函数体内导入包(如果本地不可用)
  6. 使用 .map() 进行并行处理,而不是顺序循环
  7. 安全存储密钥 - 切勿硬编码 API 密钥
  8. 监控成本 - 查看 Modal 仪表板中的使用情况和账单

故障排查

"Module not found" 错误:

  • 使用 .uv_pip_install("package-name") 将包添加到镜像
  • 如果本地不可用,在函数体内导入包

未检测到 GPU:

  • 验证 GPU 规格:@app.function(gpu="A100")
  • 检查 CUDA 是否可用:torch.cuda.is_available()

函数超时:

  • 增加超时时间:@app.function(timeout=3600)
  • 默认超时时间为 5 分钟

Volume 更改未持久化:

  • 写入文件后调用 volume.commit()
  • 验证在函数装饰器中正确挂载了 volume

如需更多帮助,请参阅 Modal 文档 https://modal.com/docs 或加入 Modal Slack 社区。

评论

支持 Markdown