ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从零搭建AI工程化系统:数据、训练、部署与监控全流程实战

从零搭建AI工程化系统:数据、训练、部署与监控全流程实战 最近两年朋友圈里开AI公司的人肉眼可见地变多了技术圈子里Ai Engineering这个title也开始频繁出现。但说实话很多挂着AI工程师头衔的人日常工作其实还是写Prompt、调API、跑开源模型离真正把一套AI系统从零搭起来还能稳定跑在生产环境里差得不是一星半点。我去年花了大概四个月从零开始完整做了一个AI工程化项目没有用任何别人封装好的AI平台就是裸手搭数据管道、选模型、写训练脚本、做评估、部署上线、再搭监控。整个过程踩坑无数但也正因为是从零起步很多原本模糊的概念被彻底打通了。这篇就把我在实战里总结的经验写出来从架构思路到具体操作都尽量讲透。先给这篇文章定个位不管你是刚入门想搞清AI工程到底在做什么还是已经写过不少模型代码但总感觉流程上缺了点什么这里面的内容应该都能帮到你。我会尽可能少说废话多放实操里真正用得上的细节和踩坑记录。1. AI工程到底是什么先搞清边界1.1 为什么不是调个模型那么简单很多人的AI项目路径是这样的找个开源模型下载权重写个Flask接口调一调Prompt能跑通就宣布上线了。这种流程在小Demo、原型验证里没问题但一旦面对真实用户流量、真实业务数据、真实故障场景几乎处处是坑。AI工程和调模型最大的区别在于它把模型当成了一个需要长期运维的软件系统而不是一个一次性生成的产物。这个系统里包含了数据版本管理、实验追踪、训练管线、离线评估、上线部署、服务监控、数据漂移检测、定期重训等多个模块任何一个环节掉链子整个系统都会出问题。我在做这个项目的时候最大的体感是模型本身的代码占比很小真正花时间的都是工程问题。比如数据怎么清洗才能喂给训练脚本训练的时候怎么记录每一步实验的差异模型上线后发现线上输入分布和训练集差异太大怎么办。这些问题市面上没有哪个AI中台能替你一键解决哪怕有人给你搭好了平台你不会从零理解底层机制出了问题也只能干瞪眼。1.2 从零开始的项目该包含哪些模块做从零项目最大的好处是逼着你把整套系统的每个环节都亲手摸一遍。我建议把整个项目拆成六大模块来规划这也差不多是生产级AI系统的最小集了数据工程采集、清洗、去重、标注、版本管理实验管理记录每次训练的数据版本、代码版本、超参配置、模型指标训练与微调租GPU、写训练脚本、处理分布式、checkpoint管理离线评估设计评测集、选定评估指标、跑基准部署服务化封装推理接口、做性能优化、处理并发和容灾线上监控模型指标监控、延迟监控、数据漂移检测、自动报警这六个模块我不会全都做得很深但在项目里至少都得有一个能跑的MVP版本。否则的话你做的还是单体实验室项目不是工程化项目。我见过太多人把精力全砸在训练环节数据集却直接用别人下好的压缩包部署也只跑得起一台开发机上的Flask。这种项目演PPT还行真挂到线上加个两万QPS机器直接冒烟。1.3 为什么从零比用平台更值得现在的AI平台产品确实多很多云厂商都有托管训练和推理服务一行命令就能跑起LLaMA。那为什么还要主张从零做我的理解是平台解决的是你已经有成熟方案但不想管运维的问题而从零解决的是你根本不理解自己的系统在干什么的问题。前者适合业务扩张期后者适合学习和打地基。换句话说如果一个人连GPU显存溢出是为什么都不知道直接上云平台的自动扩缩容那出了问题连看日志都不知往哪看。从零写一遍训练循环、手动画一次数据漂移曲线这些基本功才是真正的护城河。2. 从零搭建数据与实验管理是地基2.1 数据集的获取、清洗与版本管理很多教程喜欢把数据集当成开箱即用的东西现实中基本不存在这种事。我这次的实践是做一个电商评论情感分类器网上能找到的公开数据集质量参差不齐。有些标注颗粒度不对有些评论长度分布严重失衡有些干脆有明显错误标签。清洗这一步我引以为戒的教训是去重至少做两轮。第一轮用精确匹配把完全相同的字符串去掉第二轮用SimHash做模糊去重因为评论里很多内容只是改了标点或者加了几个空格就重新出现的垃圾数据。不去重的话模型会学到把某些常用模板当分类特征直接导致评估和线上表现不一致。数据版本管理是我强烈建议从第一天就上手的环节。我自己用的是DVC加对象存储每个版本的训练集都打一个tag记录数据的行数、标签分布、统计特征。别觉得这是多此一举等你想复盘为什么上周的模型效果好这周的不行时如果连数据都回溯不到具体版本那排查成本会高得让你怀疑人生。数据标签分布也要记清楚。我遇到过训练集正负样本几乎均衡但线上真实流量里负面评论只有5%的情况。如果不注意这个偏差模型上线后的精确率会非常好看但召回率会崩得一塌糊涂。早期建立一张分布对照表线上和线下差距会明显很多。2.2 实验追踪的正确姿势实验追踪这块说实话很多教程里只会轻描淡写一句用MLflow记录一下但真正做起来比想象中复杂。核心要记录的东西不只有准确率这一项指标我每次实验至少会记录以下信息训练数据集的版本号代码的Git commit hash模型的超参配置完整地序列化成JSON训练时长和资源占用评估集上多个维度的指标不只一个总准确率我是用MLflow搭建的实验追踪服务但快捷键是把所有记录都自动化到训练脚本里而不是手工在网页上填。每次跑实验训练脚本启动时自动读取当前Git commit、读取DVC的当前数据版本号、生成实验ID。这些听起来像小细节但真的能让实验的可复现性提高一个档次。还有一点值得专门提醒服务器上的GPU跑训练你本地再改代码这两个是完全独立的事件。如果没有把Git commit和实验记录绑紧两个星期后你根本不知道当时的模型到底是用哪段代码训出来的。这是个看似基础但影响巨大的工程问题。3. 训练与微调的工程化细节3.1 选基座模型还是从头训练考虑到算力和时间成本这个项目没有选择从头训练一个模型而是用了预训练模型加微调的路线。我做的是文本分类任务基座模型选了当时效果不错的中文预训练模型然后做领域适配微调。这条路线决策背后是有考虑的。从头训练一个Transformer的成本在单卡环境下基本不现实光是大规模中文语料的清洗和预处理就得一个月。而微调我们自己的垂直领域数据往往就能达到很可用的效果。如果后续还想继续提升也方便往上叠更大的基座。但微调这件事本身也别想得太轻巧。最关键的参数是学习率。我一开始按别人的博客经验设成2e-5结果在验证集上疯狂震荡后面调成1e-5才收敛得稳。不同任务最优学习率差异很大建议一开始用学习率扫描从1e-6到5e-5跑几组对比而不是一上来就赌一个值。3.2 训练资源规划与超参数选择的实际操作训练资源的规划是工程团队最常见的低估项。我做分类模型理论和显存占用都不大但真正卡住的是单卡效率。当时我租了一张24G显存的卡训练批次大小只能开到8跑一个epoch要将近四个小时实在想骂人。后来发现问题是出在数据加载线程和GPU利用率不够协同。数据预处理在CPU端耗时太长GPU大部分时间都在空转等待。用torch.compile动态图优化加NumPy数据预取后同样的代码GPU利用率直接从35%干到了80%以上。这个优化大家可以直接抄作业多数Pytorch训练场景都能用得上。超参选择上除了学习率最敏感的还是批次大小。我实测下来批次大小和纳米学习率必须搭配调整单纯提高批次大小不改学习率模型基本不收敛。现在很多库有自动学习率调节器但如果用PyTorch裸写就要养成同步调整的习惯。3.3 检查点与容错训练到一半挂了怎么办训练模型的过程中机器宕机、显存溢出、断网重连这些意外几乎一定会遇到。我第一次跑长训练时跑到第17个epoch服务商把机器回收了checkpoint也没传出来整个人是崩溃的。从那次之后我固定了三个习惯至少每两个epoch存一次checkpoint、存好的文件立刻同步到对象存储、训练日志实时上传。这样哪怕机器当场消失最多损失两个epoch的进度不用从头再来。Checkpoint的命名也要带元信息我的格式是epoch-{step}-{val_acc:.4f}.bin看起来文件名就能直接知道这是第几个epoch的模型和验证分数后期挑选最优checkpoint时特别省事不用到处翻日志。4. 评估环节比想象中更重要的工程模块4.1 离线评估怎么设计才可信说到评估很多人第一反应就是准备个测试集算一下准确率。实际上评估设计不合理比不评估还坑人因为你会被一个虚高的指标误导然后直接把烂模型送上线。我这次的评估集设计思路是把原来的单一测试集拆成三个维度分别验证模型在不同方面的能力。第一个维度是常规的随机采样集看整体性能第二个维度是难样本集特意收集那些混淆度很高的评论第三个维度是跨时间段的数据用来检测模型对时间漂移的鲁棒性。难样本集的构建方法是让模型先自己预测一轮把预测置信度介于0.4到0.6之间的评论挑出来人工复核。这些样本才是真正决定模型上限的内容只有准确率这一个指标根本看不出来模型在难样本上表现如何。4.2 建立你的评估基准集做评估要趁早我建议在项目第一天就顺手把评估集搭起来而不是等模型训好了再回头做。因为评估集的质量直接影响你在后续每一次训练迭代里的判断评估集本身也需要持续校准和更新。基准集建好之后还要做一致性检查。我的做法是留了一份大概两百条的人工标注金标集每隔一段时间就把当前最优模型拿出来预测一遍看看和人工标注的差异模式有没有变化。如果发现模型在不该错的简单样本上开始出错那大概率是训练数据或者代码哪里悄悄出了问题。评估报告建议自动化生成不要每次都手工去算指标。我自己写了一个小脚本每次训练结束自动跑评测把准确率、精确率、召回率、F1、以及按评论长度分组的细分指标全部输出成HTML报告。自动化报告这个投入非常值因为你在迭代过程中比较模型时如果没有统一格式的数据几乎没办法做科学的对比。5. 部署与服务化的完整链路5.1 推理服务的架构选择模型训练好之后把它变成一个在线服务这中间的门槛比大多数人想象的要高。如果只是做一个接口把模型包起来那并发一上来就会各种超时显存分配不合理直接OOM写法和训练时的预处理如果不一致还会导致预测结果和离线评估时完全不同。我这次部署用的是FastAPI搭配ONNX Runtime把PyTorch模型先转成ONNX格式再加载推理。为什么要转ONNX一是推理速度有明显提升二是ONNX Runtime的部署形态简洁可以将推理逻辑从训练环境里解耦出来减少生产服务的依赖体积。接口设计上我强烈建议加一个输入校验层。线上接口收到的输入往往五花八门空文本、超长文本、异常字符都会导致模型崩溃或者输出垃圾结果。我专门写了一个预处理中间件对输入长度做截断、对空白字符做归一化超限的请求直接返回合理的错误码而不是让模型硬吃一个几千字的文本然后崩掉。5.2 性能优化与GPU资源利用关于性能最直观的指标是P99延迟。模型本身在GPU上跑还好但瓶颈往往出在数据预处理和序列化上。文本的Tokenizer如果每次都是单条同步处理GPU推理速度再快也会被CPU拖死。优化思路是把预处理改成批量异步流水线一次性处理一批请求再统一送进模型。显存占用也要盯紧。ONNX Runtime有个session级的显存分配策略默认按需分配但实际使用中显存碎片会越来越严重。我的经验是部署初期就固定一个显存池虽然首启动稍慢但长期运行比动态分配稳定得多。线上跑了两个月没有一次因为显存碎片重启服务。另外推理服务一定要做优雅退出。模型服务在更新版本的时候直接kill进程会导致正在处理的请求全部失败。我这里的做法是注册了SIGTERM信号处理收到退出信号后停止接收新请求等已有请求全部处理完再结束进程。这个细节看似小但对线上稳定性影响非常直接。6. 监控与持续迭代让系统真正活起来6.1 线上指标监控很多AI项目死在上线即终点。模型部署上去了感觉没事可做了等到业务方反馈效果变差时才回头排查这时候已经晚了。线上监控必须从上线第一天就建立监控的维度至少包括三个层次服务健康、推理质量、数据漂移。服务健康层的监控包括GPU利用率、显存占用、请求延迟、错误率这些常规内容。我用Prometheus加Grafana搭了一套采集指标埋点在推理服务里然后起一个告警规则P99延迟超过500毫秒或者错误率超过1%持续五分钟就报警。推理质量这个层次比较容易被忽略但反而最重要。我做了一个轻量方案对预测结果做小流量人工抽检把置信度高但业务结果异常比如在售商品被预测成负面情感的样本捞出来做标注每周汇总统计分析模型在真实业务里的表现。6.2 数据漂移检测与模型更新数据漂移是我一开始完全没想清楚的环节。训练时用的评论数据和上线三个月后的评论用语几乎一定会有差异。特别是遇到大促这种时间段评论里会涌出大量包含促销相关词的新句式模型根本没有见过预测效果自然直线下降。漂移检测的做法不需要特别复杂我用的方式是记录每个上线周期内输入文本的词频分布跟训练集的词频分布做对比。一个很灵敏的指标是新词比例也就是当天请求里有多少词是训练集词表里没有的。当这个比例超过一个阈值我就触发重新采样数据和重训。模型更替流程我花了最多时间打磨。刚开始是手动更新导出新模型替换线上版本重启服务。后面迭代成半自动新模型先在影子环境跑一周对比旧模型的线上表现达到预期才自动切换流量。影子环境最大的价值是可以拿真实请求做离线验证不用等业务方反馈才发现新版本有问题。7. 常见问题与排查技巧实录7.1 训练损失不下降的排查清单这个问题我至少遇到过五六次每次原因还不一样。花在排查上的时间不比写代码少索性整理一个排查顺序遇到模型怎么都训不动的同学可以直接照单子排查检查输入到模型的数据是不是真的正确这一步最容易犯错。最常见的情况是标签和特征没对齐或者做了归一化但训练和预测时的口径不一样。先打印一批batch的样本和标签人眼确认。确认学习率没有设得离谱。学习率太大会震荡不收敛太小则几乎不动。建议从1e-4开始扫每次调整3倍左右。检查损失函数和模型输出的维度是否匹配。这种问题在改模型结构时特别容易出现维度配错但没报错的情况比较坑。检查激活函数是不是导致梯度消失。太深的网络配合Sigmoid很容易死掉换成ReLU或者加残差连接通常能解决问题。确认训练数据的顺序没有引入偏差。比如数据按标签排序喂进去模型会学到上一个样本的标签这种虚假规律。7.2 线上预测结果和离线评估差距大的原因分析模型离线测试F1有0.92上线之后业务反馈效果差这种情况大家应该都不陌生。我总结下来无非这几个原因第一离线评估集和真实线上分布的差距。最常见的表现是文本长度分布差异公开评测集里短文本多线上却经常来超长文本。解决办法是按长度分层评估不要太相信单点指标。第二数据泄露。训练集里混入了和测试集同源的数据或者做特征时不小心引用了未来信息都会让离线指标虚高。做法是对特征工程做时间旅行测试也就是只用截止时间之前的数据来预测之后的数据。第三预处理不一致。训练时做了某种特殊清洗部署时的代码却没有同步预测自然就会偏离。解法是抽一批线上请求用训练时同一套代码重放一遍离线推理对比线上返回的结果。7.3 成本控制与算力规划的经验分享现在的GPU租赁价格不算便宜没有长期的成本规划会直接把个人项目拖垮。我的经验是从小规模开始验证不要刚开始就上大模型。做分类任务一个十亿以下参数量的模型就足够跑了不必一想到AI就直接上百亿参数大模型。算力浪费的大头都在空闲等待上。我发现不少人排队租了GPU结果代码一跑就报错调半天才又重新跑显卡大部分时间空着烧钱。我的建议是上机前用CPU端把数据管线和模型前向传播完整走通一遍确认没报错再上GPU。还有训练过程中的日志要实时检查发现loss不下降就及时止损不要傻傻等到全部跑完才发现超参有问题。聊到这儿这个从零搭AI工程项目的全流程基本就过了一遍。说句实在话整个过程里最有价值的不是最终那个还算好用的分类模型而是把数据、训练、评估、部署、监控这整条链路的每个环节都亲手打通了之后脑子里建立起来的那张系统地图。以后再看到任何AI项目第一反应不再是一个模型加一堆数据而是一整条管道的问题。如果你也打算动手做类似的事情我最大的建议就一句不要跳过任何一个看起来很麻烦的环节数据版本管理也好、评估集构建也好、线上监控也好每一块偷的懒都会在后面的某个深夜以事故的形式还回来。
返回列表