mcpField
R
runpod-deployment

runpod-deployment

github.com/scientiacapital云与 DevOps28109 次安装3 周前更新
代码仓库

关于 runpod-deployment

面向 RunPod GPU 工作负载部署与运维的 Claude 技能,涵盖无服务器 Worker、vLLM 端点和专用 Pod,并提供 GPU 选择、成本控制、扩缩容与监控指导。

主要功能

  1. 01无服务器处理器模式
  2. 02部署 vLLM 端点
  3. 03GPU 与 Pod 选择
  4. 04成本和扩缩容指导
  5. 05健康检查与指标

适用场景

  1. 01部署无服务器推理端点
  2. 02通过 vLLM API 提供模型服务
  3. 03按预算选择 GPU
  4. 04监控端点健康与扩缩容

安装

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

$npx skills add https://github.com/scientiacapital/skills --skill runpod-deployment

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

包含的文件

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

config.json
reference/
cicd.md
cost-optimization.md
model-deployment.md
monitoring.md
pod-management.md
project-configs.md
serverless-workers.md
templates.md
troubleshooting.md
vllm-setup.md
templates/
runpod-worker.py

详细介绍

在 RunPod 基础设施上部署和管理 GPU 工作负载:
  1. 无服务器 Worker - 可缩减至零的处理程序,按秒计费
  2. vLLM 端点 - 兼容 OpenAI 的大模型服务,吞吐量提升 2–3 倍
  3. Pod 管理 - 用于开发/训练的专用 GPU 实例
  4. 成本优化 - GPU 选择、竞价实例、预算控制

主要交付内容:

  • 可用于生产环境的无服务器处理程序,支持流式传输
  • 部署兼容 OpenAI API 的 vLLM
  • 为任意模型规模选择经济高效的 GPU
  • 健康监控和自动扩缩配置

<quick_start> 最简无服务器处理程序(v1.8.1):

import runpod

def handler(job):
    """Basic handler - receives job, returns result."""
    job_input = job["input"]
    prompt = job_input.get("prompt", "")

    # Your inference logic here
    result = process(prompt)

    return {"output": result}

runpod.serverless.start({"handler": handler})

流式处理程序:

import runpod

def streaming_handler(job):
    """Generator for streaming responses."""
    for chunk in generate_chunks(job["input"]):
        yield {"token": chunk, "finished": False}
    yield {"token": "", "finished": True}

runpod.serverless.start({
    "handler": streaming_handler,
    "return_aggregate_stream": True
})

兼容 OpenAI 的 vLLM 客户端:

from openai import OpenAI

client = OpenAI(
    api_key="RUNPOD_API_KEY",
    base_url="https://api.runpod.ai/v2/ENDPOINT_ID/openai/v1",
)

response = client.chat.completions.create(
    model="meta-llama/Llama-3.1-8B-Instruct",
    messages=[{"role": "user", "content": "Hello!"}],
    max_tokens=100,
)

</quick_start>

<success_criteria> RunPod 部署成功的标准:

  • 处理程序能够无错误地处理请求
  • 端点能够适当扩缩(0 → N 个 Worker)
  • 冷启动时间符合使用场景的要求
  • 成本控制在预算预估范围内
  • 健康检查持续通过 </success_criteria>

<m1_mac_critical>

M1/M2 Mac:无法在本地构建 Docker 镜像

ARM 架构与 RunPod 的 x86 GPU 不兼容。

解决方案:使用 GitHub Actions 为你构建:

# Push code - Actions builds x86 image
git add . && git commit -m "Deploy" && git push

完整的 GitHub Actions 工作流请参阅 reference/cicd.md。

在 Apple Silicon 上为 RunPod 使用时,切勿在本地运行 docker build。 </m1_mac_critical>

<gpu_selection>

GPU 选择矩阵(2025 年 1 月)

GPU显存按需价格(美元/小时)竞价价格(美元/小时)最适合用途
RTX A400016GB$0.36$0.18Embedding、小型模型
RTX 409024GB$0.44$0.227B–8B 推理
A4048GB$0.65$0.3913B–30B、微调
A100 80GB80GB$1.89$0.8970B 模型、生产环境
H100 80GB80GB$4.69$1.8870B 以上模型训练

快速选择:

def select_gpu(model_params_b: float, quantized: bool = False) -> str:
    effective = model_params_b * (0.5 if quantized else 1.0)
    if effective <= 3: return "RTX_A4000"      # $0.36/hr
    if effective <= 8: return "RTX_4090"       # $0.44/hr
    if effective <= 30: return "A40"           # $0.65/hr
    if effective <= 70: return "A100_80GB"     # $1.89/hr
    return "H100_80GB"                         # $4.69/hr

详细价格和预算控制请参阅 reference/cost-optimization.md。 </gpu_selection>

<handler_patterns>

处理程序模式

进度更新(长时间运行的任务)
import runpod

def long_task_handler(job):
    total_steps = job["input"].get("steps", 10)

    for step in range(total_steps):
        process_step(step)
        runpod.serverless.progress_update(
            job_id=job["id"],
            progress=int((step + 1) / total_steps * 100)
        )

    return {"status": "complete", "steps": total_steps}

runpod.serverless.start({"handler": long_task_handler})
错误处理
import runpod
import traceback

def safe_handler(job):
    try:
        # Validate input
        if "prompt" not in job["input"]:
            return {"error": "Missing required field: prompt"}

        result = process(job["input"])
        return {"output": result}

    except torch.cuda.OutOfMemoryError:
        return {"error": "GPU OOM - reduce input size", "retry": False}
    except Exception as e:
        return {"error": str(e), "traceback": traceback.format_exc()}

runpod.serverless.start({"handler": safe_handler})

异步模式、批处理和高级处理程序请参阅 reference/serverless-workers.md。 </handler_patterns>

<vllm_deployment>

部署 vLLM

注意: vLLM 使用兼容 OpenAI 的 API 格式,但连接的是你自己的 RunPod 端点, 而不是 OpenAI 服务器。模型运行在你的 GPU 上(Llama、Qwen、Mistral 等)。

环境配置
vllm_env = {
    "MODEL_NAME": "meta-llama/Llama-3.1-70B-Instruct",
    "HF_TOKEN": "${HF_TOKEN}",
    "TENSOR_PARALLEL_SIZE": "2",        # Multi-GPU
    "MAX_MODEL_LEN": "16384",
    "GPU_MEMORY_UTILIZATION": "0.95",
    "QUANTIZATION": "awq",              # Optional: awq, gptq
}
兼容 OpenAI 的流式传输
from openai import OpenAI

client = OpenAI(
    api_key="RUNPOD_API_KEY",
    base_url="https://api.runpod.ai/v2/ENDPOINT_ID/openai/v1",
)

stream = client.chat.completions.create(
    model="meta-llama/Llama-3.1-8B-Instruct",
    messages=[{"role": "user", "content": "Write a poem"}],
    stream=True,
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
RunPod 直接流式传输
import requests

url = "https://api.runpod.ai/v2/ENDPOINT_ID/run"
headers = {"Authorization": "Bearer RUNPOD_API_KEY"}

response = requests.post(url, headers=headers, json={
    "input": {"prompt": "Hello", "stream": True}
})
job_id = response.json()["id"]

# Stream results
stream_url = f"https://api.runpod.ai/v2/ENDPOINT_ID/stream/{job_id}"
with requests.get(stream_url, headers=headers, stream=True) as r:
    for line in r.iter_lines():
        if line: print(line.decode())

HuggingFace、TGI 和自定义模型模式请参阅 reference/model-deployment.md。 </vllm_deployment>

<auto_scaling>

自动扩缩配置

扩缩器类型
类型最适合用途配置
QUEUE_DELAY流量变化较大scaler_value=2(目标 2 秒)
REQUEST_COUNT负载可预测scaler_value=5(每个 Worker 处理 5 个请求)
配置模式
configs = {
    "interactive_api": {
        "workers_min": 1,      # Always warm
        "workers_max": 5,
        "idle_timeout": 120,
        "scaler_type": "QUEUE_DELAY",
        "scaler_value": 1,     # 1s latency target
    },
    "batch_processing": {
        "workers_min": 0,
        "workers_max": 20,
        "idle_timeout": 30,
        "scaler_type": "REQUEST_COUNT",
        "scaler_value": 5,
    },
    "cost_optimized": {
        "workers_min": 0,
        "workers_max": 3,
        "idle_timeout": 15,    # Aggressive scale-down
        "scaler_type": "QUEUE_DELAY",
        "scaler_value": 5,
    },
}

Pod 生命周期和扩缩详情请参阅 reference/pod-management.md。 </auto_scaling>

<health_monitoring>

健康与监控

快速健康检查
import runpod

async def check_health(endpoint_id: str):
    endpoint = runpod.Endpoint(endpoint_id)
    health = await endpoint.health()

    return {
        "status": health.status,
        "workers_ready": health.workers.ready,
        "queue_depth": health.queue.in_queue,
        "avg_latency_ms": health.metrics.avg_execution_time,
    }
GraphQL 指标查询
query GetEndpoint($id: String!) {
    endpoint(id: $id) {
        status
        workers { ready running pending throttled }
        queue { inQueue inProgress completed failed }
        metrics {
            requestsPerMinute
            avgExecutionTimeMs
            p95ExecutionTimeMs
            successRate
        }
    }
}

结构化日志记录、告警和仪表板请参阅 reference/monitoring.md。 </health_monitoring>

<dockerfile_pattern>

Dockerfile 模板

FROM runpod/pytorch:2.1.0-py3.10-cuda12.1.1-devel-ubuntu22.04

WORKDIR /app

# Install dependencies (cached layer)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application
COPY . .

# RunPod entrypoint
CMD ["python", "-u", "handler.py"]

runpod.toml 和 requirements.txt 模式请参阅 reference/templates.md。 </dockerfile_pattern>

<file_locations>

参考文件

核心模式:

  • reference/serverless-workers.md - 处理程序模式、流式处理、异步
  • reference/model-deployment.md - vLLM、TGI、HuggingFace 部署
  • reference/pod-management.md - GPU 类型、扩缩容、生命周期

运维:

  • reference/cost-optimization.md - 预算控制、规格优化
  • reference/monitoring.md - 健康检查、日志记录、GraphQL
  • reference/troubleshooting.md - 常见问题及解决方案

DevOps:

  • reference/cicd.md - 用于 M1 Mac 构建的 GitHub Actions
  • reference/templates.md - Dockerfile、runpod.toml 配置
  • templates/runpod-worker.py - 生产环境处理程序模板 </file_locations>
## 请求路由

用户想要无服务器部署: → 提供处理程序模式、Dockerfile、部署步骤 → 参考:reference/serverless-workers.md

用户想要 vLLM 端点: → 提供 vLLM 环境配置、OpenAI 客户端设置 → 参考:reference/model-deployment.md

用户想要优化成本: → 提供 GPU 选择矩阵、竞价定价、预算控制 → 参考:reference/cost-optimization.md

用户使用 M1/M2 Mac: → 重要:构建必须使用 GitHub Actions → 参考:reference/cicd.md

用户遇到部署问题: → 检查健康端点,查看日志 → 参考:reference/troubleshooting.md

<cost_quick_ref>

成本速查

存储成本:

  • 容器磁盘:$0.10/GB/月(按 5 分钟间隔计费)
  • 网络卷:首个 1TB 为 $0.07/GB/月,之后为 $0.05/GB

成本估算:

def estimate_monthly_cost(gpu_type, daily_requests, avg_time_s):
    rates = {"RTX_4090": 0.44, "A40": 0.65, "A100_80GB": 1.89}
    daily_hours = (daily_requests * avg_time_s) / 3600
    return daily_hours * 30 * rates.get(gpu_type, 1.0)

# Example: 1000 requests/day, 5s each, RTX 4090
# = (1000 * 5) / 3600 * 30 * 0.44 = $18.33/month

</cost_quick_ref>

<cli_commands>

CLI 快速命令

# Install
pip install runpod

# Deploy endpoint
runpodctl project deploy --name my-endpoint --gpu-type "NVIDIA RTX 4090"

# Health check
runpod endpoint health ENDPOINT_ID

# View logs
runpod endpoint logs ENDPOINT_ID

# Scale workers
runpod endpoint scale ENDPOINT_ID --min 1 --max 10

# Local testing
python handler.py --rp_serve_api

</cli_commands>

<example_session>

会话示例

用户:“将 Llama 3.1 8B 模型部署到 RunPod 无服务器环境”

Claude:

  1. 首先选择 GPU——8B 模型可运行在 RTX 4090 上($0.44/小时):
gpu_type = "NVIDIA GeForce RTX 4090"
  1. 使用 vLLM,可将吞吐量提升 2-3 倍。创建端点:
env = {
    "MODEL_NAME": "meta-llama/Llama-3.1-8B-Instruct",
    "MAX_MODEL_LEN": "8192",
    "GPU_MEMORY_UTILIZATION": "0.95",
}
  1. 通过兼容 OpenAI 的 API 访问:
from openai import OpenAI
client = OpenAI(
    api_key="YOUR_KEY",
    base_url="https://api.runpod.ai/v2/ENDPOINT_ID/openai/v1",
)
  1. 成本估算:计算费用约为 $0.44/小时,空闲时缩减至零。 </example_session>

输出结果旁路文件

最后一步,将内容写入 ~/.claude/skill-analytics/last-outcome-runpod-deployment.json:

{"ts":"[UTC ISO8601]","skill":"runpod-deployment","version":"1.0.0","variant":"default",
 "status":"[success|partial|error]","runtime_ms":[estimated ms from start],
 "metrics":{"pods_configured":[n],"deployments_created":[n]},
 "error":null,"session_id":"[YYYY-MM-DD]"}

如果某些阶段失败但已生成结果,请使用状态 "partial"。只有未生成任何输出时,才使用 "error"。

评论

支持 Markdown