【学习笔记】SFT微调实战:LoRA / QLoRA / 全参微调对比(7/35)
上一篇我们看了预训练这件上层精英玩的事。从这一篇开始我们进入大多数 AI 工程师真正会亲自上手的领域——SFTSupervised Fine-Tuning监督微调。预训练造就了一个通才大脑但它有两个问题只会接话不会对话——Base 模型听到你好可能回一段你好的英文是 hello...而不是你好请问有什么可以帮您不懂你的业务——它不知道你公司的客服流程、API 规范、术语表SFT 就是解决这两件事的关键工程动作。如果你做过相关工作下面这些问题应该不陌生用 LoRA 微调效果比全参差多少什么时候必须上全参单卡 24GB 显存能不能微调 70B 模型训练数据要多少10 条够吗1 万条微调后模型忘了原来的能力怎么办LoRA 训完一堆能不能像插件一样动态切换读完本文你将能选对微调方法全参 / LoRA / QLoRA / 哪个估算微调一个 N B 模型的资源需求上手运行一个完整的 QLoRA 训练脚本避免 5 个最常见的微调坑决策是否需要 SFT——很多时候 RAG 或 Prompt 就够我们开始。一、SFT 在 LLM 工程栈中的位置1.1 Base → Chat从「会接话」到「会对话」回忆第 1 篇我们画的全链路预训练 (Base) → SFT (Instruct) → 对齐 (DPO/RLHF) → 可用模型每个阶段干一件事Base 模型知道语言是什么。喂今天天气会接很好或者如何SFT (Instruct) 模型知道指令是什么。喂总结这段话会给出总结而不是接话对齐模型知道什么回答更好。会拒绝有害请求、更礼貌、更有用HuggingFace 上模型名常见后缀后缀含义-Base/ 无后缀仅做了预训练-Instruct/-Chat/-SFT做过 SFT-DPO/-RLHF/-Aligned做过对齐生产环境用模型至少要 Instruct 版本——Base 模型直接上线就是个灾难。1.2 工程师做 SFT 的常见场景场景目标典型数据量垂直领域适配法律/医疗/金融术语认知1-10 万条业务规则注入客服回复风格、产品 FAQ5K-5 万条格式约束强制 JSON 输出、特定模板1K-1 万条Tool Use 训练教模型用特定工具几千-几万条代码助手内部代码风格、私有 API1 万私有数据吸收让模型记住知识看场景注意第 6 个场景——让模型记住知识——这是新手最容易踩的坑。SFT 不擅长让模型学新知识只擅长让模型学新格式/风格。需要让模型知道某些信息应该用 RAG。1.3 SFT vs RAG vs Prompt三选一的决策这是一个被无数团队踩坑后才搞清楚的决策矩阵需求推荐理由输出格式特定JSON / XMLPrompt → SFTPrompt 不够稳定上 SFT让模型用特定语气/风格SFTPrompt 难以稳定给模型注入新知识RAGSFT 学知识效率低、易遗忘模型理解新术语SFT RAG先 SFT 理解、再 RAG 查询复杂工具调用SFT (Function Calling 数据)Prompt 不够稳内部工作流编排SFTPrompt 链条太长单次复杂任务Prompt Chain of Thought不需要训练一个简化的优先级Prompt → RAG → SFT → 对齐微调能用 Prompt 解决不要上 RAG能 RAG 解决不要 SFT能 SFT 解决不要 RLHF。降维使用工程上最省事。二、SFT 原理速通2.1 SFT 与预训练的本质区别维度预训练SFT数据量万亿 token千-百万 sample数据格式纯文本(指令, 响应) 对训练目标下一个 token 预测仅响应部分的 token 预测学习率~3e-4~1e-5 ~ 2e-4取决于方法训练时长数月数小时-数天算力规模千-万卡单卡-数十卡最关键的区别SFT 的 loss 只算响应部分的 token不算指令部分——因为我们想让模型学会如何回答而不是如何提问。这是新手容易写错的细节下面代码会讲到。2.2 训练数据格式主流 SFT 数据格式两类Alpaca 风格早期{ instruction: 把下面文本翻译成英文, input: 你好世界, output: Hello, world }ChatML / Multi-turn 风格当下主流{ messages:[ {role:system,content:你是一个翻译助手}, {role:user,content:把你好世界翻译成英文}, {role:assistant,content:Hello, world} ] }当下生产环境几乎都用 ChatML 格式——因为支持多轮、支持 system prompt、和推理时的 prompt 格式完全一致。2.3 Chat Template让模型学会对话格式不同模型有不同的对话模板。比如 Qwen3 的模板|im_start|system {system}|im_end| |im_start|user {user_msg}|im_end| |im_start|assistant {assistant_msg}|im_end|Llama 3|begin_of_text||start_header_id|system|end_header_id| {system}|eot_id||start_header_id|user|end_header_id| {user_msg}|eot_id|...SFT 训练时必须用和推理时完全一致的模板——否则上线效果会莫名其妙差。直接用tokenizer.apply_chat_template()是最稳的做法不要手拼字符串。三、三种微调方法原理与对比3.1 全参数微调Full Fine-Tuning做法解锁所有模型参数照常用 SGD/AdamW 更新。显存需求第 3 篇推导过的训练显存公式显存 ≈ 12 × N bytesBF16 AdamW对 70B 模型12 × 70 840 GB——单 H100 80GB 装不下需要 8 张 H100 起。优点效果上限最高适合大幅改变模型行为适合预训练后再次精炼缺点显存成本极高容易灾难遗忘catastrophic forgetting—— 学新东西忘老东西训练完产物是个完整模型存储/传输不便实操场景准备发布新版本基座模型算力充足且需要极致效果大数据量10 万领域适配3.2 LoRALow-Rank AdaptationLoRA 是 2021 年微软提出的方法当下 80% 的微调任务都用 LoRA 系列。核心思路冻结原模型权重只在每一层旁边加一个低秩适配器。数学表达原模型权重W (d × d) 新增适配器B × A其中 B 是 d×rA 是 r×d 推理时实际权重W α/r × B × A中r是 LoRA 秩典型值 8、16、64α是缩放因子。为什么有效研究表明微调阶段权重的实际变化是低秩的——可以用小矩阵很好近似。视觉上原始 forward input ──→ [W: d×d] ──→ output ← 冻结不训练 input ──→ [A: r×d] → [B: d×r] ──→ output_delta ← 训练 ↑ ↑ 低秩 r8/16/64显存收益训练参数从 N 降到 ~0.1-1% × N取决于 r优化器状态减少同等比例显存降到2-4 × N bytes约全参的 1/3-1/6对比 Llama-3-70B 训练显存方法显存全参BF16Adam~840 GBLoRA r64~280 GBQLoRA r64~70 GBLoRA 的工程红利可叠加训出多个 LoRA可以加权可热切换推理时一个基座 多个 LoRA按业务切换轻量传输一个 LoRA 通常只有几十-几百 MB多任务共存不同业务不同 LoRA互不干扰这就是为什么 vLLM、SGLang 都支持多 LoRA 热加载——一个基座撑 N 个业务。3.3 QLoRAQuantized LoRA问题即便 LoRA 把训练显存降到 1/370B 模型还是要 280GB——单卡跑不动。QLoRA 的妙招把冻结的基座模型量化到 4-bitLoRA 适配器仍用 BF16 训练。基座 WNF4 量化 (4-bit) ← 冻结 LoRA A, BBF16 ← 训练 反向传播用 BF16 精度计算梯度显存进一步降到 N bytes 量级——70B 模型只需 ~70GB单 H100 80G 完全可以。关键技术细节NF4 量化专为正态分布权重设计的 4-bit 量化精度损失极小Double Quantization连量化常数本身也量化再省 10% 显存Paged Optimizer用 CUDA 统一内存OOM 时自动换到 CPU代价训练速度比 LoRA 慢约 20-40%量化/反量化开销极少数极端任务效果略差结论QLoRA 是单卡微调的事实标准。3.4 一张表总结维度全参LoRAQLoRA训练显存 (70B)~840 GB~280 GB~70 GB单卡可训(80G H100)❌❌✅双卡可训❌✅紧张✅轻松训练速度1×1.5×1×效果上限100%95-98%92-96%产物大小140 GB100-500 MB100-500 MB适合多任务部署❌✅✅3.5 选择决策树是否准备发布新基座 / 极致效果 ├─ 是 → 全参多卡 └─ 否 → 用 LoRA 系列 │ ├─ 显存充足数十 GB │ ├─ 是 → LoRA更快 │ └─ 否 → QLoRA单卡也能跑经验法则从 QLoRA 开始。除非证明 QLoRA 效果不够否则不要折腾全参。四、实战用 QLoRA 微调 Qwen3-7B下面是一个可直接运行的完整 QLoRA 微调脚本。4.1 环境准备pip install transformers4.46.0 peft0.13.0 bitsandbytes0.44.0 \ accelerate1.0.0 trl0.12.0 datasets3.0.04.2 数据准备假设我们要训一个「翻译助手」数据格式[ {messages:[ {role:system,content:你是翻译助手}, {role:user,content:把你好世界翻译成英文}, {role:assistant,content:Hello, world} ]}, ... ]数据准备代码import json from datasets import Dataset # 假设你的训练数据在 train.jsonl with open(train.jsonl) as f: data [json.loads(l) for l in f] dataset Dataset.from_list(data) print(f训练样本数: {len(dataset)})4.3 加载模型 QLoRA 配置import torch from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training MODEL_NAME Qwen/Qwen3-7B-Instruct # 1. 4-bit 量化配置 bnb_config BitsAndBytesConfig( load_in_4bitTrue, bnb_4bit_quant_typenf4, bnb_4bit_compute_dtypetorch.bfloat16, bnb_4bit_use_double_quantTrue, # Double Quantization ) # 2. 加载量化基座 model AutoModelForCausalLM.from_pretrained( MODEL_NAME, quantization_configbnb_config, device_mapauto, trust_remote_codeTrue, ) model prepare_model_for_kbit_training(model) # 3. LoRA 配置 lora_config LoraConfig( r64, # 秩 lora_alpha128, # 缩放因子通常 2r lora_dropout0.05, biasnone, task_typeCAUSAL_LM, target_modules[ # 注入 LoRA 的层 q_proj, k_proj, v_proj, o_proj, # attention gate_proj, up_proj, down_proj, # FFN ], ) model get_peft_model(model, lora_config) model.print_trainable_parameters() # 输出: trainable params: 80,478,208 || all params: 7,696,150,528 || trainable%: 1.04%几个关键参数解读r64rank。经验值小任务 8-16中型 32-64大型 64-128lora_alpha 2r缩放系数标准做法target_modules决定 LoRA 注入的层。注入 attention FFN 是当前最优配置4.4 数据处理关键只对 response 算 losstokenizer AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_codeTrue) defformat_and_tokenize(example): 关键点分离 prompt 和 responseloss 只算 response 部分 messages example[messages] # 用 chat template 构造完整文本 full_text tokenizer.apply_chat_template( messages, tokenizeFalse, add_generation_promptFalse ) # 构造 prompt不含 assistant 部分 prompt_messages messages[:-1] # 去掉最后一条 assistant prompt_text tokenizer.apply_chat_template( prompt_messages, tokenizeFalse, add_generation_promptTrue ) # tokenize full_ids tokenizer(full_text, truncationTrue, max_length2048)[input_ids] prompt_ids tokenizer(prompt_text, truncationTrue, max_length2048)[input_ids] # labels: prompt 部分用 -100 mask不计 loss labels [-100] * len(prompt_ids) full_ids[len(prompt_ids):] return { input_ids: full_ids, labels: labels[:len(full_ids)], attention_mask: [1] * len(full_ids), } dataset dataset.map(format_and_tokenize, remove_columnsdataset.column_names)⚠️新手最常踩的坑直接把整条对话拿来训导致 loss 也算了用户提问部分——模型会学到如何生成用户提问效果显著变差。4.5 训练from transformers import TrainingArguments, Trainer from transformers.data.data_collator import DataCollatorForSeq2Seq training_args TrainingArguments( output_dir./qlora-qwen3-7b, num_train_epochs3, per_device_train_batch_size4, gradient_accumulation_steps4, # 等效 batch 16 learning_rate2e-4, # QLoRA 通常比全参高 lr_scheduler_typecosine, warmup_ratio0.03, logging_steps20, save_steps500, save_total_limit3, bf16True, optimpaged_adamw_8bit, # Paged Optimizer gradient_checkpointingTrue, report_totensorboard, ) trainer Trainer( modelmodel, argstraining_args, train_datasetdataset, data_collatorDataCollatorForSeq2Seq( tokenizertokenizer, paddingTrue ), ) trainer.train() model.save_pretrained(./qlora-qwen3-7b-final)4.6 合并 LoRA 权重 推理训完后有两种部署方式方式 1保留 LoRA动态加载推荐生产from peft import PeftModel from transformers import AutoModelForCausalLM base AutoModelForCausalLM.from_pretrained(Qwen/Qwen3-7B-Instruct) model PeftModel.from_pretrained(base, ./qlora-qwen3-7b-final) # 可以在推理时切换不同 LoRA方式 2合并权重用于发布完整模型merged model.merge_and_unload() merged.save_pretrained(./qwen3-7b-translate)合并后的模型和原模型一样可以用 vLLM 等推理框架部署。4.7 vLLM 部署多 LoRA 共存vllm serve Qwen/Qwen3-7B-Instruct \ --enable-lora \ --lora-modules \ translate./qlora-qwen3-7b-translate \ customer-service./qlora-qwen3-7b-cs \ code-review./qlora-qwen3-7b-code \ --max-loras 4请求时指定要用哪个 LoRAcurl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: translate, messages: [{role:user,content:翻译: hello}] }单基座 多 LoRA 是当下生产部署的最经济方案——一份 GPU 资源服务多业务。五、避坑清单5 个最常见的微调陷阱坑 1数据质量 数据量很多人觉得我训数据越多越好结果训出来效果反而退化。反例一个团队拿 100 万条客服对话训结果模型学了大量嗯嗯啊啊等口语化噪声。对策严格清洗数据宁少勿滥1000 条高质量数据 10 万条噪声数据——Anthropic 在 Constitutional AI 中验证过数据要覆盖业务的关键场景不要全是简单 case坑 2学习率配错不同微调方法学习率差异很大方法推荐 LR全参微调1e-5 ~ 5e-5LoRA1e-4 ~ 3e-4QLoRA1e-4 ~ 3e-4Embedding 微调1e-3错配 LR 的症状LR 过大 → loss 飞起胡言乱语LR 过小 → 训练无进展效果同未训坑 3灾难遗忘微调后模型在原能力上退化。例如训一个法律助手结果模型连日常对话都答不好了。对策混入 10-20% 的通用指令数据用 LoRA 而非全参自带保护机制学习率小一些、训练 epoch 少一些DPO 阶段可以部分修复坑 4Chat Template 用错症状训练 loss 看着正常部署后效果差。根本原因训练用的 template 和推理用的 template 不一致。对策训练和推理必须用同一个tokenizer.apply_chat_template()检查 EOS token 是否正确很多模型有多个 EOS如果加了自定义 system prompt推理时也要加坑 5评估太草率反例训完用 5 个测试样例看一眼效果好就上线。结果用户场景一来全崩。对策准备至少 100 条 hold-out 测试集不要混进训练集用业务真实分布的数据评估不要用通用 benchmark同时跑通用 benchmarkMMLU/CEval确认没有灾难遗忘加入对抗性 caseprompt injection、边缘场景六、进阶话题与下一篇预告6.1 LoRA 的进化变种LoRA 之后还出了一系列改进方法改进点当下地位LoRA低秩适配主流AdaLoRA自适应分配 rank部分场景DoRA分解为方向 大小论文热门PiSSA用主成分初始化新兴GaLore梯度低秩投影接近全参效果工程上LoRA 仍然是首选其他方法在 5% 边际增益场景考虑。6.2 何时 SFT 完不够、要上 DPO/RLHFSFT 解决会做不解决做得好。下列情况要继续做对齐安全性场景医疗、法律建议用户体验场景语气、有用性、诚实性偏好选择哪个回答更好是模糊判断 详见系列第 8 篇RLHF 与 DPO。6.3 多 LoRA 合并如果你训了多个 LoRA可以加权合并from peft import PeftModel model PeftModel.from_pretrained(base, lora_a) model.load_adapter(lora_b, adapter_nameb) model.add_weighted_adapter( adapters[default, b], weights[0.7, 0.3], adapter_namemerged )适用于把格式 LoRA和领域 LoRA组合使用。6.4 SFT 数据自动化工业上越来越多用大模型生成 SFT 数据Self-Instruct模型自己生成 instructionEvol-Instruct让 GPT-4 把简单 instruction 改写得更复杂蒸馏用闭源大模型回答作为开源小模型的 SFT 数据 详见系列第 10 篇训练数据工程。结语80% 的 AI 工程师会与 SFT 朝夕相处读完本文你应该明白QLoRA 是单卡微调的事实标准从这里开始SFT 不擅长学知识擅长学格式/风格——知识用 RAG数据质量 数据量1000 条精品 10 万条噪声多 LoRA 单基座是生产部署的经济选择Prompt → RAG → SFT → 对齐按优先级降维使用参考文献SFT 微调实战LoRA / QLoRA / 全参微调对比

相关新闻

模型量化:精度损耗与推理加速的平衡

模型量化:精度损耗与推理加速的平衡

模型量化:精度损耗与推理加速的平衡一、显存瓶颈决定量化必要性 大模型推理的最大瓶颈是显存而非算力。70B参数模型在FP16精度下需要约140GB显存,远超单卡A100 80GB的容量。即使使用张量并行将模型拆分到两张A100,每张卡仍需70GB存储权重&…

2026/6/29 6:13:02阅读更多 →
XSS漏洞攻防实战:从原理到靶场实践与防御策略

XSS漏洞攻防实战:从原理到靶场实践与防御策略

1. 从“弹窗”到“接管”:为什么XSS是Web安全的头号顽疾?如果你刚接触Web安全,可能会觉得“XSS漏洞”这个词听起来有点神秘,甚至有点酷。但说白了,它的核心原理其实很简单:让一个网站执行了它本不该执行的代…

2026/6/29 6:13:02阅读更多 →
C#实现控制台多区域输出

C#实现控制台多区域输出

近一年以来,AI Agent的发展速度非常快。 如果经常使用一些Agent CLI工具,例如 Claude Code、Gemini CLI、OpenCode 等产品,会发现它们有一个共同特点: 虽然运行在终端之中,但已经完全不是传统命令行程序的样子。 在执行…

2026/6/29 6:13:02阅读更多 →
从URDF到Gazebo:深度相机集成与可视化调试全流程

从URDF到Gazebo:深度相机集成与可视化调试全流程

1. 深度相机与URDF基础概念 深度相机在机器人领域扮演着重要角色,它能同时获取彩色图像、深度信息和三维点云数据。常见的深度相机包括Kinect、RealSense等,它们通过红外结构光或飞行时间(ToF)原理实现距离测量。在仿真环境中集成…

2026/6/29 7:23:07阅读更多 →
从RTL8153-VC-CG看USB3.0千兆网卡芯片:如何为超薄设备重塑有线连接

从RTL8153-VC-CG看USB3.0千兆网卡芯片:如何为超薄设备重塑有线连接

1. RTL8153-VC-CG芯片:超薄设备的有线网络救星 每次用超薄笔记本连WiFi打视频会议时突然卡顿,你是不是也想摔电脑?别急,RTL8153-VC-CG这个指甲盖大小的芯片可能就是你的救星。作为**台湾瑞昱(Realtek)**的拳…

2026/6/29 7:23:07阅读更多 →
Python实战:平滑阶数群下Diffie-Hellman密钥交换的Pohlig-Hellman攻击

Python实战:平滑阶数群下Diffie-Hellman密钥交换的Pohlig-Hellman攻击

1. 项目概述:一次关于密码学假设的“思想实验”最近在和一些做安全研究的朋友交流时,聊到了一个听起来很“黑客”的话题:Diffie-Hellman密钥交换的破解。网上相关的讨论和“教程”不少,但很多都停留在概念层面,或者直接…

2026/6/29 7:23:07阅读更多 →
SQL注入攻防全解析:从原理到实战,构建Web应用安全防线

SQL注入攻防全解析:从原理到实战,构建Web应用安全防线

1. 项目概述:从“万能钥匙”到“安全门禁”SQL注入,这个名字在网络安全领域,尤其是Web安全方向,几乎是无人不知、无人不晓。它不像某些复杂的零日漏洞那样神秘,更像是一把被广泛流传的“万能钥匙”——原理简单&#x…

2026/6/29 7:23:07阅读更多 →
国土空间规划工作底图制作全流程解析:从数据获取到符号化呈现

国土空间规划工作底图制作全流程解析:从数据获取到符号化呈现

1. 数据采集与处理:规划底图的基石 做国土空间规划就像搭积木,数据就是那些最基础的积木块。我去年负责墨玉县项目时,光是数据准备就花了整整两周。现在回头看,有些坑完全可以避免。先说乡镇驻地数据,新手最容易犯的错…

2026/6/29 7:23:07阅读更多 →
如何在多设备间获得一致的B站深度使用体验?

如何在多设备间获得一致的B站深度使用体验?

如何在多设备间获得一致的B站深度使用体验? 【免费下载链接】PiliPlus PiliPlus 项目地址: https://gitcode.com/gh_mirrors/pi/PiliPlus 你是否曾经在手机上收藏了一个有趣的视频,但在电脑上却找不到?或者在不同的设备上使用B站时&am…

2026/6/29 7:18:07阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/6/29 3:27:55阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/6/29 2:19:08阅读更多 →
如何在3秒内从普通图片生成专业级法线贴图:DeepBump的终极指南

如何在3秒内从普通图片生成专业级法线贴图:DeepBump的终极指南

如何在3秒内从普通图片生成专业级法线贴图:DeepBump的终极指南 【免费下载链接】DeepBump Normal & height maps generation from single pictures 项目地址: https://gitcode.com/gh_mirrors/de/DeepBump 还在为3D建模中的纹理制作而烦恼吗?…

2026/6/29 0:01:47阅读更多 →
OCAuxiliaryTools:终极OpenCore配置工具,让黑苹果安装从未如此简单!

OCAuxiliaryTools:终极OpenCore配置工具,让黑苹果安装从未如此简单!

OCAuxiliaryTools:终极OpenCore配置工具,让黑苹果安装从未如此简单! 【免费下载链接】OCAuxiliaryTools Cross-platform GUI management tools for OpenCore(OCAT) 项目地址: https://gitcode.com/gh_mirrors/oc/OCA…

2026/6/29 0:01:47阅读更多 →
终极Windows 11精简指南:使用tiny11builder快速创建纯净系统镜像

终极Windows 11精简指南:使用tiny11builder快速创建纯净系统镜像

终极Windows 11精简指南:使用tiny11builder快速创建纯净系统镜像 【免费下载链接】tiny11builder Scripts to build a trimmed-down Windows 11 image. 项目地址: https://gitcode.com/GitHub_Trending/ti/tiny11builder 你是否厌倦了Windows 11系统自带的20…

2026/6/29 0:01:47阅读更多 →