mcpField
M
modal-knowledge

modal-knowledge

github.com/josiahsiegel云与 DevOps5986 次安装19 周前更新
代码仓库

关于 modal-knowledge

modal-knowledge 是面向需要了解 Modal 无服务器云平台的用户的技能,涵盖 Python 函数、GPU、部署、存储和计费等主题。它以精简操作指南与详细参考文档组织平台知识。

主要功能

  1. 01平台功能与配置参考
  2. 02GPU 函数配置
  3. 03容器镜像与依赖管理
  4. 04存储、密钥与队列
  5. 05Web 端点和定时任务
  6. 06并行处理与 CLI 命令

适用场景

  1. 01配置 GPU 加速的 Python 任务
  2. 02部署 Web API 或定时作业
  3. 03规划 Modal 存储与密钥
  4. 04查阅 Modal 计费和 CLI 操作

安装

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

$npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill modal-knowledge

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

包含的文件

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

references/
batched-dynamic-batching.md
sandboxes-code-execution.md
scaling-autoscaler.md
storage-volumes-cloud.md

详细介绍

Modal 知识技能

全面介绍 Modal.com 平台的知识,涵盖所有功能、定价和最佳实践。当用户需要详细了解 Modal 的无服务器云平台时,激活此技能。

激活条件

用户询问以下内容时,激活此技能:

  • Modal.com 平台的功能与能力
  • GPU 加速的 Python 函数
  • 无服务器容器配置
  • Modal 定价和账单
  • Modal CLI 命令
  • Modal 上的 Web 端点和 API
  • Modal 上的定时/cron 任务
  • Modal 卷、密钥和存储
  • 使用 Modal 进行并行处理
  • Modal 部署和 CI/CD

平台概览

Modal 是一个无服务器云平台,可用于运行 Python 代码,并针对 AI/ML 工作负载进行了优化,具有以下特点:

  • 零配置:所有内容均通过 Python 代码定义
  • GPU 快速启动:容器启动约需 1 秒
  • 自动扩展:可缩减至零,也可扩展至数千个实例
  • 按秒计费:仅需为活跃计算付费
  • 多云:AWS、GCP、Oracle Cloud Infrastructure

核心组件参考

应用和函数
import modal

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

@app.function()
def basic_function(arg: str) -> str:
    return f"Result: {arg}"

@app.local_entrypoint()
def main():
    result = basic_function.remote("test")
    print(result)
函数装饰器参数
参数类型描述
imageImage容器镜像配置
gpustr/listGPU 类型:”T4”、”A100”、[”H100”、”A100”]
cpufloatCPU 核心数(0.125 至 64)
memoryint内存,单位为 MB(128 至 262144)
timeoutint最大执行秒数
retriesint失败时的重试次数
secretslist要注入的密钥
volumesdict卷挂载点
scheduleCron/Period定时执行
concurrency_limitint最大并发执行数
container_idle_timeoutint保持容器预热的秒数
include_sourcebool自动同步源代码

GPU 参考

可用 GPU
GPU内存用途约费用/小时
T416 GB小规模推理$0.59
L424 GB中等规模推理$0.80
A10G24 GB推理/微调$1.10
L40S48 GB高负载推理$1.50
A100-40GB40 GB训练$2.00
A100-80GB80 GB大型模型$3.00
H10080 GB前沿应用$5.00
H200141 GB最大型模型$5.00
B200180+ GB最新一代$6.25
GPU 配置
# Single GPU
@app.function(gpu="A100")

# Specific memory variant
@app.function(gpu="A100-80GB")

# Multi-GPU
@app.function(gpu="H100:4")

# Fallbacks (tries in order)
@app.function(gpu=["H100", "A100", "any"])

# "any" = L4, A10G, or T4
@app.function(gpu="any")

镜像构建

基础镜像
# Debian slim (recommended)
modal.Image.debian_slim(python_version="3.11")

# From Dockerfile
modal.Image.from_dockerfile("./Dockerfile")

# From Docker registry
modal.Image.from_registry("nvidia/cuda:12.1.0-base-ubuntu22.04")
安装软件包
# pip (standard)
image.pip_install("torch", "transformers")

# uv (FASTER - 10-100x)
image.uv_pip_install("torch", "transformers")

# System packages
image.apt_install("ffmpeg", "libsm6")

# Shell commands
image.run_commands("apt-get update", "make install")
添加文件
# Single file
image.add_local_file("./config.json", "/app/config.json")

# Directory
image.add_local_dir("./models", "/app/models")

# Python source
image.add_local_python_source("my_module")

# Environment variables
image.env({"VAR": "value"})
构建时函数
def download_model():
    from huggingface_hub import snapshot_download
    snapshot_download("model-name")

image.run_function(download_model, secrets=[...])

存储

卷
# Create/reference volume
vol = modal.Volume.from_name("my-vol", create_if_missing=True)

# Mount in function
@app.function(volumes={"/data": vol})
def func():
    # Read/write to /data
    vol.commit()  # Persist changes
密钥
# From dashboard (recommended)
modal.Secret.from_name("secret-name")

# From dictionary
modal.Secret.from_dict({"KEY": "value"})

# From local env
modal.Secret.from_local_environ(["KEY1", "KEY2"])

# From .env file
modal.Secret.from_dotenv()

# Usage
@app.function(secrets=[modal.Secret.from_name("api-keys")])
def func():
    import os
    key = os.environ["API_KEY"]
字典和队列
# Distributed dict
d = modal.Dict.from_name("cache", create_if_missing=True)
d["key"] = "value"
d.put("key", "value", ttl=3600)

# Distributed queue
q = modal.Queue.from_name("jobs", create_if_missing=True)
q.put("task")
item = q.get()

Web 端点

FastAPI 端点(简单)
@app.function()
@modal.fastapi_endpoint()
def hello(name: str = "World"):
    return {"message": f"Hello, {name}!"}
ASGI 应用(完整 FastAPI)
from fastapi import FastAPI
web_app = FastAPI()

@web_app.post("/predict")
def predict(text: str):
    return {"result": process(text)}

@app.function()
@modal.asgi_app()
def fastapi_app():
    return web_app
WSGI 应用(Flask)
from flask import Flask
flask_app = Flask(__name__)

@app.function()
@modal.wsgi_app()
def flask_endpoint():
    return flask_app
自定义 Web 服务器
@app.function()
@modal.web_server(port=8000)
def custom_server():
    subprocess.run(["python", "-m", "http.server", "8000"])
自定义域名
@modal.asgi_app(custom_domains=["api.example.com"])

定时任务

Cron
# Daily at 8 AM UTC
@app.function(schedule=modal.Cron("0 8 * * *"))

# With timezone
@app.function(schedule=modal.Cron("0 6 * * *", timezone="America/New_York"))
Period
@app.function(schedule=modal.Period(hours=5))
@app.function(schedule=modal.Period(days=1))

**注意:**定时函数仅在使用 modal deploy 时运行,不会在使用 modal run 时运行。


并行处理

Map
# Parallel execution (up to 1000 concurrent)
results = list(func.map(items))

# Unordered (faster)
results = list(func.map(items, order_outputs=False))
Starmap
# Spread args
pairs = [(1, 2), (3, 4)]
results = list(add.starmap(pairs))
Spawn
# Async job (returns immediately)
call = func.spawn(data)
result = call.get()  # Get result later

# Spawn many
calls = [func.spawn(item) for item in items]
results = [call.get() for call in calls]

容器生命周期(类)

@app.cls(gpu="A100", container_idle_timeout=300)
class Server:

    @modal.enter()
    def load(self):
        self.model = load_model()

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

    @modal.exit()
    def cleanup(self):
        del self.model
并发
@modal.concurrent(max_inputs=100, target_inputs=80)
@modal.method()
def batched(self, item):
    pass

CLI 命令

开发
modal run app.py              # Run function
modal serve app.py            # Hot-reload dev server
modal shell app.py            # Interactive shell
modal shell app.py --gpu A100 # Shell with GPU
部署
modal deploy app.py           # Deploy
modal app list                # List apps
modal app logs app-name       # View logs
modal app stop app-name       # Stop app
资源
# Volumes
modal volume create name
modal volume list
modal volume put name local remote
modal volume get name remote local

# Secrets
modal secret create name KEY=value
modal secret list

# Environments
modal environment create staging

定价(2025 年)

套餐
套餐价格容器数GPU 并发数
Starter免费($30 额度)10010
Team$250/月100050
Enterprise定制无限制定制
计算
  • CPU:$0.0000131/核心/秒
  • 内存:$0.00000222/GiB/秒
  • GPU:请参阅上方的 GPU 表格
特别计划
  • 初创企业:最高可获 $25k 额度
  • 研究人员:最高可获 $10k 额度

最佳实践

  1. 使用 @modal.enter() 加载模型
  2. 使用 uv_pip_install 加快构建速度
  3. 使用 GPU 回退方案 确保可用性
  4. 设置合适的超时时间和重试次数
  5. 使用环境(开发/预发布/生产)
  6. 在构建期间下载模型,而非运行时
  7. 当顺序不重要时使用 order_outputs=False
  8. 设置 container_idle_timeout,平衡成本与延迟
  9. 在 Modal 控制面板中监控成本
  10. 在执行 modal deploy 前,先使用 modal run进行测试

常见模式

LLM 推理
@app.cls(gpu="A100", container_idle_timeout=300)
class LLM:
    @modal.enter()
    def load(self):
        from vllm import LLM
        self.llm = LLM(model="...")

    @modal.method()
    def generate(self, prompt):
        return self.llm.generate([prompt])
批处理
@app.function(volumes={"/data": vol})
def process(file):
    # Process file
    vol.commit()

# Parallel
results = list(process.map(files))
定时 ETL
@app.function(
    schedule=modal.Cron("0 6 * * *"),
    secrets=[modal.Secret.from_name("db")]
)
def daily_etl():
    extract()
    transform()
    load()

快速参考

任务代码
创建应用app = modal.App("name")
基本函数@app.function()
使用 GPU@app.function(gpu="A100")
使用镜像@app.function(image=img)
Web 端点@modal.asgi_app()
定时执行schedule=modal.Cron("...")
挂载卷volumes={"/path": vol}
使用密钥secrets=[modal.Secret.from_name("x")]
并行映射func.map(items)
异步启动func.spawn(arg)
类模式使用 @app.cls() 和 @modal.enter()

评论

支持 Markdown