
作为常年跟AI工程打交道的人我越来越觉得“ai-engineering-from-scratch”这个名字本身就很妙——它精准戳中了很多团队的痛点模型大家都会训但能从零把一个AI系统稳稳当当搭起来、跑起来、持续迭代下去的真没多少人。这个项目标题背后本质上是在回答一个问题当AI从论文里的实验品变成生产环境里的工具工程化到底意味着什么。这篇文章我想围绕“从零开始做AI工程”这条主线把环境搭建、数据治理、模型训练、部署监控这些环节挨个拆开聊。文章里所有结论都来自我自己的实操经验也补充了很多通用场景下的踩坑记录。适合刚入行的算法工程师、想系统化梳理AI工程流程的开发者以及正在被“模型上线难”折磨的团队参考。如果只能留一个核心观点我的答案是AI工程化的本质是把不确定性变成确定性。论文里的模型追求最高精度生产里的系统追求的是稳定、可复现、可维护。下面直接进正题。1. AI工程到底是什么——从一段代码到一个系统的距离1.1 AI工程和传统软件工程差在哪很多人把AI工程理解成“写Python代码调用模型库”这是最常见的误解。我自己刚转型做AI平台的时候也这么干过本地Notebook里跑通一个模型兴冲冲地跟团队说“完成了”结果一谈到上线就傻眼——数据从哪来、模型怎么打包、推理性能能不能扛住线上QPS、A/B测试怎么设计、模型效果变差了怎么感知每个问题都让人头大。传统软件工程讲究的是确定性输入是确定的逻辑是确定的输出是确定的我们要做的就是维护这条确定性的逻辑链。AI工程完全反过来它处理的是概率模型数据会变模型的预测会错效果会衰退整个系统里充满不确定性。所以AI工程的挑战不是“写代码”而是“设计一套机制去管理这些不确定性”。这带来两个核心差异。第一AI工程必须有一个“数据闭环”而不只是“代码闭环”。代码出问题修完可以迅速回滚数据出问题比如上游特征字段改了、标注重叠了问题往往很隐蔽可能要等线上效果指标异常才能察觉。第二AI工程是跨团队协作的产物不是某个算法工程师的独角戏数据的质量依赖数据工程师特征的时效性依赖业务工程师模型的稳定依赖运维工程师任何一个人掉链子模型效果都会跟着崩。1.2 一个完整的AI工程生命周期长什么样我在搭建自己的ai-engineering项目时把整个生命周期拆成六个模块每个模块都有明确的目标和交付物问题定义明确模型服务哪个业务场景对应的业务指标是什么。这里最容易犯的错是“为了AI而AI”先拍脑袋决定用深度学习再回头找问题。数据构建采集原始数据、清洗、标注、划分训练集验证集测试集并用数据版本控制工具管理。数据版本和代码版本一样重要这决定了模型的可复现性。特征工程原始数据到模型输入之间的桥梁包括缺失值处理、异常值处理、特征编码、特征筛选等。模型训练设计基线模型、选型、调参、评估输出一个“可上线的模型”而不是“性能最好的模型”。部署与推理把模型封装成服务或批处理任务接入生产环境保障延迟、吞吐、稳定性。监控与迭代通过线上日志和指标检测数据漂移、效果衰退触发新一轮训练或策略调整。这六个模块不是流水线式的“做完一个再做下一个”而是环形闭环。模型上线那一刻才是工程的真正开始。我个人的建议是任何AI项目开工前先花半天把这六个模块的目标和责任人画清楚哪怕只画在纸上也比直接开干稳得多。只要有一个模块缺失后期补课的代价都是指数级上升的。2. 从零开始的环境搭建与工具选型2.1 硬件和基础环境的几个关键决定搭建AI工程环境第一个问题永远是用谁的算力方案无非三种本地GPU、公司集群、云GPU。对于从零开始的个人项目我的建议是先用小规模数据在本地把完整流程跑通再上大规模算力。这个“先小后大”的思路能帮你省下大量调试时间也避免把宝贵GPU资源浪费在写bug上。硬件上显存是模型训练的第一瓶颈。粗略估算公式一个Transformer类模型在混合精度训练时显存需求大约是“单卡显存 参数量 × 2到4”。比如你要微调7B参数的模型没有16G以上显存就是自找麻烦如果只是训练几百万到几千万参数的小模型消费级显卡完全够用。这个估算不精确但用于选卡足够了。软件环境层面建议一开始就做好两件事。第一是Python版本管理直接用conda或者pyenv把项目环境隔离出来不要用系统自带的Python裸奔。第二是GPU驱动和CUDA的版本对应关系要提前确认否则装好框架后一调用GPU就报错这种问题排查起来最浪费精力。2.2 技术栈选型与项目结构设计AI工程的技术栈选择我倾向于“稳定优先于新颖”。框架层面TensorFlow和PyTorch都可选但从社区活跃度、生态完善度和人才储备来看PyTorch目前是更省心的选择。数据处理层Pandas加PyArrow处理表格数据Polars在处理大规模数据时性能更强。任务编排层Airflow或Prefect负责定时批量任务在线服务层FastAPI加Docker是核心组合。目录结构设计往往被新手忽略但它极其重要。我自己的标准结构是这样组织的ai-engineering-from-scratch/ ├── configs/ # 所有配置文件 ├── data/ # 原始数据、中间数据、最终数据 ├── features/ # 特征工程脚本 ├── models/ # 模型定义、训练脚本、模型产物 ├── services/ # 推理服务代码 ├── tests/ # 单元测试、数据验证测试 ├── scripts/ # 日常运维脚本 └── notebooks/ # 探索性分析代码重点是“四大分离”配置与代码分离、数据与代码分离、模型产物与代码分离、环境依赖与代码分离。这四条做到位项目在任何机器上都能快速复现这才是AI工程的基本功。3. 数据治理与特征工程——AI工程的地基3.1 数据处理流水线怎么搭才不容易翻车一个典型的机器学习项目里数据准备和特征工程通常要占掉60%到70%的时间这个比例一点都不夸张。我做项目时最怕听到“数据直接从仓库拉一下就完了”因为“拉一下”背后藏着无数细节不同数据源的ID格式是否统一时间字段是字符串还是时间戳类别数据里有没有拼写错误数值列里隐藏的缺失标记比如-9999有没有被识别。数据处理流水线的核心原则是“每一步都可追踪、可重跑”。我不建议在Notebook里手工处理数据因为手工处理意味着流程不可复现。我会把数据清洗写成独立Python模块配合DVC做数据版本管理每次数据处理变更都有记录模型复现时也能精确找到当时的数据版本。训练集、验证集、测试集的划分同样不能随便做。时间序列数据必须按时间顺序切分不能随机划分否则相当于用未来信息预测过去分类问题要注意类别分布的一致性避免训练集和验证集的类别比例失衡。我踩过的一个坑是模型上线后发现预测分布和训练时差很多排查到最后发现是数据划分时把同一个用户ID的样本同时放进了训练集和验证集造成了严重的数据泄漏。3.2 特征工程的常规操作与进阶思路特征工程本质上是在把业务理解翻译成模型能听懂的语言。数值特征方面量纲差异很大的特征建议做标准化或归一化否则梯度下降极其缓慢长尾分布明显的特征做log变换能有效减轻极端值的影响。类别特征方面基数低的直接用独热编码基数高的用目标编码或嵌入但目标编码要注意在训练集内做交叉验证式的编码否则又会引入泄漏。时间特征的构造常常被忽略但对很多业务场景非常有效。距上次购买天数、距注册天数、最近一周活跃次数这类“相对时间特征”比单纯的“注册日期”威力大得多。特征筛选方面可以先从相关性分析入手剔除高度相关的冗余特征再用基于树的模型特征重要性或置换重要性做进一步筛选。有一点必须强调特征工程不是越花哨越好。在生产环境里每一个特征都是要持续供数的花哨的特征往往意味着高昂的维护成本。我会从“模型增益”和“维护成本”两个维度给每个候选特征打分只保留性价比高的那些。这个习惯帮我在多个项目里避免了“特征越做越多、效果原地踏步”的窘境。4. 模型训练与调优——从基线到可上线4.1 先跑通一个“足够好的模型”再谈调优很多新手一上来就追求SOTA非要上最复杂的模型、堆最多的技巧结果连个能跑的基线都没有。我的习惯恰好相反第一个模型一定选最简单的线性模型或浅层树模型都行目的是把数据处理、评估流程、训练脚本这些管线跑通。基线模型效果虽然一般但它是整个工程链路的“冒烟测试”。拿到基线之后再根据业务场景逐步升级模型。表格数据场景XGBoost、CatBoost这类梯度提升决策树往往比深度学习更容易出好效果也更易调试文本场景可以从经典词向量模型升级到预训练语言模型的微调图像场景直接在预训练模型上做迁移学习而不是从头训练。训练脚本的设计要始终围绕“可复现”展开固定随机种子、记录训练参数、按固定间隔保存checkpoint、定期记录loss曲线。PyTorch下用Lightning框架可以省去大量样板代码它对多GPU训练、混合精度、checkpoint管理的支持都非常成熟。4.2 超参数调优和过拟合防治的实操细节超参数调优是最容易让人上头、也最容易浪费时间的地方。我的建议是先把学习率、batch size、训练轮数这几个最核心的超参数调明白再去碰那些花哨的trick。学习率一般从1e-4到1e-2之间按数量级搜索batch size受显存约束优先选能塞进显存的最大值再按学习率线性缩放的规则适配。过拟合是另一个避不开的话题。最直接的方法是增加数据量但很多时候受成本和合规约束所以正则化手段必须跟上早停法是我用得最多的防过拟合手段验证集指标不再改善时停止训练既省时间又防过拟合权重衰减在深度学习里几乎是标配常见L2系数在1e-4到1e-2之间Dropout则适合轻量级的防过拟合需求。这里要特别提醒一个训练过程中容易被忽略的环节梯度检查。真正训练大模型之前先用小batch跑几次确认梯度没有爆炸或消失能省下后面大量排查时间。我曾经因为初始化不正确加学习率过大训练loss直接变成NaN整整浪费了一天后来才发现如果一开始做梯度检查五分钟就能定位到问题。5. 部署上线与持续迭代——最后的临门一脚5.1 模型服务化的两种主流方式模型训练完成之后面临的选择是在线实时预测还是离线批量预测我的判断标准很简单——对延迟要求高、需要实时响应的场景比如推荐排序、风险拦截走在线推理对时效性不敏感、数据量大的场景比如日报生成、批量打标走离线推理。在线推理的技术栈我会选FastAPI作为服务框架把模型封装成标准HTTP接口。这里有个关键点模型服务里做的数据预处理必须和训练时的完全一致否则线上推理效果会莫名其妙变差。最稳妥的做法是把特征工程函数单独抽出来做成公共模块训练和推理共用同一份代码从源头杜绝不一致。离线推理的难点在调度和资源管理。如果只是每天跑一次直接cron或者Airflow定时触发就行如果数据量大到单机跑不动就需要用Spark或者Ray做分布式批处理。无论哪种方式离线任务都要做好失败重试和监控告警否则某天任务悄悄失败线上还在用五天前的旧数据这种事故隐蔽性极强。5.2 模型版本管理与监控体系模型上线之后的监控体系是AI工程里最容易被低估的部分。我的经验是至少监控三个层面系统层看服务是否正常包括CPU、内存、GPU、延迟、吞吐数据层看输入特征分布是否稳定比如某个特征的均值突然偏移超过三倍标准差模型层看预测结果的分布和关键业务指标是否异常。数据漂移更是需要重点关注。我遇到过最典型的情况是一个信贷风控模型上线三个月后性能明显下降排查发现是用户的还款行为模式发生了改变导致特征分布整体偏移。解决思路是建立周期性重训机制比如每周自动用最新数据微调一次模型同时结合监控指标动态触发紧急重训。这种“监控定期重训紧急重训”的三级机制是我认为最实用的AI运营方案。模型版本管理方面每个上线模型都要有清晰的版本号、训练数据版本、特征版本和评估报告一旦线上效果异常可以立刻回滚到上一个稳定版本再从容排查问题。我习惯把模型服务里“当前生效版本”做成可动态调整的配置通过配置中心下发不需要重新发布服务这让回滚操作能在秒级完成。6. 实操中踩过的坑与排查技巧实录6.1 几个典型的翻车现场与定位思路先说说我印象最深的三个问题。第一个是训练和推理特征不一致线上推理效果断崖式下跌排查很久才发现训练时做了缺失值中位数填充推理时却忘了做同样的填充。第二个是显存泄漏服务跑一两天就OOM最后定位到推理代码里每次请求都重新加载了模型导致内存无限增长。第三个看起来最小但最致命训练脚本里忘了shuffle数据模型学到的是批次顺序的伪规律验证集效果奇好一上线就崩。这三个问题的共同特点是都在“训练和推理的边界”上出了错。所以我现在做AI工程有一条铁律训练管线和推理管线必须共用同一套数据处理代码任何一方的变更都要通过自动化测试兜底。每次数据处理改动只要跑一遍全量回归测试就能确认不会波及推理阶段。6.2 把经验沉淀成一份排查速查表踩坑踩多了之后我给自己做了一份排查速查表现在分享出来供参考症状可能原因快速排查动作训练loss直接NaN学习率过大、梯度爆炸、数据含NaN检查学习率、检查输入数据统计、开启梯度裁剪验证集效果好但线上差数据泄漏、训练推理不一致检查数据划分逻辑、逐字段比对预处理函数服务延迟越来越高内存泄漏、模型加载重复复现压力测试、检查对象引用和容器内存曲线特征均值突然偏移上游数据口径变更、数据漂移对比监控告警、回溯上游数据变更记录预测结果全是一个值特征全部缺失、模型加载失败检查特征实时取值、检查模型权重文件完整性这份表的核心思想就一句话先怀疑系统再怀疑模型最后怀疑数据。因为系统问题最快能定位数据问题影响面最大模型问题往往要结合前两者才能下结论。最后再分享一点个人体会ai-engineering-from-scratch真正考验人的不是数学功底也不是Python熟练度而是“把复杂系统拆成可靠流程”的工程能力。从零开始并不意味着从算法开始而是从流程开始把数据处理、训练、部署、监控这条链路一截一截搭稳哪怕每个环节用的是最朴素的技术整个系统也会非常可靠。如果再分享一条经验那就是随时把踩过的坑记录下来。我自己维护了一个团队的踩坑文档每解决一个问题就补一条配合排查速查表使用整个团队的AI工程效率提升了不止一倍。工程这条路上没有捷径但前人踩过的坑就是最好的捷径。