/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}
上篇用 DQN 让智能体学会决策,而大模型时代「让模型快速学会新任务」最高效的方式,是 LoRA 这类参数高效微调。
引言
想让 LLaMA-7B 说"人话"、懂你的业务,传统做法是全参数微调——但 7B 模型全量微调要吃 ~80GB 显存,等于四张 A100。这对个人和中小团队是天文数字。好消息是:95% 的权重其实不用动。参数高效微调(PEFT)只训练极少参数就能接近全量效果,其中 LoRA 和 QLoRA 把门槛压到了"一张 24G 消费卡也能玩"。本篇手把手带你跑通。
一、全参数微调的显存瓶颈
训练显存 ≈ 模型参数 ×(每参数字节 + 优化器状态 + 梯度)。FP16 下:参数 2 字节、梯度 2 字节、Adam 状态(m,v)4 字节 → 每个参数约 8 字节。
| 7B | 70 亿 | ~56 GB(FP16) |
| 13B | 130 亿 | ~100 GB+ |
| 70B | 700 亿 | 多张 A100 |
显然不现实。PEFT 的思路:冻结基座,只训练旁路的小参数,显存随可训练参数骤降。
二、LoRA 低秩分解原理
核心洞察:权重更新 ΔW 在微调时往往是低秩的。于是把 ΔW 拆成两个小矩阵:
h = W₀ x + ΔW x = W₀ x + B A x
(d×k) (d×r)(r×k) r ≪ d,k
-
W₀ 冻结不动(不占梯度/优化器状态)。
-
只训练 A (r×k) 和 B (d×r),可训练参数量从 d×k 降到 r×(d+k)。
-
推理时可以把 BA 加回 W₀ 合并部署,零额外延迟。
参数量对比:以 d=k=4096、秩 r=8 为例,原权重 1677 万,LoRA 仅 8×(4096+4096)=6.5万,约 0.4%。典型配置 r=8~64 即可,参数量常能压到原模型的 0.1%~1%,效果却接近全量。
三、QLoRA:4-bit 量化微调
QLoRA 在 LoRA 基础上再砍一刀——把冻结的基座用 4-bit NF4 量化存下来,配合 分页优化器(Paged Optimizers) 在显存峰值时把优化器状态换页到 CPU,进一步省显存。
效果惊人:把 65B 模型的微调压进单张 48G 卡,7B 模型甚至能在 24G 消费卡(如 RTX 4090) 上跑。代价是 4-bit 引入极小精度损失,但配合 LoRA 往往可忽略。
import torch
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True, # 对量化常数再量化,更省
)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b-hf",
quantization_config=bnb_config,
device_map="auto",
)
四、中文指令数据构造
LoRA 只改"行为",不改"知识",所以数据质量 > 数据量。指令数据统一成 alpaca 格式:
{
"instruction": "把下面的句子翻译成英文",
"input": "今天天气真好。",
"output": "The weather is really nice today."
}
建议:
-
用你业务里的真实问答/指令,1000~5000 条高质量样本常够见效。
-
混入少量通用指令数据防遗忘。
-
去重、清洗格式,避免噪声主导低秩更新。
五、训练与权重合并部署
用 Hugging Face peft 几行接入:
from peft import LoraConfig, get_peft_model
lora_config = LoraConfig(
r=8, # 秩
lora_alpha=16, # 缩放,常取 2*r
target_modules=["q_proj","v_proj"], # 注入注意力的 Q/V
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters() # 会显示可训练参数占比 ~0.1%
# 之后用 Trainer / SFTTrainer 正常训练即可
训练完成后合并部署(消除旁路开销):
merged = model.merge_and_unload() # BA 合并回 W₀
merged.save_pretrained("./llama2-7b-lora-merged")
典型显存与效果(公开基准区间,随配置浮动,非本机实测):
| 全参数微调 | ~56 GB | 100% 基线 |
| LoRA (r=8, FP16) | ~16 GB | ~98% |
| QLoRA (4-bit) | ~6~8 GB | ~97% |
这正是"消费级显卡定制大模型"成为现实的原因。
六、经验参数与避坑
秩 r 不是越大越好:r=8 常够,r=64 未必更好还更占显存;先小后大。
学习率要放大:LoRA 参数少,常用 1e-4 ~ 3e-4,比全量微调(~2e-5)大一个量级。
target_modules 选对:通常注入 q_proj,v_proj(或全注意力),别漏了。
lora_alpha / r 比值:控制更新幅度,常设 alpha = 2r。
避免灾难性遗忘:数据里保留少量通用样本;LoRA 本身因冻结基座,遗忘风险已较低。
部署合并:上线前 merge_and_unload,否则每次推理多一次旁路计算。
总结
LoRA 用低秩分解把"微调大模型"从 A100 集群降维到单张消费卡,QLoRA 再借 4-bit 量化把门槛砍到 24G 显存。本文的 PEFT 代码可直接套你的 7B/13B 模型——记住铁律:数据质量先于参数量,r 先小后大,学习率放大一档。这是 2026 年每个想拥有"专属大模型"的开发者都该掌握的技能。
参考资料
Hu, E., et al. (2021). LoRA: Low-Rank Adaptation of Large Language Models.
Dettmers, T., et al. (2023). QLoRA: Efficient Finetuning of Quantized LLMs.
Hugging Face PEFT 文档:https://huggingface.co/docs/peft
bitsandbytes 4-bit 量化指南。
往期回顾
-
第7篇:BERT 模型原理解析与微调实战
- 第8篇:GPT 系列大模型架构演进与提示工程入门
-
多模态学习——图文联合表征前沿进展
📚 本篇出自专栏《深学之路:从感知机到智能体》 —— 从感知机到大模型智能体的完整深度学习连载(基础+工程化 +扩散模型 / RAG / Agent 等)。每篇附可运行代码与原创实验,收藏专栏不迷路。
网硕互联帮助中心






评论前必须登录!
注册