低算力也能训大模型:LoRA、蒸馏与 2025 前沿

关键词:参数高效微调(PEFT)、LoRA、QLoRA、知识蒸馏、On-Policy Distillation
适用读者:想在自己机器上微调 / 压缩大模型,但只有一张消费级显卡(8G~24G)的工程师、研究者与学生。


0. 写在前面:为什么你需要"轻量化训练"

大模型火了三年,但一个尴尬的事实是:绝大多数人根本没有足够的算力去做"全参数微调"

把一个 7B 模型(约 70 亿参数)用 AdamW 全参微调一遍,光优化器状态就要存 12 份参数副本(Adam 的 momentum + variance,每个参数 2 个状态,FP32),再加上梯度、激活值,显存轻松突破 60GB——这得 A100 80G 才够。而你我手里的,往往是 24G 的 4090、16G 的 4060 Ti,甚至笔记本上的 8G 卡。

于是,"怎么用很少的算力,让大模型学会我的任务"成了一门显学。本文把这事拆成两条主线

  1. 参数高效微调(PEFT):冻结 backbone,只训极少量参数(典型如 LoRA,可训练参数不足 1%)。
  2. 知识蒸馏(Knowledge Distillation, KD):用一个"大模型老师"教"小模型学生",让小模型在部署时又快又便宜。

下面每一条都配原理图、可跑代码和一个完整的模拟案例。所有论文均来自 arXiv 近年(含 2025–2026 最新综述),文末给出速查表。


1. 先算一笔账:全参微调到底贵在哪

训练时显存 = 模型参数 + 梯度 + 优化器状态 + 激活值。以 FP16 权重为例:

组成部分单参字节数7B 模型占用说明
模型权重(FP16)214 GB推理也要
梯度(FP16)214 GB反向传播
优化器状态(AdamW,FP32)1284 GBm+v 各 4 字节 ×2 + 主权重 4 字节
激活值视 batch/序列10~40 GB随序列长度线性涨
合计≈ 120 GB+单卡根本扛不住

关键认知:AdamW 的优化器状态是显存杀手(占 ~70%)。轻量化训练的第一性原理,就是"少存、少更新、低精度"。

下面这张图把两条主线放在同一张地图上,方便你建立全局视角:

显存不够全参微调

预训练大模型 Teacher或Base

轻量化训练两条主线

参数高效微调 PEFT
冻结主干, 只训少量参数

知识蒸馏 KD
大模型教小模型

LoRA 、 QLoRA
低秩适配 与 4bit 量化

DoRA 、 GaLore 、 Q-GaLore
方向分解 、 梯度低秩投影

白盒 用 logits 软标签

黑盒 只用语料输出

On-Policy 学生自己采样再学

单卡 24G 微调 7B


2. 主线一:参数高效微调(PEFT)

2.1 LoRA——用"低秩"偷偷改权重

核心直觉:大模型在适配某个具体任务时,权重的"变化量"其实很低维。也就是说,权重更新矩阵 ΔW 不需要是满秩的,它可以写成两个瘦矩阵的乘积。

设某层原始权重 W ∈ R^{d×k},LoRA 把它冻结,另训两个小矩阵 B ∈ R^{d×r}A ∈ R^{r×k}(r ≪ d, k),让:

h = W·x + ΔW·x = W·x + B·A·x
  • 可训练参数从 d×k 降到 r×(d+k)。取 r=8, d=k=4096 时,参数量从 1677 万降到约 6.5 万,仅为原来的 0.4%
  • 推理时可以把 B·A 直接加回 WW' = W + BA),零额外延迟;也可以保留适配器,按需切换任务。

下面这张图对比了"全参微调"和"LoRA"在反向传播时的差异:

LoRA

只前向

W 冻结

X

A 可训练

B·A

B 可训练

输出

全参微调

反向更新全部

W 可训练

梯度与优化器状态
显存爆炸

一个常见误区:LoRA 不是"越小越好"。r 太小会欠拟合,太大又回到全参微调的显存。经验值:通用指令微调 r=8~64,领域适配可适当加大;通常只加在 q_projv_proj(注意力),必要时加上 k_projo_projgate_projup_proj

2.2 QLoRA——把 LoRA 塞进 4bit 模型里

LoRA 解决了"训多少",但底座权重本身还是 16bit(14GB)。QLoRA(Dettmers et al., 2023, arXiv:2305.14314)用三招把它压到 4bit:

  1. NF4 量化(NormalFloat-4):一种针对"正态分布权重"设计的 4bit 数据类型,比普通 INT4 更省信息。
  2. 双重量化(Double Quantization):连量化所需的"缩放因子"也再量化一次,进一步省显存。
  3. 分页优化器(Paged Optimizers):用 NVIDIA 的 unified memory,显存峰值(如长序列 batch)时把优化器状态临时分页到 CPU,避免 OOM。

效果:在单张 48G A100 上微调 65B 模型;在 24G 消费卡上微调 7B~13B 也成为日常。

直觉:底座被压成 4bit 后"几乎不更新",LoRA 适配器在 16bit 精度上学习——用极低显存换"接近全参微调"的效果。

2.3 进阶三件套(2024–2025 前沿)

方法年份 / 出处一句话原理解决什么
DoRALiu et al. 2024, arXiv:2402.09353把权重拆成"幅度 + 方向"两步更新,方向部分用 LoRA更接近全参微调的收敛行为
GaLoreZhao et al. 2024, arXiv:2403.03507把梯度投影到低秩子空间再更新,省优化器状态预训练/微调都省显存,不需 LoRA
Q-GaLoreZhang et al. 2025(ICLR), PMLR v280GaLore + INT4 投影 + INT8 权重 + 层自适应在 RTX 4060 Ti 16G 上从头训 LLaMA-7B

一个硬核数据点(Q-GaLore 论文原文):微调时相比 LoRA/GaLore 再降最多 50% 显存,且在相同显存下 MMLU 上比 QLoRA 高最多 5.19 分

2.4 实战:用 QLoRA 微调一个 7B 模型

下面代码基于 transformers + peft + bitsandbytes,在单卡上即可跑。假设任务:把通用模型微调成"中文法律咨询助手"。

# pip install transformers peft bitsandbytes accelerate datasets
import torch
from transformers import (AutoModelForCausalLM, AutoTokenizer,
                          BitsAndBytesConfig, Trainer, TrainingArguments)
from peft import LoraConfig, get_peft_model
from datasets import load_from_disk

# 1) 4bit 量化配置(QLoRA 核心)
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",                 # NF4 数据类型
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True,            # 双重量化
)

model_id = "meta-llama/Llama-2-7b-hf"
tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    quantization_config=bnb_config,
    device_map="auto",
)

# 2) 只训练 LoRA 适配器
lora_config = LoraConfig(
    r=16,                      # 低秩维度
    lora_alpha=32,             # 缩放系数,通常 = 2*r
    target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()   # 典型输出: trainable params: 0.4%

# 3) 训练
train_ds = load_from_disk("./legal_sft_data")
training_args = TrainingArguments(
    output_dir="./lora-legal",
    per_device_train_batch_size=4,
    gradient_accumulation_steps=8,   # 用小 batch + 累积,弥补显存
    max_steps=500,
    learning_rate=2e-4,              # LoRA 学习率通常比全参微调大 10 倍
    fp16=True,
    logging_steps=20,
    save_strategy="steps",
    save_steps=200,
)
trainer = Trainer(model=model, args=training_args, train_dataset=train_ds)
trainer.train()

# 4) 导出:合并权重(部署时零延迟)或只存适配器(轻量切换)
model.save_pretrained("./lora-legal-adapter")          # 仅适配器,~30MB
model.merge_and_unload().save_pretrained("./lora-legal-merged")  # 合并后完整模型

踩坑提示:learning_rate 用 1e-4~3e-4(LoRA 适配器需要更大步长);gradient_accumulation_steps 是单卡低显存下的标配;若 OOM,先降 per_device_train_batch_size 再升累积步数。


3. 主线二:知识蒸馏(KD)

3.1 什么是蒸馏:老师教学生

蒸馏的本质是迁移"决策边界"而非"参数"。老师模型(大)不仅给出正确答案,还给出"软标签"——每个错误选项的概率分布,蕴含了"猫比狗更像老虎"这类结构化知识。学生(小)通过匹配这个分布,学得比只看硬标签更好。

前向得到软标签 P_T

最小化 KL散度

CE

Teacher 大模型 7B或13B

Student 小模型 0.5B、1.5B

训练语料 x

蒸馏损失

硬标签 y

常规损失

三类蒸馏信号(来自 2025 知识蒸馏综述,arXiv:2503.12067):

  • 响应/Logit 基(response-based):用最后一层 softmax 的软标签,最简单、最常用。
  • 特征基(feature-based):对齐中间层隐状态(如用 MSE 拉齐 teacher/student 的 hidden states)。
  • 关系基(relation-based):学样本之间的关系结构(如样本相似度矩阵)。

3.2 暴露偏置与 On-Policy 蒸馏(2023–2026 重点突破)

传统蒸馏是 off-policy:拿老师对"标准答案序列"的分布去教学生。但学生推理时是自己一个字一个字生成的,一旦生成了老师没见过的开头,后面就一路跑偏——这叫 暴露偏置(exposure bias)

2023–2024 的两条里程碑工作把它变成 on-policy(学生自己采样,再向老师学)

  • MiniLLM(Gu et al., ICLR 2024, arXiv:2306.08543):改用 Reverse KL 而非 Forward KL。Forward KL 是"众数覆盖",逼小模型覆盖老师全部模式→低容量学生只能"平均化"→产生幻觉;Reverse KL 是"众数寻求",让学生锁定老师分布的主峰,回答更准更自信。并用 REINFORCE(策略梯度)优化。
  • GKD(Agarwal et al., ICLR 2024, arXiv:2306.13649):通用 on-policy 框架,允许 student/teacher 序列按可调比例混合采样,任务上显著超过 SeqKD 与 SFT。

到 2026 年,已有专门综述 《A Survey of On-Policy Distillation for LLMs》(arXiv:2604.00626),把它统一在"序列决策 + f-散度"框架下,并指出下一站是 Agentic Distillation(让模型从多轮环境交互中蒸馏)

直觉记忆:off-policy = “照着参考答案抄”;on-policy = “自己先写一遍,再让老师批改你写的那版”。后者更抗跑偏。

3.3 实战:一个最小白盒蒸馏循环

下面是一个简化但可运行的 logit 蒸馏训练循环(假设能拿到 teacher 的 logits):

import torch, torch.nn.functional as F

def distillation_step(student, teacher, batch, T=4.0, alpha=0.7):
    # batch: (input_ids, attention_mask, labels)
    ids, mask, labels = batch

    with torch.no_grad():
        t_logits = teacher(input_ids=ids, attention_mask=mask).logits   # 老师软标签
    s_logits = student(input_ids=ids, attention_mask=mask).logits        # 学生输出

    # 1) 软标签损失:用温度 T 软化分布,再算 KL
    soft_loss = F.kl_div(
        F.log_softmax(s_logits / T, dim=-1),
        F.softmax(t_logits / T, dim=-1),
        reduction="batchmean",
    ) * (T * T)

    # 2) 硬标签损失:常规交叉熵
    hard_loss = F.cross_entropy(s_logits.view(-1, s_logits.size(-1)), labels.view(-1))

    return alpha * soft_loss + (1 - alpha) * hard_loss   # 两者加权

# 训练循环
for batch in dataloader:
    loss = distillation_step(student, teacher, batch)
    loss.backward()
    optimizer.step(); optimizer.zero_grad()

alpha 控制"软标签 vs 硬标签"比重(常用 0.5~0.9);T(温度)越大分布越软、知识越平滑。黑盒场景拿不到 logits,就退化为"让学生模仿老师的输出文本"(SFT on teacher outputs)。


4. 模拟案例:24G 单卡,把 7B 微调并蒸馏出 1.5B 助手

下面用一个完整、可复现思路的模拟案例,把前面所有方法串起来。

4.1 场景设定

  • 硬件:单张 RTX 4090,24GB 显存。
  • 目标:用 2 万条"电商客服"对话,① 微调出 7B 客服模型;② 再蒸馏出一个 1.5B 小模型用于线上低延迟服务。
  • 评测:自建 500 题客服测试集(准确率 + 人工打分)。

4.2 显存预算对比(同样是 7B 底座,不同方案)

方案权重精度可训练参数峰值显存单卡 24G 是否可行
全参微调(AdamW)FP16100%~120 GB❌ 不可能
LoRA(r=16)FP160.4%~18 GB✅ 可行
QLoRA(r=16)4bit+FP160.4%~9 GB✅ 宽松
GaLoreFP16100%(但省优化器态)~28 GB⚠️ 勉强,需小 batch
Q-GaLoreINT8/INT4100%~14 GB✅ 可行且更准

结论:本案例选 QLoRA 微调 7B(最稳),再用 logit 蒸馏把 7B 知识压进 1.5B

4.3 端到端流程

生成软标签、参考答案

高价值请求

低成本高并发

客服对话 2万条

QLoRA 微调 Llama-2-7B
24G 单卡, 约 3 小时

7B 客服模型

蒸馏训练

随机初始化 1.5B

1.5B 客服模型
部署延迟不到 7B 的三分之一

线上路由

4.4 模拟实验结果(标注:以下为方法预期区间的示意,非真实跑分)

模型客服准确率人工打分(5)推理显存单条延迟
基座 7B(零样本)61%3.114 GB320 ms
QLoRA 微调 7B88%4.314 GB320 ms
蒸馏 1.5B(off-policy)79%3.73.2 GB95 ms
蒸馏 1.5B(on-policy/MiniLLM 思路)84%4.03.2 GB95 ms

读图要点:蒸馏 1.5B 用 1/4 显存、1/3 延迟,拿到接近 7B 微调版 95% 的效果;on-policy 比 off-policy 再涨 5 个点,印证了第 3.2 节的结论。真实数字随数据/底座浮动,请用你自己的测试集验证。


5. 2025–2026 arXiv 前沿速览(速查表)

论文arXiv / 出处类别一句话价值
LoRA2106.09685 (2021)PEFT低秩适配开山之作,一切的起点
QLoRA2305.14314 (2023)PEFT4bit+双重量化,单卡训大模型
DoRA2402.09353 (2024)PEFT权重幅度/方向分解,更稳
GaLore2403.03507 (2024)PEFT梯度低秩投影,省优化器态
MiniLLM2306.08543 (ICLR2024)蒸馏Reverse-KL + on-policy,抗幻觉
GKD2306.13649 (ICLR2024)蒸馏通用 on-policy 蒸馏框架
Q-GaLorePMLR v280 (2025)PEFTINT4 投影,16G 卡训 7B
KD 综合综述2503.12067 (2025)综述蒸馏全谱分类(含 LLM/VLM)
LLaMA + PEFT 综述2510.12178 (2025)综述LLaMA 族 + 5 种 PEFT 一站式
From LLMs to Edge2507.23536 (2025)边缘在边缘 CNN 上基准 LoRA/DoRA/GaLore
On-Policy Distillation 综述2604.00626 (2026)综述统一 OPD 理论框架,指向 Agentic 蒸馏

6. 选型决策树:我该用哪招

显存≥80G A100

24G 消费卡

显存≤16G

否, 要多个任务切换

显存有多少?

可全参微调或GaLore预训练

只要适配一个任务?

QLoRA 必选

QLoRA 微调底座

LoRA 多适配器

要部署到端侧、低延迟?

蒸馏 大模型教小模型
优先 on-policy

直接用微调后模型

最简决策

  • 只有 1 张 24G 卡 + 1 个任务 → QLoRA,最省心。
  • 要线上低延迟 / 端侧 → 先 QLoRA 训大模型,再 蒸馏 出小模型。
  • 想从头训(预训练)→ 看 GaLore / Q-GaLore
  • 蒸馏追求高质 → 用 on-policy(MiniLLM/GKD 思路) 而非纯 off-policy。

7. 总结与资源

低算力训练不是"凑合",而是一套有理论支撑的工程学:

  • PEFT 用"冻结+低秩/低精度"把显存从 120GB 砍到个位数 GB;
  • 蒸馏 用"老师教学生"把能力从大模型迁移到能部署的小模型;
  • 2024–2026 的前沿 在把两者推到极致:DoRA 的方向分解、Q-GaLore 的 INT4 投影、On-Policy 蒸馏对暴露偏置的修正。

上手三步走:① 用 QLoRA 在手里显卡上跑通第一个微调;② 把日志里的显存/loss 曲线存下来当基线;③ 用蒸馏把成果压成小模型上线。多数团队卡在"第一步没跑起来",而本文的代码复制即改路径就能跑。

常用资源

  • huggingface/peftbitsandbytestransformers:QLoRA 三件套
  • MiniLLM 代码:github.com/microsoft/LMOps/tree/main/minillm
  • Q-GaLore 代码:对应 PMLR v280 官方实现
  • 综述配套:KD 综述 github.com/IPL-Sharif/KD_Survey

注:本文实验结果为方法预期区间的示意模拟,真实收益取决于数据质量、底座模型与超参;上线前请用你自己的测试集实测。


*如果这篇对你有用,欢迎收藏 + 关注,后续会写「QLoRA 显存调优的 10 个实战坑」与「蒸馏 loss 权重 α/T 的网格搜索实验」。

更多推荐