ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AI工程从零搭建:数据管线、评测体系与部署监控全链路实践指南

AI工程从零搭建:数据管线、评测体系与部署监控全链路实践指南 我一直觉得AI工程这个圈子里最害人的一句话是“模型不都开源了吗直接把仓库拉下来跑通不就行了”我刚上手做项目那会儿也这么想结果被现实结结实实教育了一轮。三年前我花了整整两周把别人训练好的模型跑通了推理Demo效果看起来相当惊艳但真往业务里一放全是问题数据格式对不上、线上数据和训练数据分布不一样、某天半夜模型开始对空字符串输出一堆废话、想要回滚才发现上一版参数根本没记录……那段时间我才明白“跑通一个模型”和“交付一个AI系统”之间隔着一条巨大的河。所以当我看到“ai-engineering-from-scratch”这个项目名时第一反应是这名字取得真准。它不是让你从零手写Transformer也不是让你从零预训练一个大模型而是要把AI系统的完整工程链路——数据管线的搭建、模型选型、评测体系、部署上线、监控告警——从第一行代码开始一块一块亲手搭起来。这篇东西就是我自己在“从零搭AI工程”这条路上攒下来的实操经验写给那些不想只会“调包装毕”想真正把AI系统落地、稳住、能修的人。1. 你以为的“从零”和工程里的“从零”不是一回事1.1 “跑通模型”只是全程的最后一小段网上99%的教程都长一个样一段代码加载开源模型一行prompt回车模型吐出一段一百个字的回复然后教程结束。但一个真实生产环境下的AI系统长什么样用户从App或者接口发来一条请求这条请求要先过鉴权、限流、防重系统要决定这条请求是走缓存、走规则、走小模型还是走重量级大模型模型返回之后要检查输出格式、安全过滤、兜底逻辑整个过程要有trace、有日志、有成本统计模型上线要灰度效果变差要能滚回上一版线上数据分布变了要能收到告警。这些东西绝大多数教程一个字都不会写。你照着教程跑通一个Demo大概只走完了“加载模型推理”这几十行代码。而整个AI工程是围绕这几十行代码长出来的一个完整的系统数据、训练、评估、部署、监控、迭代。Demo是发动机点火的那一下工程是整车——底盘、刹车、仪表盘、油箱管路、备用轮胎缺一样都上不了路。1.2 一个可交付AI系统的真实构成我接手过好几个半路夭折的AI项目也观察过不少团队的项目复盘发现一件很有意思的事大家几乎都高估了“模型训练”的占比。一个从零到上线、能稳定跑的AI项目实际工时分布大概是这样的基于常见项目实践的经验估计不是精确科学但足够说明问题环节占比说明数据采集与清洗30%-40%脏活累活全在这而且永远比预想的多评测集建设与回归机制20%-25%没有评测就没有迭代依据越早期越省不了模型训练/微调/服务化15%-20%真正的“炼丹”环节反而不是时间大头部署、监控、发布策略20%-25%上线之后的事决定了系统能不能长期活着为什么要把这个比例摆出来因为“跑通Demo”给你产生的错觉是模型是核心模型搞定一切就搞定。实际上模型训练在系统里只是一小段数据才是地基评测才是方向盘部署监控才是仪表盘和安全带。地基不稳模型再厉害也只是在一堆烂泥上盖高楼。所以“ai-engineering-from-scratch”这个项目真正让人兴奋的点不是“我下载了一个模型”而是“我不躲避任何一块工程拼图”——从第一个空目录开始把数据、训练、评估、部署、监控整条链路亲手搭起来。2. 动工之前先把“成功标准”钉死在文档里2.1 一份问题定义文档必须写清楚的六件事很多人做AI项目有个坏习惯一开始就在找数据集、调模型跑了两周才被人问“你到底做到什么程度算成功”——然后陷入沉默。我现在的习惯是第一周不写任何训练代码先写一份问题定义文档。这份文档不需要多花哨但它必须把六件事写清楚业务背景这个东西是给谁用的解决什么具体痛点任务类型是文本分类、抽取、生成、排序、还是RAG检索这决定了后面所有技术选型。输入Schema输入数据的字段、类型、范围、来源。线上请求长什么样必须有明确的json或字段定义。输出Schema模型输出什么格式怎么解析什么算合法输出什么算非法输出。成功指标离线指标是什么准确率、召回率、格式合规率在线指标是什么延迟、打平率、成本、badcase率。约束条件延迟预算是多少比如p99必须小于2秒、显存和成本上限多少、数据权限和隐私边界在哪。其中第5条最关键也最容易被新手忽略。我见过太多项目团队特别努力地把某个指标从89%干到92%结果一问业务方人家要的根本不是这个指标。先定指标再动手是所有AI工程的第一条铁律。2.2 为什么我建议先用一个“笨基线”跑通整条链路第二个反直觉的建议不要一上来就微调最强模型先做一个“笨得掉渣”的基线版本把整个系统链路跑通。什么叫笨基线对于一个垃圾评论分类任务先用关键词规则做一个分类器对于一个问答系统先把所有文档缓存进去命中关键词就返回对应段落。这些方案无论从哪个角度看都很笨但它们有一个不可替代的价值——它们能把整条工程链路逼着走一遍。你需要真实的数据输入输出接口需要写评估脚本需要部署一个服务需要加日志和监控。这些活儿和模型智商无关就是绕不过去的体力活。先把这条“大象肠”拉通后面把中间的“模型内脏”换掉就只是局部改动了。我自己第一次搭笨基线时发现80%的时间花在数据格式和版本对接上模型本身十分钟就接好了。这个经历本身就是一个重要提醒AI系统的复杂度大头在集成不在模型。2.3 第一周必须立起来的三个工程习惯从零开始的项目前面三天是习惯养成期。我用血的教训换来三条必须第一天就立起来的规矩一切代码进Git数据用DVC或manifest管理。宁可数据文件先放本地也要把“数据版本处理代码commit配置”这套绑定关系记录下来。没版本的数据等于没数据。每次实验必须留下记录。至少记四样训练配置、代码commit号、数据版本、跑出来的指标。用MLflow、wandb都行没有一个像样的工具之前哪怕写在Markdown表格里也比不记要好。环境锁定。用Docker镜像或者完整的依赖lock文件保证三个月后还能复现今天的结果。“我不能复现上周跑出来的结果”这句话会吃掉整个AI项目的可信度。这三条不是“锦上添花”而是“安身立命”。没有它们后面的每一次调参、每一版模型都是在流沙上盖房子。3. 数据管线地基里的脏活决定天花板3.1 数据版本没版本的数据等于没数据做AI工程的人迟早会撞上同一个噩梦上个月用一批数据训出的模型效果很好这个月想复现发现原始数据已经被覆盖了或者处理脚本改了三版谁也记不清当时用的是哪一版。解决办法不是玄学就是给数据上版本。DVC是最常用的工具但它的核心思想你不用DVC也能实现任何时候一个实验报告必须能追溯到它当时用的数据源、处理脚本版本、采样规则和校验结果。我现在每个数据集的manifest大致长这样{ data_path: s3://bucket/dataset/raw_v3.parquet, schema_version: v2, pipeline_commit: a3f9c1d, sampling: stratified_by_label, checksum: sha256:8f9a1b... }每次训练、每次微调、每次评估我都把这一条manifest直接贴在实验记录里。这样以后不管谁来问“你这个结果是怎么跑出来的”我都能在十分钟内给出可复现的完整答案。数据版本化的本质是给“实验结果”这个结论加上可追溯的证明链。3.2 随机划分、时间划分、按组划分选错会高估成绩很多人在划分训练集和测试集时闭着眼train_test_split(random_state42)。但数据划分方式选错评估结果可以虚高得一塌糊涂。三种划分方式和使用场景随机划分适合样本之间完全独立的场景比如一张张图片的分类。但如果样本之间存在关联随机划分会泄漏。最典型的是同一个用户贡献了多条数据时模型在训练集里见过这个人测试时再遇到他等于“开卷考试”。时间划分适合时序类数据比如商品评论、行情预测。按时间前80%训练、后20%测试模拟的是“用过去预测未来”的真实场景。按组划分group split当数据里存在用户、店铺、文章这类“组”的概念时必须把同一组的所有样本全部放进同一侧要么全在训练、要么全在测试。我实际遇到过的一件事做一个工单分类模型一开始随机划分准确率93%模型看起来优秀得离谱。后来改成按用户ID分组划分准确率立刻掉到81%。差距不是模型变笨了而是之前的评估在“作弊”——测试集里大量样本的用户已经在训练集里出现过了。如果你做的是用户维度、时间维度的数据随机划分就是给自己喂一颗定心丸这颗定心丸会在上线后变成毒药。3.3 清洗脚本必须进仓库notebook只配做探索Jupyter Notebook是探索工具不是生产工具。这一点我吃过大亏在notebook里“顺手”改了几个单元格清洗逻辑把空值填充方式改了跑出结果然后关了笔记本。两周后再想复现连自己都看不懂当时的操作步骤更别提换人了。正确做法是探索和可视化可以在notebook里做但所有清洗逻辑和特征工程逻辑必须写成正式脚本Python文件或dbt之类的工具纳入Git管理。脚本要做到可重跑、可追溯、有输入输出定义。想象一下半年后的你或者新来的同事他们不看notebook他们只看仓库里的代码和数据manifest——他们能不能完全复现你的数据如果不能这个项目就是一次性的不可维护也谈不上工程。3.4 一套廉价的自动数据校验清单数据问题不会只在清洗时报错更多时候是悄悄发生的。线上数据和训练数据分布漂移是AI模型静默失效的头号原因很多团队是等到badcase集中爆发才反应过来。我现在每个项目都会在数据进入训练和上线这两个环节各跑一遍自动校验清单很朴素列名和列数是否匹配预期Schema每列的字段类型是否符合定义关键字段的非空率是否低于阈值唯一性约束是否满足比如ID列枚举值是否在合法集合内标签分布是否与历史版本发生明显偏移线上推理输入的特征分布与训练集分布是否漂移用简单的均值、方差和分位数组对比就行这些校验用几十行Python就能写完但它们能在训练开始前就拦住“数据错位”这种最贵的错误。我见过有人因为爬虫字段错位导致训练数据标签整体偏了一列模型还傻乎乎地训了一整晚第二天看loss低得离谱一查才知道数据在搞笑。廉价的自动校验永远是AI工程里性价比最高的投资。4. 模型选择API、微调、从零训练到底该走哪条路4.1 三条路线的成本与控制权对比到了模型这一步很多人会陷入一个误区既然项目叫“from-scratch”那是不是必须从零训练模型不是。“AI工程从零开始”的意思是工程链路从零搭起不是模型训练从零开始。在绝大多数业务场景下用现成的托管API或者开源模型微调才是理性选择。从零预训练一个模型不管是从数据、算力还是时间成本看对普通团队来说都是天文数字。三条路线的实际权衡路线数据要求成本控制力适合场景托管API调用现成模型几乎为零按量付费成本可控低无法修改模型本身快速验证、长期效果优先于成本开源模型微调几百到几千条高质量样本需要少量GPU一次训练几十到几百元高模型归你掌控领域术语多、输出格式固定、需要私有化部署从零预训练几十亿到万亿Token级别极其昂贵最高学术研究、特殊语种/特殊模态普通业务基本不用考虑这个项目语境下的“from-scratch”是指你从空白工程出发亲手做选型、亲手验证、亲手做权衡。选哪条路是工程决策的一部分。4.2 什么时候才值得微调很多人一上来就微调这是一种“手里有锤子看什么都像钉子”的冲动。我的建议是微调这件事必须排在整个流程的后面前提条件满足再考虑先用提示词工程和RAG试过。把文档塞进上下文、把prompt调到位看效果是否已经满足业务需求。很多任务在这里就解决了不需要动模型本身。评测数据证明“差距”确实存在。拿一组有代表性的badcase出来明确看到模型在这些case上的错误模式——是领域知识缺失格式要求无法满足还是逻辑推理不足不同错误模式对应不同解法微调不是万能药。高质量样本已经备好。所谓高质量不是从网上爬一堆相关文本丢进去。而是针对目标场景标注出“理想输入-理想输出”对至少几百条越多越好。用脏数据微调等于给模型喂错了方向的强化学习。微调还有一个容易忽略的副作用灾难性遗忘。模型可能在新任务上表现好了但通用能力下降。所以微调之后必须在保留评测集上做校验确认没有把老能力弄坏。4.3 小规模微调的最低配置参考如果你的任务确实走到了微调这一步被广泛验证、成本最低的起点是LoRA。我在这里给一个基于常见实践组合的参考配置它不一定最优但作为第一天就能跑起来的起点很可靠基础模型选7B或更小的开源模型按显存和任务难度决定LoRA rank8到16学习率1e-4到2e-4配合warmup和cosine衰减训练1到3个epoch最大序列长度按任务设短文本任务1024足够使用bf16混合精度梯度累积设8左右让单卡能吃得下数据用chat template组织保持和推理时一致的格式写到这里必须再强调微调前和微调后必须跑同一份评测集用数据说话而不是“感觉变聪明了”。没有评测跑的微调和掷骰子没有区别。5. 评测体系把“感觉变聪明了”变成可回归的指标5.1 离线评测集的三层结构AI工程和普通软件开发最大的不同在于普通软件改代码可以用单测断言来守护AI系统改一个prompt改一版模型效果变化是连续分布的、不好断言的。所以评测集就是AI工程的“单测”而且是必须反复跑、持续跑的“单测”。我搭建离线评测集时分三层第一层客观自动判分。分类任务算准确率/召回率检索任务算命中率/RecallK生成任务算格式合规率。这类指标不依赖任何外部模型简单、快、稳定。第二层规则或LLM-as-judge打分。对于“这段回答是否更好”这类需要主观判断的问题用规则先做一遍硬约束有没有关键信息、有没有违反禁止项然后用另一个LLM对回答做质量评分或排序。第三层人工抽检。每周抽一批评测集里的案例人眼过一遍记录“机器认为好但人觉得差”的情况。人工抽检是评测体系的校准层不要省略。三层结构不是一次性的。每次模型版本变更、prompt调整、RAG检索逻辑修改都要重新跑一遍并产出对比报告。5.2 LLM-as-judge 的使用边界现在很多人喜欢让大模型给大模型打分省时省力但这里有两个坑第一法官模型本身是有偏好的。它可能偏爱更长的回答、更喜欢某种行文风格而这些偏好和真实用户需求不一定一致。我见过一个案例judge给了某个模型更高的分但人工抽检时发现那个模型只是在“自信地胡说八道”。第二LLM-as-judge适合排序和质量打分不适合事实性判断。回答里有没有虚构的数字、有没有编造引用来源这种场景要用检索比对、数据库核对而不是让LLM自己评自己。用LLM-as-judge之前务必拿一小批人工标注好的样本去校准judge的打分和人类的判断相关性至少要达到一个可接受水平比如用一致性比例或排序相关性来算。校准不过关就不能用。5.3 每次改动都要跑一遍回归很多团队把评测当成“上线前一次性工作”这是大错。真实情况是prompt改了一个词可能让模型从一个坏case变好同时弄坏另外20个case。没有回归评测你根本不知道。我把核心评测集当成CI来跑。任何变更——prompt调整、微调权重、RAG的切分策略、重排逻辑——都必须触发同一套评测集跑出对比报告才能合并。报告里同时展示“提升案例”和“退化案例”两个方向只看平均分很容易掩盖局部回退。生产环境侧同样不能漏常用的三种手段影子模式shadow mode复制一份线上请求给新模型跑输出不进生产、只做记录。低风险收集新模型在真实流量上的表现。流量回放把历史请求重新发给新模型看它在旧问题上的表现。线上A/B小比例流量切给新模型用在线指标延迟、badcase率、用户反馈率做最终裁决。没有这套机制你在线上做的每一次模型调整本质都是赌博。赌徒偶尔会赢但工程系统不能靠偶尔。6. 把模型推到线上部署、压测与可观测性6.1 推理服务的骨架与性能关键点模型部署这个环节最容易犯的错是用Demo代码直接当服务代码。一个稍微像样的推理服务至少包含这些模块请求进来后的处理顺序是鉴权与限流 → 输入校验 → 查缓存 → 规则/小模型兜底 → 模型推理 → 输出校验 → 返回。其中输入校验和输出校验经常被省略但恰恰是它们决定了系统在遇到脏数据时会不会静默乱来。输入不符合Schema就拒绝输出不符合预期就重试或返回兜底结果这两道闸门成本极低、收益极高。性能层面的关键点动态批处理dynamic batching把并发请求攒成batch再喂给模型吞吐能提升数倍是实现高吞吐的主流手段。量化FP16、INT8、INT4逐级降低显存和延迟但也逐级带来精度损失。我的习惯是先在FP16上建立正确性基线再逐步量化并跑评测集确认精度不垮。推理框架成熟的开源推理服务比如vLLM这类带PagedAttention、连续批处理能力的框架能省掉大量底层优化工作比手写推理循环靠谱得多。选型层面我没有写过任何框架的安装命令因为版本变化太快但思路是固定的先确认框架支持你的模型架构再小流量压测不要一上来就接生产。6.2 用压测暴露问题而不是上线后让用户发现部署完服务别急着“测试一下通不通”。要压测。压测的目的不是测出一个漂亮的并发数而是摸清服务的真实承载边界在多大QPS下延迟开始恶化显存是否撑得住CPU/GPU利用率的瓶颈在哪。我常用的工具是k6或wrk压测脚本可以简单到十几行import http from k6/http; import { sleep } from k6; export const options { scenarios: { load: { executor: ramping-vus, stages: [ { duration: 2m, target: 20 }, { duration: 2m, target: 50 }, { duration: 2m, target: 100 }, ], }, }, }; export default function () { const payload JSON.stringify({ query: 压测样例输入 }); http.post(http://localhost:8000/inference, payload, { headers: { Content-Type: application/json }, }); }跑完压测看三个数p50/p95/p99延迟、错误率、GPU利用率。如果p99在某个并发下突然飙高说明服务已经到瓶颈了如果GPU利用率不到50%而延迟已经顶不住了说明瓶颈在调度或者推理框架配置不在显卡。经验之谈没压测就上线的AI服务第一次流量高峰就是第一次故障时刻从不例外。6.3 AI服务要盯的三个特殊监控维度普通Web服务监控看的是QPS、错误率、响应时间、CPU/内存。AI服务在此基础上还要额外盯三个维度Token消耗与成本曲线。大模型服务是按Token算钱的Token用量会和输入长度、输出长度强相关。监控Token消耗本质是在监控成本。一旦某天Token消耗异常上涨通常意味着有用户在恶意灌长文或者某个prompt被改得出乎意料地啰嗦。生成长度与空回复异常。模型吐出一篇几百字废话、或者输出为空、输出无法解析这类badcase在日志里必须单独标记和告警。它们不会导致HTTP 500但它们会直接毒害用户体验——比宕机更隐蔽。输入数据分布漂移。把线上推理的输入特征与训练集分布做周期性对比。输入分布漂了模型表现必然漂。普通监控盯不住这个需要单独写漂移检测任务每天跑一次。这三点是判断一个AI服务是“活着”还是“活着但已经傻了”的分水岭。很多团队只知道服务200返回正常却完全看不见模型已经在用陈旧认知回答新问题了。7. 一条90天练兵路线从零做一个完整项目7.1 阶段一1到6周垃圾评论分类器闭环如果只有一个项目要做我最推荐从“垃圾评论/垃圾短信分类器”开始。理由很朴素公开数据集容易找、任务边界清晰、评测指标明确而且它逼着你走完整个闭环。任务明确后做这几件事收集原始数据写清洗脚本入库按策略划分训练/验证/测试集可以考虑按用户分组防止泄漏微调一个小模型或者训练一个传统机器学习模型作为基线写一套自动评测脚本输出准确率、召回率、混淆矩阵用FastAPI起一个推理服务加输入校验、限流跑一轮压测记录延迟和错误率加请求日志和基础监控。这六周不追求模型效果全球第一只追求一件事把“数据到上线”的每一个环节亲手过一遍。做完之后你脑子里会生成一张完整的工程地图再往后学什么都快。7.2 阶段二7到10周RAG知识问答系统第二阶段进入大模型应用的主流形态RAG知识问答。用你自己的文档库技术笔记、手册、或者”某个领域的说明文档“做一个问答机器人。这个项目的关键动作文档解析与切分策略、向量库索引建立、检索逻辑先粗排再重排、生成prompt设计、缓存设计、评测集构建、调用链追踪。RAG系统的坑比纯分类任务多得多——切分太碎检索不到切分太大上下文超限检索到的内容与问题不匹配时模型会一本正经地瞎编。我强烈建议从一开始就为RAG建一个小评测集准备20到50个“问题-标准答案-来源文档”每次改检索逻辑或切分策略都跑一遍看命中率变化。7.3 阶段三11到12周微调小模型和托管API算一笔账第三阶段把第二阶段的知识问答“重做”一遍但这次换一条路线微调一个3B到7B的开源小模型在同一个评测集上和托管API方案做一次完整对比。对比维度别只看效果延迟、成本、数据隐私、离线部署的难度、后续迭代维护成本全部列出来。很多团队在实际项目中卡住不是模型效果不行而是没法做决策——因为他们从来不知道“不同选型的真实代价差多少”。这个阶段练的就是决策能力。到这一步你已经不是“会跑模型的人”了。你手里有数据管线、评测体系、部署脚本、监控告警换一个任务、换一个模型你都能在两周内把整条链路重新支起来。这才是AI工程“from-scratch”这个词真正的意义。如果让我给这条路线排优先级我会把数据管线、评测体系、监控告警这三块放得比模型调参更靠前。模型效果差可以靠优化追上数据不可复现、评测不清晰、线上出了故障发现不了才是真正致命的。那些不可见的环节才是把模型变成产品的护城河。
返回列表