
先讲个真实场景。你手里有一个训练好的模型本地推理一点问题没有但到了项目上线阶段数据一进来结果就乱了或者延迟高到没法用又或者换台机器环境就崩。多数人接下来会去搜“模型上线报错怎么办”“Python import 失败怎么办”而我更建议你先停下来想另一件事把模型训练出来只占整个AI系统的两成剩下八成全在工程。这也是“ai-engineering-from-scratch”这个项目真正想解决的问题——不是教你调参炼丹而是帮你把从零开始构建AI工程的全链路打通。我一直觉得AI工程和算法研究是两门手艺。算法研究员把注意力放在模型结构和训练技巧上而AI工程师要搞定的是数据管道怎么搭、训练任务怎么稳定复现、离线模型怎么变成在线服务、上线之后怎么监控和迭代。这两者当然有交集但核心能力要求完全不一样。如果你刚接触AI不久或者已经会用Python训练一些模型但一旦涉及“把模型真正落到产品里”就卡壳那么从零梳理一条AI工程的完整路径会比继续加练模型结构有用得多。这个项目就是干这个的。它不预设你已经有多少工程基础而是从最底层开始一层一层往上搭先明确AI工程到底解决什么问题再把知识体系拆开接着选一套足够顺手的工具链最后通过一个完整的“从零到上线”的小项目把全流程走一遍中间还会穿插我这些年见过的各种坑。适合谁看适合那种“跑过模型、但没跑通系统性工程”的开发者也适合刚转行进入AI领域的算法新人以及团队里想从“单点技术”走向“全局交付”的工程师。1. 先搞清楚一件事AI工程不是炼丹1.1 AI工程师和算法工程师到底差在哪我看到太多人把这两个角色混为一谈然后在实际工作中被折腾得够呛。算法工程师的核心产出是“模型效果”他们通常在一个可控的实验环境里工作有明确的数据集、评测指标和算力资源。AI工程师的核心产出则是“稳定的服务”他们要考虑的不光是模型效果还有数据从哪来、怎么处理、怎么存储、训练任务怎么调度、模型怎么部署、线上怎么监控、出问题怎么回滚。一个很形象的类比算法工程师是研究菜谱的大厨AI工程师是设计中央厨房的人。大厨关心这道菜用什么火候、多少克的调料而中央厨房的设计者关心的是食材供应链、切配流水线、冷链运输、以及同时出几百份菜时不会出乱子。你光会做一道好菜和你能让一万个人同时吃上这道好菜需要的技能完全不一样。在AI落地项目中我见过无数团队踩同一个坑模型效果明明不错AUC高准确率也高但一上线就面临数据分布不一致、推理延迟超标、内存泄漏、任务并发顶不住等一系列问题。这些问题全部需要AI工程能力来解决。所以用项目标题里的“from scratch”这个词很准确——AI工程不是把模型装个壳就行而是从数据、训练、评估、上线到监控的全生命周期建设。1.2 “从零开始”真正要打通的东西如果只列几个关键词AI工程的核心链路大致是数据处理 - 模型训练 - 实验管理 - 模型评估 - 服务化部署 - 监控告警 - 持续迭代。每个环节里面都有大量工程细节。比如“数据处理”这一步看起来只是读取数据、清洗一下、转个格式但实际做起来涉及数据版本管理、数据校验、特征一致性问题、数据漂移检测。再比如“模型训练”不是把模型fit一下就结束了你要关注训练资源分配、断点续训、实验可复现、以及训练过程中的性能瓶颈。“服务化部署”就更麻烦了是同步还是异步用CPU还是GPU要不要批处理怎么做弹性伸缩每一个问题都能单独写一篇文章。所以“从零开始”不是一个线性的学习路径而是一个系统工程的拆解过程。你得先把整张地图画出来知道哪里有坑再决定先走哪条路。这个项目的核心价值就在这里把地图画清楚把路径标出来然后一步一步带着走。2. 知识体系别贪多按这条主线搭2.1 底层工具Linux、Python、命令行的熟练度边界先说结论你不必成为Linux系统管理专家但你必须能在命令行环境里高效完成文件操作、进程管理、环境变量配置、资源监控这几件事。为什么是Linux因为AI训练和部署环境绝大多数跑在Linux上无论是云服务器还是自建机房。Windows上的WSL能用但生产环境仍然是Linux主导。我从没见过一家公司的生产环境是Windows Server跑AI服务的。所以第一步就花点时间把Linux操作练熟尤其要掌握三件事一是文件系统与目录结构知道你的数据、日志、模型权重分别放在什么位置二是进程管理与资源查看用top、free、nvidia-smi这些命令观察CPU、内存、GPU的状态三是权限与系统服务搞清楚如何配置环境变量、如何注册一个systemd服务。Python是AI工程的核心语言这一点短期内不太会变。但很多人对Python的掌握停留在“写脚本”层面一到工程上就放飞自我。AI工程里用Python至少要具备模块化组织能力会写可复用的函数和类会管理第三方依赖会使用虚拟环境隔离项目的依赖还要会调试——logging和断点调试都得习惯用起来。命令行熟练度这块我推荐git和bash至少熟练到不用看文档的水平。版本管理不是可选项是每天都要用的。代码回滚、分支切换、合并冲突解决这些操作要形成肌肉记忆才好。2.2 数据处理最容易轻视也最容易被坑的位置AI模型训练时模型结构选型往往不是最大的坑数据预处理才是。这句话我至少对不同的团队重复过上百遍但每年还是有人掉进去。数据处理的工程界面包括几个主要内容。第一是数据采集与存储你需要判断数据量级来选择存储方案。几百MB的用Parquet文件就够了几十GB的用对象存储计算侧按需拉取TB级别的要上分布式存储或者数据湖方案。第二是清洗与转换这一步你能看到各种乱七八糟的问题字段缺失、类型不一致、重复样本、跨文件对齐失败、编码格式混乱。第三是特征与标签的处理决定哪些特征进入模型、如何编码、是否做归一化这步直接决定模型上限。有一个很关键但又总被忽略的点叫做“数据版本管理”。训练数据和代码一样需要版本化因为模型的效果高度依赖训练数据的分布。如果哪天你把模型回滚到上周的版本但训练数据已经偷偷变了你会排查到怀疑人生却找不出原因。现在的主流方案是用数据版本管理工具比如DVC把数据快照和代码版本挂在一起实验可复现性就能上一个台阶。2.3 算法理解从“调包”到“敢改”AI工程不要求你从零手写Transformer但你至少要能用准确的语言描述模型在做什么、知道主流模型架构之间的区别、能解释模型的输入输出结构。这些知识决定了你排障时能不能定位问题出在哪一层。我给你个具体的标准如果你在用一个分类模型你应该能说出来Embedding层在做什么、BatchNorm和LayerNorm的区别、Dropout为什么只在训练时开启、损失函数是怎么计算的、评价指标里精确率和召回率对你这个业务场景各意味着什么。在这个基础之上你要敢去改模型代码。我在项目里经常需要把BERT换成不同层数的变体、调整注意力头的数量、给Transformer做一个小的结构改动来适配业务输入。如果你只会用HuggingFace的AutoModel一看到源码就头大那遇到工程上的问题会非常被动。给你一个练习方法找一个小型BERT模型把它的源码打开读一遍然后把Embedding的维度改小一半重新训练看看行为变化。做过一次之后你就会明白调包和懂包是两种完全不同的境界。2.4 服务化部署AI落地和算法demo的分界线训练出一个模型只是第一步把模型变成别人能调用的服务才算真正价值落地。这正是AI工程和算法研究拉开差距的关键环节。服务化部署的核心有两个维度。维度一是接口设计。同步接口适合延迟敏感的场景比如实时推荐、在线风控异步接口适合耗时较长的任务比如批量生成、文档解析。接口要用标准协议输入输出要有清晰的schema还要有合理的错误码。维度二是资源效率。一个模型服务该用CPU还是GPU取决于你的推理吞吐和延迟要求。小模型在CPU上已经能跑得不错没必要上GPU大模型在GPU上还得考虑显存管理、批处理策略、模型量化。我自己做服务化部署时习惯用Docker把环境打包这样能解决“在我机器上是好的”这种经典问题。Docker之后再接一层API框架就可以把模型暴露成HTTP接口供上游业务调用。这个链路我会在后面的实操部分详细演示。部署完成之后还没有结束。线上模型需要监控核心看两个指标技术指标包括推理延迟、服务吞吐、错误率、资源利用率业务指标包括预测分布有没有偏移、推荐内容点击率有没有下降、风控模型拦截率有没有异常。这些指标一旦出现异常要么是模型效果退化要么是数据分布变化需要及时启动诊断流程。没有监控的AI服务就像夜里没有仪表盘的飞机飞的时间越长越危险。3. 工具链选型这一套组合够用且不折腾3.1 环境与依赖管理AI项目的环境管理一直是痛中之痛。Python解释器版本、CUDA版本、第三方库版本任何一个不兼容都能磨掉你一个下午。我一度用过Anaconda管理环境后来又试过Docker打包一切还在不同公司见过多种风格直到近两年新一代的Python包管理器成熟后我才把个人项目的环境管理统一到了uv上。用uv最大的感受就是快。传统的pip和conda在解析依赖时经常要长时间跑依赖树求解遇到版本冲突会陷入“我要解A需要BB又需要C的旧版本”的循环uv用了新的解析策略速度快很多。再配合项目级别的虚拟环境管理从头到尾一个工具就能搞定大部分事情。不过如果你在公司环境里工作已有的基础设施往往已经固化了。比如有些公司规范要求必须用conda有些项目跑在预构建的Docker镜像里这都能接受。工具是为人服务的别为了换工具而换工具。但自己从零起项目时我建议优先考虑uv能省不少时间。3.2 训练框架主流的训练框架绕不开PyTorch和TensorFlow这两大阵营。从我的实际使用感受和行业趋势来看近几年新做的项目大部分都在往PyTorch靠。原因不复杂一是生态优势HuggingFace Transformers、各个大模型的开源实现、以及绝大多数的论文代码都是PyTorch写的直接拿过来改比重新迁移到另一个框架省太多力气二是调试体验PyTorch的动态图机制对入门和排障都友好很多。TensorFlow早期在工业部署上有一些优势尤其是TFServing被一部分团队采用但现在PyTorch的推理服务方案也已经非常成熟比如TorchServe或者直接把模型导出为ONNX再跑推理引擎。对我这种同时要搞研究和落地的人来讲不折腾是很重要的所以PyTorch会是默认选项。小技巧不要在一开始就追求用分布式训练框架比如DeepSpeed、Megatron-LM。如果你的模型单卡能跑那就先在单卡上把流程跑通等确认数据量或者模型规模确实需要多卡再上分布式。过早引入分布式会让问题复杂度成倍上升新手很容易在堆代码的时候迷失方向。3.3 实验跟踪与数据版本化做AI工程最忌讳的情况是跑了20轮实验最后发现有一个效果特别好的模型但你已经不记得它用了什么参数、什么数据、哪份代码。这个场景我经历过太多次了所以我会在第一个正式项目开始前就配好实验跟踪工具。实验跟踪我推荐MLflow开源且上手门槛低。每一轮训练把项目名称、模型参数、训练数据来源、关键指标全部记录下来再配合后端存储就能支持你随时回溯任意一个实验。这其实就是工程规范的一部分只是很多人没意识到它能省下大量时间。数据版本化我建议用DVC这类工具。DVC可以跟Git挂钩Git只能跟踪代码的变化而数据文件往往很大不适合放进Git仓库。DVC把数据的元信息和存储位置记录下来放入Git数据本身保存在本地或者云存储提交时生成一个指纹。这个方案的好处是训练的“代码版本数据版本参数版本”三者可以严格绑定需要复现某个结果时直接把三个版本拉出来就能对得上。3.4 API服务与容器化模型训练完之后需要把模型变成一个在线可调用的API。这里我建议直接用FastAPI。它对异步支持很好能够处理高并发请求而且自带交互式API文档配合类型校验可以少写很多输入检查代码。如果你更熟悉Flask也可以用但面对高并发异步场景时FastAPI的Starlette底层和async支持会更有优势。容器化现在基本是标配了。把整个推理环境写进Dockerfile构建成镜像推到镜像仓库部署平台拉取镜像运行。这套流程能解决90%的环境一致性问题。镜像定义里建议把依赖锁定到具体版本而不是用“最新”标签。否则哪天基础镜像更新了你的服务在半夜悄悄升了级第二天你起来发现延迟翻倍了那种排查过程相当折磨人。如果你所在的公司有Kubernetes基础设施那Docker镜像可以很方便地拿去编排。但我要提醒一下Kubernetes的学习曲线不低熟练使用它需要一段时间。如果只是做个人项目或者小团队起步完全可以用Docker Compose管理服务先把功能跑起来再说。4. 实操实录从零到上线一个中文短文本分类系统4.1 项目目标与整体流程纸上谈兵再多也不如动手写一次。我挑了一个既能展示完整流程、又不会让机器配置门槛太高的项目来做演示中文短文本分类。具体场景是判断一段客服对话文本是否需要人工介入划分成“正常”和“需介入”两个类别。这个场景在真实业务里很常出现而且数据是自己可以标注的不碰商业机密。整体流程分四步数据准备、模型微调、模型评估、服务化部署。这个流程其实就是AI工程最小闭环,每走完一圈你都会对全流程更熟一点。4.2 数据准备阶段我找了个开源的客服对话数据初始格式是CSV包含对话文本和标签。数据是脏的有缺失值、重复项还有少量完全无关的日志行。了解AI工程的人都知道真实数据永远不会像教科书的样例一样工整所以这里正好演示数据清洗。清洗代码用Pandas就够了主要做三件事删除缺失标签的行去重过滤掉过长和过短的文本。文本过长可能是复制粘贴的重复内容过短往往是无意义符号。这里有一个细节要记住清洗规则一定要保存成代码文件以后每次跑同一条数据管道都用同一套规则。不要今天在Notebook里改一下、明天在脚本里改一下那样结果根本没办法复现。接着做数据划分按8:1:1切成训练集、验证集、测试集。特别提醒划分前先给数据加一行随机种子这样才能确保每次运行划分出来的结果一致。4.3 模型训练与实验管理中文短文本分类这里我直接用了HuggingFace上的一个中文BERT小型模型参数量对CPU也能扛得住但实际训练我还是用GPU跑。加载预训练模型、定义分类头、配置训练参数这一套流程HuggingFace的Trainer封装得很好你可以直接用现成的接口。训练参数里我认为最关键的是学习率和批次大小。学习率太大loss会抖学习率太小训练半天loss降不下去。经验值BERT微调的学习率可以定在2e-5到5e-5之间先从2e-5开始试。批次大小取决于GPU显存显存不够就调小批次同时在代码里加上梯度累积来模拟更大的批次。训练过程中我把MLflow接上了每一轮的loss和验证集指标都会同步记录到MLflow的服务端。这里有个工程习惯值得养成不要只记录最终的指标要记录完整曲线。因为调参时光看最终分数没法判断是欠拟合还是过拟合曲线一目了然。跑完训练后我要做一次严肃的模型评估不能光看准确率。对分类任务至少看混淆矩阵、精确率、召回率、F1值。对于“需介入”这类少数类召回率比准确率重要得多漏掉一条远比多转一次人工严重。评估结果如果不如预期就要回头调数据或者调参这里体现了AI工程中“实验闭环”的价值。4.4 模型导出与在线服务模型训好之后下一步是把训练好的状态文件转成可用于推理的格式这里我用ONNX做一次加速。为什么要转换ONNX Runtime在CPU上的推理比直接跑PyTorch的Eager模式快不少而且ONNX格式可以跨不同的推理框架部署兼容性更好。导出ONNX需要给模型提供固定的输入尺寸和动态轴配置。短文本分类场景输入的最大长度固定为128这样就不用处理动态维度带来的额外复杂度。导出之后测一下推理时间如果单条样本超过预期可以考虑开ONNX Runtime的优化选项或者降精度到float16。服务化部署就按前面选型的方案FastAPI搭配Docker。FastAPI里定义好一个接收文本的POST接口服务内部做分词、转为模型输入、让ONNX Runtime跑前向推理、把概率返回给调用方。测试请求返回结果再写一个简洁的Dockerfile把Python环境、模型文件、服务代码一起打包进镜像。这套流程走完模型上线静态演示是没问题的。但要成为一个合格的服务还得考虑并发和压测。我这里用模拟压测测了一下发现单worker的CPU占用偏高于是开了两个worker进程并将请求日志接入监控面板。到这一步一个“从零到在线服务”的最小闭环就算真正打通了。5. 踩坑实录这些问题我几乎都见过5.1 训练时loss正常推理结果全乱这不是个例而是非常典型的工程事故。训练的时候loss曲线光滑下降评估集得分也还可以但模型部署上线以后新数据进来结果全乱。我之前排查的一个经典案例是数据编码混乱训练数据里全是干净的Unicode字符串而线上传上来的数据带着各种码表和错误编码分词器完全跑偏。这个问题的本质是“训练时数据干净、线上数据脏”属于数据分布不一致的典型场景。第一次排查建议先看线上样本做了哪些预处理是否和训练时完全一致分词用同一个分词器版本、编码统一成UTF-8、空白处理一致、特殊符号有没有过滤。把这些前置环节对齐再考虑别的可能性。5.2 显存溢出怎么排查显存溢出out of memory是训练过程中最常见的报错。我的经验是先用排除法缩小范围。第一步看单条样本的尺寸序列长度是不是超长如果超长就要加长截断策略。第二步看批次大小调小一个级别看能不能跑通。第三步看模型本身是不是把几个大模型同时加载到了同一张卡上。如果批量已经调到很小还溢出可以考虑开启梯度检查点、混合精度训练、或者优化器状态的内存占用。混合精度训练现在已经是常规操作了只要显卡支持打开基本都有收益。5.3 上线后P99延迟飙升上线前你可能只关注平均延迟上线后你会发现问题往往出现在P99延迟上也就是最慢的那1%请求。几个常见原因值得注意首次请求触发了冷启动流程因为模型权重还没完全加载到内存推理服务被某一个大请求阻塞了CPU或者GPU资源被其他任务抢占。排查手段建议先把监控配好记录延迟分布、资源占用、并发数量。如果延迟飙升集中在某些时间段就看一下这段时间系统层面有没有其他任务在跑。如果是冷启动问题可以在服务启动时做预热请求强制加载模型。5.4 数据泄漏导致的“虚假高分”模型的评估分数高得异常先别高兴先怀疑数据泄漏。有一次我在做类似分类项目时数据预处理里没有设置随机种子导致部分测试集的数据混进了训练集评估分数直线飙升但真实线上表现一塌糊涂。排查数据泄漏要检查非常细致训练集和测试集是否有ID重叠特征里是否包含了未来信息预处理统计量是否用了全数据计算比如归一化里的均值和方差应该是用训练集统计出来再应用到测试集不能整体数据一起算。这类问题在“从零开始”的项目里尤其容易犯。5.5 环境不一致导致的“本地能跑线上挂”“在本地跑通了部署到服务器上就崩”这个场景在AI项目里出现频率非常高本质是环境差异没有在部署前处理干净。最常见的差异是依赖库版本不一致。你在本地用的是某个库的1.0版本服务器上装的是2.0接口行为变了运行逻辑就错了。把环境锁死是最有效的解法。用锁文件固定依赖版本用Docker把整个环境打包确保开发环境和生产环境用的是同一个镜像。另外给Dockerfile里的基础镜像打好版本标签不要用latest。一点个人体会“ai-engineering-from-scratch”这个词我越做越觉得它代表的不只是一个项目更像是一种思维方式永远不要只满足于“模型能跑”而要追问“整个系统能不能稳定运转”。在经历了很多线上的突发故障之后我的体会是AI工程的下限是可靠性和可维护性上限才是模型效果。先保住下限再追求上限这个顺序反了项目会越做越累越做越不可控。最后再分享一个小技巧不管项目多赶每一步都尽量把脚本和配置文件以代码形式保留下来包括清洗、训练、导出、部署。虽然这样起步会慢一点但后面每次迭代你都会因为有这块“地基”而省下大量时间。我见过太多人为了图快在Notebook里一路狂奔等到需要复现结果时才发现什么记录都没留下。从零开始的确不容易但地基打稳了楼就不会倒。