ARTICLE DETAIL

资讯详情

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

从零构建AI工程:从环境准备到生产级系统的全流程

从零构建AI工程:从环境准备到生产级系统的全流程 第一次认真琢磨AI工程这个词是好几年前在一家创业公司做技术负责人。当时我们手上的活儿说白了就是接大模型API、拼Prompt、跑几个向量库对比测试然后跟老板汇报我们正在做AI。可越往后越发现真正难的不是让模型答对一道题而是让模型在复杂系统里稳定、可扩展、可度量地工作。这个差距就是工程化。所以我今天想聊的ai-engineering-from-scratch不是说背几篇模型论文也不是把某个开源项目clone下来跑通就完事而是从一台裸机、一段原始语料、一个模糊的业务需求出发一步步把它变成能在生产环境里持续运转的AI系统。这篇文章主要面向三类人刚转行做AI开发的程序员、想给团队搭AI能力的技术负责人、以及那些已经调了不少API但总觉得心里没底的同学。我尽量把整条路线讲透包括选型逻辑、环境搭建、数据准备、微调、部署、监控这些环节也把我踩过的坑直接摆出来。1. 先想清楚AI工程到底在工程什么很多新手一上来就盯着训练模型这四个字觉得从零开始做AI就是搭个GPU服务器、跑个训练脚本、等loss降下来。真这么干的人大概率会在三个月后发现自己攒了一堆模型文件却不知道该怎么上线、怎么迭代、怎么跟业务结合。所以动手之前得先把AI工程这个概念拆开揉碎。1.1 从调接口到做系统的分水岭调接口的人关心的是Prompt怎么写、上下文窗口够不够、返回结果怎么解析。做系统的人关心的是另一层问题请求进来之后路由到哪个模型不同任务的优先级怎么排模型输出格式不稳定怎么办用户反馈怎么回流成训练数据这个分水岭我是在第一次做AI客服项目时深刻体会到的。当时我们用大模型生成回答单看几个样例效果很好但一放到生产环境就暴露出一堆问题同一个问题用户问三遍模型给三个不同答案明明是骚扰信息客服系统还一本正经地回复模型偶尔输出一长串乱码直接把下游的工单系统搞崩了。这些都不是模型效果不够好能概括的而是系统设计的问题。从那以后我养成了一个习惯在碰任何模型之前先画一张系统边界图。哪些是模型该干的哪些是规则该干的哪些是人工兜底的一开始就界定清楚。AI工程的核心不是让模型变得万能而是让模型在合适的位置发挥优势同时用工程手段把它的确定性补上。这个思路对后续所有环节都有指导意义所以放在最前面说。1.2 先搞清楚资源和目标再选技术路线从零开始做AI工程最忌讳的就是拿着锤子找钉子。看到大模型火就去微调大模型看RAG热就上向量数据库其实很多问题用一个简单的线性模型加规则就能解决。我建议第一步做两件事把业务目标翻译成可量化的指标把现有资源盘一遍。量化指标不是准确率越高越好而是跟成本、延迟、用户体验绑在一起的复合指标。比如做智能文档分类你关心的可能是分类错误导致的人工重做率和单条处理成本做代码补全你关心的可能是建议接受率和首字延迟。指标定下来之后技术选型才有依据。资源盘点更实在手上有几张显卡团队里有人写过Transformers相关代码吗数据存在哪个仓库里质量怎么样我见过太多团队明明只有一块消费级显卡却非要去跑7B模型的完整微调结果光是调显存就耗了两周。合理的路径是先量化业务指标再匹配资源能力最后决定用API还是开源模型用全量微调还是LoRA。顺序反了后面全是坑。2. 从零起步环境、算力与工具链准备确定了目标和边界下一个问题就是我在哪里跑代码。这一段我按从无到有的顺序讲不预设你已经有一台满配服务器。2.1 硬件、模型和框架怎么选先说硬件。如果只是学习AI工程流程、跑小模型实验一张RTX 4090或者二手V100就够用显存底线是24G因为很多主流开源模型7B级别做LoRA微调或者量化推理这个容量刚刚好。如果是团队共用租云GPU更划算按小时计费可以随时换配置。我自己的经验是前期别急着买服务器先用云平台把流程跑通再根据实际负载决定是否自建。模型选型上我通常按参数量-任务复杂度矩阵来对号入座简单分类用BERT类的小模型复杂生成任务用7B-13B的通用大模型多模态场景再用对应多模态模型。别一上来就追最大参数的版本参数越大部署成本、推理延迟、迭代难度都是成倍往上翻。记住一个朴素原则能用小模型解决的事绝不上大模型能用规则解决的事绝不上模型。框架层面PyTorch依然是事实标配配合HuggingFace Transformers和PEFT做微调生态最成熟。分布式训练的话单机多卡用DeepSpeed就能解决大部分问题实在要上多机再考虑Megatron-LM这套更底层的工具。新手别一上来就折腾分布式先保证单卡能跑通再谈扩展。Lightning这类封装框架可以简化训练循环但如果你搞不清底层在做什么出了问题反而更麻烦。2.2 从Hello World到第一个本地推理环境准备这块我踩过一个非常经典的坑Python版本和CUDA版本不匹配装什么包都报错。现在我的标准流程是这样先用Conda建一个独立环境指定Python 3.10然后根据显卡驱动版本确定CUDA版本比如驱动支持CUDA 11.8就装对应的PyTorch版本最后再装Transformers、Datasets、Accelerate这些依赖顺序不能乱。验证环境是否正常我建议跑一个最朴素的推理脚本不要一上来就加载巨大模型。比如加载一个几百兆的小模型输入一段文本看看输出是否符合预期。这一步能同时验证显卡驱动、CUDA后端、模型下载链路是不是都通。from transformers import AutoModelForCausalLM, AutoTokenizer import torch model_name sshleifer/tiny-gpt2 tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForCausalLM.from_pretrained(model_name) inputs tokenizer(AI engineering is, return_tensorspt) outputs model.generate(**inputs, max_new_tokens20) print(tokenizer.decode(outputs[0], skip_special_tokensTrue))很多新手下载模型卡在HuggingFace连不上国内网络环境建议配置镜像源。这个环节不用觉得丢人工程化本身就是解决各种环境的脏活累活。等这个脚本能在你的GPU上跑出结果说明基础环境已经通了可以进入下一个真正的核心环节——数据。3. 数据工程AI系统真正的地基模型训练里最影响成败的往往不是模型结构而是数据。这句话我听过无数遍但真正理解它是在做一次文本生成项目时同一个模型换了份清洗过的数据效果提升比换更大模型明显得多。从零做AI工程数据这块值得投入至少一半的精力。3.1 数据收集与清洗的实战流程第一步是明确数据边界你要解决什么任务需要什么样的输入输出对。比如做客服意图识别需要的是用户原话-意图标签的配对做摘要生成需要的是长文档-短摘要的配对。别见到数据就抓数据跟任务不对齐后面全是无效功。收集渠道通常有三类业务系统日志、公开数据集、人工撰写。日志数据的优点是真实缺点是噪声大公开数据集质量高但领域可能不匹配人工撰写成本高但往往是你产品差异化的来源。拿客服场景举例我会先把历史工单捞出来脱敏处理后作为初始语料再用规则做一次粗过滤把明显无关的日志、报错堆栈、隐私信息筛掉。清洗这一步我习惯分成四个环节去重、去噪、归一化、格式校验。去重不只是删掉完全相同的句子还要用MinHash这类算法处理近似重复否则训练时模型会反复看到同一类样本导致过拟合。去噪主要针对乱码、HTML标签、异常符号。归一化包括简体繁体转换、全角半角统一、大小写处理。格式校验则确保每一条样本都能被解析成预期的结构化字段。每一环节都建议保存清洗前后的统计量样本数、长度分布、关键词覆盖率方便追溯“效果变好是因为数据变了”而不是“玄学调参”。3.2 标注策略与评估集设计数据清洗完接下来面临的是标注。如果预算有限我的建议是别一上来就雇一堆人批量标注先自己手工标200-500条把边界情况摸清楚。这个过程不只是产出数据更是帮你想清楚任务定义什么算对什么算错边缘case怎么处理这些不定义清楚雇人来标也是白标。标注方案上分类任务用label studio这类开源工具生成类任务得自己写打分标准或者用LLM辅助初标、人工修正。质量控制在正式标注前必须先做一致性测试挑20条样本让两个标注员标算一下Cohens Kappa低于0.6就得重新对齐标准。我见过太多项目死在这数据标了几万条一训练发现标签互相矛盾。评估集的设计更不能临时抱佛脚。我通常的做法是把评估集分成三层通用能力集比如通用语料上的标准测试、领域核心集覆盖你最关心的业务场景、对抗集专门放一些用户会故意刁难的输入。评估集一旦定下来就尽量冻结改版要走流程否则你很难判断模型变好还是变差。这个评估集就是AI工程的测试用例地位等同于软件工程里的单元测试。4. 模型训练与微调吃透原理再动手对大部分业务团队来说从零预训练一个大型模型的成本既不现实也没必要。真正高频的动作是做微调也就是让一个已经具备通用能力的模型在你的领域数据上去适配。但即便是微调背后也有一些原理必须先想明白否则就是盲调。4.1 从模型结构到微调策略的原理拆解先说一个最基础的概念预训练模型学到的是语言的通用规律就像一个人已经能读写、能理解常识微调则是让这个人去熟悉某个公司的术语、话术和流程。所以微调的本质不是教模型说人话而是教模型说你的行业里的话。微调有两种主要方式全量微调和参数高效微调PEFT。全量微调是把模型所有参数都更新一遍效果上限高但需要的显存和算力大而且每次都要存完整的模型副本。PEFT的代表是LoRA在原始权重旁边加一个低秩矩阵只训练这个辅助矩阵。LoRA的好处用一句话讲就是用一个很小的参数量逼近全量微调的效果同时训练成本大幅降低。我早期做医疗文本模型时7B模型全量微调光优化器状态就能吃掉60G显存切成LoRA后一张A100轻松跑完效果差距完全可接受。如果你读过《Build a Large Language Model from Scratch》这类书会发现原理并不玄语言模型在预训练阶段做的是下一个token预测微调阶段则可以换成指令跟随、对话对齐等目标。理解了这一点你就知道为什么微调数据的质量比数量重要——模型的行为是被目标函数数据分布共同塑造的垃圾数据堆再多也只会让模型学到垃圾模式。4.2 LoRA微调实战完整配置与关键参数实操层面我以一份LoRA微调配置为例讲清楚每一步在干什么。假设任务是让模型学会把口语化的技术需求改写成规范的prompt。数据准备好之后先做格式转换把每条样本构造成指令-输入-输出三段式结构用模板拼接成模型能理解的对话格式。from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments from peft import LoraConfig, get_peft_model, TaskType from datasets import load_dataset from trl import SFTTrainer model_name Qwen/Qwen2.5-7B-Instruct dataset load_dataset(json, data_filesprompt_data.jsonl, splittrain) tokenizer AutoTokenizer.from_pretrained(model_name, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained( model_name, torch_dtypeauto, device_mapauto ) lora_config LoraConfig( task_typeTaskType.CAUSAL_LM, r16, lora_alpha32, lora_dropout0.05, target_modules[q_proj, k_proj, v_proj, o_proj], ) model get_peft_model(model, lora_config) training_args TrainingArguments( output_dir./lora_output, per_device_train_batch_size2, gradient_accumulation_steps8, learning_rate2e-4, num_train_epochs3, logging_steps10, save_strategyepoch, fp16True, ) trainer SFTTrainer( modelmodel, argstraining_args, train_datasetdataset, tokenizertokenizer, max_seq_length2048, ) trainer.train()几个关键参数我说一下心得。r是低秩矩阵的秩16是个在多数任务上稳的起点太小表达能力受限太大训练参数和显存都涨lora_alpha是缩放系数一般设为r的两倍效果和稳定性比较平衡target_modules要查模型架构文档不同模型可训练的模块名不一样别照抄别人的配置就不管了。训练时最容易翻车的是学习率。LoRA微调的经验学习率通常在1e-4到3e-4之间但具体值跟数据集大小、批次大小都有关系。我的习惯是先用一个小数据集跑几十步观察loss是否下降、是否震荡再决定调大还是调小。还有一点gradient_accumulation_steps配合小batch可以降低显存压力但等效batch size调大后学习率也要适当调大否则收敛会很慢。4.3 微调后的评估与迭代闭环模型训练完第一件事不是急着摆指标而是先把评估集跑一遍。我会依次看三个东西答案格式是否符合预期、领域关键指标是否提升、通用能力有没有退化。最后这个通用能力退化最容易被忽略——你拿一个通用助手模型微调成客服机器人结果它连常识问答都不会了这在工程上是大事故。迭代节奏上建议采用小步快跑每次改动数据或参数训练一个小版本跑完整评估记录结果再决定下一步。我通常会把每次实验的预期指标写下来训练完比对如果偏离预期就停下来查原因而不是调个参数继续跑。项目到后期真正有用的不是某个神奇的调参技巧而是一套稳定的实验记录和评判流程。5. 部署与服务化让模型真正跑进业务系统训练完了模型还只是硬盘里的一组文件。接下来要解决的问题是怎么把它变成一个稳定、快速、能应对真实流量的服务。这一环节最不性感但最能拉开普通项目和成熟产品之间的距离。5.1 推理服务接口、批处理与并发控制最朴素的部署方式是单机脚本模型加载后接收请求、生成结果、返回。这种方式只适合实验生产环境必须解决三个问题并发请求怎么排队、显存怎么复用、生成超时和错误怎么处理。我的标准做法是用FastAPI包一层接口模型常驻内存避免每次请求都重新加载。关键点是并发控制大模型生成时是计算密集型如果同时来一批请求内存会爆所以要用信号量或队列限制并发度。很多同学忽视了流式输出等到用户反馈怎么转半天不出字才想起来改其实Streaming是提升体验性价比极高的方案应该在架构阶段就设计进去。from fastapi import FastAPI import asyncio from transformers import pipeline app FastAPI() sem asyncio.Semaphore(2) # 限制同时只有2个生成任务 generator pipeline( text-generation, model./lora_output_merged, devicecuda:0 ) app.post(/generate) async def generate(payload: dict): async with sem: result generator(payload[prompt], max_new_tokens256) return {text: result[0][generated_text]}生产环境里我不会直接暴露这个Python服务给外部流量而是前面加一层Nginx负载均衡后面挂多个GPU服务实例。这里有个容易被忽视的问题多个实例各自加载同样的大模型会造成显存重复占用所以实例数量必须跟显存总量匹配别为了高并发无限横向扩容。5.2 评测、监控与线上反馈闭环模型上线不是终点而是迭代起点。线上监控至少需要三类指标性能指标延迟、吞吐量、显存占用、业务指标用户采纳率、错误率、投诉率、数据指标输入分布变化、模型置信度分布。我习惯把这三类指标接到同一个看板上这样出问题时能快速定位是模型变笨了还是业务流量变了还是机器资源不够了。线上反馈闭环是AI工程最核心的部分用户对生成结果的评分、纠错行为、后续修改都要想办法回流到数据池里经过筛选和标注变成下一版训练数据。我用过一个简单但有效的做法在返回结果的接口里埋一个是否有用的按钮点击数据落到消息队列定期汇总成增量训练集。这个机制的建立比多训几十个step有价值得多。此外还要做版本管理。模型文件、分词器、配置、训练代码、数据版本全都要像服务端代码一样纳入版本管理。模型文件用对象存储保存每个版本打一个tag线上随时可以回滚。没有这套机制一旦新模型出问题你连旧模型都找不回来那是真正的生产事故。6. 常见问题与排查技巧实录走完整套流程后你会发现AI工程的问题往往是跨环节的训练时loss不降可能是数据问题而不是参数问题线上效果差可能是训练分布和服务分布不一致。这里我把我自己遇到的高频问题整理成一份速查希望能帮你少走两个月的弯路。6.1 训练不收敛与显存不足的排查路径训练loss不降是最磨人的问题。我的排查顺序是先看数据抽样打印几条训练样本确认输入输出对没搞反、标签没标错、特殊token是否被正确处理再看梯度确认模型是否处于训练模式优化器参数是否正确传入最后才看参数学习率是不是过大导致loss震荡学习率是不是过小导致几乎不动。记住一个经验大多数玄学不收敛最后都能追溯到数据格式错误而不是模型结构问题。显存不足的常见原因有三个序列太长、批次太大、优化器状态占量巨大。我用过的实用技巧包括梯度累积减小有效显存占用、gradient_checkpointing用计算换显存、LoRA替代全量微调、输入文本做截断或摘要。如果你明明设备是A100还爆显存先看看是不是加载了多个模型副本或者device_map没有把层均匀分配到多卡上。6.2 数据泄漏与评估集污染数据泄漏是最隐蔽的错误训练集和评估集混入了相同或近似相同的内容导致评估指标虚高。最典型的场景是从同一个用户的历史数据里既抽了训练样本又抽了评估样本用户换个说法问了同一个问题模型在评估时等于见过答案。排查方式很简单但容易被忽略对训练集和评估集做一次近似重复检测。用MinHash或Embedding相似度把相似度超过阈值的样本对找出来人工确认后再决定是删除还是重新划分。按用户维度做划分也是好习惯保证同一个用户的数据不会同时出现在两个集合里。这个问题处理不好你的离线指标再漂亮上线必翻车。6.3 目标衡量偏差与幻觉问题的工程对策很多AI系统上线后最大的争议点是效果到底好不好。根子往往在于离线评估用的指标比如BLEU、ROUGE跟线上用户体验并不一致。针对生成类任务我会额外引入一套人工抽检机制每周从线上日志里随机抽100条让标注员按正确/部分正确/错误三档打分算出一个可接受率作为长期跟踪的核心指标。这套指标虽然成本高但对业务最真实。幻觉问题则要从工程层面做约束检索增强RAG给模型提供事实依据限制输出范围或者在后处理环节对敏感断言做关键词校验。想让模型完全不说瞎话是做不到的但可以通过把回答锚定在检索内容上、在Prompt里明确只基于材料回答把幻觉率压到可接受范围。这些手段组合使用比单纯在训练阶段死磕要有用得多。7. 从一个人到一支队伍AI工程的规模化进阶当你的AI系统跑稳了自然会面临下一步怎么把它交给更多人维护、怎么让更多业务接入、怎么保证每个人都按同一套标准做事情。这一步是AI工程从个人英雄主义走向组织能力的关键。7.1 多人协作的统一流程与规范我见过太多AI项目卡在只有一个人看得懂这个状态。负责训练的同事一离职整个项目就瘫痪了。要避免这个问题必须建立文档和数据字典数据从哪里来、清洗规则是什么、为什么这么做、模型效果怎么评估、上线流程是什么。文档不用写得多华丽但必须实时反映项目现状。另外代码评审和实验记录也要向正规软件开发靠拢。训练代码、推理服务、评估脚本都要走Git仓库每次提交关联对应的实验报告。我自己的习惯是给每个实验命名成日期-模型-数据版本-目标配合一个简单的实验记录表填写训练参数、评估结果、结论。时间一长这个表就是团队最宝贵的资产。7.2 安全基线、可复现性与成本治理AI工程规模化后安全和合规问题就绕不过去。用户数据必须脱敏后才能进入训练链路模型服务要做到输入输出内容的安全过滤防止恶意指令注入。这里特别提醒一点不要在生产环境直接暴露不受限的模型接口一定要做身份认证、内容审核和限流否则你不仅可能接到不合法请求还可能被刷接口刷到破产。可复现性上除了代码和数据版本还要固定依赖环境。推荐用Docker把整个训练和推理环境打包镜像的标签和模型的版本对应起来。哪怕半年后回来重新跑一遍实验也能得到同样的结果这在排查线上问题时尤其重要。成本治理同样不能忽视。大模型的日常开销主要在推理阶段常见的手段包括把小任务路由到小模型、设置超时和最大token限制、对空闲实例做自动缩容、用量化或蒸馏降低推理成本。我在一个项目里靠这四项优化把推理成本降了70%而效果几乎没有变化。很多时候控制成本不是抠门反而是倒逼系统设计变得更聪明。8. 资源推荐与自学路线最后总结一下从零开始的学习路径。如果你想系统性地打好基础我建议的路线是先读一本讲清大模型原理的书比如那本比较出名的《Build a Large Language Model from Scratch》配合动手实现一个极简的语言模型然后跑通一遍数据清洗-微调-评估-部署的完整流程接着在真实业务场景里做一个具体任务最后再回头看系统设计补上监控、安全和成本这些工程课题。工具链不用贪多PyTorch、Transformers、PEFT、Datasets、FastAPI这五个就能串起大多数AI工程的核心场景。遇到问题优先看官方文档和GitHub issue而不是搜一堆二手博客。我自己的实践经验是每学一个新工具就把它用在一个8小时能完成的小项目上比看十篇教程都管用。如果你跟着这条路线走会发现所谓AI工程并不神秘它就是把软件工程的好习惯版本管理、测试、监控、文档、可复现性和大模型的开发流程结合起来。这个领域变化很快但底层的方法论是可以稳定迁移的。我个人在带团队过程中最大的体会是从零开始做AI工程真正考验的不是数学天赋而是动手能力、排查问题的耐心以及对系统整体架构的把控力。每一次loss爆炸、评估指标和线上体验对不上、新模型上线后被业务方吐槽最后都会变成你判断力和经验的一部分。别怕踩坑把每次踩坑都记录下来这就是你从会用AI的人成长为AI工程师最快的路径。
返回列表