1. 先给“从零开始学AI工程”正个名
干这行快十年了,经常有人问我一个问题:算法工程师和AI工程师到底是不是一回事?我每次都得花十几分钟解释。简单说,算法工程师关心的是“能不能跑通”,AI工程师关心的是“能不能落地、能不能长期稳定跑”。这个“ai-engineering-from-scratch”的标题,说白了就是一套把AI系统从想法推到生产环境的完整方法论。它解决的从来不是某一个模型精度的问题,而是从数据、训练、部署、监控、迭代这条链路里的每一个环节怎么闭环的问题。
之前我带过不少新人,也面试过很多候选者,发现一个通病:简历上写着会TensorFlow、会PyTorch,一问到数据管道怎么搭、线上模型怎么更新、数据漂移怎么检测,基本就露馅了。这不是个人的问题,是整个行业的教育和自学路径,长期把AI工程和AI建模画等号,导致很多人学了一堆算法,却做不出一个真正能用的系统。
这篇文章就是写给这些人看的。不管你是计算机专业的学生、刚转行的分析师,还是已经在写代码但想往AI方向靠的工程师,只要你想把“模型”变成“产品”,这篇文章能帮你把整个技术栈的脉络理清楚。我会从上到下、从里到外,把AI工程涉及的核心模块、实操步骤、常见坑位都摊开来讲。内容不多但足够落地,看完你可以直接拿它当自己的学习清单来用。
2. 核心思路拆解:AI工程到底在“工程”什么
2.1 建模只是冰山一角,数据与系统才是水下的那九成
我见过太多人一开始学AI工程,就急着往模型上砸时间。买个GPU服务器,跑个ResNet,把准确率刷到95%,觉得自己已经入门了。但放到真实的生产环境里,一个稳定运行的AI系统,模型代码可能只占整个代码库的不到两成。数据管道的健壮性、特征的计算逻辑、训练和推理的一致性、线上监控的完整度,这些才是决定系统能不能长期活着的关键。
我自己第一次独立带项目时吃过一个大亏。当时花了一个月把文本分类模型的F1刷到0.93,老板也很满意。结果上线不到两周,线上效果直接崩到0.6以下。排查了半天,发现训练时用的特征工程逻辑和线上推理服务里的逻辑根本不一致,一个用了分词后的词频,一个没分词就硬算,两边结果对不上。这个坑不踩一次,你永远体会不到“工程”两个字的重量。
所以从零开始学AI工程,心态上要做的第一个转变是:把系统当作作品,而不是把模型当作作品。模型只是系统里的一个组件,和数据库、缓存、消息队列没有本质区别,只不过它更聪明一些罢了。
2.2 从零开始的完整知识地图
为了不让大家像我当年那样到处乱撞,我把自己踩过的路重新整理了一番,画了一个AI工程的知识全景图。这个地图没有用Mermaid,因为文字完全能讲清楚,而且更便于你记笔记。
从上到下分五层:
第一层是基础设施层。主要是GPU服务器、存储、容器化环境,还有分布式训练要用的调度系统。这一层看着不性感,但所有底层问题都出在这里。比如显存不够、数据读取太慢、训练节点挂了没告警,全在这一层解决。
第二层是数据层。包括数据采集、清洗、标注、版本管理,以及最重要的数据质量监控。很多公司对这一层投入不足,数据里一堆脏值、缺失、埋点错误,后面模型再强也白搭。
第三层是建模层。包括实验管理、超参搜索、模型评估、模型版本化。这一层是算法工程师最熟悉的部分,但AI工程视角下的建模和Kaggle式的建模不一样,核心区别在于可复现性。你上个月的实验,下个月能不能原样跑出来?实验记录完整吗?模型文件有没有归档?这些都是工程问题。
第四层是部署与服务层。包括模型转换、推理服务化、性能优化、灰度发布。简单说,就是让你训练好的模型能以足够低的延迟、足够高的吞吐运行起来,并且可以快速地回滚。
第五层是监控与迭代层。包括线上指标跟踪、数据漂移检测、模型重训策略。这一层最容易被忽略,但对生产环境的AI系统来说,这一层恰恰是续命的关键。
这五层不是说每一层都要成为专家,但至少每一层的核心逻辑和基本工具你得玩得转,这样你才具备从零到一构建AI系统的全局视角。
3. 核心技能分模块解读:每一层该怎么学、怎么做
3.1 数据层实操细节与避坑要点
数据是一切的起点。很多项目死在第一步,不是没有数据,而是不知道怎么把原始数据变成模型能吃的训练数据。我建议新手从三个能力入手练。
第一,写健壮的数据处理管道。不要用一次性脚本处理数据,要用可重入、幂等的任务来跑。一个最基本的做法是给每个处理步骤加上数据版本,哪怕这版本只是源数据的时间戳加任务ID。我最常推荐的工具组合是Python加Pandas做探索,然后转成Spark或者DuckDB跑定时批处理,数据量不大时DuckDB完全够用,还不用养一个Hadoop集群。处理完的数据落地到Parquet格式,后面读起来比CSV快一个量级。
第二,做数据质量检查与监控。不是说处理完了就完了,你得为流程加上检查关卡。比如统计字段空值率、唯一值数量、数值分布的分位数,每一项都设阈值,超了就让任务失败或者发告警。我自己习惯在每个关键字段上写几个断言,跑完数据管道立刻验证,验证不过就发消息到工作群。这一招在初期能拦住无数低级但致命的问题。
第三,把数据版本化。训练用了哪一天的哪一版数据,必须能随时回溯。很多人忽略这个,导致模型漂移后想找“当初训练时用的数据”却找不到,只能干瞪眼。轻量方案用DVC,重方案直接走湖格式加数据目录版本控制,都能实现。
这里有一个我踩过的坑值得单独提醒:小心爬虫或者采集源本身出问题。有一次我们一个数据源的字段给重新定义了,老数据全是字符串,新数据变成了数字,管道没做类型强校验,模型训练直接用了字符串拼接的方式做特征,等到上线前一天才发现,差点搞出线上故障。所以现在我在自己的项目里立了一条规矩:数据管道入口处的schema校验永远不能省,哪怕多花两天时间也要做。
3.2 建模层:实验管理的科学打法
建模层最容易陷入的误区是“野路子调参法”。今天我帮你们把建模层的实操逻辑理清楚,核心就是三件事:实验记录、超参管理、模型归档。
实验记录不是说你写完一个训练日志就算记录。真正可复现的实验室记录应该包含:代码commit号、数据集版本、随机种子、环境依赖列表、超参完整文件、指标曲线、最终模型文件。这一堆东西手动记永远记不全,直接上工具即可。我目前用得最顺的是MLflow,自托管免费,也可以配MinIO存artifact。训练代码里加一个with mlflow.start_run():包起来,自动记录params、metrics和模型文件,日志框架直接帮你把散落的信息收拢了。
超参管理建议用config文件统一管理,不要硬编码在命令行里。YAML加Hydra是我比较喜欢的组合,结构清晰,还能通过覆盖配置做实验遍历。超参搜索方面,简单项目直接Grid Search,再复杂一点用Optuna做贝叶斯搜索。注意一点,在搜索阶段就固定住数据集版本,否则搜索出来的最优参数会跟着数据一起“漂移”,你最后根本无法判断是参数好还是数据好。
模型档案要像软件制品一样管理。每个模型要有唯一的版本号,记录对应的数据和特征版本,训练时间,还有评估结果。上线前还需要经过测试集评估和shadow测试。这里我额外建议一个经验:评估时的测试集不能只从当前时期抽取,尽量包含一段跨度足够长的历史数据,模拟线上可能遇到的分布波动,这样评估出来的指标才更接近真实性能。
3.3 部署与服务化:让模型走出notebook
模型部署是很多从零起步者最头疼的一关。其实思路可以类比成“把做好的菜端到顾客桌上”,只不过这里讲究的是延迟、吞吐、容错。
最基础的做法是把模型导出成ONNX格式,然后用ONNX Runtime做推理服务,比直接用PyTorch跑推理快得多。导出时要注意动态轴问题,比如输入序列长度可变时,需要显式设置dynamic_axes。然后写一个FastAPI服务,把模型包进去,加一层请求校验、超时控制和结果缓存,基本就能跑。
进阶一点,如果你的服务需要承担高并发,就得了解部署架构。最简单的是单进程FastAPI加Gunicorn多worker,再套一层负载均衡;如果服务涉及多模型,你可以上TensorFlow Serving或者TorchServe,它们内置了模型版本管理和动态加载,对运维友好。再高级一些就是上Kubernetes加Istio,做灰度发布、金丝雀部署。但说句实在话,如果你的流量还没到每天百万级请求,别急着上K8s,光运维成本就够你喝一壶。先把单机的性能压榨到位,大多数场景已经够用。
性能优化是部署环节的重头戏。最典型的几条路径:模型量化和剪枝、批处理动态合并、缓存杀手级特征、特征平台化。举个例子,线上推理时同一个用户在一个小时内会多次调用,如果每次请求都全量算特征,代价极高。把特征计算结果缓存起来,命中率能做到70%以上,延迟能直接从40毫秒降到8毫秒,这个优化幅度是很惊人的。
3.4 监控与迭代层:系统有没有在持续“生病”
上线不等于结束,恰恰是真正AI工程的开始。生产环境里模型的性能不是一成不变的。用户行为的变化、环境的变化、数据采集口径的变化,都会导致模型效果悄悄下滑。所以监控迭代层是AI工程里最见功力的地方。
最核心的监控指标分两类:业务指标和技术指标。业务指标包括点击率、转化率、准确率等贴近业务含义的指标;技术指标则包括模型输出的概率分布、特征的统计分布、请求量、延迟、错误率。两类指标要同时盯。一个Tip:在模型输出的概率分布上做一个K-S检验或者PSI,如果PSI超过0.2,基本就能判定线上数据分布和训练分布出现了明显偏移,模型的效果衰退只是时间问题。
检测到漂移后,最常见的应对方法是定期重训。重训策略不要无脑每天跑,那会造成资源浪费。轮子只需要在有指标异常时触发,或者在数据积累到一定量级时触发,效果反而是好的。我见过有些团队每周固定重训,结果数据变化不大,模型输出却因为随机种子的原因微小振幅,导致业务方天天说线上不稳定。合理策略应该是:监控PSI、业务指标、数据量三个维度,触发阈值才重训,并且重训后先在影子环境跑24小时小流量验证,再逐步放量。
4. 实操演示:用一个完整的文本分类项目走通全流程
4.1 业务目标定义与关键指标拆解
以上说的都是框架性的东西,接下来我用一个实际做过的文本分类项目走一遍全部流程。这个项目背景很简单:平台每天有大量用户反馈工单,需要自动打标签,分成“投诉”“建议”“咨询”“表扬”四大类。
这个需求看起来像极了一个简单的分类任务,但在做AI工程时,第一步不是选模型,而是定义清楚解决问题的方式。我们和业务方碰了两轮,明确了三件事:
- 目标指标是准确率不低于90%,考虑到工单四分类本身复杂度不高,这个目标合理且可达。
- 线上关注的业务指标是“人工重分类率”,也就是模型分完类之后人工是否还需要改动。这个指标比准确率更贴近真实价值。
- 冷启动阶段可以接受人工兜底,但正式运行后自动分类率要超过70%。
把目标落到指标之后,数据的要求瞬间清晰了:我们需要至少几万条已经人工打标过的工单数据,并且类别分布不能太偏。这一步看起来不起眼,但它决定了整个工程能不能做下去。
4.2 数据管道与特征工程的完整搭建
拿到原始数据之后,我第一步做了schema校验和去重。工单数据是从业务库导出到数据仓库的,原始的字段有十几个,我们用到的只有文本内容、提交时间、客服分类结果。文本字段要去掉HTML标签、多余空白、特殊字符,然后统一小写和简繁体转换。
特征工程上,我当时没有一上来就上BERT。虽然BERT效果更好,但部署和推理成本高一截,数据量不大时反而容易过拟合。我先用TF-IDF加LightGBM做了MVP版本。这个选择的逻辑是:快速搭出基线,验证管道和部署链路没问题,再考虑升级模型。特征具体包括TF-IDF权重、文本长度、是否包含感叹号、是否包含特定关键词这几项。用Sklearn的TfidfVectorizer做的时候,注意设置ngram_range为(1,2),在中文场景下加上字级别的n-gram效果更好,因为分词器本身也会引入错误信息。
数据版本的记录当时是用DVC做的,数据管道的每个输出都带上校验和,这样后面模型训练用到哪一版数据,随时能反查。设数据管道的每一步都是独立脚本,用Makefile串起来,保证同一份代码可以重复产出同一份结果。
4.3 训练、评估与模型存档的标准流程
训练环节我用LightGBM,配合Optuna做了200组超参搜索。固定了一个实现要点:验证集不随机切分,而是按时间顺序切割,用前面90天做训练和验证,后面30天做最终测试。这个做法和随机切分效果差异很大,特别是在数据分布随时间漂移的场景下,时间切分能更真实反映模型在未来的表现。
超参搜索完成后,锁定了一组参数:学习率0.054、树深度7、叶子节点数45、L2正则0.3。在测试集上的macro F1是0.915,准确率93.2%,超出目标。我把当次实验所有参数、指标、模型文件全部用MLflow记录并归档,模型注册到名为“工单分类器”的Model Registry中,版本号v1.3。
评估报告我还做了一个额外的工作:错误分析。把测试集上预测错的样本全部打印出来,按预测标签和置信度分类看。结果发现大量把“咨询”错分成“建议”的样本,原因是这两类在文本上确实有模糊地带。这个发现后来反馈给业务方后,对方改了标签定义的细则,重标了一批数据,第二轮训练时效果又提升了一点。这个环节很多团队会跳过,我强烈建议不要省,它的价值被严重低估。
4.4 容器化部署与线上验证的完整流程
模型作为LightGBM的booster文件导出后,部署方式选择了ONNX,导入到FastAPI服务里。我的服务代码结构大概是这样的:
- 入口:FastAPI应用,定义
POST /predict接口,接收JSON格式的文本。 - 预处理:加载同一个TfidfVectorizer(已保存为joblib文件),对新文本做与训练完全一致的处理。
- 推理:ONNX Runtime加载模型执行预测,返回类别和置信度。
- 落库:预测结果和时间戳写入监控库,供后续漂移分析。
- 缓存:对相同文本的请求直接返回上次结果,很适用于工单这种内容重复度较高的场景。
容器镜像用Python 3.9的Slim版本做基础,模型和相关文件打进镜像。部署用Docker Compose起了两个实例,前面挂Nginx做负载均衡。上线流程是:先起一个shadow实例跟生产并行跑24小时,对比新旧模型的分布和耗时,没有异常后再切流量。全程不到一步是扇子。
灰度发布阶段,我用了一个特别简单的技巧:Nginx的流量比例直接配置成5%、50%、100%三档手动切,观察每次切完后的业务指标和监控指标正常才继续。
4.5 监控面板与告警配置实战
监控是部署完最不能拖的步骤。我用Prometheus加Grafana搭了一套服务。关键指标包括:
- 请求量、P95延迟、错误率。
- 每个类别的实时预测次数和时间戳分布。
- 模型输出的平均置信度。
- 输入文本特征的核心统计量,比如平均长度、关键词命中率,这些用来辅助判断数据漂移。
- 每天跑一次PSI,计算当天输入样本的TF-IDF特征均值与训练集的差异。
告警规则设了三条:连续5分钟错误率超过1%、PSI超过0.2、P95延迟超过300毫秒。这三种情况各自对应模型异常、数据漂移、资源不足,触发后发企业微信告警。到现在这个项目运行了九个多月,告警大多集中在PSI类,触发重训后指标基本都能恢复。不是每次漂移都意味着模型变差了,有些是输入文本的写法变化,比如新用户会用拍短视频的方式写报告,这类情况需要先看数据再决定要不要动模型。
5. 从零到一的环境搭建与工具链选型
5.1 本地实验环境的快速初始化
“从零开始”这四个字,最扎心的时刻就是刚准备动手,发现环境一堆问题。我建议初次上手时不要自己去拼装大而全的配置,直接用现成的Docker镜像能省下大量时间。
基础配置就三段:一台带GPU的开发机(显存至少8G,够跑绝大多数中量级CV和NLP任务)、Docker和docker compose、Python 3.9以上加虚拟环境。装PyTorch时注意先检查服务器显卡驱动版本,再选择对应的CUDA版本。这里有个常见坑:如果有多个CUDA版本需求,用conda创建不同环境,每个环境装不同的cudatoolkit,切换环境就相当于切换CUDA,比动系统级的软链接稳定得多。
实验目录建议统一为:
project_root/ ├── configs/ # 所有YAML配置 ├── data/ │ ├── raw/ # 原始数据,只读 │ ├── processed/ # 清洗后的数据 │ └── features/ # 特征数据 ├── models/ # 模型文件归档 ├── notebooks/ # 探索性分析 ├── src/ │ ├── data/ # 数据处理代码 │ ├── models/ # 模型定义与训练代码 │ ├── features/ # 特征工程代码 │ └── serving/ # 部署服务代码 ├── tests/ # 管道与接口测试 └── scripts/ # 工具脚本这种目录一开始看着繁琐,但项目一复杂,好处就体现出来了:你知道什么东西放在哪里,代码不会变成一坨乱麻。我见过太多项目最后因为目录混乱,导致谁也看不懂谁改了啥,更别提复现了。
5.2 实验管理和数据版本控制的最小可用配置
实验管理和数据版本控制,从零入手不需要上重型方案。我的最小可用配置是:
- 版本控制:Git托管代码,DVC管理数据与模型文件。
- 实验记录:MLflow Tracking,自托管在服务器上,支持多人协同。
- 配置管理:Hydra加YAML,把超参和路径全部外部化。
- 合作协同:数据管道任务用DVC Pipeline定义,一条命令触发全流程,结果带缓存,重跑时没变的环节秒级跳过。
这套组合的特点是小、快、稳。没有引入重量级平台,也不会要求你必须用Kubernetes。等团队规模大了、项目多了,再上Kubeflow或者SageMaker那一类平台也不迟。盲目追求大平台而团队规模不够,只会得到一个没人会用的“华丽摆设”。工具选型的唯一标准,永远是对你的项目有实际帮助,而不是外面流行什么。
5.3 模型服务化的选型心得与取舍
部署选型上,我项目里最终用了ONNX Runtime配合FastAPI,没选TorchServe或者TensorFlow Serving,原因有两点:一是项目逻辑相对简单,单模型推理,资源开销小;二是FastAPI生态成熟,扩展一些自定义中间件很方便,团队也容易上手。
如果模型复杂度更高,比如服务里同时有多个模型需要动态选择、需要批量实时推理,那么TorchServe是更好的选项,开箱即用地支持模型版本管理、批量推理和监控接口。如果你们整体已经是Java技术栈,而且推理服务要和Spring生态做深度整合,直接用Java的DJL,也是一个不错的路子。
引一句我经常和团队说的话:部署框架没有绝对的好坏,只有适不适合你当前的规模。任何时候,选择工具时都要弄清楚自己面临的瓶颈是延迟、吞吐、还是团队维护成本。把这个想清楚了再选,基本不会踩雷。
6. 常见问题排查与避坑经验速查
6.1 训练和线上推理结果不一致
这是AI工程里上座率最高的坑之一。现象是离线评估指标很好,线上效果却“见光死”。原因大多数出在特征计算链路不一致,或者数据预处理步骤不一致。
比如训练时你对文本做了小写转换和停用词过滤,但线上服务代码里忘了加这两步,模型输入就变了。我建议在代码层面统一封装一个特征计算工具类,训练和推理都用这同一份代码。如果训练是Python版,线上是Java实现,那就更要警惕,我遇到过两次Python分词和Java分词对同一段文本结果不一样的坑。最好办法是把预处理和特征计算打包成一个独立的服务,训练和线上都通过同一个接口调用。这个思路在规模变大后自然演变成特征平台(Feature Store)的概念,但从零开始做,一个共用模块就足够了。
6.2 数据漂移,怎么判断是“真漂移”还是“假报警”
线上PSI报警之后,别急着重训,先把报警原因分清。漂移的来源通常有三类:
- 真实用户行为变化。这是最需要干预的,一般表现为业务指标同步变化,比如点击率下降。
- 数据采集口径变化。比如前端改版后埋点规则变了,字段含义没变但数值分布变了,这种可能要修采集端。
- 特征计算时间窗口的逻辑问题。比如一个“近7天活跃天数”特征在跨月或跨年边界的算法随时间不同产生了偏差。
我有一个八字方针:先看业务,再看数据,最后动模型。业务指标和PSI同时异常,优先重训;业务指标正常但PSI异常,大概率采集端或特征逻辑有问题,先去修数据处理管道,而不是遛模型。
6.3 算力不足,但模型效果又要提升,该怎么办
小预算团队最常见的困境就是:显卡不够,数据又大,训练模型特别慢。我的建议是按这个优先级思考:
- 先用小模型跑通链路,再考虑大模型。很多任务LightGBM或BERT-base级别的模型足够满足业务诉求,不需要逼自己上几十亿参数的大模型。
- 训练加速优先看数据管道的I/O瓶颈。很多时候GPU利用率低不是算力不够,而是数据加载太慢,GPU一直在等CPU送数据。使用Prefetch、把图片解码改成内存映射、用WebDataset或者TFRecord这些流式格式,触到瓶颈往往能直接把利用率拉满。
- 再考虑模型本身的加速手段,比如混合精度训练、梯度累积、模型并行。混合精度在NVIDIA显卡上几乎是无脑收益,值得每个人掌握。
真实项目中,我见过太多团队动不动就想搞“大规模预训练”,结果几周下来模型没啥进展,工程复杂度倒是上了一个台阶。我强烈建议从小处入手,能用小模型解决绝不套大玩具,你的精力和时间应该花在把系统打磨稳定,而不是花在与算力的对抗赛上。
6.4 模型上线后算法工程师该干点啥
上线后才是AI工程真正开始发力的时候。平时我在项目里定义了一条“上线后72小时红线”,坚决不去度假式收工:
- 前24小时:盯紧基础监控指标,确认服务稳定、资源水位合理、延迟符合预期。
- 24到48小时:对比线上模型预测分布和训练集分布,发现PSI超标的现象要马上分析来源。
- 48到72小时:做一次全面的业务指标效果评估,和旧方案对比,形成一份上线效果报告发给业务方。
这个流程虽然不复杂,但能把你从“观望着被动救火”变成“提前主动判断”的角色。AI工程师和算法工程师本质区别就在这一步体现出来了。
7. 一点个人实操体会
这两年带过不少人从零走完这个流程,我最大的感触是,快速入门AI工程的关键不在于你掌握了多少模型架构,而在于你是否敢把一个端到端的项目完整地跑起来。哪怕是个几万条数据的文本分类任务,只要你愿意把数据管道、实验管理、容器部署、线上监控这四个环节全部走一遍,你学到的东西比闷头调三个月参要多得多。
我自己踩过的最深的一个坑,就是早年迷信“模型结构决定一切”,后来发现真正决定项目成败的,往往是数据质量和工程细节。工具链会过时,某项热门框架会变成昨日黄花,但“构建一个完整可用的AI系统”的能力,始终是硬通货。从零开始,意味着你不需要依赖任何现成的平台和模型hub,意味着你可以真正理解每一层是怎么工作的,出了问题能自己修,而不是只会报工单让别人解决。
接下来你可以从自己手头最熟悉的一个业务场景开始:找一份有标签的数据集、写一个最朴素的模型服务、部署到本机或一台云服务器上、加上最基础的监控告警。把这个几十小时的小项目走完,你就已经有了从零到一的底气。后面再往分布式训练、大规模特征平台、模型网关这些方向深入,路会越走越宽。