ARTICLE DETAIL

资讯详情

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

AI Engineering从零到实战:打通机器学习、RAG与LLM应用完整链路

AI Engineering从零到实战:打通机器学习、RAG与LLM应用完整链路 1. 先搞清楚AI Engineering 到底是个什么方向这几年“AI engineering”这个词被反复提起但很多人其实没弄明白它跟机器学习工程师、算法工程师、数据科学家到底有什么区别。我自己带过几个从传统后端转过来的同事也面试过不少自称“搞 AI”的候选人最深的感触是AI engineering 不是“会跑通一个模型”就完事的它更接近一条完整的工程链路——从数据整理、模型选型、训练调优到服务封装、性能压测、成本控制再到线上监控和迭代更新每一个环节都需要工程师自己扛下来。换句话说AI engineering from scratch 的意思是你不依赖别人已经帮你封装好的全流程平台而是从零开始自己动手把一个 AI 应用从 idea 做成可用的产品。这条路适合谁适合有软件开发基础、想切入 AI 领域的人也适合已经在做数据分析或算法、但总觉得“模型一上线就各种翻车”的人。它解决的问题很具体你知道模型怎么训练但你知道模型上线后怎么稳定跑三个月吗你知道数据集怎么构建但你知道数据分布变化会让准确率一夜之间掉 20% 吗下面我会结合自己从零折腾到能独立交付 AI 项目的完整经历把 AI engineering 的核心模块、实操路线和踩坑实录一次讲清楚。内容会比较长但每一步都是能直接照着做的。2. 从零开始的完整能力地图2.1 先把基础语言和工具链打牢不管目标多高Python 这一关绕不开。AI 生态里绝大多数库、框架、工具都以 Python 为第一语言虽然理论上可以用 C、Java 或者 Go 来部署模型但做实验、写训练脚本、处理数据、调接口几乎全部是 Python 的活。我见过太多人一上来就啃 Transformer 论文结果连DataLoader的collate_fn参数都搞不明白这种学习路径效率极低。基础阶段的重点不是刷语法题而是围绕数据科学和 AI 常用的几个库建立手感NumPy张量和矩阵运算的基础理解形状、广播、索引是底线。Pandas表格数据处理清洗、聚合、分组、透视表都要熟练。Matplotlib / Seaborn画图分析数据的分布和趋势不用多精美但要能快速排查数据问题。Scikit-learn经典机器学习算法、评估指标、交叉验证、特征工程的工具箱是理解深度学习之前最好的“玩具”。这个阶段最容易犯的错是陷入“教程地狱”——今天看 NumPy 教程明天又去看 Pandas 教程一周下来好像学了很多实际一个完整流程都跑不通。我的建议是直接做一个端到端的小项目比如用 Scikit-learn 对一份公开数据集做分类预测从加载数据、清洗、画分布图、训练模型、评估效果全部走一遍。跑通一个闭环比看十遍教程都管用。2.2 机器学习核心概念不能跳过很多人觉得现在大模型时代了经典机器学习可以不用学了这是很大的误区。且不说很多实际业务场景里XGBoost 或者逻辑回归依然是最稳定、成本最低的方案更重要的是机器学习的核心概念是理解深度学习和 AI 系统的基石。必须吃透几个关键点过拟合与欠拟合模型在训练集上表现好但验证集掉分这就是过拟合。正则化、Dropout、早停、数据增强都是围绕这个问题来的。训练集 / 验证集 / 测试集的划分逻辑为什么不能拿测试集调参因为信息泄漏会让评估结果虚高上线后就露馅。交叉验证的意义小数据集上怎么稳定评估模型效果K-Fold 是怎么工作的。偏差与方差权衡模型的误差来源到底是欠拟合还是过拟合决定了你下一步应该加数据还是加复杂度。损失函数与优化器回归用 MSE 还是 MAE分类用交叉熵不同任务怎么选梯度下降的变体为什么存在。这些概念不是理论考试而是工程判断的依据。举个最简单的例子你训练一个模型发现验证集损失先降后升训练集损失还在降如果你不懂早停和过拟合你就不知道应该保存哪个时间点的权重也就无法做出一个真正能用的模型。2.3 深度学习框架怎么选框架选型是很多人纠结的问题。我的结论很直接新手首选 PyTorch没有之一。原因有三点第一PyTorch 的调试体验是动态计算图print一个张量的形状、打断点、逐步执行都非常自然这对初学者理解神经网络的运行过程极其重要。第二目前学术界和工业界发布预训练模型几乎都首选 PyTorch 权重格式Hugging Face 上的模型绝大多数都是 PyTorch 的你用别的框架会平白多出很多格式转换的麻烦。第三社区生态最活跃遇到问题搜一下基本都能找到答案。TensorFlow 和 PaddlePaddle 不是不好但在通用 AI 工程领域PyTorch 已经事实上成了默认选择。你如果是为了做业务应用而非特殊硬件适配选 PyTorch 是最稳妥的。这个阶段要动手实现的东西包括手写一个简单的全连接网络跑 MNIST、用nn.Module搭建一个 CNN 做图像分类、用 LSTM 或者 Transformer 结构跑一个文本分类任务。不用追求 SOTA 效果重点是理解forward和backward的过程、Dataset和DataLoader怎么写、模型权重怎么保存和加载。2.4 LLM 时代的工程新范式经典的深度学习路线走完后要进入当前 AI engineering 的核心战场大语言模型LLM的应用工程。这部分跟上面说的传统 ML 工程有重叠但更多是新的模式和新的工具链。需要掌握的内容包括Prompt Engineering提示词工程怎么写指令、怎么给示例few-shot、怎么设计角色和约束条件让模型输出更可控。上下文管理与 Token 计算输入输出都按 token 计费怎么截断、怎么分段、怎么控制长度上限。RAG检索增强生成把私域知识库接进大模型解决模型不知道最新信息或内部数据的问题。模型微调Fine-tuning什么时候该用 RAG什么时候该微调什么时候两者结合。工具调用Function Calling / Tool Use让模型调用外部 API、查询数据库、执行代码这是 Agent 应用的基础。向量数据库Embedding 的存储和近似最近邻搜索是 RAG 链路的核心依赖。评估与监控LLM 的输出没有固定答案怎么评估质量怎么捕捉模型退化。从“训练模型”到“编排模型”这是 AI Engineering 和传统 ML 工程最大的区别。传统 ML 是你训练一个模型然后部署一个 APILLM 工程更像是你手里有一个非常强但不太听话的“实习生”你的工作是设计一套流程、工具和约束让他稳定高效地完成具体任务。3. 核心实践项目拆解3.1 环境搭建的完整指南环境问题是最劝退新手的第一道坎。我见过有人在 Windows 上装 PyTorch 折腾一整天最后发现是 CUDA 版本和显卡驱动不匹配。这里先给一套稳妥的搭建方案。建议直接用 Miniconda 管理 Python 环境不要在自己系统全局环境里乱装包。创建一个独立的虚拟环境conda create -n ai-env python3.10 conda activate ai-env然后安装深度学习框架。如果你有 NVIDIA 显卡先确认驱动支持的 CUDA 版本然后用conda或pip安装对应版本的 PyTorch。官方安装命令生成页面会给你现成的命令别再手动去下载 CUDA Toolkit 了PyTorch 的 pip 包里自带 CUDA 运行时你只需要驱动足够新就行。# 以 CUDA 12.1 为例 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121没有独立显卡也没关系CPU 版本照样可以学习和跑小型项目只是训练速度慢一些。我早期就是拿笔记本 CPU 跑完了一个文本分类模型分词、训练、评估全流程一点没耽误。接着安装 AI 应用开发的核心依赖pip install transformers datasets accelerate sentencepiece pip install langchain chromadb pip install flask fastapi uvicorntransformers是 Hugging Face 的核心库负责加载预训练模型和 tokenizerdatasets是统一的数据集接口accelerate用来做分布式训练的设备管理langchain负责 LLM 应用编排chromadb是本地的向量数据库适合个人项目起步fastapi用来把模型封装成 HTTP 服务。提示环境问题八成出在没有用虚拟环境或者没有固定版本号。每次新建项目都建议先conda create并在项目里写一个requirements.txt把关键包版本锁住不然三个月后重跑大概率复现不了。3.2 从一个真实的 RAG 问答系统开始我强烈建议第一个完整项目不要做图像、不要做语音做一个基于 RAG 的知识库问答系统。为什么选它因为它几乎覆盖了 AI engineering 的全部核心环节数据加载与清洗、文本切分、Embedding 模型选型、向量库构建、Prompt 设计、LLM 调用、服务封装、效果评估。而且它能直接解决真实问题——把自己的文档、笔记、合同、帮助中心变成问答机器人做完就有实用价值。系统架构很简单离线阶段把文档拆成小块每块文本用 Embedding 模型转成向量存入向量数据库在线阶段用户提问把问题转成向量在向量库里做相似度检索取回最相关的文本块连同问题一起拼进 Prompt交给 LLM 生成回答。我用一个具体例子来说明整条链路。假设你有一批 PDF 格式的公司制度文档要做一个内部问答机器人。第一步加载和解析文档。langchain提供了PyPDFLoader可以直接读取 PDF但要注意扫描版 PDF 没有文本层需要 OCR这是第一个容易踩的坑。我建议先用pypdf快速检测文本是否能提取不行再上 OCR 方案。from langchain_community.document_loaders import PyPDFLoader loader PyPDFLoader(./company_policy.pdf) documents loader.load() # 每页会返回一个 Document 对象包含 page_content 和 metadata第二步文本切分是 RAG 效果好坏的关键。LLM 的上下文窗口有限向量检索的粒度也影响召回质量。切太粗一个块里混了多个主题检索时噪音大切太细语义不完整模型上下文不够。我常用的策略是先用RecursiveCharacterTextSplitter以 500 到 800 个字符为一个块重叠 50 到 100 个字符from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter RecursiveCharacterTextSplitter( chunk_size600, chunk_overlap100, separators[\n\n, \n, 。, , , , , , ] ) chunks text_splitter.split_documents(documents)separators这个参数很容易被忽略它的含义是切分时的优先级顺序。按段落先切不行按句号切再不行按逗号。中文场景里默认的英文分句符并不适用必须把中英文标点都加进去否则切出来的块经常断在半句话上。第三步Embedding 模型选型。中文场景下我推荐用BAAI/bge-large-zh-v1.5或者shibing624/text2vec-base-chinese。直接用 OpenAI 的 embedding 接口也可以但要考虑数据出境和成本内网场景基本都是本地部署开源模型。加载 bge 模型的方式from langchain_community.embeddings import HuggingFaceBgeEmbeddings embeddings HuggingFaceBgeEmbeddings( model_nameBAAI/bge-large-zh-v1.5, encode_kwargs{normalize_embeddings: True} )注意normalize_embeddings开启后向量是归一化的后续用内积和余弦相似度结果等价。很多教程不强调这一点导致你比对相似度分数时总觉得不对劲。第四步构建向量库并写入。用 ChromaDB 起步最方便它支持本地持久化不需要单独跑服务from langchain.vectorstores import Chroma vectorstore Chroma.from_documents( documentschunks, embeddingembeddings, persist_directory./chroma_db )每次跑完向量数据会存在chroma_db目录下下次直接加载不需要重新 embedding。第五步设计检索策略。最简单的是直接similarity_search取 top-k但实际项目里我强烈建议做两件事一是把k值调大一点比如 6 到 8 个块让 LLM 有更多素材可用二是对召回的块加一个相关性过滤设置相似度阈值低于阈值的块直接丢弃宁可少答也不要拿错误信息硬编。docs vectorstore.similarity_search_with_score(query, k8) filtered_docs [(doc, score) for doc, score in docs if score 0.35]这个 0.35 的阈值不是拍脑袋是我在多个数据集上跑了交叉验证之后得到的经验值。不同 embedding 模型的分数分布不一样你需要先拿几十条真实问题做测试看正确答案的分数下限在哪再设阈值。这一步是 RAG 效果优化的关键很多人忽略导致模型经常拿着不相关的文本一本正经胡说八道。第六步编排生成。用langchain的RetrievalQA链可以快速搭起来但实际生产里我更建议自己写 Prompt 模板这样可控性最强from langchain.prompts import PromptTemplate template 基于以下已知信息简洁准确地回答用户的问题。 如果已知信息中没有明确答案请明确说根据现有资料无法回答不要编造。 已知信息 {context} 用户问题{question} 回答 prompt PromptTemplate( templatetemplate, input_variables[context, question] )然后组装完整的问答函数from langchain.llms import OpenAI from langchain.chains import RetrievalQA llm OpenAI(model_namegpt-3.5-turbo, temperature0) qa_chain RetrievalQA.from_chain_type( llmllm, chain_typestuff, retrievervectorstore.as_retriever(search_kwargs{k: 6}), return_source_documentsTrue, chain_type_kwargs{prompt: prompt} ) result qa_chain({query: 公司年假制度是什么}) print(result[result]) print(参考文档, [doc.metadata for doc in result[source_documents]])return_source_documentsTrue这一步很重要。它让你可以在回答下方展示“基于哪几份文档生成的”既增加用户信任感也方便你自己排查回答是来自可靠资料还是模型幻觉。3.3 什么时候该微调什么时候只做 RAG这是 AI 工程里被问得最多的一个问题。我的判断标准很朴素如果你的核心诉求是“让模型知道某个特定领域的知识”首选 RAG如果你的核心诉求是“让模型按某种固定风格、格式、行为模式输出”微调更合适更多时候两者是组合关系。举个例子。如果你想做一个“懂你家公司所有产品手册”的客服机器人知识是持续更新的产品手册每个月都会变你用 RAG 最合适——改文档、跑切分、更新向量库就完事了连模型都不用动。但如果你要做一个“把客户工单自动分类成 12 个优先级并且输出固定 JSON 格式”的系统这种任务的输入输出模式高度固定few-shot 不一定稳定那就值得做一次微调。微调的门槛比 RAG 高不少。你需要准备几百到几千条高质量的训练样本做数据格式转换、训练超参调优、效果评估还要考虑算力成本。用 Hugging Face 的transformers和peft库做 LoRA 微调是当前的主流方案因为 LoRA 只训练一小部分参数显存和训练时间都大幅下降。一个典型的 LoRA 微调脚本核心流程是加载基座模型和 tokenizer → 用LoraConfig配置低秩矩阵参数 → 加载训练数据集 → 用Seq2SeqTrainer训练 → 保存并合并权重。这里不展开完整代码但我想强调三个实操细节。第一基座模型的选择要考虑中文能力。Qwen、Yi、Baichuan这些中文语料占比较高的模型是更务实的选择。第二训练数据格式必须统一最常用的格式是instruction、input、output三段式指令、输入、期望输出都要写清楚。第三微调完成后一定要拿训练时没见过的测试集验证我见过不少人微调完在训练集上效果惊艳一上测试集就暴露过拟合原因就是数据量太少或者学习率设置过高。3.4 把模型封装成可用的 API 服务模型跑通只是第一步给业务方用才是工程真正的开始。现在最主流的方案是用 FastAPI 封装配合uvicorn启动 HTTP 服务。一个最简服务的结构from fastapi import FastAPI, HTTPException from pydantic import BaseModel app FastAPI() class QueryRequest(BaseModel): question: str top_k: int 6 app.post(/qa) async def qa_endpoint(request: QueryRequest): try: result qa_chain({ query: request.question, top_k: request.top_k }) return { answer: result[result], sources: [doc.metadata for doc in result[source_documents]] } except Exception as e: raise HTTPException(status_code500, detailstr(e))服务上线前必须考虑三个问题并发量、超时时间、错误隔离。LLM 接口推理耗时通常是几秒到几十秒如果用同步方式跑并发一高 CPU 和显存直接被打满。实际工程里要用线程池或者异步任务队列把推理放到后台执行前端轮询结果。更重的场景要上消息队列加 Worker 的架构。显存管理也是一个隐藏坑。Hugging Face 的pipeline默认会在显存里常驻模型多个服务进程各加载一份权重显存会成倍消耗。解决方案是用模型共享或者做成常驻单例模型只在进程启动时加载一次请求进来只做推理不做重复加载。4. 实操中的高频问题与排查技巧4.1 环境与依赖问题速查环境问题占了新手阶段 80% 的报错时间。我把最常见的几种情况和排查思路整理成一张表现象可能原因排查方向CUDA out of memory批量大小太大 / 输入序列太长减小 batch size、缩短 max_length、用梯度累积No module named torch装到了错误的环境which python确认当前环境再重新安装模型下载卡住网络问题导致 Hugging Face 下载失败配置HF_ENDPOINT镜像或手动下载后放到缓存目录tokenizer加载中文乱码编码格式问题确认文件是 UTF-8 编码检查encoding参数训练损失不下降学习率不合适 / 数据有大量噪音先跑通 100 条小样本再逐步放大提示遇到报错先把完整报错信息贴到搜索引擎里绝大多数问题都有人踩过。不要自己瞎改一通我在调参上浪费的时间至少有一半是因为没耐心读报错信息。4.2 数据质量与效果评估的隐形陷阱AI 工程里有一句老话垃圾进垃圾出。模型效果不好很多时候问题根本不在模型而在数据。最常见的坑是数据泄漏。比如你做时间序列预测不小心把未来的数据放进了训练集那验证集效果会好得离谱上线后立刻失效。再比如做文本分类同一篇文章的多个片段被切成了训练集和测试集等于模型考试时偷看了答案。第二个坑是类别不均衡。二分类任务里正样本占 95%负样本占 5%你全预测成正样本就有 95% 准确率但业务上毫无价值。这时候要改用 F1 score、AUC 这些对不均衡更敏感的指标或者做重采样。LLM 应用的效果评估更麻烦。传统 ML 可以用准确率、F1 来量化但 LLM 生成的文本没有标准答案。我的做法是建立一套多维度人工评估集准备 20 到 50 条有代表性的测试问题标注好“好的回答应该包含哪些要点”每次改动 Prompt、换模型、调检索参数都拿这套集子跑一遍人工打分。虽然费时间但这是唯一能持续追踪效果的办法。后来我也用过 LLM-as-a-Judge 的方式让 GPT-4 给自家模型的回答打分把“参考回答”和“模型回答”一并投给裁判模型用它的结论做初步筛选。这个方案能省不少人工但要注意裁判模型本身也会有偏好和幻觉最终还是要人来复核关键样本。4.3 线上效果和线下效果对不上这是最让人头疼的问题。你在评测集上 F1 刷到 0.9上线后用户反馈一塌糊涂。原因通常集中在几个方面。第一线下数据分布和线上不一致。你是拿 2023 年的数据训的模型线上来的全是 2024 年的新文本术语、表达方式都有变化效果自然会掉。解法是建立线上数据回流机制定期采样线上真实请求补充到评测集里。第二线上输入的类型你没见过。比如你只训练了短文本分类用户却传上来一篇几千字的文章模型的输入截断策略不同效果就变了。要在服务层对输入长度、格式、语言做防御性校验。第三延迟和并发导致超时用户等不到结果就当系统坏了。这不是模型效果问题却比模型问题更影响口碑。压测手段要提前做我用locust或者wrk做并发压测确认服务的 QPS 上限和响应时间分布。4.4 成本控制的实用技巧LLM 应用上线后成本是必须算的账。我见过创业团队把 API 调用日志打出来发现一个月花了几万块大部分是无效请求和重复请求。成本控制有几个立竿见影的做法加缓存。同样的用户问题在 Redis 里按问题内容的哈希值做一层缓存重复问题直接返回历史答案能省掉很大比例的大模型调用。减少 Prompt 长度。Context 越长 token 越多费用越高。检索来的文本块不是越多越好控制在能回答问题的范围内。用小模型。简单任务用 7B 甚至更小的开源模型本地部署每 token 成本几乎为零只有复杂推理才调用大模型。设置调用限流和告警。单个用户每秒请求数限制、每个请求的 token 上限、月度费用告警都要配上。我做过一个真实的成本对比一个知识库问答系统全部用 API 调用日均 1 万次问答按 2000 token 一次算一个月费用大概在几千到上万元换成本地部署 7B 模型 RAG 架构推理走 GPU 服务器一次性的硬件成本平摊下来跑同样量级的请求月度成本可以降到原来的五分之一甚至更低。当然本地部署要牺牲一部分效果和灵活性这就是工程上的取舍。5. 学习路线与资源规划建议5.1 主线学习资源怎么选网上 AI 学习资料多到爆炸但真正值得看的没那么多。我按阶段整理一套主线资源避免你在信息的海洋里淹死。阶段核心资源用法Python 与数据基础《利用 Python 进行数据分析》当作工具书遇到不会的查不用从头通读机器学习基础吴恩达《Machine Learning》课程 西瓜书课程建立直觉西瓜书补充数学推导深度学习PyTorch 官方 60 分钟入门 《动手学深度学习》边看边敲代码务必跑完所有实践章节Transformer 与 LLM《The Annotated Transformer》 Hugging Face 官方教程逐行理解注意力机制再学会用现成模型RAG 与 LLM 应用LangChain 官方文档 几个真实项目源码看文档不如跑项目跑通再拆解官方示例的写法书不用多关键是每本都要吃透。我个人最推荐的国产教材是李沐老师的《动手学深度学习》它最大的优点是代码和理论完全对应每一章都有可以直接运行的 Jupyter Notebook非常适合工程向学习者的节奏。5.2 项目驱动的学习节奏设计学习 AI 工程最忌讳的就是只学不练。我的建议是把学习周期分成三个项目驱动的阶段每个阶段都有可见的产出。第一个项目是做经典机器学习全流程。用 Kaggle 的 Titanic 或者 House Prices 数据集做特征工程、模型训练、交叉验证、提交结果。这个项目让你把数据科学的完整流程走通也能让你体会到特征工程的重要性。第二个项目是做计算机视觉或者 NLP 的深度学习。比如用 PyTorch 训练一个 CNN 做图像分类或者微调一个 BERT 做中文情感分析。这个阶段要重点关注数据加载的写法、训练的循环、模型的保存和加载、推理的封装。做完你就掌握了深度学习工程的基本套路。第三个项目就是前面说的 RAG 问答系统。做成一个完整的产品有数据上传、有向量检索、有流式输出、有历史记录、有服务日志。这一步做完你已经具备了一个初级 AI 工程师解决真实问题的能力。5.3 持续进阶的方向AI 工程这个领域变化极快三个月不看新东西就会被甩下。但我不建议每天刷几十条资讯制造焦虑更有效的方式是跟踪几个关键信号主流大模型的测评榜和发布说明了解当前能力边界在哪里。Hugging Face 的 Trending 页面看社区在集中做什么方向。自己维护一个“每周动手做一个小实验”的习惯比如这周研究 Function Calling下周研究多模态输入再下周研究流式输出。每次实验产出一篇笔记三个月后你会发现自己已经建立起一片属于自己的知识体系。参与开源项目从给文档补注释、修 bug、补测试用例开始。这不仅能提升代码能力也能认识一批同路人。我个人经验里进步最快的阶段不是看书最多的阶段而是被真实需求逼着解决问题的阶段。所以当你学完基础后一定要尽快找一个真实场景——哪怕是帮朋友做一个会议纪要总结工具、帮社群做一个入门资料问答机器人——把技术放进真实约束里去打磨。6. 最后说几句实在话根据我个人的体会AI Engineering from Scratch 这条路最难的不是某个技术点而是耐心的分配。很多人容易在前期沉迷调参刷榜却在“把模型变成服务”这种脏活累活上失去耐心。但恰恰是后者决定了你在真实团队里值多少钱。最后再分享一个小技巧无论你做什么 AI 项目从一开始就要养成写实验记录的习惯。模型版本、数据集版本、Prompt 版本、超参数、当时的效果指标全部记下来。没有实验记录的项目三个月后大概率是灾难——你会发现自己调过的参数全忘了复现不了效果也没有办法向别人说明“为什么这个方案可行”。养成这个习惯比多看十篇教程都重要。
返回列表