
1. 从零搭建AI工程能力为什么我劝你别再收藏那些“速成清单”了“ai-engineering-from-scratch”这个标题第一次看到的时候我愣了一下。不是因为它有多花哨恰恰相反它朴素得有点不像这个时代的标题。现在满屏都是“三天掌握大模型”“一周转型AI工程师”“零基础也能拿高薪”突然冒出来一个“from scratch”反而让我觉得踏实。我自己是从传统后端转过来的踩过的坑不比任何人少。最开始那半年我收藏了上百篇“AI学习路线图”硬盘里躺着几十个G的教程视频结果真正动手写第一个能跑通的推理服务时连张量维度都对不齐。后来我才明白AI工程这件事收藏再多清单都没用你得真的从零开始一行一行把东西搭起来。这篇文章想聊的就是“从零搭建AI工程能力”这件事本身。不是给你一份新的清单而是把我自己走过的路、踩过的坑、以及那些真正让我从“调包侠”变成“能独立交付AI系统”的关键节点完整地拆开来讲。适合谁看如果你已经会写Python对机器学习有模糊的概念但一让你从零搭一个完整的AI工程链路就发怵那这篇内容就是写给你的。如果你已经是资深从业者里面关于工程化取舍和踩坑的部分或许也能让你会心一笑。核心关键词“ai-engineering-from-scratch”我会在全文反复提到因为它不是一个标签而是一种做事的方式。我理解的AI工程能力不是会调多少个API而是当你要解决一个真实问题时能从数据、模型、服务、监控这条完整链路上做出合理的工程决策。这件事真的只能从零开始练。2. 先想清楚AI工程到底在工程什么2.1 别被“模型”两个字骗了工程的重心根本不在那很多人一提AI工程脑子里第一反应就是模型。选哪个架构、用哪个预训练权重、微调多少轮好像把这些搞定了AI系统就建成了。我刚开始也这么想直到第一次把模型部署到线上才发现模型在整个系统里占的代码量可能连百分之五都不到。一个能用的AI系统模型只是中间的一个环节。往前推有数据采集、清洗、标注、版本管理往后推有推理服务、批处理调度、结果缓存、降级策略再往外围还有监控告警、效果评估、反馈闭环。这些东西加起来才是AI工程真正要处理的对象。我见过太多人模型训得漂漂亮亮一到工程落地就抓瞎就是因为把百分之九十的精力花在了那百分之五上。所以“ai-engineering-from-scratch”的第一层含义就是你要从系统的角度去理解这件事。模型是核心但不是全部。你得知道数据怎么流进来推理结果怎么流出去中间出了问题怎么兜底。这些工程决策比选哪个模型重要得多。2.2 从零开始先搭骨架再填肉我自己的做法是不管做什么AI项目先画一张数据流图。从最左边的数据源开始到最右边的用户可见结果中间经过哪些环节每个环节的输入输出是什么先把这个骨架搭出来。骨架搭好了再去填每个环节的具体实现。这个顺序特别重要。很多人反过来先纠结用什么模型然后硬生生把数据往模型上套最后发现数据格式对不上、推理延迟太高、结果没法解释。从零开始的意思就是你先别管模型先把数据链路想清楚。数据从哪来长什么样量有多大更新频率如何这些问题的答案会直接决定你后面所有的工程选择。举个例子如果你做的是离线批量推理那模型选大一点、推理慢一点都没关系反正跑一晚上出结果。但如果你做的是在线实时服务那模型大小、推理框架、缓存策略就完全是另一套逻辑。这些决策的起点都是你对数据流的理解而不是对模型的偏好。2.3 工程能力的三个层次你在哪一层我把AI工程能力粗略分成三层。第一层是“能跑通”就是给你一个模型和数据你能把它跑起来输出结果。这一层其实不难现在开源工具这么丰富照着文档走基本都能跑通。第二层是“能交付”就是你能把这个东西包装成一个服务让别人能用有基本的错误处理有日志有监控。这一层开始有门槛了因为你要考虑的不再是单次运行而是持续运行。第三层是“能迭代”就是系统上线之后你能根据反馈持续优化数据变了模型能更新效果差了能定位原因业务需求变了能快速调整。大部分卡在“ai-engineering-from-scratch”这个阶段的人其实是在第一层和第二层之间挣扎。能跑通但交付不了。我自己在这个阶段卡了很久后来发现问题的根源在于我一直在用“脚本思维”写代码而不是用“工程思维”搭系统。脚本思维是线性的从头跑到尾就完事工程思维是模块化的每个环节可替换、可监控、可回滚。这个思维转变比学任何具体技术都重要。3. 数据链路从零搭建时最容易偷懒也最不能偷懒的地方3.1 数据清洗不是可选项是生死线我见过太多项目死在数据上。模型没问题服务也没问题就是数据太脏导致线上效果一塌糊涂。从零搭建AI工程能力数据清洗这一关你必须自己过一遍不能假手于人也不能指望自动化工具一键搞定。数据清洗具体做什么首先是格式统一。你拿到的数据可能来自多个源有的是JSON有的是CSV有的是数据库导出字段名还不一样。你得先把它们统一成一种格式字段对齐类型对齐。这一步听起来简单但实际做的时候你会发现各种奇葩情况比如同一个字段有的用字符串存数字有的用浮点数有的还带单位。这些都得处理。然后是缺失值和异常值。缺失值怎么填异常值怎么判这些决策没有标准答案取决于你的业务场景。但关键是你要有意识地去处理而不是让它们悄悄溜进模型。我自己的习惯是在数据清洗阶段就把所有处理逻辑写成可复用的函数每个函数只做一件事这样后面数据变了改一个函数就行不用从头再来。注意数据清洗阶段一定要保留原始数据的一份副本所有清洗操作都在副本上进行。我吃过这个亏有一次清洗逻辑写错了把原始数据也覆盖了结果只能重新采集白白浪费了一周时间。3.2 数据版本管理别再用文件名区分了刚开始做AI项目的时候我的数据版本管理就是给文件改名。data_v1.csv、data_v2.csv、data_v2_final.csv、data_v2_final_真的final.csv相信很多人都有过这个阶段。这种做法的坏处太明显了过两个月你自己都不知道哪个文件对应哪个实验。从零搭建AI工程能力数据版本管理是必须跨过去的一道坎。我的建议是哪怕你一开始不用专业的工具也要建立一个简单的版本记录机制。每次数据变更记录变更时间、变更内容、变更原因以及对应的模型实验编号。这个记录可以就是一个Markdown文件但一定要有。等你稍微成熟一点可以引入DVC或者类似的工具把数据和代码版本关联起来。这样你就能做到给定一个模型版本能准确回溯到它用的是哪份数据。这个能力在排查线上问题时特别有用因为很多时候模型效果下降根源不在模型本身而在数据分布变了。3.3 数据管道的自动化从手动到自动的临界点数据管道要不要自动化什么时候自动化这是个工程决策。我的经验是当你发现同样的数据处理步骤你手动执行了三次以上就该考虑自动化了。但也不要一上来就搞一套复杂的调度系统那属于过度工程。从零开始的话我建议先用最简单的脚本串联。写一个主脚本按顺序调用各个处理函数中间结果落盘。这个脚本可以手动触发也可以挂个定时任务。关键是流程要固定下来每一步的输入输出要明确。等这个流程稳定运行一段时间你确认没有大问题了再考虑用Airflow或者Prefect这类工具做更复杂的调度。这里有个坑要提醒自动化之前一定要确保你的处理逻辑是幂等的。也就是说同一份数据跑两次结果应该一样。如果做不到幂等自动化之后出了问题会很难排查。我见过一个案例数据处理脚本里有个随机采样步骤每次跑出来的结果都不一样导致模型训练结果无法复现排查了好久才发现是这个原因。4. 模型训练与实验管理别把时间浪费在重复试错上4.1 实验记录你记得住三次实验记得住三十次吗模型训练最耗时间的不是训练本身而是试错。调一个参数跑一次训练看结果再调再跑。如果每次实验的结果你都不记录那很快就会乱套。我刚开始就是凭脑子记前三次还能记住到第五次就完全混了不知道哪个参数对应哪个结果。从零搭建AI工程能力实验管理是必须养成的习惯。最简单的做法是每次实验都写一个配置文件把超参数、数据版本、代码版本都记下来实验结果也追加到同一个文件里。这个文件可以就是YAML或者JSON不需要多复杂。关键是你要坚持做每次实验都做。稍微进阶一点可以用MLflow或者Weights Biases这类工具。它们能自动记录训练过程中的指标曲线还能对比不同实验的结果。我用过一段时间MLflow最大的好处是当你需要复现某个历史实验时能一键找到对应的配置和数据版本。这个能力在团队协作时尤其重要因为别人需要验证你的结果。4.2 训练脚本的工程化从Notebook到可复用模块Notebook适合探索不适合工程。我见过太多人把训练代码写在Notebook里一个单元格跑到底中间改个参数就得从头再跑。这种模式在实验阶段还能忍一旦要反复训练不同配置的模型效率就太低了。我的做法是把训练代码拆成几个模块数据加载、模型定义、训练循环、评估逻辑。每个模块单独一个文件通过配置文件来组合。这样我想换模型只改模型定义文件想换数据只改数据加载文件。训练脚本本身就是一个入口读配置、组装模块、启动训练。这个拆法还有一个好处就是方便做超参数搜索。你可以写一个外层脚本遍历不同的配置组合依次调用训练入口。每个实验的结果自动记录到实验管理工具里。这样你就能在睡觉的时候让机器帮你跑几十组实验第二天早上看结果就行。提示训练脚本里一定要设置随机种子并且把种子值记录到实验配置里。不然你的实验结果无法复现这在排查问题时是致命的。4.3 模型评估别只看准确率模型评估是另一个容易偷懒的地方。很多人训练完模型看一眼准确率觉得还行就上线了。结果上线之后发现效果完全不是那么回事。问题出在离线评估和线上表现之间有很大的鸿沟。从零搭建AI工程能力评估环节你要多花点心思。首先评估指标要跟业务目标对齐。准确率高的模型不一定业务效果好有时候召回率更重要有时候排序质量更重要。这个得跟业务方对齐不能自己拍脑袋。其次评估数据集要能代表线上分布。如果你的评估集是从训练集里随机切出来的那评估结果会偏乐观。更好的做法是单独留出一份跟线上分布一致的数据做评估甚至用线上真实流量做A/B测试。我自己的习惯是至少准备两份评估集一份是常规的留出集一份是专门收集的困难样本集后者更能反映模型的真实短板。最后评估要自动化。每次训练完自动跑评估结果自动记录。这样你就能持续跟踪模型效果的变化而不是等到上线才发现问题。5. 推理服务与部署从能跑到能用的关键一跃5.1 推理服务的三种形态你该选哪种推理服务大概有三种形态批处理、在线实时、流式。选哪种取决于你的业务场景没有绝对的好坏。批处理适合对延迟不敏感的场景比如每天凌晨跑一遍全量数据生成推荐结果存到数据库白天用户直接读数据库。这种形态最简单工程复杂度最低我建议从零开始的话优先考虑这种。你只需要写一个脚本读数据、跑模型、写结果挂个定时任务就行。在线实时适合对延迟敏感的场景比如用户点一下按钮就要出结果。这种形态需要你把模型包装成一个HTTP服务考虑并发、超时、降级这些问题。工程复杂度高不少但也不是遥不可及。用FastAPI或者Flask包一层再用Gunicorn或者Uvicorn起多进程基本就能撑住中等规模的流量。流式适合持续产生的数据比如日志、传感器数据。这种形态需要你接入消息队列逐条或逐批处理。工程复杂度最高一般从零开始的项目不太会一上来就做流式。如果你确实需要建议先用批处理模拟等业务量上来了再改成流式。5.2 模型序列化与加载别在线上重新训练我见过一个很离谱的案例有人把训练代码直接搬到线上服务里每次请求都重新训练一遍模型。这当然是个极端例子但背后的思维误区很常见没有把训练和推理分开。正确的做法是训练阶段把模型参数序列化保存下来推理阶段直接加载参数不涉及训练逻辑。序列化的格式有很多选择PyTorch用state_dictTensorFlow用SavedModel通用一点可以用ONNX。选哪个取决于你的推理框架但原则是一样的训练和推理解耦。加载模型的时候要注意线上环境和训练环境的依赖版本要一致。我踩过这个坑训练时用的PyTorch版本和线上不一致导致加载模型时报了一堆莫名其妙的错。后来我养成了习惯用容器把训练环境和推理环境都固定下来确保版本一致。5.3 服务监控上线只是开始服务上线不是终点而是起点。你得知道它运行得好不好有没有出错延迟高不高结果对不对。这些都需要监控。最基础的监控是存活监控就是服务还在不在。这个用健康检查接口就能实现每隔几秒调一次连续失败就告警。稍微进阶一点是性能监控记录每次请求的延迟、吞吐量、错误率。这些指标能帮你发现性能瓶颈比如延迟突然升高可能是某个依赖服务变慢了。最重要的监控是效果监控。模型返回的结果质量有没有下降这个最难监控但也最有价值。我的做法是在服务里埋点记录每次请求的输入和输出定期抽样人工评估或者用另一个模型做自动评估。一旦发现效果下降就能及时触发模型更新。注意监控数据本身也要有保留期限和清理策略。我见过一个服务监控日志写了半年没清理把磁盘写满了导致服务崩溃。这种低级错误踩过一次就记住了。6. 常见问题与排查技巧实录6.1 训练时loss不下降先查这五个地方Loss不下降是训练阶段最常见的问题原因可能有很多。我自己的排查顺序是这样的第一查数据。数据里有没有NaN标签有没有对齐输入和标签是不是一一对应。我遇到过标签错位的情况模型怎么学都学不对查了半天才发现是数据加载时打乱了顺序但没同步打乱标签。第二查学习率。学习率太大loss会震荡甚至发散学习率太小loss下降极慢。可以试试用学习率扫描找一个大致的合理范围。第三查模型结构。层数对不对激活函数对不对输出维度对不对。特别是输出维度跟标签维度不匹配的话loss计算会出问题。第四查损失函数。分类问题用交叉熵回归问题用均方误差用错了loss不下降是正常的。第五查初始化。权重初始化太差模型可能一开始就陷入饱和区。可以试试换一种初始化方法或者加BatchNorm。6.2 线上推理结果和离线不一致通常是这三个原因离线评估好好的一上线结果就不对这种情况太常见了。我总结下来原因通常有三个第一个是数据预处理不一致。离线用的预处理逻辑和线上不一样比如归一化的均值方差不同或者特征顺序不同。这个最隐蔽因为两边代码看起来都对但就是不一致。解决办法是把预处理逻辑封装成一个共享模块离线和线上都调同一个模块。第二个是模型加载不完整。有时候模型保存了但加载时漏了某些层或者加载了错误的版本。这个可以通过在服务启动时打印模型结构来排查。第三个是环境差异。依赖库版本不同硬件不同甚至随机种子不同都可能导致结果差异。这个只能靠容器化来根治确保离线和线上环境完全一致。6.3 排查问题速查表问题现象可能原因排查方法训练loss不下降数据、学习率、模型结构、损失函数、初始化逐项检查先用小数据集过拟合线上离线结果不一致预处理不一致、模型加载不完整、环境差异对比预处理代码打印模型结构容器化环境推理延迟高模型太大、批处理不当、依赖服务慢性能剖析看时间花在哪一步服务内存泄漏缓存无上限、对象未释放、日志堆积监控内存曲线定期重启加缓存淘汰策略模型效果逐渐下降数据分布漂移、反馈闭环缺失监控输入分布定期重新训练6.4 几个让我少走弯路的实操心得第一个心得小步快跑别憋大招。我刚开始总想一次搭一个完美的系统结果拖了几个月什么都没交付。后来改成先搭一个能跑通的最小版本哪怕很粗糙先上线再迭代。这个转变让我的交付速度快了很多。第二个心得日志要打够但别乱打。日志是排查问题的命根子但打太多也会淹没关键信息。我的习惯是每个关键决策点打一条INFO日志每个异常打一条ERROR日志中间过程用DEBUG级别线上默认不开。第三个心得配置和代码分离。所有可能变化的参数都放到配置文件里代码里不写死。这样改参数不用改代码不用重新部署风险小很多。第四个心得定期做故障演练。故意把某个依赖停掉看服务能不能优雅降级故意把数据搞脏看监控能不能发现。这种演练能帮你提前发现系统的脆弱点。7. 从零到一之后持续迭代的工程习惯7.1 反馈闭环让系统自己变好一个AI系统上线之后最重要的能力是持续迭代。而持续迭代的前提是你要有反馈闭环。用户的行为、系统的输出、业务的结果这些数据要能回流到训练环节形成闭环。最简单的闭环是人工标注。定期抽样线上结果人工判断对错把标注结果加入训练集重新训练模型。这个闭环虽然慢但最可靠。稍微进阶一点是自动闭环用规则或者另一个模型自动判断结果好坏自动生成训练样本。这个快但需要小心因为自动判断本身可能出错错误会累积。我自己的做法是先做人工闭环确保流程跑通再逐步引入自动判断。自动判断的准确率要达到一定阈值才能用不然宁可不做。7.2 技术债管理AI项目也有技术债AI项目的技术债跟传统软件不太一样。传统软件的技术债主要是代码质量问题AI项目的技术债还包括数据债和模型债。数据债是数据质量差、覆盖不全、标注不一致模型债是模型结构过时、超参数没调优、评估不充分。这些债不还会怎样短期看不出来长期会拖慢迭代速度。每次想改点什么都发现被各种历史问题绊住。我的建议是每个迭代周期留出一定比例的时间专门还债比如百分之二十。不要等到债台高筑才想起来还那时候成本就太高了。7.3 团队协作别做孤胆英雄从零搭建AI工程能力一个人可以走很远但要走得远还是得有团队。团队协作的关键是标准化。数据格式标准化、代码风格标准化、实验记录标准化、部署流程标准化。标准化的目的是降低沟通成本让每个人都能快速理解别人的工作。我自己的团队里我们有一套简单的规范所有数据必须有schema定义所有代码必须过lint所有实验必须记录配置和结果所有部署必须走CI/CD。这些规范不复杂但坚持下来协作效率提升非常明显。最后再分享一个小技巧定期做知识分享。每个人把自己踩过的坑、学到的新东西讲一讲不用很正式午饭时间聊二十分钟就行。这种非正式的分享往往比正式培训更有用因为讲的是真实经验不是教科书上的东西。这个内容后续还可以这样扩展如果你已经走完了从零到一的过程下一步可以研究怎么把AI工程能力产品化做成内部平台让更多团队受益。那又是另一个层面的挑战了但基础还是这些从零搭建时打下的功底。