ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

从零构建AI工程体系:数据管道、模型训练与部署监控全链路实战

从零构建AI工程体系:数据管道、模型训练与部署监控全链路实战 1. 从零搭建AI工程体系我为什么劝你别急着调包ai-engineering-from-scratch这个标题第一次看到的时候我愣了一下。市面上讲AI的教程铺天盖地但绝大多数都是教你import torch然后跑个预训练模型或者调个API接口就完事。真正从零开始、把AI工程当作一门系统工程来拆解的内容少得可怜。我自己在这个领域摸爬滚打了七八年带过团队也踩过无数坑。最深的体会是AI工程和AI研究是两码事。研究关注的是模型能不能跑出SOTA指标工程关注的是这套东西能不能稳定、高效、可维护地跑在生产环境里。前者是实验室里的艺术品后者是工厂里的流水线。这个项目标题的核心价值在于from scratch——从零构建。它不是让你从零训练一个GPT-4那既不现实也没必要。它真正要解决的是当你面对一个实际的AI需求时如何从最底层的逻辑出发一步步搭建出完整的工程体系。这包括数据处理管道、特征工程、模型选型、训练流程、评估体系、部署方案、监控告警以及最重要的——迭代闭环。适合谁来参考我认为有三类人第一类是刚入行的AI工程师学校里教的多半是算法原理工程实践几乎空白第二类是从传统后端转过来的开发者代码能力没问题但对AI这套东西的工程化缺乏系统认知第三类是小团队的技术负责人资源有限需要一个人把整条链路都撑起来。这篇文章我会把从零构建AI工程这件事拆开揉碎不讲虚的全是实操层面的东西。每个决策背后的为什么每个步骤的怎么做以及我踩过的那些坑都会毫无保留地分享出来。2. 整体架构设计先想清楚数据怎么流2.1 为什么架构设计要从数据流开始很多人做AI项目上来就选模型、调参数这是典型的本末倒置。我见过太多项目模型效果怎么调都上不去最后发现是数据管道有问题——训练数据和推理数据的分布不一致或者特征计算逻辑在线上线下两套代码里出现了偏差。AI工程的第一性原理是数据决定上限模型逼近上限。所以架构设计必须从数据流开始。一个完整的AI工程体系数据流大致是这样的原始数据采集 → 数据清洗与校验 → 特征工程 → 训练样本生成 → 模型训练 → 模型评估 → 模型部署 → 在线推理 → 日志回流 → 数据再采集。这是一个闭环任何一个环节断了整个系统就是瘸腿的。我习惯把这个闭环画成三层离线层负责数据处理和模型训练近线层负责特征回填和模型评估在线层负责实时推理和日志采集。三层之间通过标准化的数据契约来通信而不是靠人肉同步。2.2 技术选型的核心考量选型这件事我的原则是不追新看生态不唯性能看维护成本。拿数据处理来说Spark和Flink怎么选如果你的数据量在TB级别以下且对实时性要求不高Spark就够用了生态成熟招人也好招。如果数据量更大或者需要秒级延迟再考虑Flink。别为了技术先进而选型那是给自己挖坑。模型训练框架PyTorch现在是事实标准这一点没什么好纠结的。但要注意版本管理我吃过亏——生产环境用的PyTorch版本和训练时不一致导致模型加载失败。后来我们强制要求所有环境用Docker镜像统一镜像里锁定所有依赖版本这个问题才彻底解决。特征存储这块很多人会忽略。小规模的时候用Redis或者MySQL存特征没问题但一旦特征数量上千、需要做时间旅行查询point-in-time correctness就必须上专门的Feature Store。我们当时自研了一套简易版核心就是两张表一张存特征元数据一张存特征值带时间戳。查询的时候根据训练样本的时间戳去对齐特征避免数据泄露。部署方案小团队直接上FastAPI Gunicorn就够了别一上来就Kubernetes运维成本扛不住。等QPS上来了再考虑容器编排。2.3 目录结构设计的一个实用模板从零构建项目目录结构很关键。我推荐这样一个模板ai-project/ ├── configs/ # 配置文件按环境分 │ ├── base.yaml │ ├── dev.yaml │ └── prod.yaml ├── data/ # 数据相关 │ ├── raw/ # 原始数据 │ ├── processed/ # 清洗后数据 │ └── features/ # 特征数据 ├── src/ │ ├── data/ # 数据处理代码 │ ├── features/ # 特征工程代码 │ ├── models/ # 模型定义 │ ├── training/ # 训练流程 │ ├── evaluation/ # 评估逻辑 │ └── serving/ # 推理服务 ├── tests/ # 测试用例 ├── notebooks/ # 探索性分析 ├── scripts/ # 运维脚本 └── requirements.txt这个结构的好处是职责清晰新人进来能快速定位代码。configs目录用YAML管理配置不同环境覆盖不同参数避免硬编码。notebooks目录允许存在但必须约定notebook里的代码不能直接上生产必须重构到src里。我见过太多项目核心逻辑散落在几十个notebook里维护起来简直是灾难。3. 数据处理管道脏数据是万恶之源3.1 数据采集阶段的防坑指南数据采集看起来简单实际上坑最多。第一个坑是数据源不稳定。我们曾经依赖一个第三方接口拉数据结果对方接口时不时超时导致训练数据缺失。后来我们加了重试机制和本地缓存每次拉取的数据先落盘处理失败可以从本地恢复。第二个坑是数据格式不一致。同一个字段今天传过来是字符串123明天变成数字123后天变成123.0。这种问题在JSON接口里特别常见。解决办法是在采集层就做严格的Schema校验用Pydantic或者Great Expectations这类工具不符合Schema的数据直接拒掉并告警。第三个坑是时间戳时区问题。这个坑极其隐蔽我们曾经因为时区问题导致训练数据里混入了未来数据模型离线指标好得离谱上线后直接崩盘。后来我们强制要求所有时间戳统一用UTC存储展示层再做转换。3.2 数据清洗的标准化流程数据清洗我总结了一个五步法去重根据业务主键去重注意有些重复是合理的比如用户多次点击要区分对待。缺失值处理数值型字段看分布均值/中位数填充或者标记为缺失类别型字段可以填充unknown作为一个独立类别。异常值检测用IQR或者3-sigma方法但要注意业务含义。比如用户年龄出现200岁那肯定是异常但用户消费金额出现极大值可能是真实的大客户。格式统一日期格式、字符串大小写、单位统一这些琐碎但必须做。一致性校验比如订单金额应该等于商品单价乘以数量加上运费这种业务规则校验能发现很多隐藏问题。注意清洗规则一定要版本化。我们曾经因为改了清洗规则但没有记录导致新旧数据混在一起训练模型效果莫名其妙下降。后来所有清洗规则都写在配置文件里每次变更都记录版本号和变更原因。3.3 特征工程的实操要点特征工程是AI工程里最需要领域知识的部分。我的经验是先做业务特征再做统计特征最后考虑自动化特征工程。业务特征就是直接从业务逻辑里提取的比如用户的最近一次登录时间、过去7天的订单数。这类特征可解释性强效果稳定。统计特征包括均值、方差、分位数、趋势等。做这类特征要注意窗口选择窗口太短噪声大窗口太长反应迟钝。我们通常会同时计算多个窗口的特征让模型自己去学哪个窗口重要。自动化特征工程工具比如Featuretools在特定场景下有用但不要迷信。我试过在几个项目里用效果提升有限反而增加了特征管理的复杂度。特征工程还有一个关键点线上线下一致性。训练时用Spark算特征推理时用Python算特征两套代码逻辑稍有偏差就会导致效果下降。我们的做法是把特征计算逻辑封装成独立的库训练和推理都调用同一个库只是执行引擎不同。这样虽然牺牲了一点性能但保证了正确性。4. 模型训练与评估别被离线指标骗了4.1 训练流程的工程化改造从零构建训练流程核心是把实验变成流水线。实验是随机的、不可复现的流水线是确定的、可复现的。第一步是配置管理。所有超参数、数据路径、模型结构都写在配置文件里代码里不允许出现魔法数字。我们用Hydra做配置管理支持配置继承和命令行覆盖非常方便。第二步是实验追踪。每次训练都要记录用了什么数据、什么配置、什么代码版本、最终指标是什么。我们用MLflow轻量级部署简单。关键是要把Git commit hash记录下来这样才能追溯到具体的代码版本。第三步是检查点管理。训练过程中定期保存模型检查点但要注意存储成本。我们的策略是每个epoch保存一次但只保留最近3个和最佳1个其他的自动清理。第四步是分布式训练。单卡不够用的时候数据并行是最简单的方案。PyTorch的DDP用起来不难但要注意几个坑batch size要按卡数放大学习率也要相应调整数据加载的worker数量要合理太多会导致CPU瓶颈。4.2 评估体系的设计原则离线评估最容易骗人。我见过太多模型离线AUC 0.95上线后业务指标纹丝不动。问题出在评估体系上。评估指标要分层。底层是模型指标AUC、F1、RMSE等中层是业务指标点击率、转化率、GMV顶层是最终目标用户留存、营收。模型指标好不代表业务指标好业务指标好不代表最终目标达成。评估数据集要划分合理。随机划分是最偷懒的做法但很多时候不适用。比如时间序列数据必须按时间划分否则就是数据泄露。用户相关数据要按用户划分同一个用户不能同时出现在训练集和测试集。要做在线评估。离线评估通过后先做小流量AB测试观察核心指标有没有显著变化。AB测试要注意样本量计算别跑了半天发现统计不显著。4.3 过拟合与欠拟合的排查思路过拟合和欠拟合是训练中最常见的两个问题但排查思路完全不同。过拟合的表现是训练集指标远好于验证集。排查方向数据量是否足够、模型复杂度是否过高、正则化是否到位、有没有数据泄露。我遇到过一次严重的过拟合最后发现是特征里包含了标签信息属于典型的数据泄露。欠拟合的表现是训练集和验证集指标都不好。排查方向模型容量是否足够、特征是否充分、学习率是否合适、有没有欠训练。有时候欠拟合是因为特征太弱这时候加特征比换模型更有效。实操心得遇到效果不好先别急着调模型花80%的时间检查数据和特征。我统计过自己解决过的模型效果问题至少七成根源在数据上。5. 部署与监控上线才是真正的开始5.1 模型部署的三种模式模型部署没有银弹要根据场景选模式。在线推理适合对延迟敏感的场景比如推荐、风控。模型常驻内存请求来了直接算。要注意的是模型加载时间大模型加载可能要几十秒服务启动时要做好健康检查别让流量打到还没准备好的实例上。批量推理适合对延迟不敏感、数据量大的场景比如离线报表、用户分群。用Spark或者Ray做分布式推理效率很高。流式推理适合实时性要求高的场景比如实时风控。通常和流计算平台结合模型作为UDF嵌入。我们大部分场景用的是在线推理架构是FastAPI ONNX Runtime。ONNX的好处是推理速度快而且可以跨框架。PyTorch模型导出ONNX要注意opset版本不同版本支持的算子不一样。5.2 监控体系的搭建模型上线后监控是生命线。监控要覆盖三个层面系统层面CPU、内存、GPU利用率、请求延迟、错误率。这些用Prometheus Grafana就能搞定。模型层面输入分布、输出分布、特征缺失率、预测置信度。输入分布偏移是模型效果下降的最常见原因要重点监控。我们用PSIPopulation Stability Index来衡量分布偏移PSI大于0.2就告警。业务层面核心业务指标的变化。这个要和业务方一起定义比如推荐系统的点击率、风控系统的拦截率。监控告警要分级。P0告警直接打电话P1告警发消息P2告警记录到日报。别所有告警都打电话那样大家会麻木。5.3 模型迭代的闭环设计模型迭代不是训练一个新模型替换旧的那么简单。完整的闭环包括监控发现效果下降 → 分析原因 → 补充数据 → 重新训练 → 离线评估 → 在线AB测试 → 全量上线。这个闭环里数据回流是最关键的一环。线上推理的输入和输出都要记录下来这些数据是下一轮训练的宝贵素材。但要注意隐私合规敏感信息要脱敏。我们曾经忽略数据回流结果模型上线半年后效果持续下降想重新训练却发现没有线上数据可用。后来我们强制要求所有推理服务必须记录日志日志保留至少3个月。6. 常见问题与排查技巧实录6.1 训练不收敛的排查清单训练不收敛是最让人头疼的问题。我整理了一个排查清单按优先级排序排查项检查方法常见原因数据标签随机抽样检查标签错误、标签泄露学习率打印loss曲线太大导致震荡太小导致不下降数据归一化检查特征分布特征量纲差异大模型初始化检查初始loss初始化不当导致梯度消失损失函数核对实现损失函数与任务不匹配梯度打印梯度范数梯度爆炸或消失这个清单我用了很多次基本上能覆盖90%的不收敛问题。6.2 线上效果下降的应急处理线上效果下降第一反应不应该是重新训练模型而是先止损。止损的手段包括回滚到上一个版本、降低模型权重、切换到规则兜底。止损之后再做根因分析。常见原因有三类数据问题输入分布变了、模型问题模型文件损坏、系统问题特征计算服务挂了。排查顺序是先系统后模型再数据因为系统问题最容易排查。我们有一次线上效果突然下降排查了半天发现是特征计算服务的一个依赖库升级了导致某个特征的计算结果变了。这种问题极其隐蔽后来我们在特征计算服务里加了单元测试每次升级都要跑一遍确保输出一致。6.3 团队协作中的工程规范AI项目往往需要多人协作工程规范很重要。我总结了几个必须遵守的规范代码规范统一用black格式化用flake8做静态检查提交前必须通过。这不是形式主义统一的代码风格能大幅降低review成本。分支管理用Git Flowfeature分支开发develop分支集成master分支发布。模型训练代码和数据要分开管理数据用DVC或者Git LFS。文档规范每个模块必须有README说明输入输出和依赖关系。模型卡片要记录模型的基本信息、训练数据、评估结果、使用限制。评审规范模型上线前必须经过评审评审内容包括离线指标、在线AB测试结果、监控方案、回滚方案。踩过的坑曾经有个同事直接在master分支上改代码训练模型结果把别人的实验覆盖了。后来我们强制要求所有训练必须从feature分支发起并且记录commit hash。7. 从零构建的进阶方向7.1 自动化机器学习流水线当团队规模扩大、模型数量增多时手动管理每个模型的训练和部署会变得不可持续。这时候需要考虑自动化流水线。核心是CI/CD/CT持续集成代码变更自动测试、持续交付模型自动部署、持续训练数据变更自动触发训练。我们用Airflow做任务编排用Jenkins做CI用Argo CD做部署。整套流程跑通后新模型从提交代码到上线只需要半天。7.2 模型性能优化模型上线后性能优化是永恒的话题。优化方向有三个模型压缩、推理加速、硬件利用。模型压缩包括剪枝、量化、蒸馏。量化是最容易见效的FP32转INT8通常能提速2-3倍精度损失在1%以内。但要注意不是所有模型都适合量化有些对精度敏感的模型要谨慎。推理加速可以用TensorRT、OpenVINO这些工具针对特定硬件优化。硬件利用主要是GPU利用率通过批处理、多流并发等手段提升。7.3 特征平台的建设当特征数量超过几百个、多个团队共用特征时就需要建设特征平台。特征平台的核心功能包括特征注册、特征版本管理、特征血缘追踪、在线离线一致性保证。我们自研的特征平台花了大概三个月核心是一套元数据管理系统加上一套特征计算引擎。元数据管理用PostgreSQL特征计算引擎支持Spark和Flink两种模式。上线后特征复用率从30%提升到70%新模型开发周期缩短了一半。这个方向内容很多展开讲能再写一篇长文。核心思路是先把流程跑通再考虑平台化先解决有无问题再解决好坏问题。别一上来就追求大而全的平台那是给自己找麻烦。我在实际项目中的体会是AI工程从零构建最难的不是技术而是坚持工程化的思维。很多人做着做着就回到了调包跑通就行的老路结果项目越做越乱最后无法维护。把每个环节都当作系统工程来对待哪怕慢一点长期来看都是值得的。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进