尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

从零搭建AI工程能力:数据管道、模型训练与推理部署全链路实战

从零搭建AI工程能力:数据管道、模型训练与推理部署全链路实战 1. 从零搭建AI工程能力为什么“会用模型”和“会做工程”是两回事很多人第一次接触AI项目时都会经历一个相似的阶段在笔记本里跑通一个模型准确率看着还不错于是觉得“AI也就这么回事”。可一旦要把这个东西交给团队、部署到线上、让真实用户去用问题就全冒出来了——推理延迟忽高忽低、显存说爆就爆、模型版本对不上、数据管道三天两头断流。这时候你才会意识到训练一个模型只是整个AI工程链条里最靠前的一小段真正决定一个AI产品能不能活下来的是后面那一整套工程能力。“ai-engineering-from-scratch”这个标题说的就是从零开始把AI工程这套东西搭起来。它不是一个具体的框架也不是某个现成的工具而是一种能力建设的路径。我把它理解为不依赖某个大厂的全家桶也不指望一个AutoML平台帮你搞定一切而是自己动手把数据、训练、评估、部署、监控这几块拼图一块块拼起来。这件事听起来很硬核但恰恰是当前很多团队最缺的能力。为什么这么说因为现在的AI工具链已经非常成熟了成熟到有点“过度封装”的程度。你调一个API就能拿到推理结果你用一个库就能完成微调表面上看门槛很低。但一旦出了问题比如模型输出质量下降、推理成本失控、某个环节的吞吐跟不上如果你对底层工程没有概念就完全无从下手。会用模型的人很多会做工程的人很少这就是差距所在。这篇文章适合几类人看一是刚入行AI、想系统了解工程链路的开发者二是从传统后端转过来、想补齐AI工程知识的技术人三是小团队里那个“什么都得管”的全栈工程师。我会按照从零搭建的思路把每个环节的核心问题、常见方案、实操细节和踩坑经验都讲清楚。不追求覆盖所有工具而是让你理解每一步为什么这么做以及实际做的时候会遇到什么。2. 数据管道AI工程里最不起眼却最容易翻车的一环2.1 为什么数据管道值得单独拿出来讲如果你问一个有经验的AI工程师项目里最花时间的是什么十有八九会告诉你数据处理。不是训练不是调参而是把原始数据变成模型能吃的格式并且保证这个过程稳定、可复现、可扩展。很多项目在Demo阶段跑得挺好一上生产就崩根源往往就在数据管道上。数据管道在AI工程里的角色有点像城市的下水道系统。平时没人注意它但它一旦堵了整个城市就瘫痪了。模型训练需要数据模型评估需要数据线上推理的输入也是数据监控模型表现还是靠数据。数据管道是贯穿整个AI生命周期的动脉它的质量直接决定了上层所有环节的天花板。从零搭建数据管道核心要解决三个问题数据从哪里来、数据怎么变、数据怎么存。听起来简单但每个问题下面都有一堆细节。2.2 数据采集与接入的常见模式数据来源通常分几类业务数据库、日志系统、第三方API、人工标注、公开数据集。不同来源的接入方式完全不同。业务数据库一般用CDCChange Data Capture的方式增量同步日志系统通常是流式写入消息队列第三方API需要做限流和重试人工标注则要设计好标注平台和质检流程。我自己的经验是不要试图用一个统一的管道处理所有来源。早期为了“架构优雅”把所有数据源都往一个消息队列里塞结果发现批处理和流处理的语义完全不一样混在一起后维护成本极高。后来改成两条线批量数据走对象存储加调度任务流式数据走消息队列加消费程序各自独立反而清晰很多。这里有个容易被忽略的点数据接入的时候就要做好schema管理。很多团队是先把数据拉过来再说结果上游字段改了、类型变了下游训练脚本直接报错。建议在接入层就引入schema注册表每次数据写入都校验schema不匹配就拒绝并告警。这个习惯在项目早期看起来多余等到数据源多了之后会救你无数次。2.3 数据清洗与特征处理的工程化思路数据清洗这件事在Notebook里做和在生产环境里做是两码事。Notebook里你可以随便写个pandas脚本读进来、处理完、存出去。但生产环境要求的是可调度、可重试、可监控、幂等。我一般会把清洗逻辑拆成几个独立的步骤每个步骤是一个纯函数输入输出都是明确的数据结构。这样做的好处是每个步骤可以单独测试、单独重跑。比如去重、缺失值填充、异常值处理、格式标准化各是一个步骤。然后用一个调度器把它们串起来每一步的中间结果都落盘方便排查问题。特征处理是另一个重灾区。训练时的特征计算逻辑和线上推理时的特征计算逻辑如果不一致就会导致训练-服务偏差training-serving skew这是AI工程里最隐蔽也最致命的bug之一。模型离线评估AUC很高上线后效果一塌糊涂很多时候就是这个问题。解决办法是特征计算逻辑只写一次训练和推理共用同一套代码。具体做法可以是用特征存储Feature Store来统一管理也可以简单一点把特征计算封装成独立的库训练管道和推理服务都依赖这个库。关键是不要在两处各写一遍。2.4 数据版本管理与可复现性模型可以版本化代码可以版本化数据同样需要版本化。没有数据版本管理你就无法回答“这个模型是用哪份数据训练的”这个问题也就无法复现实验结果。数据版本管理不一定要用很重的工具。最简单的做法是每次数据处理产出一个快照记录快照的路径、时间戳、数据量、校验和。训练时指定快照ID这样任何时候都能回溯。进阶一点可以用DVC或者LakeFS这类工具把数据版本和代码版本关联起来。注意数据版本管理最容易犯的错误是只记录路径不记录内容哈希。路径可能被覆盖但哈希不会骗人。每次数据变更都算一个内容哈希训练配置里记录哈希值这样才能真正保证可复现。3. 模型训练与实验管理从“跑通”到“跑得明白”3.1 训练脚本的工程化改造在Notebook里训练模型和在生产级别的训练管道里训练模型中间隔着一整套工程化改造。Notebook适合探索但不适合作为生产训练的载体。你需要把训练逻辑抽成脚本或模块让它能在命令行、容器、调度系统里运行。改造的核心是配置与代码分离。学习率、批次大小、模型结构参数、数据路径这些都不应该硬编码在代码里而是通过配置文件或环境变量传入。这样做的好处是同一个训练脚本可以跑不同的实验不需要改代码。我习惯用YAML做配置文件结构清晰也方便版本管理。一个典型的训练配置大概长这样experiment: name: bert-finetune-v3 seed: 42 data: train_path: s3://bucket/data/train/snapshot-20240115 val_path: s3://bucket/data/val/snapshot-20240115 max_length: 256 model: base: bert-base-chinese num_labels: 8 dropout: 0.1 training: batch_size: 32 learning_rate: 2e-5 epochs: 5 warmup_ratio: 0.1 gradient_accumulation: 2 output: checkpoint_dir: s3://bucket/checkpoints/bert-finetune-v3这个配置里每个字段都有明确含义实验名、随机种子、数据路径、模型参数、训练超参、输出路径一目了然。随机种子一定要固定否则同样的配置跑两次结果不一样你根本不知道是改动生效了还是随机波动。3.2 实验追踪别让实验结果散落在各处做AI实验最痛苦的事情之一就是跑了十几个实验之后忘了哪个配置对应哪个结果。没有实验追踪系统你的实验记录就是一堆散落的日志文件和口头记忆。实验追踪工具的核心功能是记录每次实验的配置、指标、产物并且能对比不同实验。常用的有MLflow、Weights Biases、TensorBoard等。选哪个看团队习惯但一定要有一个哪怕先用最简单的表格记录也行。我自己的做法是在训练脚本里集成一个轻量的追踪库每次训练自动记录配置、每个epoch的loss和指标、最终模型路径。这样跑完实验后可以在面板上直接对比不同配置的效果不用去翻日志。这里有个实操心得指标记录要区分训练指标和评估指标。训练loss下降不代表模型变好评估指标才是判断依据。而且评估指标要选和业务目标一致的不要只看准确率要看召回、F1、AUC这些更能反映实际效果的指标。3.3 超参数搜索的工程实现超参数搜索是AI工程里比较有意思的一块。简单来说就是给定一组超参数的搜索空间自动跑多组实验找到效果最好的组合。方法有网格搜索、随机搜索、贝叶斯优化等。从工程角度看超参数搜索的关键是并行化和资源管理。你不能串行地跑几十组实验那样太慢。需要有一个调度器把不同的超参数组合分发到不同的计算资源上并行跑同时管理好GPU的分配和回收。我一般会用Optuna或者Ray Tune这类框架它们内置了搜索算法和并行调度。但要注意并行实验之间要隔离包括输出目录、日志文件、缓存路径否则会互相覆盖。每个实验用一个独立的运行ID作为目录名是最简单的隔离方式。还有一个坑是早停策略。有些超参数组合明显不行跑一两个epoch就能看出来没必要跑完。设置一个早停条件比如验证集指标连续两个epoch不提升就终止能省下大量计算资源。3.4 模型评估的陷阱与正确姿势模型评估看起来简单其实坑很多。最常见的错误是用测试集调参。你在测试集上反复评估、调整最后报告的那个指标已经过拟合了。正确的做法是训练集、验证集、测试集严格分开验证集用于调参和早停测试集只在最后用一次。另一个坑是评估指标的选择。不同任务适合的指标不一样。分类任务看准确率、召回、F1、AUC生成任务看BLEU、ROUGE、 perplexity排序任务看NDCG、MAP。选错指标会导致优化方向完全错误。还有一个容易被忽略的点是评估的统计显著性。两个模型在测试集上差0.5个百分点这个差异是真实的还是随机波动如果测试集不够大这个差异可能没有统计意义。可以用bootstrap或者交叉验证来估计指标的置信区间。提示评估脚本要和训练脚本一样工程化。固定随机种子、固定数据划分、输出结构化结果。不要每次评估都手写一遍代码那样迟早会出错。4. 模型部署与推理服务让模型真正跑起来4.1 推理服务的几种形态与选型模型训练完之后要变成能对外提供服务的东西中间还有不少工程工作。推理服务的形态大致分几种批处理推理、在线实时推理、流式推理。选哪种取决于业务场景。批处理推理适合离线场景比如每天跑一次给所有用户生成推荐结果。在线实时推理适合需要即时响应的场景比如搜索排序、对话系统。流式推理适合持续输入输出的场景比如视频分析。从工程复杂度看批处理最简单在线实时推理最复杂。在线推理要考虑延迟、吞吐、并发、容错、扩缩容每一项都是坑。我建议从批处理开始逐步过渡到在线服务不要一上来就搞实时推理那样很容易被工程细节淹没。在线推理服务的技术栈常见的有TensorFlow Serving、TorchServe、Triton Inference Server也可以自己用FastAPI或者Flask封装。选哪个看模型框架和团队熟悉度。如果模型是PyTorch的TorchServe或者Triton比较顺手如果是多框架混合Triton的兼容性更好。4.2 模型序列化与版本管理模型从训练环境到推理环境需要经过序列化。不同框架的序列化方式不一样PyTorch用torch.saveTensorFlow用SavedModelONNX是一个跨框架的中间格式。这里有个实操建议推理时尽量用推理专用的格式。比如PyTorch模型可以导出成TorchScript或者ONNX推理性能通常比直接加载Python模型好。而且推理格式不依赖训练代码部署时更干净。模型版本管理是另一个关键点。线上可能同时跑多个版本的模型比如A/B测试。你需要一套机制来管理模型版本、控制流量分配、支持快速回滚。最简单的做法是用模型注册表每个版本有唯一ID推理服务根据配置加载对应版本。我踩过的一个坑是模型文件和环境依赖没有一起版本化。模型是用某个版本的库训练的推理环境装了另一个版本结果加载失败或者结果不一致。后来改成模型文件和依赖清单一起打包部署时按清单安装依赖问题就解决了。4.3 推理性能优化的几个实用手段推理性能直接影响用户体验和成本。优化手段有很多我挑几个最实用的讲。批处理是最直接的优化。单条推理和批量推理的吞吐差距可能有好几倍。但批处理会引入延迟需要根据业务场景权衡。在线服务可以用动态批处理攒一小段时间的请求一起推理兼顾吞吐和延迟。量化是另一个常用手段。把FP32的模型转成FP16或者INT8推理速度能提升不少精度损失通常可控。但量化不是万能的有些模型对量化很敏感需要评估后再用。模型剪枝和蒸馏适合对延迟要求极高的场景。剪枝是去掉模型中不重要的参数蒸馏是用小模型学大模型的行为。这两种方法都需要重新训练或微调工程成本较高。缓存是最容易被忽略的优化。如果同样的输入反复出现缓存推理结果能省下大量计算。比如推荐系统里热门物品的向量完全可以缓存起来。4.4 推理服务的监控与告警推理服务上线不是终点而是起点。你需要监控它的运行状态及时发现问题。要监控的指标分几类系统指标CPU、内存、GPU利用率、延迟、吞吐、业务指标请求量、成功率、错误率、模型指标输入分布、输出分布、预测置信度。模型指标特别重要因为系统指标正常不代表模型正常。模型可能因为输入数据分布变化而效果下降但系统层面看不出来。监控输入特征的分布和训练时的分布对比如果偏移太大就告警。监控输出结果的分布如果突然集中到某一类也可能是异常。告警策略要合理设置阈值太敏感会天天误报太迟钝会漏掉真问题。我一般会先观察一段时间的正常波动范围然后设置比正常范围稍宽的阈值再根据实际告警情况调整。5. 持续迭代与反馈闭环AI工程不是一次性交付5.1 线上反馈数据的回收与利用模型上线后会产生大量真实交互数据。这些数据是宝贵的资产但很多团队没有好好利用。线上反馈数据是模型迭代的燃料没有它模型就只能停留在初始版本。回收反馈数据的方式取决于业务形态。如果是推荐系统可以记录用户的点击、停留、转化行为。如果是对话系统可以记录用户的后续追问、满意度评价。如果是分类系统可以记录人工复核的结果。回收来的数据不能直接拿来训练需要经过清洗、去噪、标注。线上数据往往有偏比如用户只点击了展示在前面的结果后面的结果没有曝光机会直接用这些数据训练会让模型越来越偏。需要用一些去偏技术比如逆倾向加权。5.2 模型迭代的节奏与策略模型迭代不是越频繁越好。太频繁会导致系统不稳定运维成本高太慢又跟不上业务变化。需要找到一个合适的节奏。我一般会分几个层次紧急修复随时可以做比如模型出现严重bug小版本迭代按周或双周比如用新数据重新训练大版本升级按月或按季度比如换模型结构、加新特征。每次迭代都要有明确的评估流程。新模型先在离线评估指标达标后做小流量A/B测试确认线上效果后再逐步放量。不要一次性全量替换那样风险太大。5.3 工程债务的识别与偿还AI项目跑一段时间后会积累不少工程债务。比如数据处理脚本越来越臃肿、训练配置散落各处、推理服务里塞了一堆临时逻辑。这些债务不还迟早会拖慢迭代速度。识别工程债务的信号改一个小功能要动好几个地方、新同事上手要很久、每次发版都提心吊胆。出现这些信号就该停下来整理一下了。偿还债务的方式可以是重构代码、补充文档、统一配置管理、增加自动化测试。不一定要一次性做完可以每次迭代留出一点时间做清理。持续小步偿还比攒着一次性重构风险小得多。6. 从零搭建AI工程能力的实操路线图6.1 不同起点的切入策略从零搭建AI工程能力起点不同路径也不同。如果你是一个人或者小团队建议从最痛的点切入。比如数据管道最乱就先理数据部署最麻烦就先搞部署。不要试图一次性把所有环节都做到完美那样永远开始不了。如果你是从传统后端转过来的优势是工程基础好短板是AI知识。建议先补AI基础概念然后从推理服务入手因为推理服务更偏工程容易上手。数据管道和训练管理可以边做边学。如果你是AI算法出身优势是懂模型短板是工程。建议先学容器化、调度系统、监控告警这些基础设施然后逐步把训练和推理工程化。6.2 工具选型的取舍原则AI工程工具链非常丰富选型容易挑花眼。我的原则是优先选团队熟悉的其次选社区活跃的最后选功能最全的。功能再全团队不会用也是白搭。另外要避免过度设计。早期不要引入太重的框架能用脚本解决的就用脚本能用手动流程的就先手动。等业务量上来了再逐步替换成更专业的工具。过早优化是AI工程里最常见的浪费。还有一点是保持技术栈的收敛。不要每个环节用一套不同的工具那样维护成本太高。尽量选能互相集成的工具比如实验追踪和模型注册用同一家的数据版本和训练管道用同一套生态的。6.3 团队协作与流程规范AI工程不是一个人的事需要团队协作。协作的基础是流程规范。代码怎么管理、实验怎么记录、模型怎么发布、问题怎么排查这些都需要有明确的规范。我建议至少建立这几条规范代码必须走代码评审、实验必须记录配置和结果、模型发布必须经过评估流程、线上问题必须有排查记录。规范不用太复杂关键是执行。另外文档和知识沉淀很重要。AI工程里很多经验是隐性的比如某个参数为什么这么设、某个坑怎么绕过去。这些如果不记下来人一走就丢了。建议维护一个内部知识库把踩过的坑和解决方案都记进去。6.4 常见误区与避坑清单最后列几个我见过或踩过的常见误区供你参考。误区后果正确做法训练和推理特征逻辑各写一遍训练-服务偏差线上效果差特征计算逻辑统一训练推理共用不做数据版本管理实验结果无法复现每次数据变更记录快照和哈希用测试集调参指标虚高上线打脸训练/验证/测试严格分开推理服务一次性全量上线出问题影响面大小流量A/B测试逐步放量不监控模型输入输出分布模型退化无法及时发现监控特征和输出分布设置告警过度追求工具先进性维护成本高团队跟不上选团队熟悉的逐步演进这些误区看起来都是常识但实际做的时候很容易犯。因为项目早期压力大大家都想快点出结果就会走捷径。捷径走多了后面要花更多时间还债。我个人在实际操作中的体会是AI工程能力的建设没有捷径但有方法。方法就是从最痛的点入手小步快跑持续迭代。不要追求一步到位也不要照搬大厂的方案因为你的业务场景、团队规模、资源条件都不一样。找到适合自己的节奏把每个环节做扎实能力自然就长出来了。还有一个实用的小技巧每次遇到问题解决之后花十分钟写个简短的记录记下问题现象、排查过程、根因、解决方案。积累一段时间后这就是你自己的AI工程避坑手册比任何教程都管用。
返回列表