从零开始做AI工程,我入行前以为要把模型原理吃透,真正上手后才明白完全不是这么回事。第一次把训练脚本跑通的时候,我觉得自己已经算是个AI工程师了,结果等到要把一个带着AI功能的系统真正交付出去,前后折腾了小半年。这半年里,花在模型和参数学里面的时间可能不到三分之一,剩下的时间全部消耗在数据反复出问题上、指标和业务对不上上、服务扛不住流量被迫优化上,还有模型更新之后老用户效果回退的排查上。这些才是AI工程。
所以如果有人问我“ai-engineering-from-scratch”要从哪里下手,我会说先把手里的机器学习书合上,先建立一个观念:AI工程不是从模型开始的,是从接管问题、理解数据、搭建可以稳定运行的链路开始的。模型训练只是整条流水线里的一个环节,而“从零开始”的真正难点,在于把这条流水线的每一个环节都用工程手段打通。
1. AI工程首先是工程,其次才是AI
1.1 模型只是整条链路中的一环
刚接触这个领域的人最容易犯的一个错误,就是把“AI工程”等同于“训练模型”。线性回归跑通了、PyTorch里写了个简单的神经网络,就觉得自己已经入门了。但实际的工作流里,模型训练只占很小一部分,前后左右全是工程问题。
一条完整的AI系统链路大致是:数据接入、数据清洗、特征处理、数据版本管理、训练、评估、部署上线、推理优化、线上监控、反馈回流,然后才是下一轮迭代。任何一个环节出问题,整个系统都要停下来。模型精度再高,如果数据管线每天在凌晨三点断掉,线上服务照样会挂;实验做得再漂亮,如果训练出的模型无法被还原,出了问题也没法排查。
我个人的建议是,从第一天起就把自己当成“系统工程负责人”,而不是“模型训练员”。这不是说算法不重要,而是说算法只有在整套系统稳定运转的前提下才有意义。工程视角的核心是:我要对结果负责,而不只是对精度数字负责。
1.2 从零开始的认知模型
从零开始,首先要建立一个对AI工程的分解式认知。日常要对付的实际上是四个层面:
第一个层面是数据和特征。数据从哪来,质量如何,字段类型是否稳定,缺失率和迟到率多少,数据的更新频率怎样,有没有敏感信息需要脱敏。这一层如果没做好,后面所有工作都是空中楼阁。
第二个层面是训练和评估。怎么切分数据、怎么设计有效的验证集、怎么追踪一组一组的实验、怎么避免模型在选择验证集时过拟合但不解决真实问题。
第三个层面是部署和推理。模型是TensorFlow还是PyTorch写的完全不重要,重要的是如何在线上稳定地提供服务。吞吐量、响应时间、并发连接、显存占用,这些才是AI工程师每天真正要面对的。
第四个层面是监控和迭代。模型上线只是开始,不是结束。线上分布变了怎么办,新数据进来之后效果下滑怎么办,怎么收集反馈,怎么判断什么时候需要重训。
这四个层面就是一个从零开始的AI工程基本盘。任何一个环节松动,整个项目都会在地面上拖出一条长长的血痕。
2. 数据和数据管线,是AI工程的第一道大门
2.1 现实数据几乎永远是脏的
书本上的数据集是“被整理过的”:标签齐全、字段整齐、类目均衡。真实世界的数据完全是另一个物种。我自己踩过最大的坑,就是拿到一份看起来挺规整的日志数据,直接做了清洗开始训练,结果线上效果完全崩掉——后来排查发现这个数据从源头就有问题:一部分关键字段的缺失率达到90%,还有一批来自上游接口的样本天然带时区偏差,时间特征算出来全是错的。
所以我现在会建议所有从零开始的人:拿到数据的第一件事不是训练,而是做数据勘察。逐个字段检查取值分布、缺失率、类型是否恒常、代码值是否有变化。把数据本身的健康状况摸清楚,再谈建模。
我习惯在每个数据落地节点做三层校验:
- 结构校验:字段是否齐全、类型是否一致、必填字段有没有空值
- 取值校验:取值范围是否越界、类别数是否突变、统计量是否异常
- 时间线校验:数据到达有没有延迟、有没有重复推送、时间戳是否可信
这三层校验听起来很基础,但能提前干掉线上过半的问题。每次数据批次进入就自动触发校验,不通过的直接拦截并告警,这是我做过性价比最高的事情。
2.2 数据集划分不能偷懒
训练集、验证集、测试集的划分方式,直接决定了模型评估有没有意义。很多人随手做个随机打乱就完了,但对于绝大多数真实业务数据,这个做法是错的。
核心原因是数据泄漏和时间相关性。同一用户在训练集和验证集里出现,模型就会“记得”这个人而不是学会预测规律;当月的样本泄漏到上一轮的训练里,时间线上的因果就被破坏了。
我现在最少做两件事:
- 按时间切分:用过去的数据训练,用后来的数据验证,模拟真实预测场景
- 按主体分组:如果一个用户会产生多条样本,就按用户ID分组,确保同一个主体的所有样本只落在一个集合里
表格对比一下三种划分方式:
| 划分方式 | 场景 | 常见问题 |
|---|---|---|
| 随机划分 | 样本独立且无时间敏感性 | 容易造成泄漏,评估过于乐观 |
| 按时间划分 | 时序数据、用户行为序列 | 训练集和验证集分布可能有差异 |
| 按分组划分 | 多记录同主体、推荐场景 | 实现稍微复杂,但评估更可信 |
如果业务强调时序,还要注意做时间留出验证而不是普通交叉验证。交叉验证在这类场景下经常给出虚假的高分。
2.3 数据版本管理,从第一行代码开始
模型要迭代,数据也会变。最常见的情况是:你今天训了一个效果很好的模型,两周后想复现,发现数据库里的数据已经被新数据覆盖了,或者上游改了字段,代码根本跑不通。这种问题不是算法问题,是数据版本管理没做。
从零开始不用上很重的工具,只要做到三件事:
- 训练时记录数据集的存储路径、版本号或快照位置
- 把数据生成脚本和特征脚本纳入代码仓库一起管理
- 每次训练记录数据快照的哈希值或唯一ID
最小实现可以就是一行代码:把数据集文件名加个带时间戳的标签存进训练记录。后面出问题要回溯时,这一个小动作能省下你整整两周的排查时间。
3. 训练与实验管理:让“涌现”变成可控的产物
3.1 用工程流程替代临时脚本
零基础起步的时候,很多人训练模型的方式是把所有代码写在一个Python脚本里,跑一遍是一遍,结果记录在终端输出里。这个阶段在Demo里没问题,但一旦要做真实项目,麻烦马上就来:上次跑这个实验的时候用的什么学习率?这个模型是哪个数据集训练的?为什么今天的结果跟昨天不一样?这些问题一个都答不上。
我现在的习惯是把训练流程固化成以下几个环节:配置管理、执行训练、记录评估、注册产物。训练脚本从“写一段代码”变成“跑一条流水线”。
伪代码大概长这样:
# 最小可用的训练编排逻辑 experiment = {"project": "user_ctr", "exp_id": "20240612_001"} cfg = load_config("configs/baseline.yaml") data_version = load_data_manifest("latest") run_training(cfg=cfg, data_version=data_version) metrics = evaluate(phase="validation") log_experiment(experiment, cfg, data_version, metrics) register_model_if_better(metrics)训练本身不复杂,复杂的是把训练这件事变成可重复、可比较、可追溯的标准流程。
3.2 实验追踪:别靠记忆做AI
可以不用很复杂的平台,但一定要用实验追踪工具。从零开始,哪怕你用一张结构化的表格记都可以,关键是每条记录必须信息完整:实验名称、代码提交ID、数据版本号、关键超参数、验证集评估结果,缺一不可。
推荐记录的最小字段集合见下表:
| 字段 | 说明 |
|---|---|
| experiment_id | 唯一标识,可关联到代码提交 |
| data_version | 训练所用数据快照 |
| model_architecture | 模型结构的关键摘要 |
| hyperparameters | 完整参数,建议直接存配置JSON |
| metrics | 至少包括验证集核心指标 |
| artifacts_path | 模型产物存储位置 |
一旦实验可以复现、结果可以追溯,你才真正拥有了迭代的资本。否则每个模型都是“开盲盒”,上线靠运气,出了问题靠猜。
3.3 评估指标不要被单一数字绑架
刚入门时我最关注准确率,后来发现这个指标在真实场景里经常是陷阱。分类不均衡的时候,准确率极高也说明不了任何问题。
举个例子:一个欺诈检测系统,99%的样本都是正常交易,模型把全部样本都判成正常,准确率也有99%。但真正的欺诈一个都没抓到,一点价值都没有。
所以评估体系至少要看几个维度:
- 基础分类指标:精确率、召回率、F1,必要时看PR曲线和ROC曲线
- 群体差异:模型在不同用户群、不同时间段上是否表现稳定
- 业务指标对照:模型输出带来的业务结果,比如转化率、留存、坏账率变化
- 校准情况:模型预测的概率是否真的可信
从零开始,我建议把规则定为:无论训练阶段的指标多好看,都要到业务场景里做一轮小流量验证,用真实的业务反馈来校准模型的虚拟“价值”。
4. 部署与推理优化:从“能跑”到“跑得稳”
4.1 把模型封装成服务的关键一跃
训练好的模型不部署上线,就永远不会产生业务价值。从零开始,第一步不是上Kubernetes、搞CI/CD流水线,而是把模型封装成一个可以直接调用的服务。
我常用的最小方法是用FastAPI或Flask包一层HTTP接口,把模型加载到内存里,请求进来就走一次前向推理,返回结果。这一步看起来简单,却能把模型的调用方式、版本管理、并发控制都纳入到标准工程流程里。
下面是一个最小示例的核心思路:
# 模型服务化最小示例(伪代码级简化) from fastapi import FastAPI import model_loader app = FastAPI() predictor = model_loader.load("current_model_v3.pt") @app.post("/predict") def predict(features: dict): sample = preprocess(features) result = predictor.infer(sample) log_prediction(features, result) # 关键:预留预测日志 return {"prediction": result}这里面有一个极容易被忽略的细节:预测日志。每一条线上请求都应该被记录,包括输入特征、预测结果、置信度、耗时。后面做监控、评估、重训,都要靠这些日志提供数据。没有日志就没有反馈闭环。
4.2 推理优化的三个基本手段
模型部署到线上之后,性能问题马上暴露。我把最基本的三个优化手段整理一下:
第一个是量化。把模型权重的精度从32位浮点数降为16位甚至8位整数,模型体积缩小很多,推理速度明显提升。大多数场景下精度损失是可接受的。
第二个是批处理推理。很多模型对单条请求推理很慢,但如果把小批量样本合并成一个张量做推理,单位吞吐量会大幅上升。前提是延迟要求允许额外等一批请求。
第三个是缓存和动态路由。如果请求里存在大量重复特征组合,可以用缓存直接命中结果,把高成本推理绕过去。
这些优化不深奥,但都是必须会的实战技能。没有优化的推理服务,跑起来慢是一个问题,更难受的是,用户的请求流量稍高一点,服务就直接超时崩溃,那种感觉做过一次就再也不想经历。
4.3 多版本模型共存的管理
模型不会只出一次版本。几乎一定会有V2、V3、V4,并且线上可能出现新旧模型并行对比的情况。
最简单的管理方案是做好模型目录结构和版本号约定:
models/ user_ctr/ v1_20260101/model.bin v2_20260301/model.bin v3_20260501/model.bin目录里不仅放模型权重,还要放对应的配置文件和评估报告。这样做的好处是,任何版本的模型都是独立完整的一包里放着,可以随时切换和回滚。
有人问我为什么最后都做了灰度切换,我的经验是新模型直接全量上线几乎必然会翻车。要么在老用户身上效果回退,要么线上特征跟训练数据分布不一致导致批量异常。稳妥的做法是切5%流量到新版本,对比线上指标,观察一两天再放量。
5. 监控、评估与反馈闭环:模型上线只是开始
5.1 为什么离线指标好,线上效果为什么对不上
几乎每一个AI项目都会遇到这个问题:验证集上指标很漂亮,上线之后却表现平平甚至更糟。原因就藏在两个地方:数据漂移和概念漂移。
数据漂移是指线上输入数据的分布和训练数据的分布发生了变化。比如训练阶段用户的年龄分布在20到30岁,上线之后突然涌入大量40到50岁的用户,模型在陌生人群上自然表现不佳。
概念漂移则是数据和标签之间的映射关系本身变了。比如一个内容推荐系统,用户对“感兴趣”的界定从点击变成了阅读时长,旧模型训练时学到的规则就失效了。
解决这个问题的前提是监控。从零开始,至少要监控三类信号:
- 线上输入特征的分布变化,我会自己做特征的分布统计,和训练期基线做对比
- 预测结果的分布变化,比如模型预测某类别的概率是否突然集中或漂移
- 业务核心指标的变化,转化率、留存率、时长等直接产出指标
5.2 低成本监控和非监督下的护栏
小团队做监控,不需要一开始就上完善的监控平台。有三个低成本手段可以立刻用起来。
第一,留出1%线上预测样本做人工抽检。把模型预测的结果随机拿出来让业务同学看一遍,积累真实反馈样本。这个比例看起来很小,但一个月下来就能积攒几百上千条高质量对照数据,足够支撑后续评估。
第二,做浅层统计的预警。对关键特征的均值、方差做滚动统计,一旦偏离训练集基线超过阈值就报警。这远比等业务方投诉后来排查有效得多。
第三,预测日志一定要落库。没有日志的模型系统就是黑盒,出问题只能靠猜。而有了日志,就可以随时还原线上场景、复盘错误样本,甚至构造新的验证集。
5.3 反馈闭环:从“跑模型”到“持续进化”
AI系统之所以有价值,就在于它能在使用中不断变好。但持续进化不是自动发生的,它需要你设计一套闭环机制。
常规闭环是:
- 线上预测并记录日志
- 抽样回流和人工标注
- 周期性的更新训练集
- 重新训练和评估
- 灰度上线
- 继续监控
关键点是“热度要保留下来”。如果你不主动抽样、不主动做人工标注,那么再好的模型也会随着时间推移逐渐失效。如果后续我重新开始一个项目,会提前把这一环设计好,而不是等到线上效果下跌了再做补救。
6. 从零一路升级的个人路线图与踩坑记录
6.1 给自己搭一条分阶段的项目阶梯
零基础阶段找项目练手时,最大的矛盾是:项目太大做不下去,项目太小没价值。结合我的经验,可以按这样的阶梯推进。
第一个阶段,选一个数据相对干净、任务边界清晰的项目。比如垃圾短信分类、商品评论情感分析,可以自己爬数据整理标签,也可以直接用现成的开源数据集。重点是走通从数据清洗、训练、评估到部署的完整链路。
第二个阶段,选一个有真实业务背景的项目。比如给一个本地生活平台做商户评论的主题分类,或者做一个小型搜索的排序模型。这个阶段的关键挑战是数据是脏的、逻辑是乱的,需要真实地处理工程问题。
第三个阶段,目标是做一个持续运行的AI系统。比如一个推荐系统,要求你具备监控和反馈闭环能力。项目做完不是结束,要持续运行一个月,观察线上效果,并根据反馈做迭代。
这三个阶段走完,AI工程的各个核心环节就都摸过一遍了。
6.2 学习精力怎么分配才算合理
从零开始最容易犯的时间分配错误是:80%时间研究模型,20%时间研究工程。我重新来一次会反过来,至少用六成精力在工程和数据处理上。
理由很简单:模型是相对标准化的,只要不是做科研,开源社区已经有大量成熟的模型可以直接用。真正拉开项目成败差距的是工程能力——谁能把数据管得稳稳当当、把模型部署得漂漂亮亮、把线上问题排查得又快又准。
我的时间分配大致是:数据和工程基本功40%,模型训练和评估25%,部署和运维20%,监控迭代15%。这个比例可以微调,但方向不变。
6.3 三个最容易踩的坑
第一个坑,过分追求模型调优。有一次我花了两周时间调模型,从baseline把精确率提高了3个百分点,成就感满满。结果发现数据里有一批重复样本没去重,评估流程本身有缺陷,把重复样本处理干净之后,模型提升只有0.5个百分点。先花时间把数据流程做对,会比调参有价值得多。
第二个坑,不关注数据的时间属性。很多业务数据天然随时间变化,如果不记录数据的抽取时间、特征的计算时间,训练和预测就会错位,线上效果自然崩。
第三个坑,模型产物不做管理。训练完之后模型权重随手丢在一个目录里,没有版本号、没有评估报告。等模型线上一出问题,想找到能复现的旧模型,只能翻聊天记录。
这三个坑我全踩过,写下来就是希望从零开始的人不要再花一遍冤枉时间去走这些弯路。
最后再说一个小技巧。如果让我重新从零开始,我会在第一周就把“数据健康检查”这个环节搭起来,而不是等出了问题再回头补。它会很快把一个看似混乱的项目变成有韧性、可推进的工程实体。这个底层习惯是我做下来收益最大的一件事。