课题组私有AI实战:国产开源模型选型、RAG与LoRA微调部署全流程 1. 为什么课题组需要一个私有AI1.1 通用大模型的三个硬伤课题组用通用大模型做科研辅助用久了会发现三个绕不开的问题。第一是领域知识缺失你问它一个材料合成里的具体参数比如某种前驱体在特定温度下的分解行为它要么给一个泛泛的教科书答案要么直接编一个看起来很像真的数值。第二是数据安全顾虑课题组未发表的实验数据、专利草稿、基金申请书这些东西不可能往公网接口上贴。第三是成本与稳定性高频调用按token计费一个学期下来账单不小而且网络波动、服务限流都会打断工作流。私有AI要解决的就是这三件事把领域知识灌进去、把数据留在本地、把调用成本压到接近零。听起来像是一个很大的工程但拆开来看无非是四个环节——选模型、建知识库、做微调、搞部署。每个环节都有成熟的国产开源方案一个人花两三周就能跑通全流程。1.2 私有AI的能力边界在哪里先把预期摆正。私有AI不是要造一个超越通用大模型的东西它的定位是领域专家助手。通用模型像一个知识面很广但不懂你课题的本科生私有AI要做的是把这个本科生培养成熟悉你课题组研究方向、记得住你们组历史论文和实验记录的研究生。它能做的事基于课题组积累的文献和文档回答问题、辅助撰写论文的文献综述部分、根据历史实验记录给出参数建议、帮新入组的同学快速了解组内技术积累。它做不了的事替代实验设计、保证生成内容的绝对准确性、处理需要实时外部信息的任务。注意私有AI的输出永远需要人工复核尤其是涉及具体数值和实验方案的部分。把它当成一个记忆力极好但偶尔会自信地胡说八道的助手。1.3 整体技术路线概览整个流程可以拆成五步后面每个章节会展开讲模型选型从国产开源模型里挑一个基座考虑参数量、中文能力、许可证、社区活跃度。知识库构建把课题组的PDF、Word、Markdown、实验记录整理成结构化语料做切分和向量化。RAG检索增强让模型在回答前先检索知识库把相关片段作为上下文喂进去。微调用LoRA/QLoRA在领域语料上做轻量微调让模型学会课题组的表达习惯和领域术语。量化与部署用GPTQ或AWQ压缩模型用vLLM做高并发推理服务。这五步不是必须全做。如果课题组文档量不大、问题以检索为主只做RAG就够了。如果发现模型对领域术语的理解总是跑偏再上微调。量化部署是最后一步目的是让模型跑在有限的GPU上还能支撑多人同时用。2. 国产开源模型选型不追最大只选最合适2.1 选型的四个维度选基座模型不是越大越好。课题组通常只有一两张消费级显卡或者一张专业卡参数量直接决定了你能不能跑起来。我一般从四个维度打分维度说明权重参数量与显存匹配7B模型FP16约需14GB显存4bit量化后约4GB高中文能力中文语料占比、中文benchmark表现高许可证是否允许商用、是否允许二次分发中社区生态微调教程、量化版本、部署工具支持中参数量这块给个粗略的参考7B模型4bit量化后推理显存占用大约4到5GB加上KV Cache和框架开销一张12GB的卡能跑得比较舒服。14B模型4bit量化后约8到9GB24GB卡可以。32B以上就需要多卡或者专业卡了。2.2 几个值得考虑的国产基座Qwen系列是目前中文开源模型里生态最完整的。Qwen2.5的7B和14B版本在中文理解、指令遵循上表现稳定社区有大量LoRA微调教程和量化版本Hugging Face上直接能搜到GPTQ和AWQ的预量化权重。许可证是Apache 2.0的变体对学术用途没有限制。GLM系列的中文能力也很强尤其是对中文长文本的处理。ChatGLM3-6B是一个经典的轻量选择显存需求低适合起步阶段。不过社区微调资源相比Qwen少一些。Baichuan系列在中文医疗、法律等垂直领域有专门的微调版本如果课题组方向正好匹配可以省不少事。但通用能力上略逊于前两者。InternLM系列的书生·浦语在学术圈口碑不错提供了从1.8B到20B的多个尺寸方便根据显存梯度选择。它的微调工具链XTuner做得比较完善。我的建议是首选Qwen2.5-7B-Instruct作为起步基座。理由很简单——中文够好、显存够低、社区资源够多、量化版本够全。等跑通全流程之后如果觉得能力不够再换14B或者32B。2.3 选型时容易踩的坑第一个坑是只看benchmark不看实际表现。有些模型在C-Eval上分数很高但实际对话时指令遵循很差你让它输出JSON它给你输出一段散文。选型时一定要自己拿几个课题组真实问题去测。第二个坑是忽略tokenizer的中文效率。不同模型对中文的token化效率差别很大同样一段中文有的模型切成100个token有的切成150个。这直接影响推理速度和上下文窗口的实际可用长度。Qwen的中文tokenizer效率在国产模型里属于第一梯队。第三个坑是没注意模型的上下文窗口。RAG场景下你需要把检索到的多个文档片段塞进上下文如果模型只支持4K上下文实际能用的知识片段非常有限。现在主流模型都支持32K甚至128K选型时至少要求32K。实操心得下载模型之前先算一笔账。模型权重文件大小约等于参数量乘以精度字节数。7B模型FP16约14GB4bit量化约3.5GB。再算上推理时的KV Cache7B模型32K上下文大约需要2到4GB额外显存。把这些加起来对比你手头的显卡显存就知道能不能跑。3. 领域语料构建知识库的地基3.1 课题组有哪些可用的语料课题组的语料来源比想象中多但散落在各种地方。我一般按优先级整理已发表论文的PDF组里历年发表的论文这是质量最高的语料结构清晰、术语准确。学位论文师兄师姐的硕博论文通常有详细的文献综述和实验方法描述信息密度极高。实验记录本电子版的实验记录包含大量具体参数和操作细节但格式可能很乱。组会PPT和文档技术路线图、阶段性总结适合提取研究思路。代码仓库的README和注释如果课题组有自研工具这些文档能帮助模型理解组内技术栈。外部文献领域内的经典论文和综述可以作为补充知识。语料不是越多越好。我见过有人把整个arXiv上相关领域的论文全爬下来结果知识库里充斥着重复和低质内容检索效果反而变差。质量比数量重要先把手头组内的高质量文档整理好通常几十到几百篇就够用了。3.2 文档解析与清洗的实操细节PDF解析是第一个拦路虎。学术论文的PDF有双栏排版、公式、图表、参考文献直接提取文本会得到一堆乱序内容。我试过几个工具PyMuPDF速度快对双栏排版有一定处理能力但公式和表格会丢失结构。pdfplumber对表格提取比较好但速度慢。Marker基于深度学习的PDF转Markdown工具效果最好能把公式转成LaTeX、表格转成Markdown但需要GPU加速。MinerU国产的PDF解析工具对中文论文支持好输出Markdown格式适合学术文档。我的流程是先用Marker或MinerU把PDF转成Markdown然后人工抽查几篇确认公式和表格没有严重错乱。如果发现某类文档解析质量差就单独处理或者直接跳过。清洗环节要做的事去掉页眉页脚、去掉参考文献列表除非你希望模型能引用文献、合并被切断的段落、统一标点符号。这些用正则表达式就能搞定大部分。import re def clean_markdown(text): # 去掉页眉页脚常见的页码模式 text re.sub(r\n\s*\d\s*\n, \n, text) # 去掉连续的空白行 text re.sub(r\n{3,}, \n\n, text) # 统一中文标点 text text.replace(,, ).replace(;, ) return text.strip()3.3 文本切分策略不是越碎越好切分是RAG里最容易被忽视但影响最大的环节。切得太碎每个片段缺乏完整语义检索出来答非所问切得太粗一个片段里混了好几个主题模型抓不住重点。我常用的策略是按语义结构切分而不是简单地按固定字数切。具体做法优先按Markdown标题切分每个二级或三级标题下的内容作为一个候选片段。如果某个片段超过800字再按段落切分保证每个片段在300到800字之间。片段之间保留10%到20%的重叠避免关键信息正好落在切分边界上。每个片段前面加上来源信息论文标题、章节名这样检索时模型能知道这段话的出处。from langchain.text_splitter import MarkdownHeaderTextSplitter headers_to_split_on [ (#, 标题1), (##, 标题2), (###, 标题3), ] splitter MarkdownHeaderTextSplitter( headers_to_split_onheaders_to_split_on, strip_headersFalse ) chunks splitter.split_text(markdown_text)对于实验记录这种没有明显结构的文档可以按时间戳或者实验编号切分。关键是保持语义完整性让每个片段读起来是一个完整的意思。注意切分后的片段一定要人工抽查。我遇到过按标题切分后某个片段只有标题没有内容或者表格被切成了两半。这些脏数据会严重拖累检索质量。3.4 向量化模型的选择切分好的文本需要转成向量才能做语义检索。向量化模型的选择要考虑三点中文效果、维度大小、推理速度。BGE系列是国产向量化模型里综合表现最好的。BGE-M3支持多语言、多粒度输出1024维向量在中文检索任务上表现优秀。M3E系列也是不错的选择维度更低768维速度快一些。GTE系列在长文本检索上有优势。如果课题组有GPU可以用本地向量化模型数据不出内网。如果没有也可以用API但要注意数据安全。我的建议是本地跑BGE-M3一张消费级显卡就能支撑向量化几百篇文档也就几分钟的事。向量数据库的选择上Chroma适合小规模快速起步Milvus适合大规模生产环境Qdrant在过滤检索上比较灵活。课题组场景下Chroma或Qdrant就够用了。4. RAG检索增强让模型先查再答4.1 RAG到底解决了什么问题RAG的核心思路很简单模型在回答问题之前先去知识库里检索相关内容把检索结果作为上下文一起送给模型。这样模型不需要把知识记在参数里而是每次现查现用。这解决了微调的一个根本问题——知识更新。微调是把知识写进模型权重更新一次要重新训练成本高。RAG是把知识放在外部数据库更新知识只需要更新数据库模型本身不用动。对于课题组这种知识在不断积累的场景RAG是更灵活的方案。但RAG也不是万能的。它的瓶颈在于检索质量。如果检索出来的片段和问题不相关模型再强也答不好。所以RAG优化的核心是提升检索的命中率。4.2 检索策略从朴素到进阶最朴素的RAG是向量相似度检索把问题转成向量在向量数据库里找最相似的Top-K个片段。这个方法简单但对复杂问题效果一般。进阶策略有几种混合检索同时做向量检索和关键词检索BM25把两路结果融合。向量检索擅长语义匹配关键词检索擅长精确匹配。比如你问XX材料的带隙是多少关键词检索能精确找到包含带隙和材料名的片段向量检索能补充语义相关的片段。重排序先用向量检索召回Top-20个候选片段再用一个重排序模型如BGE-Reranker对这20个片段做精细打分选出Top-5送给模型。重排序模型比向量检索慢但精度高很多。这个两步走的策略在实践中效果提升明显。查询改写用户的问题可能表述不清晰或者用了和文档不同的术语。可以用一个小模型先把问题改写成更适合检索的形式或者生成多个查询变体分别检索再合并结果。from langchain.retrievers import EnsembleRetriever from langchain_community.retrievers import BM25Retriever from langchain_community.vectorstores import Chroma # 向量检索器 vector_retriever Chroma(...).as_retriever(search_kwargs{k: 10}) # BM25关键词检索器 bm25_retriever BM25Retriever.from_documents(chunks, k10) # 混合检索 ensemble_retriever EnsembleRetriever( retrievers[vector_retriever, bm25_retriever], weights[0.6, 0.4] )4.3 提升RAG命中率的几个技巧片段元数据增强每个片段除了文本内容还存一些元数据比如来源文档、章节标题、发表年份。检索时可以按元数据过滤比如只检索近三年的文献。也可以在片段文本前面拼接元数据让向量化时把这些信息也编码进去。父子片段策略检索时用小的片段比如200字做匹配命中后返回它所属的大的父片段比如1000字给模型。这样既保证了检索精度又保证了上下文完整性。问题类型路由不同的问题需要不同的检索策略。事实型问题XX的熔点是多少适合精确检索综述型问题XX领域有哪些主要方法适合多片段聚合。可以用一个分类器先判断问题类型再选择对应的检索参数。实操心得RAG调优是一个迭代过程。我一般会准备一个测试集包含20到50个课题组真实问题每个问题标注好正确答案所在的文档片段。每次调整检索策略后跑一遍测试集看命中率Hit Rate和MRRMean Reciprocal Rank的变化。没有测试集的调优就是盲调。4.4 RAG的常见瓶颈与应对瓶颈一知识库里没有答案。模型检索不到相关内容就会用自己的参数知识回答可能产生幻觉。应对方法是让模型在检索结果相关性低于阈值时明确说知识库中没有找到相关信息而不是强行回答。瓶颈二检索到多个矛盾片段。不同论文对同一问题的描述可能不一致。应对方法是在prompt里要求模型标注信息来源并指出存在的矛盾。瓶颈三长文档检索效果差。一本书或者一篇长综述切分后片段很多检索时容易漏掉关键信息。应对方法是做层次化检索先检索到相关章节再在章节内做细粒度检索。瓶颈四多跳问题。有些问题需要综合多个片段的信息才能回答比如对比A方法和B方法在XX任务上的表现。单次检索可能只召回了A方法的信息。应对方法是做多轮检索第一轮检索后让模型判断是否需要补充检索需要的话生成新的查询再检索一轮。5. LoRA与QLoRA微调让模型学会说行话5.1 什么时候需要微调RAG能解决知识检索的问题但解决不了风格和术语的问题。如果你发现模型回答时总是用通用表达不懂课题组的特定缩写或者输出格式总是不符合组内规范那就需要考虑微调了。微调不是必须的。我的建议是先把RAG跑通用一段时间收集模型表现不好的案例。如果发现问题是知识缺失优先补知识库如果发现问题是表达风格不对再上微调。5.2 LoRA的原理为什么它有效LoRALow-Rank Adaptation的核心思想是微调时不动原始模型权重而是在每一层旁边加一个小型的低秩矩阵只训练这个小矩阵。原始模型权重冻结梯度只更新新增的小矩阵。为什么这样有效因为微调时模型需要学习的增量通常是一个低秩变化。也就是说从通用模型到领域模型的变化不需要改动全部参数只需要在少数方向上调整就够了。LoRA把这个低秩假设显式地建模出来用两个小矩阵A和B的乘积来近似权重更新。这样做的好处很直接可训练参数从几十亿降到几百万。7B模型的LoRA微调可训练参数通常只有几百万到几千万一张消费级显卡就能跑。训练完的LoRA权重文件只有几十MB方便分享和切换。5.3 QLoRA在更小的显存上微调QLoRA是在LoRA基础上进一步压缩显存。它把原始模型权重量化到4bit然后在上面加LoRA适配器。这样7B模型的显存占用从14GB降到4GB左右一张12GB的卡就能微调7B模型。QLoRA的关键技术是NF4量化和双重量化。NF4是一种针对正态分布权重优化的4bit格式比普通的4bit量化精度更高。双重量化是对量化常数再做一次量化进一步节省显存。代价是训练速度会慢一些因为每次前向传播都要反量化。但对于课题组场景慢一点不是问题能跑起来才是关键。5.4 微调数据集的构建微调数据集的质量直接决定微调效果。数据集格式通常是指令-回答对{ instruction: 请解释XX材料在YY条件下的相变机制, input: , output: XX材料在YY条件下会发生从A相到B相的转变主要驱动力是... }数据来源可以是课题组论文的摘要和引言把论文的核心内容改写成问答对。组会问答记录把师兄师姐回答问题的内容整理成指令-回答对。实验记录把实验目的和实验结论整理成问答对。人工构造针对模型表现不好的问题人工写标准答案。数据量不需要很大。对于LoRA微调500到2000条高质量数据通常就能看到明显效果。关键是质量每条数据都要准确、格式规范、风格一致。注意微调数据里不要包含敏感信息比如未发表的实验数据、专利申请中的技术细节。如果必须用做好脱敏处理。5.5 LoRA微调的实操参数用LLaMA-Factory或者XTuner这类工具微调7B模型的典型配置参数推荐值说明LoRA rank8-32越大容量越强但容易过拟合LoRA alpha16-64通常设为rank的2倍学习率1e-4到2e-4LoRA的学习率比全量微调大batch size4-8受显存限制可用梯度累积训练轮数3-5多了容易过拟合截断长度1024-2048根据数据长度调整# LLaMA-Factory 微调示例 llamafactory-cli train \ --model_name_or_path Qwen/Qwen2.5-7B-Instruct \ --stage sft \ --do_train \ --dataset my_dataset \ --template qwen \ --finetuning_type lora \ --lora_rank 16 \ --lora_alpha 32 \ --output_dir ./output \ --per_device_train_batch_size 4 \ --gradient_accumulation_steps 4 \ --learning_rate 1e-4 \ --num_train_epochs 3 \ --lr_scheduler_type cosine \ --warmup_ratio 0.1 \ --logging_steps 10 \ --save_steps 100 \ --bf16 true训练过程中要盯着loss曲线。如果训练loss持续下降但验证loss开始上升说明过拟合了需要减少训练轮数或者降低rank。如果loss一直不降可能是学习率太小或者数据格式有问题。5.6 微调后的效果评估微调完不能只看loss要做实际测试。我一般从三个维度评估领域术语理解问一些包含课题组特定术语的问题看模型是否能正确理解。比如组内对某个材料的简称、某个实验方法的缩写。输出风格看模型的回答是否符合课题组的表达习惯。比如论文里常用的结果表明值得注意的是这类表达。通用能力保持微调后模型不能变成只会回答领域问题的偏科生。要测试一些通用问题确保基础能力没有严重退化。如果发现通用能力退化明显说明微调过度了需要降低学习率或者减少训练数据中领域数据的比例。6. 知识蒸馏让小模型继承大模型的能力6.1 蒸馏在课题组场景下的价值课题组通常没有大显存设备但你又希望模型能力尽可能强。知识蒸馏提供了一个思路用一个大的教师模型比如Qwen2.5-72B或者GPT-4级别的模型生成高质量的回答然后用这些回答去微调一个小模型比如Qwen2.5-1.5B或7B。蒸馏的本质是用大模型的计算换小模型的部署成本。教师模型只在数据生成阶段用一次之后部署的是小模型推理成本大幅降低。6.2 蒸馏数据的生成流程蒸馏数据生成分三步准备问题集从课题组语料里提取问题或者人工构造覆盖领域知识点的问题。问题要多样化覆盖事实型、解释型、对比型等不同类型。教师模型生成回答把问题送给教师模型让它生成详细、准确的回答。可以加一些约束比如要求引用来源、要求分点作答。质量过滤对教师模型的回答做质量检查去掉明显错误、重复、格式不规范的数据。# 蒸馏数据生成示意 import openai def generate_distill_data(questions, teacher_modelgpt-4): dataset [] for q in questions: response openai.ChatCompletion.create( modelteacher_model, messages[ {role: system, content: 你是一个科研助手请用准确、专业的语言回答问题并标注信息来源。}, {role: user, content: q} ], temperature0.7 ) answer response.choices[0].message.content dataset.append({instruction: q, output: answer}) return dataset6.3 蒸馏的注意事项教师模型的选择教师模型的能力上限决定了学生模型的上限。如果教师模型在领域知识上就不行蒸馏出来的学生模型也好不到哪去。可以先用RAG增强教师模型让它基于知识库生成回答再蒸馏给学生。数据多样性如果问题集太单一学生模型会过拟合到特定类型的问题。要确保问题覆盖领域内的各个子方向难度也要有梯度。蒸馏与微调的结合蒸馏数据可以直接用于LoRA微调也可以和人工标注的数据混合使用。我通常会把蒸馏数据和人工数据按7:3的比例混合既保证数据量又保证质量。实操心得蒸馏数据生成后一定要人工抽查至少50条。我遇到过教师模型在某个细分领域持续给出错误答案的情况如果不检查这些错误会被学生模型全盘继承。7. GPTQ与AWQ量化把模型塞进小显存7.1 量化的基本原理量化是把模型权重从高精度FP1616位压缩到低精度INT44位的过程。7B模型FP16需要14GB显存INT4只需要3.5GB压缩了4倍。量化的核心挑战是精度损失。简单的四舍五入量化会让模型效果明显下降。好的量化方法会分析权重的分布对重要的权重保留更高精度对不重要的权重做更激进的压缩。7.2 GPTQ与AWQ的对比GPTQ是一种训练后量化方法它逐层量化权重用校准数据来最小化量化误差。GPTQ的优点是压缩率高、推理速度快缺点是量化过程需要校准数据且对某些模型可能效果不稳定。AWQActivation-aware Weight Quantization的核心洞察是不是所有权重都同等重要应该根据激活值的大小来保护重要权重。AWQ在量化时会识别出对模型输出影响大的权重通道对它们保留更高精度。实测下来AWQ在相同压缩率下通常比GPTQ精度略好尤其是对指令遵循能力保持得更好。对比项GPTQAWQ压缩率4bit/3bit4bit精度保持好略好推理速度快快校准数据需求需要需要社区支持广泛广泛适合场景通用指令模型7.3 量化的实操流程用AutoGPTQ或AutoAWQ库可以几行代码完成量化from awq import AutoAWQForCausalLM from transformers import AutoTokenizer model_path Qwen/Qwen2.5-7B-Instruct quant_path ./qwen-7b-awq model AutoAWQForCausalLM.from_pretrained(model_path) tokenizer AutoTokenizer.from_pretrained(model_path) quant_config {zero_point: True, q_group_size: 128, w_bit: 4, version: GEMM} model.quantize(tokenizer, quant_configquant_config) model.save_quantized(quant_path) tokenizer.save_pretrained(quant_path)量化完成后一定要做效果对比。我一般用同一组测试问题分别跑原始模型和量化模型对比回答质量。如果发现量化后模型在某个类型的问题上表现明显下降可能需要调整量化参数或者换一种量化方法。7.4 量化后的效果验证量化不是无损的。4bit量化通常会有1%到3%的效果下降具体取决于模型和任务。验证时重点关注指令遵循模型是否还能正确理解并执行指令。领域知识量化后领域知识的保持程度。输出稳定性多次运行同一问题输出是否一致。长文本处理量化对长上下文的影响。如果量化后效果下降太多可以考虑混合精度量化对关键层保留8bit其他层用4bit。或者用更小的分组大小group size从128降到64精度会好一些但模型体积会增大。8. vLLM高并发推理让全组人都能用上8.1 为什么需要vLLM课题组有十几个人如果每个人都直接加载模型推理显存根本不够。vLLM解决的就是多用户共享一个模型实例的问题。vLLM的核心技术是PagedAttention它把KV Cache分成固定大小的块来管理像操作系统管理内存页一样。这样做的好处是显存利用率大幅提升可以同时处理多个请求吞吐量比朴素实现高几倍到几十倍。8.2 vLLM的部署配置vLLM的部署很简单一条命令就能起服务python -m vllm.entrypoints.openai.api_server \ --model ./qwen-7b-awq \ --quantization awq \ --dtype float16 \ --max-model-len 8192 \ --gpu-memory-utilization 0.9 \ --port 8000 \ --host 0.0.0.0关键参数说明--max-model-len最大上下文长度根据显存和需求设置。设太大浪费显存设太小不够用。--gpu-memory-utilizationGPU显存使用率上限0.9表示用90%的显存。留一点余量给系统。--quantization量化方法和模型量化格式对应。--tensor-parallel-size多卡并行时设置单卡不用管。起好服务后它兼容OpenAI的API格式可以直接用openai库调用from openai import OpenAI client OpenAI(base_urlhttp://localhost:8000/v1, api_keydummy) response client.chat.completions.create( modelqwen-7b-awq, messages[{role: user, content: 解释一下XX材料的合成方法}], temperature0.7, max_tokens1024 )8.3 并发性能调优vLLM的默认配置不一定适合所有场景。几个调优方向批处理大小vLLM会自动做连续批处理但你可以通过--max-num-seqs控制同时处理的最大请求数。设太小吞吐量上不去设太大显存不够。KV Cache管理--block-size控制KV Cache的块大小默认16。调大可以减少块管理开销但可能浪费显存。调度策略vLLM支持多种调度策略默认是FCFS先来先服务。如果有些请求需要优先处理可以配置优先级调度。实测下来一张24GB的卡跑7B AWQ量化模型8K上下文同时处理10到20个并发请求没有问题。响应时间在可接受范围内。8.4 与RAG系统的集成vLLM提供的是模型推理服务RAG的检索逻辑需要在应用层实现。典型的集成架构是用户在前端提问。后端接收问题调用检索模块向量数据库重排序获取相关片段。把问题和检索结果拼成prompt调用vLLM的API。vLLM返回生成结果后端处理后返回给前端。def rag_query(question, retriever, llm_client): # 检索 docs retriever.invoke(question) context \n\n.join([d.page_content for d in docs]) # 构造prompt prompt f基于以下参考资料回答问题。如果资料中没有相关信息请明确说明。 参考资料 {context} 问题{question} 回答 # 调用vLLM response llm_client.chat.completions.create( modelqwen-7b-awq, messages[{role: user, content: prompt}], temperature0.3 ) return response.choices[0].message.content注意RAG的检索和生成是两个独立环节可以分别优化。检索慢就优化向量数据库索引生成慢就优化vLLM配置。不要混在一起调。9. 常见问题与排查技巧实录9.1 模型加载与显存问题问题模型加载时报CUDA out of memory排查思路先算模型权重大小7B FP16约14GB4bit约3.5GB。再看KV Cache需求8K上下文7B模型约需1到2GB。加上框架开销1到2GB。如果显存不够优先用量化版本其次减小max-model-len最后考虑换更小的模型。问题vLLM启动后显存占用比预期高vLLM会预分配显存--gpu-memory-utilization 0.9意味着它会占用90%的显存。这是正常行为不是内存泄漏。如果希望留更多显存给其他程序把这个值调低。9.2 RAG检索效果差问题检索出来的片段和问题不相关排查步骤先检查切分是否合理片段是否太碎或太粗。再检查向量化模型是否适合中文。然后看检索参数Top-K是否太小。最后考虑加BM25混合检索和重排序。问题知识库明明有答案但检索不到可能是表述差异导致的。用户问XX的合成温度文档里写的是制备XX时采用的加热条件。向量检索对这种语义匹配有时会失效。解决办法是加关键词检索或者用查询改写把用户问题改写成更接近文档表述的形式。9.3 微调效果不理想问题微调后模型输出格式不对检查训练数据的格式是否统一。如果训练数据里回答格式五花八门模型学不到一致的格式。另外检查prompt template是否和训练时一致。问题微调后模型通用能力下降严重这是过拟合的典型表现。降低学习率、减少训练轮数、降低LoRA rank、增加通用数据在训练集中的比例都能缓解。问题微调后模型在领域问题上仍然答错可能是训练数据覆盖不够。检查训练数据是否覆盖了模型答错的那类问题。如果训练数据里没有类似问题模型自然学不会。9.4 量化后效果下降问题4bit量化后模型回答质量明显变差先确认量化方法是否适合该模型。有些模型对GPTQ敏感换AWQ试试。如果还不行用更小的group size64或32或者对关键层保留8bit。问题量化模型推理速度反而变慢检查是否用了正确的推理后端。AWQ模型要用支持AWQ的推理框架GPTQ模型要用支持GPTQ的框架。用错了后端会走反量化路径速度反而慢。9.5 常见问题速查表问题现象可能原因排查方向模型加载OOM显存不足用量化、减小上下文、换小模型检索结果不相关切分/向量化/检索参数检查切分粒度、换向量模型、加混合检索微调后格式乱训练数据格式不统一统一数据格式、检查prompt template微调后通用能力降过拟合降学习率、减轮数、加通用数据量化后质量降量化损失换量化方法、减小group size、混合精度vLLM并发低配置不当调max-num-seqs、检查GPU利用率回答有幻觉检索没命中加相关性阈值、让模型说不知道实操心得排查问题时先隔离变量。比如RAG效果差先单独测检索模块看检索出来的片段对不对。如果检索没问题再测生成模块。不要一上来就同时调检索和生成那样根本不知道是哪个环节的问题。10. 从零到一的落地路线建议10.1 分阶段实施路线不要试图一次把所有环节都做完。我建议分三个阶段第一阶段1周跑通RAG。选Qwen2.5-7B-Instruct用Chroma做向量库BGE-M3做向量化LangChain串联流程。目标是能基于课题组文档回答问题。第二阶段1到2周加微调。收集500到1000条领域问答数据用LLaMA-Factory做LoRA微调。目标是让模型学会课题组的术语和表达风格。第三阶段1周量化部署。用AWQ量化模型vLLM起服务写一个简单的Web界面或者接入现有的聊天工具。目标是全组人都能用上。10.2 硬件配置建议阶段最低配置推荐配置RAG开发16GB内存CPU32GB内存一张12GB显卡LoRA微调一张12GB显卡一张24GB显卡量化部署一张12GB显卡一张24GB显卡全流程一张24GB显卡一张48GB显卡如果课题组没有GPU可以用CPU做RAG向量化用CPU版模型生成用API但微调和本地部署就必须有GPU了。10.3 团队协作与知识管理私有AI建好之后要建立维护机制。知识库需要定期更新新发表的论文、新的实验记录要及时入库。微调数据也要持续积累把模型答不好的案例收集起来人工写好答案后加入训练集。建议指定一个人负责知识库维护一个人负责模型迭代。其他人使用过程中发现问题反馈给维护人员。这样形成一个持续改进的循环。最后分享一个小技巧在RAG的prompt里加一句如果参考资料不足以回答问题请明确说根据现有资料无法回答不要编造。这一句话能大幅减少幻觉实测有效。