去年我们团队把大模型应用的交付方式从头捋了一遍最终沉淀出一套内部代号 23.7 的 CI/CD 全流程。这里说的 CI/CD 不再是传统软件里编译、打包、上线那套东西而是把模型训练、评估、部署自动化全部串起来让应用可以持续迭代。这套流程跑通之后最直观的变化是一个模型从训练完成到灰度上线人工介入从十几次降到两三次发布周期从按周算变成按天算。这篇文章就把这套体系的设计思路、关键环节、实操配置和踩过的坑完整拆开讲一遍。如果你正在做大模型应用工程化或者想把算法团队的训练流程纳入规范的交付体系这篇内容应该能给你一份可以直接参考的底稿。1. 为什么大模型应用需要一套完整的 CI/CD 流水线先说个很多团队会遇到的现象模型训练在 Notebook 里完成评估是算法同学手工跑几个脚本部署靠运维临时写启动命令。第一版上线没问题等迭代到第三版、第五版问题全冒出来了——这版模型是谁在什么数据上训的评测指标为什么和线上表现对不上出问题了要回滚到哪个版本没人能立刻答上来。本质原因是大模型本质上也是代码但它比普通代码多了一层不确定性和数据依赖如果没有一套自动化的交付管道整个迭代过程很快就会失控。1.1 传统软件 CI/CD 和大模型 CI/CD 最核心的差别传统 CI/CD 的流水线对象是源代码加二进制产物。代码提交之后自动触发编译、单元测试、构建镜像、部署到测试环境这一套大家已经很熟了。但大模型应用的交付物是什么是模型权重文件、推理服务代码、prompt 模板、评测数据集、甚至向量库索引这些资产加在一起才算一个可交付的版本。这里有一个关键差异普通代码的编译结果一般是确定性的同样的输入必然产生同样的输出但模型训练天然带随机性换一次初始化种子结果就有波动。所以我当时定了一个原则流水线里不能只记录“这版用的是哪个训练脚本”必须把训练代码、数据集版本、超参数、基础模型版本、随机种子、评估结果全部作为一个整体快照保存下来。没有这个快照后面所有的回滚、对比、审计都无从谈起。另一个差异是质量门槛。传统 CI 的质量门槛是跑测试用例绿了就过大模型应用的质量门槛是一套评估集加一组指标阈值。而且这个评估集本身也要版本化因为评测集一旦换了模型指标就不能直接跨版本比较。1.2 23.7 这套流程要解决的四个真实问题我们在设计 23.7 这个版本时指向的是四个线上真实遇到的问题。第一是模型发布靠记忆哪个版本在线上跑、对应的训练数据是什么完全依赖某个同学记得人一走信息就断。第二是训练资源浪费严重实验频繁人工启动GPU 利用率长期不到一半。第三是线上效果回退发现太晚模型指标在离线评测里是涨的上线后业务指标反而跌过了两三天才被反馈回来。第四是回滚周期太长老版本模型要手工重新加载、重新配服务一次回滚动辄半小时以上。这四个问题放在一起就不是某个环节的小修补能解决的必须从流程层面把训练、评估、部署串成一条自动运转的链路。23.7 的版本号不是随便起的这是我们第七次整体重构流水线架构也是首次把训练阶段完整纳入主流程。1.3 这条流水线跑通之后到底能省下什么直接说数据。流程跑通前一个模型从开始训练到灰度发布平均要 3 到 5 天其中大部分时间浪费在等待人工确认和手动搬运产物。跑通后全自动场景下最快 6 小时可以完成从训练触发到灰度发布。而且因为每个版本都有完整快照问题定位时间从小时级降到了分钟级——出问题直接比对指标快照不用再回溯聊天记录找“上次怎么跑的”。对于团队协同价值更明显。算法、后端、运维三方原来在发布节点上互相等待现在通过流水线工件仓库传递产物各自只需要维护自己负责的阶段配置。2. 流水线整体设计与阶段拆解23.7 的流水线在结构上分五个阶段触发与准备、训练、评估、部署、监控反馈。每个阶段都独立配置、独立告警但产物和状态是串起来的。下面按阶段拆开讲。2.1 五个阶段的职责划分触发与准备阶段负责监听代码仓库的变更、数据集的版本标记和人工触发信号满足条件后统一装配本次训练的运行参数。训练阶段在隔离的计算环境里执行训练任务同时记录完整的训练元数据。评估阶段加载评估集对训练产物做多维指标计算并与历史表现做比对。部署阶段把评估通过的产物构建成推理服务镜像按发布策略灰度上线。监控反馈阶段持续采集线上业务指标触发质量门禁或自动回滚。阶段之间的关系是严格的前后依赖不允许跳级。哪怕只是改了一个 prompt也必须走完评估才能上线这条约束在执行层面没有例外。为什么要这样严格串行因为大模型应用里任何一层改动都可能对最终效果产生非线性的影响。不经评估直接上线的 prompt 修改我是见过翻车的某次只是精简了一句系统提示语线上回答长度直接下降 30%用户反馈“变蠢了”。2.2 训练阶段怎么安全地接到流水线里训练纳入 CI/CD 有个天然矛盾训练任务耗时太长、成本太高不适合每次代码提交都跑。我们的解法是把训练触发条件拆成三层。第一层普通代码改动只触发轻量检查比如训练脚本语法、数据格式校验、prompt 渲染测试不做全量训练。第二层数据集或基础模型版本变更触发完整训练流程。第三层人工通过流水线界面或命令行指定参数触发训练适合算法同学做回归实验。在训练环境隔离上我们采用了每次训练独立计算容器的方式避免多个训练任务互相抢占或污染环境。训练镜像里固化好所有依赖库版本训练代码通过工件仓库拉取固定版本。每次训练任务的超参数、数据集版本、随机种子都显式写入训练清单训练结束后自动上传关键 checkpoint 和指标摘要。这里有个很容易被忽略的点训练生成的中间文件和日志要统一命名规则。建议按照流水线运行编号加任务类型来组织路径否则排查问题时会浪费大量时间在“这个文件是谁产生的”上面。2.3 评估阶段如何拦截不合格模型评估是整套流水线里最关键的质检关卡。我们内部把它戏称为“考门”过了才能进部署。评估阶段不只看单一指标而是同时跑三类检查。第一类是离线指标集评估针对标准评测集算指标保证模型基本能力不下滑。第二类是回归测试集评估专门挑选历史上出过问题的场景用例防止旧问题复发。第三类是逻辑校验检查输入输出格式、输出长度边界、违禁内容命中率这些工程层面的硬约束。评估完成后流水线会生成一份对比报告把当前版本和正在线上的版本在相同评测集上的指标摆在一起。即使当前版本总体指标更高只要有任何一个关键维度显著回退流水线就会判定为不通过。阈值怎么定不能拍脑袋。我们先用线上真实数据统计出历史波动范围再根据容忍度设置例如单指标回退超过 3% 就拦截而不是相对历史最高点降 1% 就告警。2.4 部署阶段的发布策略选择部署阶段解决的问题是新模型确实评估通过了但怎么上线才能保证线上稳定。大模型推理服务和普通 Web 服务有一点不同——模型加载耗时久、显存占用高不能搞“启动失败就立刻退出”这种轻量策略需要更谨慎的发布方式。我们当时在蓝绿发布和灰度发布之间选了灰度发布。原因很实际大模型的行为空间太大离线评测过了不代表线上所有场景都适配灰度发布可以在小流量下快速发现问题。具体做法是新版本推理服务先拉起并发数设为零等显存加载完成、接口健康检查通过之后再把 5% 的线上流量分过去观察 10 分钟。没有异常则逐步提高到 20%、50%、100%任何一步指标异常立刻将流量全部切回旧版本。这里有一个坑要提醒推理服务的健康检查不能只看进程存活必须做真实推理探测。我们写了一个持续请求脚本每隔几秒请求一个问题比对返回内容和耗时是否在正常区间避免“进程活着但不干活”的情况。2.5 监控反馈与持续迭代回路部署上线不是终点监控反馈环节才是闭环的关键。我们给线上服务接了三个维度的监控业务指标、资源指标、模型行为指标。业务指标包括请求量、响应成功率、业务转化率资源指标关注 GPU 利用率、显存占用、时延分位数模型行为指标包括输出长度、拒绝率、平均置信度。监控的价值不只是发现问题更重要的是为下一轮迭代提供数据。每个月我们都会从线上采样一批真实用户输入经过脱敏后加入评估集让模型迭代方向始终贴合真实场景。这一点我觉得是大模型应用和传统软件最大的区别——传统软件的迭代依据是需求变更大模型应用的迭代依据是线上数据反馈没有回收机制等于闭着眼睛开车。3. 实操记录把一整条自动化链路在项目里落地前面讲完设计下面进入实操部分。这里以一个模拟的大模型应用项目 X智能客服场景为例记录我们落地 23.7 流程时的具体做法。项目背景可以理解为服务通过开放平台 API 对外提供对话能力模型需要按周迭代对响应质量和稳定性要求都比较高。3.1 场景设定与基础环境项目 X 的部署形态是容器化微服务推理模块是独立服务前后端通过标准 HTTP 接口通信。基础环境采用内部容器平台所有节点统一管理。训练和推理共用同一套 GPU 资源池但通过资源标签和配额做隔离保证训练任务不会挤占线上推理资源。代码和配置统一存储在内部代码仓库所有变更都走合并请求评审。CI/CD 流程基于通用开源 CI 系统搭建控制节点负责调度和状态管理。工件仓库统一存放模型文件、镜像包、评测报告和元数据快照。流水线配置用 YAML 描述存进仓库统一版本管理。这里有个经验流水线配置必须跟着代码仓库走不能散落在各个 CI 控制节点上。否则你改了一版配置可能这台机器生效、那台机器不生效追踪起来极其痛苦。3.2 流水线配置文件的关键片段23.7 的流水线配置结构大致如下我用简化过的 YAML 展示核心逻辑pipeline: id: pipeline-project-x-237 stages: - id: prepare type: trigger events: - dataset-updated - base-model-updated - manual-trigger actions: - assemble-run-params - validate-training-env - id: train type: training depends-on: prepare image: training-runtime:1.4.2 resources: gpu: 2 memory: 32Gi params: dataset-version: ${DATASET_VERSION} base-model: ${BASE_MODEL} epochs: ${EPOCHS} seed: ${SEED} hooks: on-success: upload-checkpoint on-failure: collect-logs - id: evaluate type: evaluation depends-on: train image: eval-runtime:1.2.0 eval-sets: - standard-basic - regression-set - logic-checks gates: metric-lower-bound: 0.95 # 相对线上版本的关键指标下限 single-metric-drop-limit: 0.03 - id: deploy type: deployment depends-on: evaluate strategy: canary canary-steps: - traffic: 5 duration: 600 - traffic: 20 duration: 600 - traffic: 50 duration: 600 health-check: type: real-inference-probe interval: 5s timeout: 60s - id: monitor type: monitoring depends-on: deploy metrics: - business-success-rate - latency-p95 - gpu-utilization - refusal-rate alert: on-drop: rollback-to-previous这里面的关键设计是质量门禁参数。metric-lower-bound表示当前模型相对线上版本的综合指标下限设为 0.95 意味着不能比线上差 5% 以上。single-metric-drop-limit控制单指标回退容忍度防止某些团队为了刷平均分牺牲了某个重要维度。部署阶段的canary-steps代表灰度流量比例和观察时长的矩阵。5% 流量观察 10 分钟20% 再观察 10 分钟50% 观察 10 分钟全部稳定后放量到 100%。monitor阶段的on-drop配置了指标下降自动回滚策略这是对线上稳定性最后的兜底。3.3 质量门禁参数怎么定质量门禁是整个流水线里最需要业务方深度参与的地方参数定松了等于没设防定紧了会导致上线极其困难。我们实际定参过程分了四步先基于线上数据统计历史指标均值再计算标准差然后根据业务容忍度确定合理波动范围最后用过去三个月的真实版本回测验证这些阈值不会挡掉本该通过的版本。以响应时延 p95 为例。过去一个月波动在 1.8 秒到 2.4 秒之间均值约 2.0 秒。如果直接定阈值“p95 不得超过 2.4 秒”可能把一个在边缘波动的合格版本拦住。我们结合业务要求“用户等待超过 3 秒会明显流失”最终把 p95 的硬上限定为 2.8 秒同时要求 p50 不得超过 1.5 秒。这样既给波动留空间又防止整体变慢。指标选择上有一个原则必须同时包含“能力指标”和“行为指标”。能力指标如理解准确率行为指标如平均输出长度、敏感内容拦截率。只盯准确率容易遗漏工程风险比如某次模型输出质量没变但输出长度暴增导致响应时延严重超限用户等得更久。3.4 从提交代码到发布上线的完整执行流下面模拟一次真实迭代场景数据集更新了 5 万条新对话样本需要训练新版本并上线。这次迭代完全通过流水线自动执行。第一步数据团队完成数据脱敏和标注将新数据集打上标签dataset-2024-11-15并推送到数据集仓库。这一步触发了流水线的dataset-updated事件。第二步流水线进入 prepare 阶段自动拼接本次运行的完整参数清单基础模型沿用线上版本训练轮数沿用配置默认值 4 轮随机种子取当前时间戳派生值。校验训练环境资源充足后写入运行开始日志。第三步train 阶段启动训练任务。两个 GPU 节点被分配镜像拉取、数据集加载都自动完成。训练过程约 3 小时。训练完成checkpoint 上传到工件仓库训练摘要loss 曲线、训练耗时、资源消耗自动归档。第四步evaluate 阶段启动。先跑标准评测集得到基础指标再跑回归测试集和逻辑校验。比对结果显示新版本对话连贯性有小幅提升但历史回归集里“地址识别”这个子项指标下降了 3.5%超过 3% 的阈值。流水线判定为不通过本次候选版本被拦截不会进入部署。第五步流水线发送详细报告给团队标注问题集中在哪个子项以及可能原因。算法同学根据报告判断是数据集标签错误还是模型过拟合修正后重新触发训练。这个场景下问题在上线前就被拦截线上没有受到任何影响。如果评估顺利通过则会进入部署流程镜像服务在集群中拉起加载权重探针确认模型正常响应按 5%、20%、50% 分阶段导流。全部稳定后新版本正式承接全量流量旧版本保留为回滚副本。整个过程大约 40 分钟基本不需要人工操作。4. 踩坑实录与问题排查速查表落地这套流程的过程中我们踩过的坑不少。有些坑在文档和教科书里根本不会提但实际操作几乎必踩。我把典型问题整理出来按阶段分类每个都附上排查思路和解决办法。4.1 训练触发不稳定的几个坑训练阶段最开始接入 CI/CD 时我们遇到过触发事件丢失的问题。现象是数据集已经更新标签也打了但流水线迟迟没有启动。排查下来发现是事件监听器对仓库变更事件做了去重相同 commit 哈希的连续推送被当成同一事件忽略掉了。解决办法是在推送信息里增加一个单调递增的构建序号字段保证每次推送的事件 ID 唯一。另一个坑是训练环境缓存污染。某个实验版本改了依赖库版本pip缓存让后续训练复用了旧的依赖包结果训练结果无法复现。后来我们给训练镜像加了一层强校验每次训练启动前强制校验依赖锁文件与当前环境的哈希一致不一致直接终止。还有一次是 GPU 资源抢占。训练任务和另一个团队的评测任务在同一资源池里调度两边都以为资源是先到先得结果训练中途显存不足直接退出。后面我们在资源配额里给训练任务设置了独立的空间同时加入排队机制任务等待超过 30 分钟会自动通知管理员。4.2 评估标准和线上真实效果脱节评估阶段踩过一个比较大的坑离线评估集是从历史数据里抽样的但数据分布会漂移。某个版本离线指标全部上涨上线后业务转化率却掉了。后来分析发现测评集里新品类问题占比高而线上流量仍然以旧品类为主评估结果高估了模型在真实流量上的表现。解决办法是建立“月度流量快照”制度每个月从线上请求里随机采样 2 万条真实对话严格脱敏后混入评估集重新校准评测分布。从这以后离线评估结果和线上表现的相关性明显提升。顺便说一句评估集本身也需要版本管理否则历史对比没有意义。另一个问题是评估集的题目泄露。有一次评估集里包含了少量训练数据模型“背答案”导致评估虚高。现在每个数据集都有去重脚本专门检测训练集和评估集的高相似内容一旦发现直接驳回数据集更新请求。4.3 部署回滚不干净引发的脏数据问题部署环节最让我们头疼的是回滚不干净。新版本灰度到 50% 时发现输出质量异常触发自动回滚。结果流量切回旧版本了但新版服务实例没有完全销毁还在消费上游消息队列里的部分请求。这些请求产生的对话记录被写入线上日志库导致后续评估数据混入了新版本的行为特征。后面把所有回滚操作改成了“销毁优先切流其次”的顺序先确认新实例彻底退出再切换流量配置。另外在业务日志里增加全链路标识字段每个请求都带上模型版本号后面统计分析时按版本号严格过滤不会再出现数据污染问题。还有一个容易踩的坑是模型加载状态判断。推理服务进程起来了但权重没加载完接口返回的是模型不可用或超时错误。如果在此时把流量导进去会造成大量 5xx。健康检查必须要做真实推理请求通过一次最小请求确认模型能正常输出再开放流量。这个问题我们在灰度发布的前期阶段踩过一次之后就增加了探针拦截。4.4 常见问题速查表结合内部团队踩坑记录整理一份速查表按阶段归类索引时可以先定位出问题的环节问题现象可能原因排查方向与解决建议训练任务未被触发事件消息去重、标签格式不符检查事件 ID 唯一性确认数据集标签匹配流水线配置训练结果无法复现依赖环境版本漂移、随机种子未固定锁定依赖版本 记录训练种子增加环境哈希校验训练中途显存不足资源配额未隔离、同资源池的并发任务过多独立资源空间设置任务队列上限离线评估通过但线上不达预期评估集与真实流量分布偏差定期混入线上采样数据校准评估集评估集包含训练集内容数据去重脚本未生效增加训练集与评估集相似度检测灰度发布后请求大量超时模型权重未加载完成就开始导流完善健康检查必须做真实推理探测自动回滚后业务日志含异常数据旧实例未销毁、流量先切回调整回滚顺序先销毁再切流日志按版本号过滤模型指标监控长时间无数据监控服务拉取权限失败、日志字段缺失检查接口权限确认日志携带全链路标识字段流水线执行时间过长评估集过大、训练参数保守评估集分层抽样替代全量执行调整训练轮数多个实验版本同时跑管理混乱缺乏统一实验版本管理以流水线运行编号为唯一主键统一管理实验记录这套速查表本质上是我们团队的知识沉淀一边跑流程一边填充进去的。每踩一次坑就把现象和排查路径标准化后面的人遇到了直接查表不用重复走弯路。我个人在实际操作中最深的一点体会是大模型应用工程化难的根本不是某个单点技术难的是把训练、评估、部署、监控这些环节从“人的协作”变成“系统的协作”。这套 23.7 命名为“流程”但它真正改变的是团队的工作方式。从“某个同学记得上次怎么跑的”变成“流水线记录了一切”从“上线了再观察”变成“过不了门禁就不准上”。如果你也打算给自己的大模型应用配 CI/CD建议不要上来就追求功能大而全先把数据集版本管理、评估集版本管理、质量门禁这三个底座打好再往上加训练和部署的自动化。这三个点稳住了后面扩展其他环节都会顺手很多。