资讯动态

DeepSeek与Qwen3大模型LoRA微调实战:从数据到vLLM部署全记录

发布时间:2026/10/22 10:17:46 来源:尧图企业网站定制
最近刚帮朋友把一个实际业务场景的大模型微调项目完整跑通模型选的是 DeepSeek 和 Qwen3从准备数据到 LoRA 微调再到 vLLM 部署上线的全链路都走了一遍。这套流程现在确实已经很成熟工具链也顺手但真正上手时很多新手还是会卡在数据格式、训练参数和部署细节上。这篇就是我实操过程的完整记录包括命令、参数解释、部署方案和踩过的坑给打算做同样事情的朋友一个参考。先说清楚这篇文章解决什么问题如果你有一个垂直场景比如客服问答、公文写作、合同抽取希望用开源大模型做定制化微调同时考虑效果、成本和部署难度那么这篇文章可以帮你绕过大部分弯路。我会用两个模型做案例一个是 DeepSeek 系列中的蒸馏模型一个是 Qwen3让不同硬件条件下的读者都能找到适合自己的方案。1. 微调前先别急选型比训练更重要1.1 用RAG还是微调先回答三个问题我见过太多人一上来就微调结果训完发现不如检索增强生成RAG效果好白烧了一堆显卡时间。微调不是万能药在动手之前一定要先回答清楚三个问题第一你的知识更新频率高不高如果说的是单一静态知识库比如一个产品手册用 RAG 就能解决微调反而会把新知识“固化”在参数里后续更新成本极高。第二你的任务是否改变模型的“说话方式”比如你需要模型始终用某种称呼、某种格式、某种情绪输出那这就是风格和指令遵循问题微调非常擅长。第三你需要的是“学会知识”还是“学会行为”知识型需求优先考虑 RAG行为型需求才更适合微调。在我的案例里业务方要求模型在面对售后场景时不能顺着用户乱说必须严格按照规定的回答框架输出同时要对产品细节保持一定的上下文理解能力。这种“遵守框架”的行为约束用 RAG 很难精确做到于是才决定做微调。1.2 模型选型DeepSeek与Qwen3怎么选这里说的 DeepSeek 主要指目前开源生态里常用的 R1-Distill 系列Qwen3 则指阿里的 Qwen3 开源系列。两者都适合做微调但各有偏向。从我的实际体验来看Qwen3 系列在中文指令理解、代码生成和对 JSON 等结构化输出的支持上都很稳社区生态也大遇到问题容易搜到答案。DeepSeek-R1-Distill 系列的强项是继承了推理风格适合做数学题、逻辑推理和需要“思考过程”的场景但如果你微调的目标是业务问答它有时会输出过长的“内心独白”反而影响体验。选型可以参考这张表。对比维度DeepSeek-R1-DistillQwen3中文能力优秀推理风格明显优秀指令跟随更自然多轮对话容易带思考痕迹更符合业务对话习惯结构化输出一般需要强约束较好支持函数调用/JSON微调生态和Qwen同源较多兼容最成熟资料多适合场景推理、数学、分析客服、写作、业务系统实际项目里如果业务偏“逻辑推理加决策”比如金融分析助手可以考虑 DeepSeek-R1-Distill 作为底模如果业务偏“对话交互加内容生成”比如售后客服、文档写作Qwen3 会更省心。我的两个案例正好各选一个后面分别讲。1.3 算力预估显存是关键约束算力决定了你能用什么规模、什么方式微调。很多朋友以为微调一定需要多卡集群其实用 LoRA 方法单卡也能跑。经验值大概是这样的7B~9B 级别的模型在 16-bit 精度下做 LoRA 微调需要约 20~26GB 显存如果开启 8bit 量化加载可以压到 14~18GB用 4bit 量化甚至可以降到 8~12GB但训练会慢一些精度也可能略受影响。我的配置是单张 RTX 4090 24GB 显卡所以两个案例都选择的 7B~8B 模型。如果你的显存只有 16GB建议用 Qwen3-4B 或者 8bit 量化方案如果只有 12GBQwen3-4B 配合 4bit 加载也能勉强跑起来。不要一上来就想着微调 70B 参数先从小模型打通全流程收益会快得多。2. DeepSeek微调实战从数据到LoRA训练选型确定后我开始跑第一个完整案例用 DeepSeek-R1-Distill-Qwen-7B 做售后客服场景微调。整套流程用的是 LLaMA-Factory它对 DeepSeek 和 Qwen 的兼容性都很不错基本不用改源码。2.1 环境搭建首先是环境。我用的服务器是 Ubuntu 22.04显卡驱动已装好CUDA 用的是 12.1PyTorch 2.1 以上都能支持。建议新建一个独立的 conda 环境避免和系统 Python 环境互相污染。conda create -n llm python3.10 -y conda activate llm pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 pip install llama-factory[torch2.1]安装完成后可以用llamafactory-cli version验证是否成功。这里要提醒一句不要用pip install llama-factory裸装一定要带[torch]或者显式安装 PyTorch否则后续会报版本冲突。2.2 数据格式一句话最简最有效微调数据的格式是最容易出错的地方但也是最值得花时间的地方。LLaMA-Factory 的标准 alpaca 格式长这样[ { instruction: 你是某品牌售后客服请根据知识库内容回答用户问题。, input: 我上周买的手机屏幕出现绿线可以维修吗, output: 您好很抱歉给您带来不便。您的设备在保修期内可以凭购买凭证到官方售后网点免费检测维修。请您先尝试备份数据避免维修过程中丢失。 } ]如果你只有多轮对话数据也可以用 sharegpt 格式[ { conversations: [ {from: human, value: 你们售后网点在哪}, {from: assistant, value: 请问您所在的城市是哪个地区我帮您查询最近的官方网点。}, {from: human, value: 我在杭州西湖区。}, {from: assistant, value: 西湖区文三路某大厦一楼有官方售后服务中心营业时间是周一至周日9:00-18:00。} ] } ]我的经验是单轮固定风格问答用 alpaca 格式就够需要模拟真实多轮会话用 sharegpt 格式。数据量不需要太夸张我用了 5000 条高质量语料效果已经比用 5 万条重复噪声数据要好得多。提示数据清洗这一步不要省略。我清洗时做了三件事一是剔除包含内部联系方式的内容二是把所有回复里的“可能”“大概”这类模糊词统一改成确定的表述三是保证每条输入都和目标场景一致不要混入无关闲聊。2.3 训练参数LoRA参数不是越大越好微调 DeepSeek-R1-Distill 时我用的是 LoRA 方案。LoRA 的核心思想是冻结原始模型参数只训练一部分低秩矩阵这样显存占用小训练速度快召回时也能随时切换回原模型防止灾难性遗忘。我的训练配置文件如下model_name_or_path: deepseek-ai/DeepSeek-R1-Distill-Qwen-7B template: deepseek stage: sft finetuning_type: lora lora_rank: 64 lora_alpha: 128 lora_target: all dataset: customer_service cutoff_len: 2048 per_device_train_batch_size: 2 gradient_accumulation_steps: 8 learning_rate: 2.0e-4 num_train_epochs: 3.0 lr_scheduler_type: cosine warmup_ratio: 0.1 bf16: true gradient_checkpointing: true logging_steps: 10 save_steps: 500 output_dir: outputs/deepseek_cs_lora这里解释几个关键参数lora_rank: 64表示低秩矩阵的秩秩越大能容纳的信息越多但显存也会更高。对 7B 模型来说64 是个比较平衡的值。lora_alpha: 128是缩放系数决定微调后权重的影响幅度一般设置为 rank 的 1~2 倍。lora_target: all表示对所有线性层都注入 LoRA实际操作效果通常比只注入 Q/K/V 层更好尤其适合风格迁移类任务。cutoff_len是输入文本的最大长度我设置为 2048因为售后场景最长对话也不会超过这个长度。如果设成 4096训练时间和显存都会大幅增加。2.4 开始训练先跑100步再全量第一次训练时我建议不要直接跑完整命令而是先跑一小部分验证数据流。llamafactory-cli train config.yaml如果训练正常终端会出现类似loss: 2.30这样的指标。我发现正常衰减节奏大概是这样刚开始 loss 在 1.8~2.5 之间2 个 epoch 后会降到 1.2 以下。如果 loss 完全不动大概率是数据格式有问题或者学习率太高导致梯度消失。训练过程中可以通过 TensorBoard 监控tensorboard --logdir outputs/deepseek_cs_lora训练完之后LoRA 权重会单独保存原始模型权重不变。这个设计非常好用我可以在多个 LoRA 之间切换、合并也能随时回滚到前一个版本。3. Qwen3微调与部署另一个完整案例Qwen3 与 DeepSeek-R1-Distill 在代码上高度相近但有几个细节需要注意。第二个案例我用 Qwen3-8B 做公文写作场景微调训练流程虽然类似但踩了一些模板和部署的坑。3.1 与DeepSeek的差异模板与Chat TemplateQwen3 的对话模板和 DeepSeek 不同。表面上都是system user assistant但内部的处理函数会决定是否输出“思考环节”。如果直接用 DeepSeek 的模板去训练 Qwen3轻则回复格式错乱重则模型直接输出一堆乱码。LLaMA-Factory 对各模型的template做了内置映射例如qwen3模板会自动加上相应标记。训练前可以用一个简单的测试脚本验证llamafactory-cli chat --model_name_or_path Qwen/Qwen3-8B --template qwen3先跟原始模型聊几句确认它能听话回答再开始微调。这一步能排除数据、模板、显存之外的基础环境问题。3.2 数据设计让模型学会“结论先行”公文写作场景里不需要模型有太强的推理但要求格式规范、用词稳重。我给 Qwen3 设计的数据格式和 DeepSeek 案例类似但 output 部分加入了明确结构{ instruction: 请根据以下会议纪要生成正式会议通知。, input: 时间本周五下午2点地点三号会议室议题项目验收准备参会人各部门负责人。, output: 关于召开项目验收准备会议的通知\n\n各部门负责人\n定于本周五下午2点在三号会议室召开项目验收准备会议请相关人员准时参加。\n\n特此通知。 }这里关键不是内容多复杂而是每个 output 都严格保持同样的版式。微调的本质是让模型在参数里记住这种“条件反射”式风格所以数据一致性比文本多样性更重要。3.3 训练过程同样的LoRA不同的教训训练配置与 DeepSeek 案例基本一致只是把template改为qwen3学习率我稍微调低到1.5e-4。为什么Qwen3 对学习率更敏感第一次我用2e-4训练到第二个 epoch 时模型出现了明显的重复文本现象降低学习率后很快恢复。训练命令llamafactory-cli train qwen3_config.yaml这里记录一个参数调优思路如果模型在只跑 100 步时已经出现过拟合在验证集上 loss 上升优先降低lora_rank或者增加数据量而不是动学习率。数据量和模型参数规模之间需要匹配对于 5~8B 模型2000~5000 条高质量样本通常够用过多反而容易过拟合。3.4 部署vLLM和Ollama两种方式都试过Qwen3 微调完成后我用了两种部署方案。方案一直接用 vLLM 启动 OpenAI 兼容 API。vLLM 对 Qwen3 支持很好显存利用率高吞吐量大适合线上服务。python -m vllm.entrypoints.openai.api_server \ --model outputs/qwen3_doc_lora/merged \ --served-model-name qwen3-doc \ --tensor-parallel-size 1 \ --max-model-len 8192 \ --port 8000调用方式和你调 OpenAI 接口一样curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d {model: qwen3-doc, messages: [{role: user, content: 写一个项目启动会通知}]}方案二本地轻量调试用 Ollama。先把 LoRA 权重合并到原模型转换成 GGUF 格式再编写一个 ModelfileFROM ./qwen3-doc-merged.gguf TEMPLATE {{- if .System }}system {{ .System }} {{- end }} user {{ .Prompt }} assistant {{ .Response }} PARAMETER temperature 0.3然后执行ollama create qwen3-doc -f Modelfile ollama run qwen3-doc我的实测结论是vLLM 适合正式环境QPS 高Ollama 适合个人电脑快速验证不折腾显存优化。做项目优先 vLLM。4. 评估、量化与效果调优微调完不等于能上线。我每次微调后都会做一轮系统评估避免模型“看似聪明实则完全偏离业务”。4.1 评估方法别只看LossLoss 下降只代表模型在训练集上学会了拟合不代表业务表现好。我的习惯是把数据按 8:2 分成训练集和验证集再用验证集和一份完全没见过的测试集分别评估。评估指标分两块客观指标BLEU、ROUGE、准确率、JSON 解析成功率。比如售后场景我会重点看回复中关键产品词是否准确。主观指标找三个不同背景的人对 50 条典型输入打分合理性、礼貌程度、格式正确度。这是最直接的手段。我在 Qwen3 案例里还额外验证了“负面防护”故意用偏离业务的输入测试模型是否乱答。比如问“你会写简历吗”理想回复应该是“我是公文助手只处理公文相关需求”。如果模型开始大谈简历模板说明数据里缺乏拒答样本需要补充“不在职责范围”的语料。4.2 过拟合与灾难性遗忘LoRA 虽然不容易灾难性遗忘但如果 LoRA 权重占比过大、训练轮次过多模型仍然会逐渐偏向新数据丢掉通用能力。我的调整建议出现验证集 loss 上升、训练集 loss 继续下降立即减少num_train_epochs到 2 或 1。出现生成文本只围绕训练数据复读降低lora_alpha或lora_rank。如果业务场景多样性高考虑准备 5%~10% 的通用数据混入训练集可以有效缓解遗忘问题。结合 DeepSeek 案例我发现同一个 LoRA 参数在不同底模上的表现差异很大。DeepSeek-R1-Distill 更耐“大力出奇迹”但 Qwen3 反而更适合轻量微调。所以参数不是抄来的是试出来的。4.3 量化部署牺牲多少精度换速度部署阶段往往是性能瓶颈。7B 模型 fp16 裸跑需要约 16GB 显存很多服务器扛不住。量化是常见解法但能接受的精度损失有限。我用llamafactory-cli export将 LoRA 权重合并到模型权重再用 GGUF 或者 AWQ 格式量化。经验值如下量化方式显存占用8B模型推理速度效果损失FP16约16~18GB快无INT8约9~10GB更快极低INT4约5~6GB更快可感知慎用如果业务要求高我会用 INT8 作为线上默认如果机器只有 16GB 显存INT4 也能接受但需要在测试集上跑一遍关键场景确认没有出现明显“胡说”。5. 避坑清单我实际遇到的5个问题最后总结一下这段时间遇到的典型问题每一条都是我亲手踩过的直接对标排查方向。5.1 显存溢出OOM最常出现在准备微调时候。我的对策是per_device_train_batch_size从 4 降到 2gradient_accumulation_steps从 4 升到 8开启gradient_checkpointing。这三步能把显存需求降低 30%~40%。如果还不够只能换更小的模型或者启用量化加载。5.2 Loss 一直不下降先看数据格式是否被正确解析。用llamafactory-cli自带的 dataset 测试接口打印几条训练样本确认 instruction、output 没有串位。其次检查学习率3e-4以上对大多数 7B 模型来说偏高容易震荡。还有一点容易被忽略cutoff_len设置太长、数据里的输出被截断loss 也会异常。5.3 部署后输出和训练时候差很远这个坑我栽过一次。训练好之后用llamafactory-cli对话效果很好但部署到 vLLM 后输出风格明显不对。排查半天发现是 Chat Template 没有自动加载。vLLM 需要从模型目录读取tokenizer_config.json中模板如果你的模型是手动合并的一定要确认模板文件完整或者部署时显式指定--chat-template。5.4 模型复读机一旦生成内容反复循环第一反应是降低温度到 0.2~0.3。如果降低后仍然复读一般是微调数据里存在大量重复句式模型形成了惯性。我会检查训练集中同质化样本的数量合并相似样本后重新训练。5.5 中文标点与格式错乱LoRA 微调后有概率改变原始模型的输出格式偏好。我的解决办法是在数据清洗时统一把所有标点转为全角并在每个 output 末尾强制换行符这能显著降低标点混乱的问题。如果是结构化成 JSON我会先让 ChatGPT 或规则引擎把数据整理成严格的 JSON 字符串再喂给模型。6. 我个人实操中的最后一点体会两个案例跑下来我的最大感受是微调的难点往往不在模型本身而在你对业务问题的拆解深度。选 RAG 还是微调选 DeepSeek 还是 Qwen3选 LoRA 还是全参每个决策背后都要对得起具体场景。把数据做干净、把模板对齐、把显存算清楚比堆一堆高大上的多卡集群更有价值。如果你现在正准备做类似的事情我的建议是先拿 300 条数据、1 张 24GB 显卡、1 个晚上跑通最小闭环。模型选 Qwen3-8B 或 DeepSeek-R1-Distill-7B工具直接用 LLaMA-Factory别自己从头写训练脚本。跑通之后再慢慢加数据、调参数、上部署。这样你能在最短时间内看到真实效果也能更快判断这个方案到底适不适合你的业务。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑