如果你是在逛技术社区的时候刷到“ai-engineering-from-scratch”这种仓库名,大概率第一反应和我一样:这年头还有人从零开始学AI工程?我真正把“从零开始”这四个字当回事,是因为一次内部评审会——一个面试者谈起接口调用、模型微调、prompt调优头头是道,但一问“线上效果衰减了半小时,模型指标却没掉,你会先去翻哪份日志”,对方当场卡住。那一刻我意识到,很多人不是不努力,而是知识结构是悬浮的:太擅长使用工具,太不擅长理解系统。
从零开始做AI工程,不是让你重复造轮子,而是把数据、模型、算力、评测、发布这条链路亲手走一遍。这篇文章就按我自己的实践经验,拆解一遍如何从一张白纸搭出一个能上线、能迭代、能定位问题的最小AI工程闭环,同时把那些文档里不写、经历了才明白的教训一并说出来。
1. 为什么我劝你“从零开始”——不是重复造轮子,而是找回工程判断力
1.1 知识地图断层:我们太擅长用API,太不擅长理解系统
现在的技术栈一层叠一层:底层是GPU驱动和容器,中间是分布式训练框架,再往上是模型仓库和推理服务,最顶层才是业务代码和产品交互。绝大多数从业者常年待在最顶层,底下的东西全是黑盒。黑盒一旦出问题,表面的症状往往和根因隔着三层间接关系。
我见过一个很典型的案例。团队要接一个OCR能力,候选模型在测试集上表现不错,结果一上生产,彩色扫描件的识别率断崖式下跌。新人第一反应是去调置信度阈值、换预处理函数、反复抽测样本,折腾了两天没有进展。后来一位老工程师打开预处理日志,发现生产环境的图片经过了另一道压缩服务,分辨率被压到了原来的一半。问题根本不在模型参数,而在于上游pipeline偷偷改掉了输入分布。这种问题,只有对整条链路有“从零到一”的完整认知,才能在第一时刻定位到可疑环节。
这正是为什么我主张每个人都应该至少完整地从零搭过一遍AI工程:不是写Transformer,不是训练大模型,而是把数据怎么进、模型怎么跑、指标怎么报、线上怎么发、挂了怎么查这五件事亲手串起来。你一旦亲手串过一遍,大脑里就有了一张地图,遇到问题你知道该去哪一栋楼、哪一层、哪个房间找证据。没有这张地图,你只能在外围绕圈子。
1.2 “from-scratch”的真实价值:建立心理模型与判断力
心理学里有个概念叫心理模型,指的是人在头脑中对某个系统运转方式的内化表达。有心理模型的人看到一个现象,能马上在脑中跑一遍因果链,判断出最可能的故障点;没有心理模型的人只能靠试错。AI工程的能力差异,说到底就是心理模型的精细度差异。
我自己第一次从零搭推荐系统的时候,踩的坑可以用“惨烈”来形容。数据切分没做时间隔离,导致模型在离线评测里AUC高达0.78,上线后业务指标纹丝不动;训练和推理的特征处理各写了一套逻辑,线上特征和离线特征对不上,模型效果直接崩了一半;监控面板只挂了CPU和内存,结果深夜模型推理延迟飙升,第二天早上才被用户投诉吵醒。这些错误现在回头看都不高级,但每一刀都砍在真实位置上。砍完了,你对AI工程的理解才真正长在身上。
所以“from-scratch”的价值不在于“我会写代码”,而在于你建立了一套判断系统:当事情不对劲的时候,你能迅速圈定范围,而不是把时间浪费在表面症状上。这种判断力,是所有高级工程师最核心的资产。
2. AI工程到底“工程”在哪——四条边界线先划清楚
很多人分不清“AI工程”和“跑模型”,以为把模型训练出来、接口调通就算完事。实际上AI工程真正花时间的地方,在于和现实世界博弈的那一圈外围工作。我习惯把AI系统切成四条边界线:数据边界、模型边界、基础设施边界、产品边界。每一条边界都有它独特的坑。
2.1 数据边界:脏数据、分布漂移和反馈回路
数据边界是第一道分水岭。Kaggle竞赛里的数据是干净、静态、已经标注好的,而真实业务的数据是脏的、不断变化的,而且分布漂移的幅度常常超出预期。
两个最常见的坑:
- 训练分布和线上分布不一致。比如训练语料是几个月前的用户行为,线上用户的偏好已经变了。
- 脏数据迭代慢。业务方标注一批新数据要一周,等发现线上badcase并转成训练样本,问题已经发酵了很久。
我在实践中养成的习惯是:任何数据集进管线之前,先跑一遍schema校验、空值率统计、类别分布检查,并把这些指标以版本号形式记录在案。数据变更和模型变更一样需要可追溯,否则你没法回答“指标变了是因为数据变了还是模型变了”。这条习惯救过我很多次,后面我会给到具体实现。
2.2 模型边界:离线指标和线上效果的断层
模型边界的核心矛盾是:离线指标涨了,线上业务不一定涨;离线指标跌了,线上反而可能涨。原因在于离线评测和线上业务之间存在系统性偏差。
具体表现有三类:
- 评测集偏差:评测集和真实分布不一致,尤其当评测集长期不更新或者太小、太偏。
- 目标函数偏差:离线你优化的是LogLoss或AUC,线上业务要的是转化率或留存,这两个目标只是弱相关。
- 反馈滞后偏差:线上效果需要几天甚至几周才能体现,而离线指标是即时算出来的。你指望用即时指标预测滞后业务,本质上是盲人摸象。
所以我的经验是:离线指标只用于模型筛选和回归预警,真正的裁判永远是线上灰度。做AI工程,一定要尽早建立“离线只是漏斗,线上才是上帝”的觉悟,而不是天天沉迷把评测集刷到小数点后第四位。
2.3 基础设施边界:训练和推理的运维成本
基础设施是AI工程里最容易被低估的部分。训练阶段GPU排队、资源碎片化、排查OOM都是日常,推理阶段则要面对延迟、吞吐、成本之间的三角权衡。
训练侧最常见的问题:GPU利用率极低。我见过团队说自己在训练模型,一问用了什么框架,答曰“几个人各开一块卡,各自跑各自的实验”。GPU很贵,混部、复用、按优先级调度是基本操作。推理侧则要严格定义延迟预算,例如广告场景200毫秒以内,内容推荐500毫秒以内,超出预算的模型结构再花哨也要砍。
我在基础设施方面的原则是:起步阶段不用上大型集群调度平台,单机多卡加一个模型仓库就够了,等到并发任务超过十组再迁移到正式的资源调度系统。过度设计,也是AI工程里一种很昂贵的错误。
2.4 产品边界:AI只是功能不是产品
最后一条边界最关键也最容易被忽略:AI只是产品里的一个功能模块,不是产品本身。用户不会因为你有模型就买单,他要的是一个完整的、可用的、可理解的体验。
产品边界的工程问题包括:
- 模型结果如何渲染成用户能理解的形态?推荐结果总要配理由、配可视化。
- 模型出错时怎么兜底?延迟太高怎么办?结果明显荒谬怎么办?
- 用户行为和模型结果之间的交互怎么记录?模型怎么利用用户反馈持续迭代?
我常说AI工程的成熟度,不取决于模型多复杂,而取决于产品在模型失效时表现得多体面。一个只有“模型返回结果”的单点系统,是谈不上工程的。真正的工程,是把这个单点放进一张危机处理网里,让它在任何异常场景下都有替代方案。
3. 一份从零开始的落地路线:基础设施、数据管线、模型迭代、评测回归
划清楚边界之后,接下来是具体的落地路线。我按自己指导新人的顺序,把从零搭建AI工程拆成四步:最小闭环、数据管线、迭代纪律、评测发布。每一步都有可以直接照搬的实践。
3.1 第一步:用最小闭环搭起实验环境
很多教程一上来就铺Kubernetes、分布式训练、GPU调度,我强烈不建议初学者这么干。起步阶段的正确姿势,是一台带GPU的机器,加三个组件:
- 数据存储用MinIO,兼容S3协议,本地部署轻量。
- 实验跟踪用MLflow,记录每一次运行的超参数、指标和模型产物。
- 推理服务用FastAPI包一层HTTP接口,先跑通输入输出。
为什么是这套组合?因为MinIO解决“数据版本化但不想上云”的问题,MLflow解决“实验过程可复现”的问题,FastAPI解决“模型可被调用”的问题。这三个组件的组合,刚好覆盖了AI工程最核心的三个可复现性锚点:数据可复现、实验可复现、服务可复现。
搭建流程很简单:
- 用Docker Compose启动MinIO和MLflow,数据目录和artifacts目录挂载到本地磁盘。
- 在训练脚本里加入mlflow.log_param和mlflow.log_metric,每个实验的配置和结果自动落库。
- 训练结束后用mlflow.register_model把选中的模型注册到模型仓库,推理服务从这里拉取模型。
这一步大概半天到一天就能完成。很多新人卡在“我要不要先从K8s学起”,我直接说:不用。K8s解决的是规模问题,不是认知问题。你连单机实验都没理顺,上K8s只会多一层排障负担。
3.2 第二步:数据管线先于模型
第二步是把数据管线搭起来,这一步必须在模型之前完成。原因很简单:数据决定模型的上限,模型只是逼近这个上限。
我的数据管线至少包含四层:
- 数据接入层:从业务库、日志、第三方接口采集原始数据。
- 质量检查层:跑schema校验,检查字段类型、范围、空值率,超过阈值就告警拦截。
- 清洗转换层:去重、归一化、特征计算,输出统一的训练样本格式。
- 数据版本层:用delta或iceberg这类支持快照的存储格式管理数据版本,每次训练记录读取的是哪个版本的数据。
举个具体的配置示例。我习惯在质量检查层写一个简单的空值率监控脚本:
import pandas as pd REQUIRED_FIELDS = ["user_id", "item_id", "label", "timestamp"] NULL_THRESHOLD = 0.05 def validate_dataset(df: pd.DataFrame) -> None: for col in REQUIRED_FIELDS: if col not in df.columns: raise ValueError(f"missing column: {col}") null_ratio = df[col].isna().mean() if null_ratio > NULL_THRESHOLD: raise ValueError(f"column {col} has null ratio {null_ratio:.2f} > {NULL_THRESHOLD}") print(f"validation passed, shape={df.shape}")这个脚本虽然简简单单,但它逼着每个人都对数据质量负责。线上跑的每一批训练数据都要过这一关,不允许“先跑起来再说”。越过这条红线,后期排查各种数据分歧会耗费数倍时间。
3.3 第三步:模型开发策略和迭代纪律
模型开发是大家最喜欢动手的一环,但恰恰是最容易被迭代纪律毁掉的一环。我的策略总结成一句话:先跑通最弱的基线,再一步步加复杂度,每一步都留证据。
为什么先跑弱基线?因为弱基线代表的是“最粗糙的模式能取得的下限”,后续所有改动都要和它对比,判断新增的复杂度到底值不值。很多人一上来就上最先进的模型,效果好不知道好在哪里,效果差更不知道差在哪里,整个迭代过程完全失去方向。
实际迭代时,我对每次实验规定必须记录六个维度:
| 维度 | 记录内容 | 作用 |
|---|---|---|
| 数据版本 | 训练数据版本号、样本量 | 排除数据变更干扰 |
| 特征集合 | 新增/删除了哪些特征 | 定位特征贡献 |
| 模型结构 | 模型类名、层数、参数 | 确认架构变更 |
| 损失函数 | 使用的损失及权重 | 对齐优化目标 |
| 训练配置 | 学习率、batch size、epoch | 复现实验条件 |
| 评测结果 | 离线指标、推理耗时、显存占用 | 综合对比 |
这六个维度缺一不可。有了记录,当那个“意外涨点”出现时,你能快速提炼出真正有效的改动。很多团队最有价值的财富不是模型本身,而是这张记录完备的实验史。
另外,特征处理必须做成独立模块,训练和推理共用同一份特征代码。我吃过一次大亏:训练脚本里顺手写了个归一化逻辑,推理服务又写了另一套,差了一个版本,线上效果直接腰斩。从此我坚决要求特征代码库只维护一套,谁也不能在两边各写各的。
3.4 第四步:评测回归与发布决策
模型开发完成后,评测和发布是最后一道闸门。这一步的原则是:宁可漏上去一个差模型,也不能把一个不确定的模型直接推向全量流量。
离线评测我维护三套评测集:
- 固定回归集:包含历史所有badcase,防止模型优化新问题时牺牲旧问题。
- 新鲜度探针集:采样近一周的新数据,观察模型能不能跟上最新分布。
- 长尾压力集:专门选取低频、难样本,检验模型泛化能力。
发布决策我用一张表格来做:
| 检查项 | 通过标准 | 未通过处理 |
|---|---|---|
| 离线回归 | 关键指标不跌 | 禁止发布 |
| 空值推断 | 线上输入可被安全处理 | 增加兜底逻辑 |
| 延迟预算 | P99延迟低于目标 | 降级模型或优化推理 |
| 灰度表现 | 核心业务指标正向或持平 | 回滚或触发兜底 |
| 回滚预案 | 代码和配置一键可回滚 | 补齐再发 |
灰度策略上,我习惯用5%流量起步,观察一小时无异常再逐步放大。遇到指标抖动时,不要急于做结论,先看是不是同期有产品改版、数据链路变更或者节假日干扰。AI工程的发布决策,本质上是一个“排除干扰项”的过程。
4. 从零到一之后:三类“看不见的工程”决定你能走多远
跑通整个闭环、上线第一个模型,这只是“从零到一”。接下来决定系统能不能长期稳定运转的,是三类容易被忽略的“看不见的工程”。
4.1 可观测性:日志、trace、指标三位一体
很多团队第一版监控只有系统层指标:CPU、GPU、内存、网络。但我认为AI系统必须建立三位一体的可观测体系:系统层、模型层、业务层。
模型层至少保留以下几项:
- 推理延迟分布(均值、P50、P99并行查看,只看平均值会掩盖长尾抖动)。
- 输入数据分布监控:空值率、类别分布、文本长度,任何大幅偏移都可能是上游数据链路出问题的信号。
- 模型输出置信度分布:如果置信度整体走低,往往意味着输入分布和训练分布偏离。
我习惯给每条推理请求打上request_id,日志里至少记录输入摘要、预测结果、响应时间、模型版本。只有这样,线上任何反馈才能快速回溯到底是哪条链路、哪个版本、哪个环节出了问题。没有这套东西,你面对线上的坏结果只能大海捞针。
4.2 系统韧性:降级、兜底、人工介入通道
AI模型没有100%靠谱,系统必须设计成“模型垮了,产品还能活着”。韧性设计分三层:
第一层是逻辑兜底。比如推荐模型超时,用缓存热榜顶上;内容审核模型服务不可用,切保守策略并转人工。 第二层是流量管控。给推理服务配熔断和限流,流量异常时优先保护核心接口,次要功能可以牺牲延迟甚至直接关闭。 第三层是人工介入。为运营和客服提供标记工具,用户反馈的badcase进入审核队列,审核结果回流到训练数据集。人工通道不只是容错机制,更是数据飞轮的起点。
我见过一个极端案例:一个对话系统上线三个月后,某一类用户输入的badcase率高达30%,但因为缺少人工标记回流机制,这些badcase全部沉底,模型迭代完全依赖冷冰冰的自动指标。直到一个自然月后技术团队偶然翻到用户反馈工单,才发现问题已经积累到一个不可思议的量级。没有兜底和回流,系统的演进就是蒙眼开车。
4.3 成本和治理:算力成本与合规审计
最后一类是很多小团队容易忽略的成本与治理问题。从零到一阶段不关心这些还说得过去,但一旦系统进入常态运行,这两件事就会反复敲打你的钱包和合规底线。
算力成本上,我的四条原则是:
- GPU预留实例按需采购,避免高估峰值而买了大量闲置算力。
- 训练任务尽量做混部,把不同优先级的任务调度到同一批机器上。
- 日志和checkpoint定期清理,写下自动的过期策略,别让存储成本偷偷膨胀。
- 模型推理前先做延迟和吞吐压测,评估单GPU实例能扛多少QPS,再决定部署几台。
治理与合规上,需要建立基础的数据资产清单和访问权限分级:数据文件落盘有归属,模型上线有审批,用户反馈有处理记录。这听起来很“流程化”,但一旦规模变大,没有这套基础治理,审计风险和数据安全风险会直接把你从“工程问题”拖入“组织问题”。我在团队里坚持每周过一遍数据血缘图更新,确保每个人都有全局视角,而不仅仅是自己那一亩三分地。
说到底,AI工程能力和很多手艺活一样,最扎实的学法是亲手做一遍。我第一次完整走完数据、训练、评测、部署、监控的闭环后,最大的改变不是掌握了哪个框架,而是那句“先看数据再调模型”变成了肌肉记忆。你遇到的所有疑难杂症,九成以上都能靠“顺着数据链路走一遍”找到答案——空洞的理论救不了你,亲手拉通一条线却可以。希望这篇路线图能帮你少走我当年走过的那些弯路,然后稳稳地把第一个模型从零推到线上。