ARTICLE DETAIL

资讯详情

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

从预训练到RAG:LLM领域适配与部署全流程实战指南

从预训练到RAG:LLM领域适配与部署全流程实战指南 1. 先把全流程想清楚个人开发者到底需要什么1.1 从预训练到领域适配链路比想象中长说到LLM全流程实践很多人第一反应是我又不训练大模型关心预训练干嘛。其实这个理解有个误区。个人开发者真正需要的不是从头搓一个几十亿参数的底座而是搞清楚这样一条链路选什么样的预训练模型当底座、怎么用领域数据继续预训练、怎么微调对齐、怎么把领域知识注入系统、最后怎么部署上线。这个链路里每一环都有坑而且坑和坑之间还互相牵连。拿我自己踩过的经历来说。最早我在一个医疗问答场景里直接拿通用开源模型做推理效果惨不忍睹专业术语张冠李戴药品剂量直接胡编。后来我把流程补完整先做领域增量预训练再做指令微调最后加上RAG知识库兜底才算勉强能看。这个过程中我意识到个人开发者想玩转LLM不能只盯某一个环节得把全流程都想明白。这篇文章不是学术论文而是基于我真实操作过的方案写的实操记录。适合正在做LLM应用落地、想在垂直领域把模型调得更好用、或者刚入门想建立整体认知的开发者。1.2 模型选型通用底座怎么挑预训练模型的选型决定了后续几乎所有工作的成本。开源社区现在可选余地很大从几B到几十B的模型都有。个人开发者选底座我建议看三个指标中文能力、指令跟随质量、显存友好度。中文能力这块像Qwen系列、Yi系列、Baichuan系列都是经过中文预训练语料充分打磨过的直接拿来用比用纯英文模型再自己做中文适配省太多事。指令跟随质量可以看Open LLM Leaderboard这类公开榜单但要小心榜单分数高不代表你的领域表现好领域表现还得实际跑任务才知道。显存友好度则直接决定你本机能不能跑起来7B模型量化后大概需要6-8G显存13B要10-14G这个账算清楚再动手。还有一个容易被忽略的点检查模型底座的开源协议。有的模型允许商用有的只允许研究使用个人开发者如果后续想商业化这一关不过后面全是雷。我见过不止一个团队做完了整个适配流程最后发现协议不允许商用白忙一场。2. 预训练这关怎么过数据、语料与继续预训练2.1 数据清洗与去重别让语料库拖垮训练很多人一听预训练就想到千亿级token觉得是巨头才能干的事。实际上个人开发者做的是继续预训练Continue Pretraining也叫增量预训练是在通用模型基础上用领域语料再做一轮训练让模型学会领域里的表达方式和知识结构。但这轮训练的效果七成取决于数据质量。我见过太多人在数据上偷懒直接把爬来的网页扔进去训练结果模型学会了各种病句和戾气表达。数据清洗是第一个硬门槛。首先要做的是去重。领域语料里经常有大量近似重复的句子比如产品说明、法律法规条文的各种转载版本。重复数据会让训练陷入过拟合模型记住了具体句子而不是背后规律。我用过MinHash去重方案效果靠谱能把语料体积压缩20%-40%而且不会误伤真正有价值的长文本。其次是质量过滤。规则层面可以干的事很多去掉全是乱码的段落、过滤过短的碎片文本、删除URL堆积的噪声内容。再进一步可以用困惑度Perplexity过滤拿一个已有的通用模型跑一遍语料那些让模型困惑度异常高的段落往往是噪声或者非正常语言可以直接丢掉。这个思路很像用模型自己当数据质检员。最后是隐私与合规过滤。涉及个人身份信息、敏感数据的语料坚决清理。这一条既是合规底线也是技术必要——模型一旦记忆了不该记忆的东西后续想删都删不干净。2.2 增量预训练用领域语料补齐通用模型的短板领域语料准备干净之后增量预训练的目标就是让模型学说话——学会领域里的术语体系、表达风格、知识关联。具体参数设置上我的经验值是这样学习率要比正常预训练小一个数量级一般设在1e-5到3e-5之间。因为底座模型已经是一个成熟的通用模型学习率太大会把原有知识破坏掉我们只需要轻微拨动参数方向而不是推倒重来。训练步数也要克制。我做过一个法律领域项目一共只有8000万token的领域语料一开始心急跑了10个epoch损失函数虽然降了但测试集上通用能力明显退化法律问答准确率反而下降了。后来改成2个epoch效果好很多。这里有个核心直觉增量预训练是为了补充领域知识不是为了在领域语料上刷到最低loss。还有一个必须提的点混合采样。不要只喂领域语料要掺入一部分通用语料建议比例在3:7到5:5之间。目的是保持模型通用能力不退化。这就好比一个人不能只看本专业书还得看点别的书保持知识面。我习惯的做法是每个batch里70%通用语料、30%领域语料混着来。训练过程中的监控指标也要切换思路。除了loss之外更值得关注的是领域困惑度变化。用一套固定的领域评测集每隔几百步算一次困惑度看到困惑度不再明显下降就该准备收手了。2.3 Tokenizer与词表扩展的权衡增量预训练遇到的另一个实际问题领域术语被拆得七零八落。举个我印象很深的例子。在医学领域模型原本的词表把阿莫西林克拉维酸钾这个药名拆成了五六个token每个token单独看都没有医学含义模型自然学不好这个词的整体语义。中文场景更麻烦分词粒度不对语义就会飘。解决思路有两个方向。第一是扩展词表把高频领域术语加进去重新训练embedding层和LM Head层。这个方案有效但技术细节多新加的token需要从头训练且要防止词表膨胀导致推理速度下降。第二是不动词表依赖模型的subword能力靠增量预训练让模型学会把碎片token组合成有意义的语义单元。后者适合领域术语不是特别生僻的场景实现成本低我大多数项目都选了这条路。如果你确实需要扩展词表我的建议是先统计领域语料中的高频子串用BPE训练出一个候选词表只挑那些出现频率高、语义完整、切分后损失大的词加入原有词表。别贪多一次加500-2000个词就差不多了。加完之后新embedding用原模型平均向量初始化比随机初始化收敛快得多。3. 领域适配的两种主流路径微调与RAG3.1 SFT与LoRA低成本适配的核心方案增量预训练完成之后模型对领域知识有了感觉但还不会干活——不会按你需要的格式回答问题不会遵循指令。这一步需要做监督微调SFT。SFT的核心是数据。构造高质量的指令数据这是整个流程里最花时间且最考验功力的环节。我常用的构造方法有三种人工撰写标准问答对从领域文档里抽取三元组转成问答用更强的模型生成初稿再人工校对。第三种方法在2024年之后已经很主流了但要注意AI生成的数据一定要经过人工验收否则模型会学会那种空洞的口水话风格。微调方式上我强烈推荐LoRA。先说结论全参数微调在个人开发者场景下基本是灾难显存不够、容易灾难性遗忘、产出多个不同版本的大模型文件难以管理。LoRA只训练一小部分低秩适配器显存需求大幅降低训练速度快效果在绝大多数任务上与全参数微调差距很小。LoRA的秩rank设置也有讲究。秩太小拟合能力不足适配不足秩太大失去了参数高效的意义。我的经验是常规任务64-128足够复杂推理任务再往上提。还有个容易被忽视的参数alpha它控制LoRA权重的影响力。alpha和rank的比值维持在两倍左右比如rank64时alpha128效果比较稳定。SFT阶段的学习率比增量预训练再低一档用2e-5以下比较安全。损失函数关注的是response部分而不是prompt部分这一点很多框架默认做了但如果自己写训练脚本一定要注意。3.2 RAG用知识库把模型喂饱微调解决会干活的问题但还有一个关键矛盾模型的知识是训练时就固化的领域知识一更新模型不知道。这时候RAG登场。RAG的思路非常直白检索相关文档片段拼进提示词让模型基于这些材料回答。这个方案的优势在于知识可以随时更新、可以溯源、幻觉问题大幅缓解。我在部署过微调模型的场景里几乎都会再加一层RAG做兜底。这两者不是互斥关系而是互补关系。RAG落地有三个核心组件文档切分、向量化、检索策略。文档切分最讲究。切得太碎语义碎片化检索到的是没头没尾的片段切得太长一是向量检索精度下降二是塞进上下文里浪费token。我习惯用结构感知切分优先按章节、段落等文档结构切而不是死板地按固定字数切。每个块控制在300-600字左右再保留一定重叠。向量化要选对embedding模型。中文场景下开源的有BGE系列、M3E系列效果都不错。有一个细节查询query和文档document的编码方式可能不同很多embedding模型提供了query指令前缀用对了检索效果立竿见影。检索策略上基础的Top-K向量检索只是起点。实际场景中经常遇到相似语义但答案不同的文档这时候需要结合重排Rerank模型把向量检索出来的候选集重新精排。重排模型虽然多一道延迟但对于答案准确率要求高的场景值得。3.3 微调与RAG如何选型组合这是我在各种分享里被问到最多的问题做领域适配到底用微调还是RAG我的回答是先看你的需求性质。如果是需要模型改变行为模式、输出格式、语气风格比如把模型调成这个领域的客服专家口吻那微调更合适。如果是需要模型知道某些事实知识比如公司内部制度、产品文档、最新政策那RAG更合适因为这类知识变化快、有明确来源。实际上成熟的方案是微调检索组合用微调让模型学会领域表达和输出规范用RAG把最新知识和具体事实喂给模型。我在一个智能客服项目里就是这么做的底座模型做增量预训练加SFT让它成为领域通每一次问答请求时从知识库检索相关内容拼进提示词模型再给出最终答案。两者各司其职效果比单用任何一个都好。这里还要提一下GraphRAG。传统RAG把文档切成块做向量检索缺点是缺乏全局关系理解。GraphRAG在文档块之外构建实体关系图能回答一些需要跨文档推理的问题比如这个产品涉及的所有上下游组件有哪些。代价是实现复杂度高普通场景不需要一上来就上GraphRAG从标准RAG起步就够了。4. 部署与评测让模型真正用起来4.1 量化与ONNX部署的工程细节模型调试好了下一步是上线。个人开发者的算力有限部署环节做量化基本是必选项。量化最直接的理解把模型权重从FP16精度压到INT8甚至INT4换取显存占用降低和推理速度提升。经过量化后7B模型可以从14G显存占用降到6-8G很多消费级显卡就能跑起来。我用的最多的是GPTQ和AWQ这两种量化方案。两者的区别简单说GPTQ基于误差补偿思路量化后误差小AWQ基于激活值感知思路对重要性高的权重通道保留精度。实际体感上AWQ在低比特率下表现略稳GPTQ在生态支持上更成熟。如果你要部署在英伟达显卡上用vLLM量化格式上用GPTQ仍然是最稳妥的选择。ONNX部署是另一种思路适合需要跨平台运行的场景。把PyTorch模型导出为ONNX格式后可以在不同推理引擎上运行甚至可以往边缘设备上推。导出过程有几个常见坑动态轴设置不对导致输入长度受限算子在转换时不被支持直接报错。我的建议是导出的第一步先跑通onnxruntime的基本推理再逐步优化精度和速度。量化后的精度损失需要实测把控。我见到的说法是量化损失可以忽略实际并非如此尤其是在数学推理、代码生成这类对精确度敏感的任务上INT4量化后效果下降肉眼可见。稳妥起见对精度要求高的任务用INT8对资源实在不够用的场景再上INT4。4.2 LLM网关与API封装模型部署好之后工程化的下一步是封装成统一的API服务。这时候LLM网关的价值就体现出来了。LLM网关这个词听起来高大上本质就是一个模型路由层。它解决的核心问题是当你的应用可能有多个模型、多个版本、多个服务商时怎么统一接入和管理。网关可以把底层的模型地址、推理参数、负载策略都封起来上层应用只需要面对一个稳定的API接口。我自己搭过一个简单的网关主要做了几件事第一是统一鉴权所有请求走同一套API Key第二是模型路由可以按需求把请求分发到不同后端比如简单问题走小模型省钱复杂问题走大模型保质量第三是请求日志所有输入输出落日志方便后续排查和评测。框架层面LiteLLM这类开源项目可以直接参考个人开发者不用从零造轮子。还有一个务实的理由模型版本迭代时网关可以做到旧版不停、新版灰度上线。我在项目里压测新版本模型时就是通过网关把10%的流量切到新版上对比效果稳定后再全量切换。4.3 用LLM as Judge做效果评测领域模型做得好不好不能靠感觉得有评测手段。传统做法是拿人工标注的测试集跑指标但个人开发者人力有限标注200条就得累半死。LLM as Judge的思路是用一个大模型当裁判给待测模型的输出打分或做对比。这个方案省人力还能一致性复现。但直接拿来做评测会踩坑最典型的是位置偏见——当模型被要求比较多份回答时它倾向于选位置靠前或靠后的那份和内容质量无关。应对的办法有几个一是多次运行打乱顺序取多数结果二是设计更细致的评分标准要求裁判给出具体理由而不是光打分三是用GPT-4这类强模型当裁判裁判本身能力不够时评价质量也堪忧。我在实践中还会用一套混合评测方案自动化指标BLEU、ROUGE、BERTScore等做初筛LLM as Judge做大面的质量评估最后再用人工抽检关键case。三层结合才能既省力又靠谱。经常有人问哪种评测最准确答案是人工最准但贵自动化最便宜但有盲区。LLM as Judge是性价比平衡点。4.4 单元测试给LLM应用加保险最后想说一个很多人忽略的环节LLM应用的单元测试。传统软件的单元测试在LLM应用里不那么直接因为LLM的输出是概率性的同样的输入两次结果可能不一样。但正因如此才更需要测试来兜底。我在项目里会给每个Prompt模板写测试——测试正常输入能触发预期格式、测试边界输入不会崩溃、测试恶意输入不会被诱导绕过约束。这些测试不必每天全套跑但每次改Prompt、换模型版本、调推理参数时都应该跑一遍回归。我有一次改了一个Prompt措辞自测时看着没问题跑回归才发现某些追问场景下模型开始输出空内容多亏测试拦住了。LLM应用的回归测试是很多个人开发者最容易跳过、但也最容易翻车的环节。5. 实操中的坑与心得5.1 训练数据泄漏一个容易被忽视的元凶做增量预训练和SFT时我最想提醒的一个坑就是数据泄漏。什么是数据泄漏就是用于评测的测试数据混进了训练语料里导致测评分数虚高上线后实际效果打回原形。这个问题在公开数据集中很常见。很多公开中文数据集里的题目原始出处就在网上被各种文章转载过当你爬语料时很容易就把含答案的原文爬进去了。我处理过的一个项目里测试集准确率高达0.85后来一排查光测试集来源页面出现在训练语料的就占了三成去掉之后真实效果掉到0.6。防泄漏的正确姿势是提前做好文本去重匹配。训练语料构建完成后用MinHash或者SimHash把测试集里的句子和语料库做一轮比对把重复度高的样本从训练集中剔除。这个步骤耗时不多但能救你一命。5.2 灾难性遗忘模型越调越笨的真相增量预训练和SFT过程中最常遇到的问题之一就是灾难性遗忘——模型在领域数据上变强了但在通用能力上明显变弱了。我见过最惨的例子一个做金融领域适配的项目模型在金融问答上表现得非常出色但让它做个简单的数学题或者回答常识问题就开始胡说八道了。这意味着模型不再是通用的智能体只变成了一个领域复读机。应对策略有三个层次一是混合训练数据通用语料和领域语料掺着用二是控制训练步数和学习率不要过度拟合领域数据三是用LoRA这类参数高效方法训练只更新低秩参数对原有参数的破坏小很多。我现在的项目都优先选LoRA一个重要的原因就是它的抗遗忘能力明显比全参数微调好。5.3 上下文长度与成本一个现实约束随着模型支持上下文越来越长很多开发者倾向于什么资料都往上下文里塞。结果就是每轮请求都在烧钱烧算力推理延迟也在上涨效果却不一定更好。实际工程里一个原则是检索到的内容要精不要多。RAG的设计目标就是把最相关的内容送进上下文而不是把所有候选都塞进去。我在系统里常常会对检索结果做两层筛选第一层用向量检索召回Top 50第二层用规则或重排模型精选Top 3-5最终塞进上下文的内容控制在1000-2000个token以内。还有一个细节是token消耗的估算。中文场景下一个汉字大致对应1.5-2个token每次请求的prompt加上输出乘以调用频率就是你的成本。上生产环境之前这个成本模型要算清楚不然业务跑起来账单会吓你一跳。5.4 最后分享一个小技巧评测集要动态更新项目上线不代表评测工作结束。我最开始固定了一套静态评测集用着用着发现过拟合了——模型在这套评测集上的分数已经判断不出它是否进步。后来我养成了一个习惯每两周从真实线上日志里找20-30条新问题人工标注好答案后加入评测集。这样评测集始终保持一定的新鲜度模型的真实水平波动也能及时暴露出来。这个做法听起来很简单但它是我整个LLM全流程实践中最有价值的一个习惯。
返回列表