PEFT 全谱:LoRA / GaLore / LISA / DoRA
ms-swift 的 train_type 支持十多种 PEFT 方法,包括 HF PEFT 全谱、加上自家集成的 GaLore / LISA / LongLoRA。本章把每种说清楚。
7.1train_type 全清单
| train_type | 来源 | 典型 trainable% |
|---|---|---|
| full | — | 100% |
| lora | HF PEFT | 0.1-1% |
| dora | HF PEFT | 同 LoRA + 0.5% |
| longlora | ms-swift 自家 | ~0.5% |
| llamapro | ms-swift 自家 | ~10%(加 layer) |
| galore | ms-swift 集成 | 100%(全参,省显存) |
| lisa | ms-swift 集成 | 100%(每次随机激活几层) |
| liger | Linkedin Liger kernel | 不算 PEFT,是 fused kernel |
| adalora / boft / vera / fourierft | HF PEFT | ~0.1% |
| ia3 / loha / lokr / oft | HF PEFT | ~0.05% |
| reft | 实验 | 极小 |
7.2GaLore:全参省显存
GaLore(Gradient Low-Rank Projection)是 2024 提出的"全参微调省显存"方法:
把梯度矩阵投影到低秩子空间存储 optimizer state,训完仍是全参更新,但 optimizer 显存近似 LoRA。
swift sft \
--model Qwen/Qwen2.5-7B-Instruct \
--train_type galore \
--galore_rank 128 \
--galore_update_proj_gap 200 \
--galore_scale 0.25 \
--galore_proj_type std
核心参数:
galore_rank:投影秩,128-256;galore_update_proj_gap:每几步重新做 SVD(开销大);galore_scale:投影后梯度缩放因子;galore_proj_type:std / reverse_std / right / left / full。
GaLore vs LoRA
| LoRA | GaLore | |
|---|---|---|
| 参数更新 | 只更新 BA | 全参(投影方式) |
| 显存 | ~14 GB (7B) | ~16 GB |
| 效果 | ~98% 全参 | ~99% 全参 |
| 训练速度 | 1.0× | 0.85×(SVD overhead) |
7.3LISA:随机层激活
LISA(Layerwise Importance Sampled AdamW):每个 step 随机激活 K 层、其他层冻结。理论上等价于全参,但每 step 显存只需 K 层。
swift sft \
--train_type lisa \
--lisa_activated_layers 2 \
--lisa_step_interval 20
典型设置:32 层模型选 2 层激活,每 20 step 切一次。显存接近 LoRA,效果接近全参。
7.4LongLoRA:长上下文专用
LongLoRA 的核心是 shifted sparse attention (S²-Attn):把 attention 分组(每组 1/4 序列),错位重叠以保留长距依赖。配合 LoRA 训练可以把 LLaMA 上下文从 4K 扩到 100K。
swift sft \
--train_type longlora \
--max_length 32768 \
--lora_rank 8 --lora_alpha 16
7.5LLaMA-Pro:增量加 layer
LLaMA-Pro 思路:base 模型不动,在每个 transformer block 后插入一个新 block(初始化为 identity),只训这些新加的 block。适合"加入新领域知识"场景。
swift sft \
--train_type llamapro \
--llamapro_num_new_blocks 8
7.6Liger Kernel
Liger 是 Linkedin 开源的 fused PyTorch kernel 库:fused RMSNorm / RoPE / SwiGLU / cross_entropy 等。开 --use_liger_kernel true 可以省 60% activation 显存、训练快 20%。
swift sft \
--train_type lora \
--use_liger_kernel true
注意 Liger 跟 attention 实现不冲突,可以和 flash-attn 一起开。
7.7选择决策表
| 需求 | 选 |
|---|---|
| 第一次微调,要稳 | lora r=16 |
| 显存极紧 + 想全参效果 | galore |
| 显存紧 + 不想 LoRA | lisa |
| 长上下文(> 32K)训 | longlora |
| 持续学习 / 增量领域 | llamapro |
| 追极致显存效率 | + liger_kernel |
7.8swift 的 tuner 抽象 vs PEFT 关系
初学者常误以为 swift 的 LoRA = HF PEFT。实际是两套并存:
| 维度 | HF PEFT 路径 | swift 自家 tuner 路径 |
|---|---|---|
| 启用 | --tuner_backend peft(默认) | --tuner_backend swift |
| 类 | peft.PeftModel | swift.tuners.SwiftModel(base.py:30) |
| 支持算法 | LoRA / DoRA / IA³ / OFT 等所有 PEFT 方法 | 11 个 swift 独门 tuner(见 7.9) |
| 多 adapter | PEFT 原生 | SwiftModel 自带多 adapter dict |
| config 扩展 | swift 在 LoraConfig 加了 lora_dtype / lorap_lr_ratio / lorap_emb_lr 三个字段 | 独立 dataclass |
| 保存格式 | 同 PEFT 标准 adapter_model.safetensors | swift 自己的 additional_config.json 共存 |
7.9swift 自家的 11 个 tuner
swift 自己实现的 tuner 集中在 swift/tuners/,按 SWIFT_MAPPING(mapping.py:30–42)注册:
| tuner | 位置 | 用 |
|---|---|---|
LoRA | lora.py + lora_layers.py(27 KB) | swift 自家 LoRA(带 VRAM 优化) |
Adapter | adapter.py | 经典 bottleneck adapter |
Prompt | prompt.py | swift 版 prompt tuning |
ReFT | reft.py | Representation Fine-Tuning(修改 hidden state) |
Side | side.py | side-network tuning |
ResTuning | restuning.py + restuning_components.py | 残差 tuning |
LongLoRA | longlora/longlora.py | shift attention 长上下文 |
NEFTune | neftune.py | embedding noise 增强 |
LLaMAPro | llamapro.py | 逐层渐进解冻 |
SCETuning | scetuning/scetuning.py | Selective Component Extraction |
Part | part.py | 部分参数训练 |
7.10tuner_plugin:插件式 tuner
swift/tuner_plugin/ 提供另一套抽象。基类 Tuner(base.py)只要实现 3 个方法:
class Tuner(ABC):
@classmethod
def prepare_model(cls, model, args): ...
@classmethod
def save_pretrained(cls, model, save_dir, ...): ...
@classmethod
def from_pretrained(cls, model, model_dir, ...): ...
现有插件:
| 插件 | 用 |
|---|---|
lora_llm | LoRA + LLM 层(trainer mixin 默认用这个) |
ia3 | IA³ scale 向量 |
dummy | 不挂任何 tuner,纯全参(debug 用) |
"我要写一个新 tuner 让 swift 全套 trainer 自动支持" → 推荐写 plugin 而不是直接改 swift/tuners/,因为 plugin 更松耦合。
7.11多 adapter:swift 的实战 API
SwiftModel 支持 多 adapter 共存 + 动态激活,跟 PEFT 的 add_adapter / set_adapter 类似但语法不同:
# 训练时不需要写代码;swift sft 自动支持
swift sft \
--train_type lora \
--target_modules all-linear \
--resume_from_checkpoint saves/v0-xxx \
--adapter_name lora_v2 # ★ 在已有 adapter 基础上新增
# 推理时切换
swift infer \
--adapters saves/v0-xxx,saves/v1-yyy \
--adapter_name_or_path lora_v2 # 激活第二份
HF PEFT 同样支持,但 swift 给了 CLI 一等公民地位,不用写一行 Python。多 adapter 切换是 ms-swift 在多任务部署时的强项。
7.12这章你需要带走的
- ms-swift 的 PEFT 比 HF PEFT 多了 GaLore / LISA / LongLoRA / LLaMA-Pro;
- GaLore 是"全参省显存",LISA 是"逐层激活",两者思路完全不同;
- 长上下文专用 LongLoRA + S²-Attn;
- Liger Kernel 是"加速器"不是 PEFT,可以叠在任何 train_type 上。