算法与Infra协同实战:从冲突到共赢的模型上线指南

发布时间:2026/9/7 6:54:54
算法与Infra协同实战:从冲突到共赢的模型上线指南 先说一个我见过无数次的场景周会上算法同学兴奋地说“离线 AUC 又涨了 3 个点新模型可以上了”infra 同学面无表情地回了一句“延迟涨多少显存多占多少现在单机 QPS 已经贴着水位线了”。然后两边各执一词谁也说服不了谁会议在沉默中结束模型上线的事又被拖了一周。这个场景在几乎所有做算法落地的团队里反复上演。算法和 infra 明明是在为同一个业务目标服务却总像两个语言不通的部门。我在两边都待过既写过排序模型、调过 CTR 预估也搭过推理服务、扛过大促流量今天想把“算法-infra协同”这件事从头到尾讲清楚为什么会有冲突、冲突的本质是什么、怎么用工具和流程把“互相拖后腿”变成“互相成就”。这篇内容适合算法工程师、infra/后端工程师以及所有需要带着算法团队落地的技术管理者读全是实操里磨出来的经验不是教科书上那种“要加强协作”的空话。1. 为什么算法和 infra 老在互相“背刺”——两个团队的目标函数从来就不一样先别急着怪谁。两边吵架的根源通常不是人品问题而是各自的 KPI 和考核方式天然对立。1.1 效果指标与工程指标本身就是一对矛盾算法同学的核心考核是离线评测集上的指标AUC、NDCG、召回率、准确率。为了让指标好看最直接的办法是把模型做得更复杂——加特征、加深网络、上 attention、上 Transformer。这是算法同学的本能也是论文和竞赛里验证过的“正确路径”。但同样的改动在 infra 同学眼里完全是另一笔账。模型复杂了单次推理的 FLOPs 涨了显存占用涨了延迟涨了单机支撑的 QPS 降了。线上资源是有限的GPU 卡是花钱买来的延迟是 SLA 里写死的。你的 AUC 涨千分之三意味着他可能要再多申请几十台机器或者要熬夜调优推理引擎才能兜住性能。我在实际项目里见过最典型的一次推荐排序模型从 LR 换成深度模型离线 AUC 涨了接近 4%算法很开心。结果上线前压测发现单次推理耗时从 2ms 涨到 7ms而当时的流量预估是日均千万级扩机器的话成本要翻一倍不止。项目直接卡了一个月最后靠量化算子融合才把延迟压回去。两边都很委屈算法觉得“效果提升你看不见吗”infra 觉得“成本超支你来担吗”。这张表基本概括了两个团队的典型视角差异维度算法团队视角infra 团队视角核心指标离线 AUC、NDCG、线上点击率/转化率QPS、TP99 延迟、资源利用率、稳定性时间尺度以周/月为迭代周期以分钟/小时为告警和响应周期对待变更希望频繁上线新模型验证效果希望变更越少越好降低稳定性风险对“崩了”的定义指标负向服务不可用、超时率升高常见抱怨“infra 不支持我的模型结构”“算法只丢个模型文件就不管了”1.2 时间尺度不同频导致“对方在拖我后腿”的错觉算法迭代是周级别的这周跑实验、下周调参、再下周出结果。但 infra 对线上稳定性负责告警是分钟级的大促保障是小时级的。两边节奏完全不同频。算法同学通常会觉得 infra 响应太慢“我提了个需求怎么排到下个月了”而 infra 同学的视角是“你上周临时改了特征这周模型要上线大促前谁敢给你发”这种节奏差会让两边都觉得对方是阻力时间久了就变成互相不信任能不沟通就不沟通。1.3 认知盲区才是最大的那堵墙比 KPI 冲突更可怕的是两边对彼此领域的无知。算法同学不了解线上推理的实际瓶颈。他不知道单卡 GPU 到底能扛多少 QPS不知道显存带宽和算力哪个先到瓶颈不知道 TensorRT 和原生 PyTorch 的推理延迟能差多少倍。所以他提需求时经常在无形中给 infra 挖坑模型结构不支持高效算子、特征数量膨胀导致预处理 CPU 打满、动态 shape 让显存预分配策略失效。infra 同学通常也不懂模型。他不知道哪些层对效果贡献大、哪些层剪掉也无所谓不敢动模型结构只能简单粗暴地“加机器”“升级配置”。这导致很多本可以通过算法侧微调就解决的问题硬生生变成了资源成本问题。协同的第一步不是搞团建、不是建群而是把这层认知盲区补上让两边能用对方听得懂的语言说话。这就是下一节要说的“翻译”能力。2. 协同的第一步不是写代码而是学会“翻译”——从效果语言到工程语言很多团队一谈协同就想着搞平台、搞系统我觉得第一步其实是把语言对齐。算法说的话和 infra 说的话根本不在一个维度上你不翻译清楚后面全是扯皮。2.1 把“效果提升”翻译成工程资源预算算法同学说“这个模型效果更好”的时候infra 同学真正关心的是三个问题要花多少机器延迟涨多少稳定性风险多大所以在我们的团队里定了一条死规矩任何模型要进入评估流程算法必须先填一张资源预算单。不需要特别复杂但必须包含以下字段模型文件的体积以及推理时的显存占用预估单次查询的预估计算量可以用 FLOPs 粗估也可以直接给模型结构让 infra 用 profile 工具跑目标线上 QPS 和延迟上限P99新增特征或数据依赖的接口调用预估耗时压测报告的链接这张单子的意义不是卡算法同学而是逼他在提需求之前先自己推演一遍我的模型变大以后算力够不够延迟会不会超如果连这些基本问题都没想过那确实不应该进入评审。填完以后infra 同学才有依据去评估“这事能不能接、要花多大代价”。2.2 建立共享的推理链路基线第二个要统一的是“基线”。很多团队连当前线上模型单次请求各阶段耗时是多少都说不清楚出了问题就变成互相甩锅算法说服务端有问题infra 说模型太重了。解决思路是在全链路加 trace把一次推理请求拆成特征工程、模型推理、后处理、结果返回四个阶段每段的耗时占比用监控系统展示出来。有了这个基线数据讨论才有依据比如“延迟涨了 5ms是特征服务超时造成的不是模型变慢”或者“模型推理占 80% 耗时该做量化了”两边对着同一份数据说话吵不起来。2.3 在线/离线一致性校验是最容易踩坑、也最值得投入的一件事在我见过的所有协同问题里发生频率最高、排查难度最大的就是“离线效果好线上不涨”甚至“线上负向”。绝大多数时候根因是离线训练时的特征处理方式和线上 serving 时不一致。举一个真实例子某个特征在线上因为存储超时返回了空值serving 端默认填 0离线训练时相同的缺失情况在样本里也填 0。看起来一样对吧但线上的“0”是缺失填充离线训练时的“0”可能恰好是真实值。两边对“0”的语义理解不同模型学到的东西和线上运行的东西根本不是一个东西。这种问题哪边单独排查都查不出来必须两边坐在一起。我们现在的做法是每次新模型要上线算法同学必须跑一个在线/离线一致性校验脚本。具体操作是从线上随机抽样一部分真实请求用离线 pipeline 重新推一遍和线上服务的结果做对比看 top-K 结果的重合度。重合度低于某个阈值比如 0.9就直接打回不允许上线。为此infra 侧配合做了一个特征样本回放服务让算法同学能方便地拿到线上真实请求做验证。这算是一个不大不小的平台投入但回报极高。2.4 一份可以直接照抄的“算法需求评审单”总结一下我们团队现在用的评审单长这样你可以直接拿去改项目必填内容说明模型概述模型结构、参数量、输入输出让 infra 知道要支持什么资源预估显存占用、单请求推理耗时、目标 QPS不填默认不允许评审特征变更新增/修改特征列表、数据来源涉及特征服务的跨团队依赖在线/离线一致性抽样请求重合度指标不达标不允许上线回滚方案模型版本回退策略、依赖接口降级方案没有回滚方案直接打回压测报告压测环境、流量模型、P99 延迟不能用“大概能扛住”糊弄这套东西真正跑起来以后你会发现算法和 infra 之间的无效沟通大幅减少。因为评审单逼着双方把事情在纸面上过了一遍会议时间从两小时缩短到二十分钟而且每次都能当场给出明确结论。3. 从“能跑”到“能上线”——模型交付流程里的协同实战填完评审单只是开始。真正复杂的环节在于模型怎么从离线实验变成线上服务这一个过程里藏着大量认知差异和工程细节。3.1 离线评测的局限不能靠运气补离线实验本质上是在历史数据上做“事后验证”它的局限非常明显样本分布会和线上实时数据偏移特征的新鲜度会衰减用户反馈有延迟。更麻烦的是离线评测通常不经过真实网络调用、不经过特征服务、不经过后处理排序所以它衡量的是“纯模型能力”而不是“线上真实服务水平”。很多团队在离线指标上高兴完就急着上线结果线上效果差得离谱再一排查发现线上特征服务经常超时模型实际吃到的是大量默认值——根本没发挥出离线时的水平。所以协同的第一个动作就是减少环境差异。离线 pipeline 要和线上 serving 共用一个特征处理库、共用一个模型导出格式、共用一份配置管理。3.2 影子环境跑流量是成本最低的试错方式在没有充分信心的时候不要直接开 A/B更不要全量上线。影子环境shadow mode是性价比最高的中间环节把线上真实请求复制一份打到新模型上但不把新模型的结果返回给用户只是记录下来和旧模型的结果做比较。影子模式的价值在于第一用的全是真实流量评估结果比离线数据可信得多第二不影响线上用户体验出任何问题都不会造成业务损失第三可以很方便地观察新模型对资源的消耗、对延迟的影响。我们团队在上新模型前都会跑几天影子环境观察特征命中率、结果分布、推理耗时是不是和离线评估一致。这一步做扎实了后面灰度出问题的概率会低很多。3.3 压测不是随便打点请求就行压测是模型上线前最容易被忽视、又最容易犯错的环节。很多团队拿 ab 工具打一堆固定请求就算压测完了然后上线当天被真实流量直接打崩。为什么因为真实流量不是均匀的它有突发、有毛刺、有热点 key 集中访问而且用户的请求分布和压测脚本里的固定请求完全不是一回事。我们现在的做法是流量回放压测把线上前一天的真实请求录制下来按时间序列重放到预发环境让新模型在“虚拟的真实流量”下跑一遍观察 P99 延迟、CPU/GPU 利用率、内存水位、超时率。这种压测方式能暴露很多传统压测看不到的问题比如某个热点特征触发了慢路径、某个 batch 策略在峰值时段失效、某个后处理排序算子在高并发下出现竞争。还要特别强调一点压测必须看长尾不能只看平均。延迟平均值很好看但 P99 涨了一倍用户实际体验就是“隔三岔五卡一下”这是绝对不能接受的。3.4 灰度发布检查清单灰度是模型上线的最后一道防线。我们的标准流程是把灰度比例分成 1%、5%、10%、30%、50%、100% 几档每档跑一段时间观察指标任何一档有异常就立即回滚或暂停。这个流程本身不复杂真正考验的是监控和回滚做得够不够到位。检查项要求负责人模型版本可回滚旧版本镜像和配置要随时可拉起infra核心指标监控点击率/转化率等业务指标不能低于基线算法性能监控P99 延迟、超时率、错误率设阈值infra资源水位监控CPU/GPU/内存/带宽趋势和压测基线对比infra特征服务依赖上下游接口的 SLA 有没有变化算法infra回滚演练每季度至少做一次模拟回滚infra3.5 一个真实案例推荐模型上线的完整协同时间线为了让你有更直观的体感我完整复盘一次我们团队近期的一次模型上线这版模型改动不大就是把原来单塔结构改成双塔离线 AUC 涨了 0.8 个千分点。第 1 天到第 3 天算法提交评审单infra 评估后认为模型结构变化会导致单请求计算量增加约 30%需要做算子优化。第 4 天到第 7 天算法跑在线/离线一致性校验发现新模型在部分特征缺失场景下输出分布和离线不一致排查后确认是特征默认值逻辑不同修复后重新校验通过。第 8 天到第 10 天infra 做算子融合和 batch 策略优化把单请求推理耗时从 6ms 压回 4.5ms。第 11 天到第 13 天流量回放压测发现新模型在高峰期 P99 延迟超出目标 20%infra 继续调优将动态 batch 的超时窗口从 50ms 调整到 30ms问题解决。第 14 天影子环境跑 48 小时效果指标和离线评估一致。第 16 天到第 22 天灰度逐步放量期间做过一次回滚演练。第 23 天全量上线线上指标正向资源消耗增加约 15%在预期范围内。可以看到整个流程里没有一个环节是能靠“单个团队”完成的每一次沟通都是跨团队的。协同得好这个时间线可以在三周内走完协同不好拖两三个月都很正常。4. 资源冲突的根子不在“不够用”在“不可预期”——算力编排的实操经验算力资源是算法和 infra 争论最激烈的话题。算法永远觉得卡不够infra 永远觉得资源利用率不够高。真正出问题的往往不是资源总量不足而是资源使用方式不可预期导致无法做任何规划。4.1 训练和推理的算力诉求完全是两回事先说清楚一点训练和推理对资源的要求截然不同。训练任务要的是吞吐看重的是单位时间内能处理多少样本。它允许延迟波动甚至允许任务被抢占、被暂停再恢复只要整体进度不落下就行。推理任务要的是低延迟看重的是单次请求时延和稳定性。它不能容忍资源被抢占更不能容忍突发的等待。这意味着把训练任务和推理任务混在同一个 GPU 集群里处理不好就会互相伤害。训练任务突然占满算力推理服务的 P99 延迟就会飙上去推理服务为了预留缓冲而空置资源训练任务又觉得浪费。4.2 比较实用的资源分配策略我们团队现在的做法是物理隔离为主、配额管理为辅。训练集群和推理集群在物理上分开避免互相干扰。训练集群内部按项目配额分配按优先级调度低优先级任务可以被抢占。推理集群单独管控按业务重要性排布核心业务和非核心业务的资源配额分层。另外训练任务要设置资源上限。很多团队踩过的坑是某个算法同学起了个数据加载任务OOM 把整个集群搞挂了或者某个测试脚本忘记关GPU 被白白占了一个月。为了避免这种问题我们全部接入配额管理和超时回收机制每个任务必须带资源申请超过时限自动释放杜绝“僵尸任务”。4.3 模型优化是协同的最大公约数与其在“要不要加机器”上讨价还价不如共同做一件事把模型变小、变快。这是算法和 infra 利益完全一致的地方也是协同红利最大的地方。常用手段包括量化把 FP32 模型量化为 INT8推理速度能提升 2-3 倍显存占用降低 75%。代价是精度可能会有小幅损失但很多业务场景损失在 0.1% 以内完全可接受。剪枝去掉模型中对效果贡献极小的参数或神经元。关键是要做敏感性分析看哪些层可以剪、哪些是敏感层不能动。蒸馏用一个大的 teacher 模型教一个小 student 模型效果接近但推理开销大幅降低。算子融合把多个小算子合并成一个大算子减少 kernel 启动开销和显存读写。比如把 ConvBNReLU 融合成一个算子工程上已经非常成熟。动态 batch把多个请求拼成一个 batch 一起推理能显著提高 GPU 利用率但要注意延迟长尾问题。这里的关键是模型优化需要算法和 infra 共同参与算法同学负责评估优化后对效果的影响提供敏感性分析数据infra 同学负责 benchmark 工具链和优化后的性能验证。4.4 一个端到端优化案例排序模型从 100ms 压到 25ms分享一个我们做过的真实优化案例过程很有代表性。起初一个排序模型在 GPU 上单次推理耗时 100ms怎么看都不可接受。我们做了四步性能剖析先 profile发现瓶颈不在矩阵运算而在频繁的 kernel 启动和 CPU 与 GPU 之间的数据拷贝。这超出很多人的直觉。算子融合把几十个小算子合并成大算子kernel 启动次数从 200 多次降到 30 多次延迟从 100ms 降到 60ms。量化从 FP32 压到 INT8精度损失 0.05%延迟从 60ms 降到 30ms。动态 batch 特征裁剪把特征中贡献极小的部分剪掉减少输入数据量进一步把延迟压到 25msP99 也从 150ms 降到了 40ms。整个过程历时三周效果提升没有变化但推理成本降到了原来的四分之一。如果没有算法和 infra 的配合这一步是走不下来的——算法不松口量化不敢做infra 不搭工具链连瓶颈在哪都找不到。5. 线上事故是最差的沟通方式——三类高频冲突场景的复盘说实话很多团队的协同不是在没出事时建立的而是在出事故时被迫“磨合”出来的。但线上事故是最好的老师每一次都值得复盘。我挑三类最高频的冲突场景每个都有血泪教训。5.1 场景一“特征没生效”原来是默认值口径不一致事情经过算法同学上线一个新模型效果一直不达预期排查发现很多请求的核心特征都是 0。算法一口咬定“特征没生效”infra 说“特征服务明明返回了”。两边僵持了一整天最后发现特征服务在某些情况下会返回空值serving 端判断为空后填 0但算法同学看的日志里线上特征值一直是 0他以为特征是 0 是正常的实际上那个 0 是错误填充。教训是“空值”和“0”在算法模型里是完全不同语义的但工程实施里很容易被简化成同一个值。这个问题的根子在两边没有统一特征缺失的处理逻辑。现在我们的规矩是特征协议里明确区分“真实 0”和“缺失填充 0”并且特征校验脚本里加了一条“缺失率监控”超过阈值直接告警。5.2 场景二大促流量高峰调度把训练任务挤掉了事情经过大促活动开始前infra 为了保证在线服务稳定性把训练任务全部暂停。结果活动结束后算法同学发现自己的模型还是三天前的版本活动期间线上的效果指标一路走低白白损失了流量。教训训练任务和在线服务资源不是“非此即彼”的关系而是需要分级保障。核心业务在线服务优先级最高没问题但训练任务也应该有保底资源。我们后来给训练任务划分了最低资源保障线大促预热阶段就把需要用的模型提前训练好大促期间只允许低优先级任务暂停核心训练任务不受影响。5.3 场景三定时任务把夜间服务打抖动事情经过算法团队每天凌晨 2 点跑一个全量模型重训任务这个任务会同时触发特征数据的大规模重算占满 CPU。而那段时间恰好是海外用户的流量高峰结果夜间的 P99 延迟严重超标部分请求直接超时。教训定时任务不是“想跑就跑”一定要和 infra 确认好业务低峰时段同时考虑任务的资源限制。我们现在的做法是所有周期性任务必须经过资源调度系统注册设置好 CPU/内存上限并错峰执行。定期重训任务放在流量最低谷还要提前压测确认对在线服务无影响。5.4 复盘流程不追责追的是“下一个同学怎么不踩坑”每次事故后我们会拉一个四方的复盘会议算法、infra、测试、负责人到齐按固定格式走受影响范围是什么实际损失多大直接原因是什么触发点在哪根本原因是什么为什么会存在这个触发点改进项是什么每一改进项的负责人和时间点验证方式是什么怎么确认这次是真的修好了复盘最重要的原则是不追责而是把问题变成预防机制。比如前面说的“特征缺失”问题复盘后加了一个自动校验环节“定时任务抖动”问题复盘后加了错峰调度和资源上限。真正让团队变强的不是找到“谁错了”而是找到“流程哪里漏了”。5.5 冲突处理的最终决策原则当算法和 infra 真正吵起来的时候必须有一个清晰的决策原则不能靠拍桌子。我们内部是这么定的冲突类型决策原则谁说了算效果指标 vs 成本指标以业务目标为准看投入产出比业务负责人上线节奏 vs 稳定性核心链路稳定性优先infra但必须给出明确时间表模型结构 vs 性能优化先优化再改结构仍不达标则结构调整infra 提方案算法做效果验证资源分配矛盾优先级由业务价值决定不能按嗓门平台负责人这套原则不一定适合所有团队但核心思想是一致的影响线上稳定性的决策infra 有一票否决权但算法有充分的解释权和申诉权。如果 infra 单纯是觉得“麻烦”而不支持算法需求那就是流程的问题而不该用否决权压人。6. 真正让协同持续的是机制而不是人缘——组织与流程建设人跟人之间的磨合再紧密也架不住人员流动。一个团队如果依赖“我和 infra 关系好所以事情好办”那这个协同状态是非常脆弱的。真正能落地的是把它变成机制。6.1 模型上线评审会怎么开才不流于形式评审会很容易变成走过场关键是控制会议内容和节奏。我们现在的模型上线评审会是这样开的会前算法必须提交评审单和压测报告不提交不排会。会中只讨论评审单上列出的风险和依赖不临时发散。会后输出明确的结论和待办每个待办有 owner 和 deadline。评审会不是“技术宣讲会”而是“风险确认会”。它的产出是“这版模型能不能上线需要什么条件”而不是“这版模型有多牛”。6.2 统一看板让两边看同一份数据很多团队有两个数字算法一个infra 一个开会时对不上账。我们的解法是建一个统一看板把四类数据放一起算法效果趋势CTR、CVR、AUC、线上主要业务指标资源水位GPU 利用率、CPU 利用率、内存、带宽性能指标TP99、P99、平均延迟、超时率变更记录模型版本、发布时间、回滚记录这个看板让两边每天看的是同一份数据。算法看到资源水位接近上限的时候会主动讨论是否要优化模型infra 看到效果指标连续下降时也会主动去查是不是服务有问题而不是只看自己的告警。6.3 轮岗和例会共享是“换位思考”最快的办法我们内部有一个强制性的“一方参与另一方例会”的制度算法团队每周派一个人参加 infra 的周会infra 也每周派一个人参加算法的周会。不需要发言只是旁听。这个做法的效果出奇地好。算法同学听了几次 infra 的周会后终于理解了为什么自己提的“小需求”要排到下周——因为线上有大量稳定性维护事项在排队。infra 同学听了算法周会后也终于理解了为什么算法同学那么在意特征上线的时间点——因为离线实验错过了那个时间点整个迭代周期就要后移两周。更进一步的做法是短期轮岗让算法工程师值班一次 infra 的 oncall亲身体验一下告警轰炸的感受让 infra 工程师跟着跑一次模型实验亲身感受一下“训练到一半任务挂掉”的崩溃。这个做法需要一定组织支持但投入产出比非常高一次轮岗带来的相互理解比十次团建都有效。6.4 知识库把“约定”沉淀成“文档”最后所有协同的约定都必须沉淀成文档写进知识库形成团队记忆。我们团队的知识库里现在维护着这些内容模型注册表所有线上模型的信息包括版本、负责人、输入输出、资源申请、依赖特征。资源申请规范怎么申请训练资源、怎么申请推理资源、怎么评估成本。上线 Checklist刚才说的灰度发布检查清单每次上线前必须所有人勾一遍。事故复盘库每次复盘的全文记录包括根因分析和改进项方便后人查阅。这些文档最直接的价值是降低“上下文成本”——一个新人入职后不需要靠“口口相传”才能把模型推上线他只需要照着规范一步步做就能避免大部分坑。我在算法和 infra 两边都坐过工位最大的体会是算法-infra 协同的本质不是靠“态度好一点”就能解决而是靠机制把不确定性变成确定性。你不可能让所有冲突消失但你可以让每一次冲突都有清晰的解决路径。给一个最小成本的启动建议从下周的周会开始让算法同学报效果的时候同时报延迟预算和资源预估让 infra 同学报资源水位的时候同时给出性能瓶颈分析。只要这个习惯养成了协同就已经在路上了。

相关新闻