大模型灰度发布配置:从准备到验证的实操流程
大模型灰度发布配置的核心,是在不一次性替换全部线上流量的前提下,把一部分请求先切到新版本模型服务,确认效果和稳定性后再逐步放量。
本文用 Nginx 作为流量入口,演示按比例分流和按请求头分流两种做法,适合零基础运维照着操作。
先确认环境与前置条件
这套配置不依赖特定云厂商,只要你能控制请求入口即可。
需要准备:
- 两台已运行的大模型推理服务,旧版本记为
model-v1,新版本记为model-v2,各自监听不同端口,例如8001和8002。 - 一台 Nginx 作为统一入口,版本建议使用官方稳定版,执行
nginx -v确认已安装。 - 两个后端服务都能通过
curl http://127.0.0.1:8001/health和curl http://127.0.0.1:8002/health返回正常状态。 - 明确灰度比例,例如先放 10% 流量到新版本。比例不要凭感觉,最好结合业务可接受的错误率来定。
如果后端服务还没有健康检查接口,先在应用层补一个,否则 Nginx 无法判断节点是否可用。
用 upstream 定义新旧两个池子
编辑 Nginx 配置文件,路径通常是 /etc/nginx/conf.d/llm-gray.conf。
先定义两个 upstream,分别指向新旧服务:
upstream llm_v1 {
server 127.0.0.1:8001;
}
upstream llm_v2 {
server 127.0.0.1:8002;
}
这里不要把两个版本直接写进同一个 upstream,否则 Nginx 的负载均衡无法按版本区分。
分成两个池子后,后续分流逻辑才可控。
改完先执行 nginx -t 检查语法,出现 syntax is ok 和 test is successful 再继续。
按比例分流:split_clients 配置
Nginx 自带的 split_clients 模块可以按百分比把请求分到不同变量。
在 http 块内加入:
split_clients "${remote_addr}${http_user_agent}" $llm_version {
10% llm_v2;
* llm_v1;
}
这段配置表示约 10% 的请求进入 llm_v2,其余进入 llm_v1。split_clients 基于哈希计算,同一个客户端在条件不变时通常会落到同一侧,适合观察稳定性。
然后在 server 块中把请求代理到对应池子:
server {
listen 80;
server_name llm.example.com;
location /v1/chat/completions {
proxy_pass http://$llm_version;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 120s;
}
}
注意 proxy_pass 后面使用变量时,Nginx 不会自动拼接路径,所以后端服务需要直接处理 /v1/chat/completions 这个路径。
如果后端路径不同,用 rewrite 或 proxy_pass 带 URI 的方式调整,改完同样执行 nginx -t 再 nginx -s reload。
按请求头或白名单精准切流
比例分流适合放量阶段,但联调时更希望只让指定用户进入新版本。
可以用 map 根据请求头判断:
map $http_x_gray_release $llm_target {
default llm_v1;
"true" llm_v2;
}
然后在 location 中把 proxy_pass http://$llm_target; 替换进去。
测试时带上请求头:
curl -H "X-Gray-Release: true" http://llm.example.com/v1/chat/completions
如果希望按用户 ID 白名单,可以把 map 的匹配条件换成 $arg_user_id 或从 Cookie 中取值,但要注意不要让外部用户随意伪造请求头绕过灰度控制。
更稳妥的做法是在入口层校验签名或由网关统一注入该请求头。
常见报错与避坑
- 502 Bad Gateway:先看
curl http://127.0.0.1:8002/health是否正常,再检查 Nginx 错误日志tail -f /var/log/nginx/error.log。多数情况是新版本服务没启动或端口写错。 - 分流比例明显不对:
split_clients是哈希分流,小样本下比例会有偏差,不要用几十次请求判断。可以临时把比例调大观察趋势。 - 改完配置不生效:确认改的是被
include的配置文件,执行nginx -t后nginx -s reload,不要直接restart造成连接中断。 - 长文本请求超时:大模型响应时间较长,
proxy_read_timeout默认值可能不够,按实际推理耗时调大,但不要无限放大。 - 回滚要提前想好:把灰度比例改回 0% 或删除
split_clients中的新版本行,执行 reload 即可回滚,不需要停服务。
验证灰度是否按预期生效
配置完成后,用多次请求观察分流结果。
可以在后端服务日志中打印接收到的请求,或者临时在 Nginx 返回头中标记版本:
add_header X-Served-By $llm_version always;
然后执行:
for i in $(seq 1 50); do curl -s -o /dev/null -D - http://llm.example.com/v1/chat/completions | grep X-Served-By; done
统计 llm_v2 出现次数是否接近设定比例。
同时观察新版本服务的错误率和响应时间,确认没有明显异常后再逐步提高比例。
灰度发布配置不是一次配完就结束,比例调整、日志观察和回滚预案都要跟着走。
如果后端服务本身支持按模型版本路由,也可以在应用层做灰度,Nginx 这一层负责兜底和统一入口。
两种方式不冲突,关键是每次变更都能验证、能回滚。