大模型推理服务的CI/CD与平滑更新

说明如何用 GitHub Actions 串联 vLLM 镜像与模型版本发布,并以 Argo Rollouts 的 Canary 流量权重、暂停观察、指标核验和版本切换建立可恢复的更新流程。

大模型推理服务的 CI/CD 应把模型版本、容器镜像和部署清单绑定为同一发布单元,经自动检查后再进入生产;平滑更新则先控制新版本承接的流量,再决定是否切换。大模型部署不只是把 vLLM 启动起来:暂停观察、指标判断与回退条件必须先写进发布流程,否则流量已经切换后才发现异常,处置就会很被动。

大模型部署应先固定发布单元

先记录本次使用的 model ID、镜像引用、engine args、预期指标和回退入口。vLLM 的 Docker 文档给出的官方镜像是 vllm/vllm-openai,示例命令挂载 Hugging Face 缓存、映射 8000 端口并启动 OpenAI-compatible server:

docker run --runtime nvidia --gpus all \
  -v ~/.cache/huggingface:/root/.cache/huggingface \
  --env "HF_TOKEN=$HF_TOKEN" \
  -p 8000:8000 \
  --ipc=host \
  vllm/vllm-openai:latest \
  --model Qwen/Qwen3-0.6B

这条命令适合作为本地基线。进入流水线后,应把 latest 换成已经验证的固定镜像标签,并让测试环境与生产环境引用同一构建产物,避免各环境重新构建后出现差异。

CI/CD:让每次发布都有明确入口

GitHub 的 工作流触发事件说明指出,push 会在提交或 tag 被推送时运行工作流;未指定 activity types 时,pull_request 会在 PR 被打开、重新打开或其 head branch 更新时运行。

据此,可以把仓库流程分成这些发布动作:

  • PR 更新时构建候选镜像,运行配置检查和基础接口检查,不直接替换生产版本。
  • commit 或 tag 推送后,把已经验证的候选镜像交给部署任务,不在生产环境临时重建。
  • 部署任务同时记录 model ID、镜像标签和 rollout 策略,再进入流量更新。
  • 在生产切换前保留人工确认点;确认条件应包含指标结果、异常处理方式和回退入口,而不是只写“人工处理”。

平滑更新:先控制流量,再完成切换

Argo Rollouts 的 Canary 策略会把少量生产流量发送给新版本。setWeight 用于设置送往 Canary 的流量比例,pause 用于暂停 rollout;如果暂停步骤没有设置 duration,它会持续等待,直到暂停条件被移除后才继续推进。

如果更希望新 ReplicaSet 可用后直接切换 active service,可以采用 BlueGreen。其 策略文档说明,新的 ReplicaSet 可用后,控制器会让 active service 指向它;旧 ReplicaSet 则在 scaleDownDelaySeconds 结束后缩容。

需要渐进观察时,Canary 更便于按指标决定是否继续;需要以可用状态触发服务切换时,BlueGreen 的流程更直接。无论采用哪种方式,都应在进入 pause 前写清继续推进、保持现状和回退的条件。不要凭空套用固定回退命令,应按当前 Argo Rollouts 文档和实际 rollout 清单执行。

验证:比较更新前后的服务指标

进入流量切换前,先记录相同请求条件下的基线。vLLM 的 生产指标文档列出了 vllm:num_requests_running、vllm:num_requests_waiting 和 vllm:kv_cache_usage_perc;它们都是 gauge,其中 vllm:kv_cache_usage_perc 的值 1 表示 100% 使用率。不要在没有自身基线时套用统一阈值,应比较更新前后的变化,并结合请求是否正常完成来判断。

如果服务另行暴露 Prometheus 经典直方图,可以参考其 查询函数文档中的按 job 查询示例。聚合时必须保留 le:

histogram_quantile(0.9, sum by (job, le) (rate(http_request_duration_seconds_bucket[10m])))

这条查询针对文档中的 http_request_duration_seconds_bucket,不是 vLLM 默认指标;只有服务确实暴露对应序列时才能使用。

常见出错点

  • 把文档示例中的 latest 直接当作生产版本标识,导致无法准确复现或回退。
  • 将 engine args 放在镜像 tag 前,或者遗漏共享内存设置。vLLM 的 Docker 文档要求 engine args 位于镜像 tag 后,并说明应使用 --ipc=host 或 --shm-size 提供共享内存。
  • 只观察 rollout 是否继续,不检查请求执行、等待请求和 KV cache 使用情况。
  • 把“控制器已经推进”当成“业务验收通过”,或让回退说明停留在“必要时人工处理”,却没有对应入口和操作清单。

本文步骤均按正文所链接的官方文档整理,未运行或测量;使用前应按当前版本复核。

资料来源