首页 / 资讯中心 / 文章详情

算法与基础设施协同:模型生产环境稳定落地的关键实践

算法与基础设施协同:模型生产环境稳定落地的关键实践 ★ FEATURED ARTICLE
算法和infra协同这个组合词最近两年在技术社区里出现的频率越来越高。算法模型训练出来只是个开始真正让它稳定跑在生产环境、承受住真实流量靠的是基础设施团队和算法团队之间那条既看不见又极其关键的协作链条。我同时蹲过算法组和平台组两边都待过深知这套协同做不好再漂亮的模型指标都是空中楼阁线上出问题时两边还容易互相甩锅。这篇文章我想把真实项目里遇到的协作痛点、职责边界、流水线设计、性能博弈和监控拉通这些事掰开揉碎讲清楚希望能帮正在被这类问题困扰的团队少走几条弯路。1. 本地一切正常一上生产就翻车差异到底藏在哪里这个问题几乎每个月都会发生一次。算法同学在本地或离线训练环境里把模型调得漂漂亮亮评估指标全线达标结果一部署到线上推理服务延迟飙高、显存溢出、甚至直接OOM崩溃第一反应就是“infra那边有问题”。但多数时候问题根源不在基础设施本身而在训练环境和推理环境之间那些不起眼的差异。1.1 训练环境与推理环境的“微小”偏差先说CUDA和驱动。训练集群的驱动版本通常是新部署的GPU型号也相对统一比如V100、A100。但线上推理集群可能是不同批次采购的混着T4、P40这种老卡。同一个PyTorch模型在不同算力、不同驱动版本下算子的kernel选择逻辑会发生变化结果就是本地benchmark延迟10毫秒线上却跑出40毫秒而且没人说得清这30毫秒差在哪。再说Python依赖。训练代码里的numpy、pandas版本和线上推理镜像里的版本很难保证完全一致尤其是那些用Cython写的库版本升级后同一段代码执行路径可能完全不同。还有CPU指令集训练时多数运算在GPU上但数据预处理、padding、tokenizer这些逻辑跑在CPU上线上容器的CPU型号如果少了某个AVX指令集性能会肉眼可见地下降。最隐蔽的是数据形状变动。训练时你习惯用固定batch size比如128但线上服务收到的请求数量是实时变化的推理框架会动态拼batch。动态shape会让GPU算子频繁做kernel重编译这一下就把延迟从“平稳”变成“过山车”。我记得有次把padding长度从固定64改成动态截断本意是省算力结果线上p99延迟反而涨了3倍就是因为kernel重编译和显存碎片化。1.2 一次延迟突刺的完整复盘那次事故我印象很深。某个推荐模型的p99延迟从日常20毫秒突然跳到120毫秒持续了将近半小时。infra同事第一时间看网络、看容器CPU、看磁盘IO全都没异常算法同学看GPU利用率发现只有30%就认定“资源肯定够是infra调度的问题”。两边僵了一个小时最后我把模型推理日志和infra监控拉到同一张时间轴上才发现那半小时里请求文本长度分布发生了明显右移长文本比例从5%涨到35%。模型对长文本的注意力计算复杂度是平方级上升的同时动态padding又导致GPU算子频繁重建两件事叠加延迟自然爆炸。根子在于算法团队做离线评估时用的数据集是“平均长度”从没考虑到线上长度长尾分布。那次之后我们定了一个规矩任何模型上线前算法必须提供“线上输入分布分析”infra根据这个分布决定batch策略、显存预留和弹性伸缩阈值。这比出了事再排查高效得多。2. 算法和infra的职责边界谁的模型谁负责但中间地带必须有人管很多团队一开始会把算法和infra当成纯粹的上下游算法把模型文件一交剩下的全是infra的事。这种边界意识看似清晰实则埋雷。2.1 常见的两类错误认知第一类算法觉得“我只出模型部署是infra的事”。于是模型文件丢过来没有文档、没有版本说明、没有输入输出约束infra同学只能靠猜。第二类infra觉得“我只管服务稳定模型效果和我无关”。结果线上A/B实验效果负向两边互相推诿算法说“是infra容量不够导致超时”infra说“模型自己不行”。真实情况是模型的服务化效果是两边的共同产物。算法决定“做什么”和“做多好”infra决定“跑多快”和“花多少钱”中间重叠地带恰恰是决定线上成败的关键。2.2 正确的边界地图我总结了一张职责划分表格每次新项目启动会都拿出来对齐效果比嘴上说一百遍都强职责域算法团队infra团队中间地带必须协同模型效果指标AUC、召回率、线上业务指标负责不负责但需要知情效果波动时的归因分析模型正确性输入输出逻辑、特征处理一致性负责不负责特征上线前的字段评审推理延迟性能负责提供模型性能基线负责部署调优性能预算的制定与遵守服务可用性SLA、容灾、扩容不负责负责容量规划时算法需提供QPS预估资源成本不负责负责成本与收益的权衡评估这张表的核心是任何一项职责都不是单方面的中间地带要有一个明确的接口人。我们在每个项目里会指定“算法对接人”和“infra对接人”凡是跨域问题只需要找对接人不需要各自拉群扯皮。2.3 中间地带的协调机制中间地带最常见的问题是“性能预算”缺失。所谓性能预算就是线上环境下单个推理请求允许消耗的最大资源比如“单次推理不超过50毫秒、显存不超过2GB”。算法在模型选型时就要背着这个预算去做而不是做一个精度很高但重到跑不动的模型然后指望infra硬扛。我见过一个反例算法同学选了一个700M参数的Transformer模型离线精度确实比小模型高1.5个点但线上单卡只能扛5 QPS而业务要求是200 QPS最后只能拆成多机分布式推理成本翻了8倍。如果一开始就定好性能预算算法大概会换一个更轻量的模型加上蒸馏方案。3. 从训练产物到线上服务一条能对齐双方的流水线长什么样如果每次上线都依赖“算法口头说明 infra临场猜测”协同成本高到没法看。我比较认同的做法是把交付过程标准化让模型上线像软件发版一样有章可循。3.1 交付物规范化模型卡与依赖固定所谓模型卡就是一份模板化的说明文档里面必须写清楚模型用途、输入输出定义、特征依赖、离线评估结果、资源需求、已知风险这六项。它不是什么科研产出而是给infra同学看的“安装说明书”。依赖固定更关键。训练一份模型时必须把Python包版本、CUDA版本、模型框架、推理引擎都锁定下来。一个很实用的做法是训练环境生成一份requirements-lock.txt同时把推理镜像构建放在CI流程里任何依赖变更都自动触发重新构建避免“本地能跑镜像不能跑”的尴尬。3.2 推理接口协议输入输出schema、错误码、健康检查算法和infra之间最容易出问题的就是接口字段的隐式约定。算法觉得“这个字段命名很自然”infra却不知道它的取值范围和边界。我们后来约定所有模型推理接口必须显式定义JSON Schema字段含义、类型、是否可空、取值范围、默认值全部写清楚。类似这样{ model_name: click_rank_v3, model_version: 3.2.1, inputs: [ { name: user_features, type: array, items: {type: number}, description: 用户侧特征向量长度固定为128 }, { name: item_list, type: array, items: { type: object, properties: { item_id: {type: string}, item_features: {type: array, items: {type: number}} } } } ], outputs: { scores: {type: array, items: {type: number}} } }健康检查的接口也要统一约定。infra的负载均衡器需要知道服务是否真正可用不能只返回“进程还在”就万事大吉。健康检查接口应该做一次最小化推理或者至少校验模型文件是否加载完整、依赖的特征服务是否连通避免流量打到一台“半死不活”的节点上。3.3 发布流程离线评估和在线验证怎么衔接模型发布不能是“一把梭”我比较推荐的流程是“离线评估 → 影子流量 → 金丝雀发布 → 全量上线”四步走。影子流量阶段把线上真实请求复制一份打到新模型服务上但不影响真实返回结果用来观察新模型在真实负载下的推理耗时和显存占用看看有没有性能问题。金丝雀发布阶段把1%-5%的真实流量切到新模型同时盯着业务指标和系统指标确认没问题再逐步放量。如果效果指标异常要能一键回滚到旧版本这个回滚能力必须在第一次发布前就验证过别等出了事再研究怎么回滚。4. 性能与成本博弈算法同学和infra同学如何用数据对话算力资源永远不够预算永远紧张。算法想用更大的模型、更宽的特征infra想控制成本、提高资源利用率。两者碰撞是常态但有一点可以确定靠感觉争论没有意义只有用数据对话才解决得了问题。4.1 谁来决定GPU卡型和副本数这是两个团队之间最常见的分歧。算法希望分到一张大显存卡infra希望能用多张小卡跑更多服务。合理做法是算一笔账先确定单请求的推理延迟SLA再看单卡能支撑的最大QPS反推出需要的副本数。比如业务要求单请求算法部分不超过30毫秒模型在T4上单卡单batch是12毫秒支持动态batch后单卡可以扛40 QPS业务高峰期需要400 QPS那就至少需要10个副本加上冗余至少12个。这些数字都算清楚申请资源时就不用“我觉得”了。4.2 加速手段的收益和代价infra团队经常喜欢用量化、算子融合、蒸馏这些手段来加速推理但算法团队天然对精度损失敏感。这里需要一个评估机制加速手段不能单方面决定要跑一遍离线评估把精度变化报告拿出来一起决策。加速手段收益风险/代价谁来评估FP16半精度推理显存减半吞吐提升明显可能出现精度损失、数值溢出算法评估精度infra评估吞吐INT8量化吞吐提升最大精度损失更明显需校准数据集算法主导infra配合算子融合减少kernel启动开销延迟降低工程复杂度高调试难infra主导模型蒸馏延迟和显存双降需要重新训练周期长算法主导我见过最顺滑的协同模式是infra把加速方案的预期收益和风险写清楚算法负责评估精度影响双方共同决定是否上线。从一开始就保持透明就不会出现“你量化完了模型烂了”这种秋后算账的事。4.3 自动扩缩容的坑很多团队一步到位上Kubernetes的HPAHorizontal Pod Autoscaler以为设好CPU阈值就万事大吉。但模型推理服务有个特点请求量上来时GPU利用率不一定马上升高因为瓶颈可能在CPU预处理或内存拷贝上。等CPU指标反映出来流量已经洪峰过境了扩容完全来不及。更实际的方案是用自定义指标做扩缩容比如“排队请求数”或“推理线程池积压长度”。积压超过阈值立即扩容积压清空再逐步缩容。配合最小副本数避免冷启动延迟和资源抖动。这个方案需要算法和infra共同设计因为“排队长度”这个指标和模型推理时延强相关。5. 线上监控和根因定位算法指标与系统指标必须放在一张图上看每次线上出问题算法和infra各看各的监控看板谁也说服不了谁。我后来学到一个教训监控必须拉通两个团队必须习惯在同一个时间轴上排查。5.1 割裂的监控是问题查不清的根源有次线上推荐业务点击率掉了10%算法团队怀疑是特征数据延迟infra团队怀疑是网络抖动两边各自查了两小时也没结果。最后把会话日志和系统指标对齐发现那个时段里特征服务的响应时间从5毫秒涨到了800毫秒根因是特征服务所在机器磁盘IO被打满而磁盘IO的波动在infra看板上有明显峰值只是算法团队从来没看过那块面板。如果两边从一开始就在同一个看板里看问题这次故障定位大概只需要十分钟。5.2 两张必须拉通的看板我现在做项目都会要求团队搭两张看板并且放在同一个监控系统里方便随时联动。模型指标看板QPS、推理延迟p50/p95/p99、batch大小均值、排队长度、错误率、超时率、输入特征分布漂移、模型预测分数分布漂移。系统资源看板CPU使用率、内存使用率、GPU利用率、GPU显存占用、GPU温度、磁盘IO、网络带宽、容器重启次数。关键不是静态展示而是要有“同一个时间轴上的事件联动”。比如模型p99延迟上涨时旁边就能看到GPU利用率是否饱和、batch大小是否突然变化、输入分布是否偏移。这样根因定位从“猜谜”变成了“看图说话”。5.3 联合排障的SOP有了一套协同看板之后还得有一套联合排障的标准动作。我们内部跑过一次演练后总结出来的流程大概是确认最近变更清单包括模型版本、代码、配置、特征数据、资源容量任何一项有变动都要列入嫌疑列表看整体服务状态确认是局部实例问题还是全局限流按“输入 → 模型计算 → 输出 → 下游调用”这条链路逐段检查每段都有明确负责人每15分钟同步一次进展避免“查着查着就跑偏”。这套SOP看起来很简单但有和没有完全不一样。6. 长期协作沉淀把一次次的“吵架”变成流程和文档最后聊聊团队文化和长期机制。技术问题盘根错节但绝大多数摩擦的根源是信息不对称。把踩过的坑变成制度和文档比在会上喊“大家要多沟通”有用一百倍。6.1 我踩过的三个典型坑第一个坑是随机种子和固定数据顺序。算法训练时没固定随机种子导致每次训练出来的模型虽然指标差不多但对特定样本的预测行为差异很大。上线后业务方反馈“模型行为变了”两边查了很久最后发现只是随机种子变动导致的。这种问题必须在训练脚本里把seed固定下来并且写进模型卡里。第二个坑是共享特征服务升级协议不兼容。infra团队升级了一个特征服务的RPC协议以为“向下兼容没问题”结果新模型用了新字段旧模型还在用旧字段测试时没覆盖到全部模型版本线上部分请求拿不到特征直接走了兜底分支模型效果明显下降。从那以后凡是涉及共享服务的变更必须有一个“影响面评审”把所有模型版本和调用方列清楚再动手。第三个坑是SLA没人定。团队快速扩张期没人明确说这个推荐服务该保证几个9的可用性、允许的延迟是多少、QPS峰值预估是多少。结果流量翻倍时服务直接雪崩谁都没提前做过容量规划。现在所有模型服务上线前必须写一个SLA文档哪怕只是“尽力而为”白纸黑字写下来后续责任自然清晰。6.2 对协作有效的几个小习惯我现在倾向于在团队里推行几个轻量级习惯不搞复杂流程和重型平台先让协作跑起来。变更日历所有模型版本、配置改动、推理镜像更新、特征口径调整提前一天登记到一个共享日历里关联负责人和影响范围。好处是出问题时能快速排除“最近谁动过东西”这个嫌疑。故障复盘机制每次故障不是追责而是画时间线、列触发点、写改进清单。只有真正把“事故”变成“案例”协作才可能一次比一次顺滑。轮值接口人算法和infra团队各指定一个轮值接口人负责当周的跨团队需求流转和紧急问题响应。避免每次都是“临时的沟通靠人脉、长期的问题靠运气”。我现在越来越觉得算法和infra之间的协同不是简单的上下游交接而是一套共享目标、共享边界、共享责任的工作方式。模型是算法团队的心血服务是infra团队的地基两者拼在一起才是真正能在线上创造价值的产品。每个团队的情况不一样但把流程标准化、数据透明化、责任明确化这几点做到位大概率不会跑偏。
阅读完成 · 觉得有帮助?
咨询建站