ARTICLE DETAIL

资讯详情

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

AI工程从零构建实战:技术栈选型、项目落地与避坑指南

AI工程从零构建实战:技术栈选型、项目落地与避坑指南 如果你逛过招聘网站的 AI 岗位大概率会看到“AI工程”这个方向。它不是纯做算法研究也不是传统后端开发而是夹在两者中间、负责把一个个模型真正变成线上服务的那类工作。这篇文章就围绕 AI工程从零开始构建这个主题把技术栈选型、完整项目落地、问题排查这几块我最常被问到、也最常踩坑的内容一次讲清楚附带一个从零搭起来的评论情感分析系统作为贯穿案例。适合刚入门机器学习但想往工程方向走的开发者、想转 AI方向的工程师以及已经在做算法但总觉得上线很费劲的朋友。1. 先搞清楚AI工程到底在解决什么问题1.1 一个模型demo和一套AI系统的差距很多人在 notebook 里训练过一个分类模型打印出 accuracy0.95觉得自己已经会做 AI了。但真实业务需要的不是“一个跑得通的模型”而是“一套长期稳定运行的 AI系统”。这两者的差距在哪里举几个最直观的例子notebook 里只处理干净的 CSV生产环境的数据来自接口、日志、数据库字段缺一堆格式天天变。notebook 里一次跑一个 batch生产环境每秒可能要处理几十上百个请求还有延迟预算。notebook 里模型精度掉了可以重新训练再跑一次生产环境模型挂了、效果变差了需要有监控、告警和回退机制。notebook 里只有你自己看生产环境有调用方、有业务方接口参数变化要兼容日志要能排查问题。一套完整的 AI系统至少包括数据接入层、特征处理层、模型推理层、服务暴露层、监控告警层和调度重训层。只训练一个模型等于只做了整个系统里的一小块。1.2 AI工程师到底和算法工程师、数据工程师怎么分工我这些年见过不少团队算法工程师觉得模型上线是大工程后端工程师觉得模型逻辑是个黑盒两边一推项目就卡住了。AI工程这个角色本质上就是来填这个空档的。一个简单的分工对比角色核心职责主要产出算法工程师研究模型结构、优化训练方法实验报告、新的模型方案数据工程师负责数据采集、清洗、数仓建设数据管道、数据表、指标字典AI工程师把算法、数据、工程整合成可运行的线上系统模型服务、监控系统、端到端落地AI工程师不一定要发明新模型但要能把已有模型稳定、高效地跑在生产环境里。这句话听起来简单做起来涉及的东西非常多既要懂一点模型的输入输出又要懂特征怎么算还要写服务、搞部署、盯监控。本质上AI工程是在解决“模型的最后三公里”问题就是从模型训练完到业务真正用上之间那段路。理解了这一点你就会明白为什么纯算法背景的人做上线总觉得使不上力为什么纯后端背景的人看模型代码总觉得无从下手。两个方向的人都需要往中间走而 AI工程就是那条中间路线。2. 从零开始的技术栈怎么选2.1 选型逻辑先看生态再看团队最后看趋势很多新手在选技术栈时容易陷入纠结比如 PyTorch 还是 TensorFlowFastAPI 还是 Flask要不要直接上 Kubernetes。我的建议非常直接先从生态最成熟、社区最多人用的东西开始。Python 在 AI领域依然是绝对主力没有之一。虽然 Java 服务端、Go 服务端都有但模型训练、数据处理、特征工程相关的库几乎全部集中在 Python 生态里。哪怕你以后要写高性能服务也是先写 Python 的遇到瓶颈再局部替换。深度学习框架方面PyTorch 已经是学术和工业界事实上的标准。HuggingFace Transformers 覆盖了绝大多数文本任务torchvision 覆盖常见图像任务选 PyTorch 基本不会错。TensorFlow 在部分存量项目里还存在但新项目直接用 PyTorch 起步更省心。服务化框架我推荐 FastAPI。它的异步性能不错自带参数校验和接口文档能少写很多基础代码。相比 FlaskFastAPI 对模型推理这种 IO 密集和计算密集混合的场景更合适。2.2 一套最小可用技术栈清单我给初学者整理过一个最小可用技术栈意思是只用这些东西就能把一个模型从训练到上线完整跑通。层级最小可用方案说明语言Python生态最全AI领域的代表语言训练框架PyTorch Transformers覆盖文本、图像、表格主流任务实验管理MLflow记录参数、指标、模型产物服务化FastAPI快速包一层 HTTP 推理服务容器化Docker解决环境一致性问题调度cron shell 脚本先跑手动的再讲编排监控日志 简单统计脚本先理解线上数据再上监控平台这套组合拳能解决 80% 初期的需求。很多人一上来就学 Kubernetes学完发现本地连个集群都没有纯属浪费时间。Kubernetes 是出现“多服务、多实例、自动扩缩容”这些问题之后才需要引入的而不是一开始就学的。到一个什么阶段再上进阶工具我的判断标准是当前方案出现了明确的痛点再换。比如手动记录实验参数太痛苦了引入 MLflow 才有价值。手动跑模型重训经常忘再考虑 Airflow 或 Prefect。单机部署扛不住流量再学 Kubernetes 也不迟。日志文件太多根本没法查再上 Prometheus Grafana 和集中日志系统。2.3 学习技术栈的顺序不要先啃原理AI工程涉及的命令、工具、框架非常多但真正需要一开始就学透的极少。我的建议顺序是这样第一步先把 Python 基础语法过一遍会写函数、会用类、会处理文件就够了。第二步学会 pandas 处理表格数据这是 AI工程最常用的利器。第三步把 sklearn 和 PyTorch 的基本 API 用熟能跑通训练和推理。第四步学 Docker只需要达到“会写 Dockerfile 把服务打镜像跑起来”的程度。第五步学 FastAPI 把模型包成一个接口。Linux 命令和 git 一定要熟悉这两个是工程化的底层基础设施。不会 git 协作你的代码永远只能自己玩不会基本 shell 命令你在服务器上寸步难行。这个顺序最大的特点是把“能跑通端到端”放在最前面。很多技术细节比如模型并行、分布式训练、特征存储等你真正遇到问题后再去学效率和动力都高得多。3. 从零搭一个情感分析系统的完整过程3.1 业务问题怎么翻译成模型问题项目管理里最怕的就是需求不明确。我一般会先花时间把业务问题翻译成机器学习问题这一步做好了后面都顺。举个例子电商平台的运营同学想看用户评论里的负面反馈人工看不过来希望用模型自动识别。这个需求怎么定义第一步确认输入输出。输入是一条评论文本输出是“正面”或“负面”两个类别。这里先不做三分类因为“中性”这个类别的标注一致性非常差一条“买了还没用等用了再评价”到底算中性还是正向先二分类上线后续需要再加类别。第二步确认评估口径。运营最关心的是“负面评论有没有被漏掉”也就是说模型对负面评论的召回率比整体准确率更重要。这一点必须在训练前沟通清楚否则后面用准确率评估模型把90%的都判成正向准确率照样很高但业务完全不认账。第三步确认置信度阈值。模型不会天然给出一个“是负面”的答案而是给出一个概率。业务方要决定概率大于多少算负面大于多少要人工复核这些参数直接影响后续的系统设计。这些问题在写第一行代码之前就应该有答案。跳过这一步直接开始训练是我见过最多的返工原因。3.2 数据要花多少心思才算够用数据是 AI工程里最花时间、最不显眼、但决定了效果上限的环节。我从零搭这个情感分析系统时数据大概率是这样来的从业务数据库里导出一段时间内的用户评论加上手动构造一些边界情况。起步数据量多少合适对于用预训练模型微调这种方案几千条标注数据已经可以让效果达到可接受水平。不要一上来追求几万甚至几十万的标注量那是稳定迭代之后的事情。准备工作里最容易踩的坑是“标注规范不一致”。比如“物流有点慢但东西本身不错”这句评论应该算正面还是负面如果三个人标注三个答案模型学到的东西就会很乱。我的做法是先写一个简单的标注文档把边界情况统一掉标注原则以评论整体表达的情绪倾向为准。包含抱怨但最后给好评的算正面。包含夸奖但明显是反讽的算负面。不确定的交给多人投票。数据划分也要讲究。AI工程里最常见的划分方式是按照时间切分而不是随机切分。因为线上永远预测的是未来用过去和未来的时间边界来划分训练集和测试集更接近真实场景。随机切分容易让模型“偷看”未来信息导致离线指标很好看上线效果却一塌糊涂。文本清洗这一步要根据业务做定制。电商评论里有大量的 HTML 标签、颜文字、连续重复字符。我测试下来把 HTML 标签去掉、统一全角半角、把 URL 替换成占位符能让最终准确率和召回率稳定提升一到两个百分点。清洗逻辑一定要写成独立的函数后面训练和推理都用同一个函数避免两边不一致。3.3 训练实验怎么组织才会有复现性数据准备好之后训练本身其实没什么神秘的。但“有复现性的训练”不是随便跑跑就行要满足几个条件实验参数有记录、模型产物有版本、指标可以横向对比。我先说模型选型。对文本二分类这种任务直接用中文版的 BERT 系列预训练模型效果稳定微调成本也不高。HuggingFace 生态里加载和训练非常方便from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments model_name bert-base-chinese tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForSequenceClassification.from_pretrained(model_name, num_labels2)接着是数据集的封装。用 HuggingFace 的 Dataset 类能把 tokenizer、数据集 shuffle、按 batch 取数据这些事情打包好比手写 DataLoader 要省事。这里要注意tokenizer 的词表长度和模型的 embedding 维度是绑定的不要随意改。微调的关键超参数我用的默认经验值如下参数取值理由learning_rate2e-5预训练模型已经学到语言知识学习率太大容易灾难性遗忘batch_size16显存允许范围内尽量大结合 GPU 显存动态调整epochs3文本分类微调通常是2-5轮太多会过拟合weight_decay0.01简单有效的正则化warmup_ratio0.1前10%步数线性升温训练更稳定训练过程中我强烈建议用 MLflow 记录每一次实验而不是自己手写一个 Excel 记录import mlflow with mlflow.start_run(): mlflow.log_param(learning_rate, 2e-5) mlflow.log_param(epochs, 3) mlflow.log_metric(eval_f1, 0.87) mlflow.log_artifact(model.pt)为什么要这么繁琐因为一旦模型效果不好了你要能快速回溯当时用的哪套数据、预处理代码、训练参数。光靠文件名加日期根本撑不住你一定会遇到“昨天结果好今天结果差但死活找不回昨天是怎么跑的”那种崩溃时刻。效果评估那一环我先看负样本的召回率和 F1而不是准确率。电商评论里本身正向就远多于负向如果只看准确率模型把所有评论都判成正向也能有 85% 以上那是毫无意义的。只有把评估指标和对业务的价值对齐训练出来的模型才能真正被接受。训练完不要急着部署先做一次误差分析。我把模型在验证集上预测错的所有样本打印出来逐条看。有一类错误值得注意模型把“物流慢”这种负面子句当成了整条评论的负面信号导致“物流慢但东西不错”被判成负面。这往往不是模型的错而是标注规范里写的不够清楚或者训练数据里这类样本太少。发现了就补一批这样的样本重新训练比调参管用得多。3.4 把模型变成一个真正可以调用的服务模型训练完只是万里长征走了一半剩下的一半是“让模型可以被业务调用”。我用 FastAPI 完成这一步代码结构非常简单from fastapi import FastAPI from pydantic import BaseModel from transformers import AutoTokenizer, AutoModelForSequenceClassification import torch app FastAPI() model_name /models/sentiment_bert tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForSequenceClassification.from_pretrained(model_name) model.eval() class Item(BaseModel): text: str app.post(/predict) def predict(item: Item): inputs tokenizer(item.text, return_tensorspt, truncationTrue, max_length128) with torch.no_grad(): logits model(**inputs).logits probs torch.softmax(logits, dim-1).tolist()[0] return {sentiment: positive if probs[1] 0.5 else negative, confidence: max(probs)}这里有个细节模型和 tokenizer 要在模块加载时初始化千万不要放在每个请求函数里去加载。模型加载是个重量级操作放函数里会导致第一个请求超时并发一上来直接卡死。这个坑我见过不止一次。输出的时候不要只返回标签把概率也返回。业务方拿到概率之后可以根据实际情况调整阈值而不需要每次改代码重新发布。再一个容易忽略的问题是文本预处理的一致性。训练时清洗文本用了去掉 HTML 标签、替换 URL、统一全半角这三步推理接口也必须做一模一样的操作。我建议把这两个函数放在同一个工具模块里训练和推理共同引用从根源上杜绝了不一致的问题。上下文长度也要处理。BERT 系列一般有 512 token 的限制实际请求里一条评论很少会超长但还是要开 truncation 并设置最大长度。我实测下来128 token 对电商评论这类任务完全够用长度太大反而增加推理延迟和显存消耗。3.5 上线之后只做监控还不够还得设计好回退方案模型上线以后很多人会觉得松口气其实这才是监控工作的开始。我见过太多模型上线第一天效果不错两周后指标开始下滑等发现问题时业务已经被影响了很久。监控的第一层是基础运维指标请求量、延迟、错误率。这些用普通的日志统计就能做关键是要有告警比如某个接口的错误率超过5%就打电话。第二层是模型指标。要对线上每个请求的预测概率做分布统计。正常情况下模型给出的正面概率分布是相对稳定的。如果某天开始分布明显变化说明线上数据和训练数据出现了漂移。不需要一开始就用很重的平台每天统计一下预测值分布趋势图肉眼就能看出问题。第三层是真实效果验证。我推荐“抽样人工标注”的办法每周从线上采样固定数量的评论让业务方打标和模型结果比对估算真实线上的准确率和召回率。这个办法不花哨但非常有效。最容易被忽略的是回退方案。不管理论上模型多好上线后一定会有异常情况。我的做法是每次发布模型时保留旧版本的服务地址一旦新模型效果异常切回去。部署架构上通过一个开关就能切换新旧版本不要搞成只能重新发版才能回退。监控跑了一段时间之后自然会有重训的需求。先不要急着把“自动重训”做成一个复杂的编排流程。我的建议是先用 cron 定期跑一轮全量数据重训人工比较效果流程稳定以后再考虑自动化。4. 我在实际项目中踩过的坑和排查思路实录4.1 训练和推理逻辑不一致精度直接腰斩有一次情感分析系统上线以后我拿线上真实请求回测发现准确率比线下评估低了快15个百分点当时非常蒙。排查过程说来也简单我在训练前做了文本清洗去掉 HTML 标签把 URL 替换成占位符。但推理服务里直接用了原始文本没有做任何清洗。模型训练时见过的是清洗后的文本线上来的全是带标签的原始文本分布完全不一样效果自然崩了。这个问题的坑点在于线下评估时常用清洗后的干净文本而线上拿到的原始文本带着各种噪音。解决方法是把清洗逻辑抽成公共函数训练和推理共用。上线前加一条回归测试把清洗前后文本分别送入推理接口确认输出符合预期。这个现象太常见了。数据预处理、特征工程的每一步只要训练和推理走的是两份代码迟早会出问题。核心原则就一条训练和推理共用同一套处理代码代码文件相同版本一致。4.2 数据泄露让离线指标虚高上线直接翻车另一个让我记忆尤深的坑是数据泄露。当时我在做一个用户评论分类任务离线 F1 高达 0.95一上线连 0.8 都保不住。后来排查发现问题出在特征工程环节我在做 TF-IDF 特征时是先在整个数据集上进行了 fit然后再切分的训练集和测试集。这意味着测试集里的特征分布已经通过词频统计“看”过了整个数据集测试集不再干净。模型在评估中偷看了答案指标自然虚高。这种问题在 AI工程里非常隐蔽因为表格型数据的特征工程步骤比较多稍不注意就用了全量数据做归一化、分布统计之类的操作。排查看起来也简单检查所有特征计算是否发生在数据集划分之后。注意任何用到全局统计的操作都必须只基于训练集计算再应用到验证集和测试集上。4.3 线上数据分布和训练数据差太多模型像换了个人模型上线之后数据分布通常都会悄悄发生漂移。最典型的场景是电商大促期间评论里突然冒出大量关于“价格”“促销”“到货速度”的内容这些内容在训练集里占比很低模型处理起来很容易乱。我的做法是上线之前先定义好监控指标。比如统计预测为正面的比例这个比例在平时大约是60%某天突然变成80%就要警惕了。再进一步可以看输入文本的分布字符长度变化、高频词变化都能提示数据漂移。一旦确认漂移有两个选择轻量处理是快速切换回旧版本或者用规则兜底重量处理是补充最近时段的数据重新标注训练。无论如何先保证线上稳定再考虑模型更新。4.4 不平衡样本却只用准确率评估等于自欺欺人情感分析这种任务天然存在类别不平衡。正向评论可能占80%以上负向可能只有不到20%。只用准确率作为评估指标模型把所有样本都判成正向准确率也有80%以上。这种模型上线之后业务方发现负向评论一个都找不出来自然觉得系统是个废品。解决办法是评估指标用负样本的精确率、召回率和 F1再不济也要看混淆矩阵。我之前用过一个比较稳的组合指标看什么业务含义精确率负面判成负面的样本里真负面占多少模型说这是负面可信度多高召回率负面真负面的样本里模型找出来多少负面评论被漏掉的比例F1负面精确率和召回率的调和平均综合评价负面捕捉能力上线前我还习惯把阈值从默认的0.5调低一些比如0.3这样负样本召回率更高虽然会附带更多误报但可以引导业务方人工复核。很多时候代价可控的误报比漏报更容易接受。4.5 模型服务化之后的连锁问题模型服务化之后会遇到一些奇怪的问题。我遇到过一次 GPU 显存被占满导致服务直接崩溃排查发现是因为没有限制并发请求量多个请求同时进入模型推理显存叠加就爆了。解决思路是加并发限制或者把请求做一个队列每次只处理一个 batch。再一个常见问题是冷启动超时。模型在启动时需要从磁盘加载权重几百 MB 甚至几个 GB 的模型加载时间可能超过网关默认的超时时间。部署时做一次预热请求让服务在接收流量前把模型加载好。模型推理延迟优化这块用半精度推理是个性价比非常高的操作。BERT 模型在 GPU 上用 float16 推理速度几乎翻倍对精度的影响通常肉眼都看不出来。我在部署时就固定采用 float16代价低收益高。5. 给零基础者的一份实践路径5.1 一个可执行的三个月入门路线AI工程从零开始最大的障碍不是知识难度而是知识范围太广让人迷茫。我这里给一条走过、验证过可行的路线按周分配每周都有一个明确产出。时间内容预期产出第1-2周Python基础语法、编写简单脚本能用Python处理文件、写基本函数第3-4周pandas数据处理、SQL基础能对表格数据做清洗、分组统计第5-6周机器学习基础、sklearn实战能在表格数据上跑完一个分类任务第7-8周Pytorch基础、Transformers库能微调一个预训练模型第9-10周FastAPI服务化、Docker部署能把训练好的模型包成接口并跑在容器里第11-12周端到端项目综合实践完成一个带监控、带回退的完整小系统这套路线非常功利每一周都是为了下一周服务。如果你已经有 Python 基础前两周可以压缩成几天。目标永远奔着一个去用最快的速度建立“训练到部署”的闭环。理论细节可以后面补第一次跑通的经验才是信心的来源。5.2 应该刻意练习什么可以放心跳过什么AI工程日常要做的“刻意练习”并不是刷算法题而是反复训练一类能力把一个模型从训练开始到线上稳定运行的过程快速走通。我建议把这些环节反复练到不需要查文档写数据清洗代码并且让它可复用地处理新数据。训练一个模型把模型产物保存下来。写一个推理接口加载模型产物完成预测。用 Docker 把推理接口打包跑到服务器上。写一个脚本定时统计线上请求和预测结果。这些能力覆盖了 AI工程 80% 的日常工作。可以用来跳过的东西也不少复杂的模型并行训练、自研模型结构、完整的 Kubernetes 集群治理、大规模特征平台这些都属于“遇到需求再学”的范围提前花大量时间学性价比很低。5.3 作品集怎么攒才有说服力入门者找工作或转岗时最怕的就是简历上只有“做过几个练手项目”。我见过的有效作品集不是堆数量而是展示一条完整的工程链路。一个能打动人的AI工程项目应该包含的内容一个清晰的业务问题背景比如“电商评论里负面反馈发现率低”。明确的技术选型为什么用这个框架、这个部署方式。完整的数据处理方案包括标注规范和划分方式。训练实验的记录包括关键指标的变化。部署服务的代码仓库Dockerfile 和推理接口都在。上线后的监控方案至少说明你如何评估模型是不是在退化。把这些内容整理成 README 放在 GitHub 上并且部署一个可访问的演示服务说服力会直线上升。真实项目不需要多大完整跑通一条链路比十个没有部署的 notebook 有价值得多。5.4 初学者最常见的几个误区这些年我看了很多来咨询的新手有几个误区反复出现只看教程不写代码代码能力停留在“看得懂”阶段上来就啃深度学习论文学了一个月还不会跑通一个模型不理解数据的重要性总想跳过数据处理直接调模型不写文档也不写测试代码过一个月自己都看不懂。还有一个很隐蔽的误区以为 AI工程 就是调模型算法。实际工作中数据清洗、特征一致性、服务稳定性、监控告警占用的时间远远超出模型结构设计。谁早意识到这一点谁就早脱离“永远在入门”的状态。最后一类误区是方法论层面的老想着“等我准备好了再动手”。AI工程这个领域永远不会有完全准备好的时候工具和框架更新太快唯一的应对方式就是带着一个真实问题边做边学。每完成一个端到端的项目你的经验库就多了一个可复用的模块下一次再做类似的事情就是平移而不是从零开始。我个人做AI工程做下来最深的体会是从零起步的时候不要贪多不需要掌握所有技术只要能走通一条最小的链路后面各个模块都可以慢慢补。第一次完整地跑通数据、训练、部署、监控这四件事可能需要几周甚至两个月但一旦跑通一次后续的项目基本就是照方抓药。最初我做的那个情感分析系统非常简单它却让我真正理解了生产环境和 notebook 是两个完全不同的世界。正在从零出发的你找一个小场景把整条链路走通比看任何教程都管用。
返回列表