- 人工智能
- 大模型
- 预训练
- 微调
- LoRA
- RLHF
- 强化学习
- 分布式训练
【免费下载链接】PaddleNLP
Easy-to-use and powerful LLM and SLM library with awesome model zoo.
导读:本文是一篇面向初学者的端到端精调实战指南,以 PaddleNLP 开源库(GitHub 加速计划 / pa / PaddleNLP 镜像仓库)中
docs/zh/llm/docs/finetune_tutorial.md为核心脉络展开。你将首先理解"预训练 vs 精调"的核心差异与 Alpaca 有监督数据格式,然后跟随完整命令对 Qwen2.5-0.5B 模型完成 SFT 全参精调、Prefix Tuning 与 LoRA 参数高效微调(PEFT),并结合llm/run_finetune.py、llm/config/qwen/下的真实配置与paddlenlp.peft源码,深入掌握各精调方法的底层原理、配置文件每个字段的含义与选型建议。学完本文,你将能独立搭建一条"数据准备 → 配置编写 → 单卡/多卡训练 → 权重保存/合并 → 推理"的完整精调流水线。
1. 什么是精调(Fine-tuning)
经过预训练,我们拥有了具备通用语言能力的基础模型(base model)。但如果把这个模型直接应用于某一个特定领域(如广告文案生成、医疗问答、法律文书),效果往往并不理想——原因在于预训练语料没有针对特定任务场景进行特化。幸运的是,大模型经过预训练已经拥有了很强的通用能力,只需要少量特定领域的有监督数据,就可以大幅提升其在特定领域的能力,这一过程就是精调(Fine-tuning)。
预训练与精调的核心差异可以简单对比为:
| 对比维度 | 预训练(Pre-training) | 精调(Fine-tuning) |
|---|---|---|
| 数据量 | 海量通用文本 | 少量特定任务数据 |
| 训练目标 | 学习通用语言知识 | 优化具体任务表现 |
| 训练时间 | 很长 | 较短 |
在 PaddleNLP 仓库中,预训练与精调分别由两条独立的脚本入口承载:预训练对应 llm/run_pretrain.py,精调对应 llm/run_finetune.py。两者共享同一套"配置文件 + 命令行参数"的启动方式,因此从一个入口切换到另一个入口非常顺滑。本文聚焦精调链路。
2. 精调数据:理解 Alpaca 有监督数据格式
与预训练使用的无监督语料不同,精调数据是有监督数据——每一条样本通常由一个"指令(instruction)"(向大模型说的话)和一个"输出(output)"(大模型应该给出的回应)组成。PaddleNLP 精调脚本最常用的数据格式是Alpaca 格式,一个简单样本如下:
{ "instruction": "给出首都:", "input": "法国", "output": "巴黎" }各字段含义:
instruction:用户向大模型输入的指令;input:任务相关的输入,通常为空;output:大模型的预期输出。
除了 Alpaca 格式,llm/docs/finetune.md 还说明了精调脚本另一套常见数据约定:每行一个 JSON 字典,包含src(模型的输入指令/提示,str或List(str))与tgt(模型的输出)两个字段。也就是说,无论使用instruction/input/output还是src/tgt结构,llm/run_finetune.py 都能通过 llm/utils/data.py 中的转换函数适配为 token id 序列用于训练。
2.1 获取 demo 数据集
本教程使用tatsu-lab/alpaca的 demo 数据集。首先克隆 PaddleNLP 仓库(如果之前已经操作过,可以跳过这一步):
git clone https://gitcode.com/gh_mirrors/pa/PaddleNLP.git进入llm运行目录并下载、解压 demo 数据:
cd PaddleNLP/llm wget https://bj.bcebos.com/paddlenlp/datasets/examples/alpaca_demo.gz tar -xvf alpaca_demo.gz解压后得到的data目录即作为配置文件中dataset_name_or_path的取值。从 llm/run_finetune.py#L765-L830 的create_dataset实现可以看到,脚本会自动寻找dataset_name_or_path/train.json(或train/*.json)作为训练集、dev.json(或dev/*.json)作为验证集、test.json(或test/*.json)作为测试集,也支持直接传入内置数据集名称。
3. 精调(Fine-tuning)的两条技术路线
对大模型的精调,本质上是对其参数进行微调,这里有两条路线可选:
- SFT(Supervised Fine-Tuning,监督式微调):精调大模型的全部参数;
- PEFT(Parameter-Efficient Fine-Tuning,参数高效微调):精调大模型的部分参数。
如果拥有足够的计算资源对全部参数进行微调,选择 SFT;如果资源不足或受限,则选择 PEFT,只对模型的小部分关键参数(或新增参数)进行微调。PaddleNLP 对两类方法都封装好了精调脚本,用户只需切换不同模型的配置文件,直接执行命令即可进行精调,无需编写训练循环。
3.1 SFT:全参精调 Qwen2.5-0.5B
SFT 的训练过程就是让模型根据输入尽可能产生与给定输出一样的输出。以 Qwen2.5-0.5B 为例,单卡启动命令如下(约需 12G 显存):
python -u run_finetune.py ./config/qwen/sft_argument_0p5b.json多卡启动命令如下(约需 45G 显存,使用 8 卡数据并行):
python -u -m paddle.distributed.launch --devices "0,1,2,3,4,5,6,7" run_finetune.py ./config/qwen/sft_argument.json对应的真实配置文件是 llm/config/qwen/sft_argument_0p5b.json 与 llm/config/qwen/sft_argument.json。前者面向 0.5B 小模型、使用 FP16 混合精度;后者面向 Qwen2-7B、使用 BF16 并开启 FlashAttention。两者核心字段对比如下:
| 配置字段 | sft_argument_0p5b.json(单卡演示) | sft_argument.json(8 卡) | 说明 |
|---|---|---|---|
model_name_or_path | Qwen/Qwen2.5-0.5B-Instruct | Qwen/Qwen2-7B | 预训练模型名称或本地模型路径 |
dataset_name_or_path | ./data | ./data | 数据集目录,含 train/dev/test |
output_dir | ./checkpoints/sft_ckpts | ./checkpoints/sft_ckpts | 模型与 checkpoint 保存目录 |
per_device_train_batch_size | 1 | 1 | 单卡 micro batch,建议配合梯度累积 |
gradient_accumulation_steps | 4 | 4 | 梯度累积步数,等效 batch = 1×4 |
num_train_epochs | 3 | 3 | 训练轮次 |
learning_rate | 3e-05 | 3e-05 | 优化器初始学习率 |
src_length/max_length | 1024 / 2048 | 1024 / 2048 | 输入上下文长度 / 输入+生成最大长度 |
fp16/bf16 | fp16: true | bf16: true | 混合精度开关 |
fp16_opt_level | O2 | O2 | O2 级别下模型参数直接转为半精度 |
use_flash_attention | false | true | 是否使用 FlashAttention |
sharding | stage2 | stage2 | 分组参数切片的数据并行策略 |
关键训练参数说明(对应 llm/docs/finetune.md#L292-L317 的 TrainingArguments 说明):
per_device_train_batch_size:训练集单卡批处理大小(micro batch),越大越占显存、训练代价越高;gradient_accumulation_steps:梯度累积步数,多次计算梯度累加后一次性更新参数,等效于把 batch size 扩大该倍数,建议 batch size 设为 1、用梯度累积控制有效 batch;num_train_epochs:训练轮次,默认为 3;learning_rate:优化器初始学习率,SFT 全参精调通常取1e-5 ~ 5e-5量级;warmup_steps:warmup 步数,配置为 30 表示前 30 步学习率线性爬升;evaluation_strategy/save_strategy:评估/保存策略,epoch表示每个 epoch 结束时执行,也支持steps与no;fp16_opt_level:O1下仅白名单算子用半精度计算,O2下模型参数直接转为float16/bfloat16;recompute:重计算,开启后通过丢弃并重算中间激活降低显存,从而支持更大 batch;tensor_parallel_degree/pipeline_parallel_degree/sharding:分别控制张量并行、流水线并行与参数切片并行,即 4D 并行策略的核心开关;unified_checkpoint:统一 checkpoint 格式,便于多并行策略间的权重转换与续训;load_best_model_at_end/metric_for_best_model:训练结束时自动加载验证集上accuracy最优的 checkpoint。
从源码看,llm/run_finetune.py#L113-L135 的main()通过PdArgumentParser解析(GenerateArgument, ModelConfig, ReftArgument, DataConfig, SFTConfig)五组参数;当命令行第一个参数以.json结尾时,调用parse_json_file_and_cmd_lines()读取配置文件,并允许命令行参数覆盖配置文件中的字段。这意味着你可以在不改动 JSON 的前提下,随时通过追加命令行参数(如--learning_rate 1e-4 --num_train_epochs 5)调整训练设置。此外,脚本会检测output_dir下已存在的 checkpoint 并自动续训(llm/run_finetune.py#L137-L145),这是断点续训的底层机制。
3.2 PEFT:只更新小部分参数
在实际业务环境中,常常需要对参数量较大的模型进行微调,此时若使用 SFT,显存与时间开销都可能过大。PEFT 方法只更新小部分参数(或新增少量参数),常见的路线有参数附加方法(如 Prefix Tuning)与低秩分解方法(如 LoRA)等。PaddleNLP 的 PEFT API 统一实现在 paddlenlp/peft 目录,单卡/分布式 LoRA 与 Prefix-Tuning 均开箱即用;run_finetune.py的create_peft_model()(llm/run_finetune.py#L563-L737)会根据配置依次构建对应的 PEFT 模型。
3.2.1 Prefix Tuning:向每层插入可学习前缀
Prefix Tuning(前缀调优)是一种参数高效微调技术:在预训练大语言模型的每一层前面插入一段可学习的"前缀向量"(prefix embedding),而不是更新模型的全部参数,从而实现任务适配。
举例来说,在 SFT 中模型的输入是"输入句";而在 Prefix Tuning 中,输入会变成:
prefix + 输入句即模型会新增一部分专门处理 prefix 的网络,这部分多出来的参数就是我们要微调的部分。从原理层面看,prefix embedding 由专门的 prefix encoder 网络生成数个张量,以past_key_value的方式被插入到语言模型每一层的 hidden_state 之前(详见 llm/docs/peft.md#L20-L28)。和 LoRA 类似,Prefix Tuning 会冻结整个预训练模型的所有参数,只对 prefix embedding 进行梯度更新,训练参数量通常只有常规 SFT 的 0.1% 量级。
启动单卡 Prefix Tuning 命令如下(约需 10G 显存):
python run_finetune.py ./config/qwen/pt_argument_0p5b.json对应的配置文件 llm/config/qwen/pt_argument_0p5b.json 与 SFT 配置的最大区别在于只增加了一行"prefix_tuning": true,同时学习率由 SFT 的3e-05提升到3e-02(Prefix Tuning 只更新新增的少量前缀参数,需要相对更大的学习率)。7B 模型的 Prefix Tuning 配置见 llm/config/qwen/pt_argument.json。
从源码看,llm/run_finetune.py#L566-L591 会调用get_prefix_tuning_params(model)自动从模型配置中提取num_attention_heads、num_hidden_layers、hidden_size、multi_query_group_num等维度,据此构造PrefixConfig并包装为PrefixModelForCausalLM。底层实现位于 paddlenlp/peft/prefix,其中mark_only_prefix_as_trainable()只把 Prefix embedding 与 Prefix projection 层标记为可训练。需要注意的是:Prefix Tuning 目前不支持流水线并行(llm/run_finetune.py#L567-L568 会直接抛出NotImplementedError)。
PrefixConfig的核心可配置项(详见 llm/docs/peft.md#L195-L230):
num_prefix_tokens:前缀 token 个数(如 64);num_attention_heads、num_hidden_layers、hidden_size、multi_query_group_num:与 base model 结构对齐的维度参数;prefix_projection:是否对 prefix tokens 做 projection,默认为False;prefix_projection_hidden_size:开启 projection 时投影层的 hidden size;prefix_dropout:prefix projection dropout 比例,默认为 0.0。
3.2.2 LoRA:低秩分解参数高效微调
LoRA(Low-Rank Adaptation,低秩适配)是目前最流行的大模型微调方法。其核心思想是:向模型插入少量可训练的低秩矩阵,在不改变原模型参数的前提下完成微调任务。如图中示例所示,一个很大的参数矩阵(灰色部分)可以近似分解为两个较小的矩阵 A 与 B 相乘,从而把一个需要整体更新的大矩阵,替换为参数量大幅减少的两个小矩阵。
其数学形式为:对于预训练权重矩阵 $W_0$,通过引入两个低秩矩阵 $A \in \mathbb{R}^{r \times k}$、$B \in \mathbb{R}^{d \times r}$ 近似权重的更新过程:
$$ W_0 + \Delta W = W_0 + BA $$
训练期间 $W_0$ 参数被冻结,只对 A、B 两个矩阵进行梯度更新,前向传播公式为:
$$ h = W_0x + BAx $$
由于训练参数减少,训练过程会减少大量中间变量的存储,从而大幅节约训练显存。在训练完成后推理时,将原本的参数矩阵与微调的参数矩阵相加,既不影响原本的预训练参数,也能实现微调效果——这种"即插即用、随取随合"的优点让 LoRA 成为大模型微调的热门方法。
启动单卡 LoRA 命令如下(约需 9G 显存):
python run_finetune.py ./config/qwen/lora_argument_0p5b.json对应的配置文件 llm/config/qwen/lora_argument_0p5b.json 同样是在 SFT 配置基础上增加了一行"lora": true,学习率取3e-04(介于 SFT 与 Prefix Tuning 之间);llm/config/qwen/lora_argument.json 为 7B 模型版本。
从源码看,llm/run_finetune.py#L593-L628 会通过get_lora_target_modules(model)自动收集模型中的线性层作为 LoRA 目标模块,然后构造LoRAConfig(默认r=8、lora_alpha=16,即2 * lora_rank)并包装为LoRAModel,最后model.print_trainable_parameters()打印可训练参数占比。底层实现在 paddlenlp/peft/lora 与 paddlenlp/peft/lora/lora_model.py:
LoRAConfig常用字段:r(A/B 矩阵秩,默认 8)、target_modules(适配 LoRA 的模块名或正则 List)、lora_alpha(alpha 值)、lora_dropout(dropout 比例)、tensor_parallel_degree(张量并行度,须与 base model 保持一致)、dtype(LoRA 矩阵参数类型);LoRAModel关键方法:mark_only_lora_as_trainable()冻结主干参数、save_pretrained()/from_pretrained()保存与载入权重、print_trainable_parameters()打印可训练参数统计;- 保存时会生成
lora_model_state.pdparams权重文件与lora_config.json配置文件(详见 llm/docs/peft.md#L51-L69)。
3.2.3 更丰富的 PEFT 算法族
除了 LoRA、Prefix Tuning,PaddleNLP 还支持LoKr、VeRA、MoRA、ReFT、rsLoRA、LoRA+、PiSSA、MoSLoRA等多种精调算法,以及DisLoRA、TARE等。这些算法由run_finetune.py中的create_peft_model()统一调度——lora/prefix_tuning/lokr/dislora/reft/vera/tare等开关对应不同分支(llm/run_finetune.py#L563-L737),对应实现分布在 paddlenlp/peft 的lora/、prefix/、lokr/、dislora/、reft/、vera/、tare/子目录中。
从 llm/docs/finetune.md#L240-L331 的参数说明可以归纳出各算法的关键开关:
| 开关参数 | 对应算法 | 关键扩展参数 |
|---|---|---|
rslora | rsLoRA(对缩放因子按秩调整) | 与lora搭配使用 |
lora_plus_scale | LoRA+(B 与 A 使用不同学习率) | 设置 B 与 A 的学习率比例 |
pissa | PiSSA(对主干做 SVD 初始化) | 需lora: true |
lora_use_mixer/mixer_num | MoSLoRA | 暂不支持张量模型并行 |
use_mora | MoRA(高秩非低秩分解) | 暂不支持张量模型并行 |
vera | VeRA(共享随机基向量的低秩微调) | vera_rank,默认 8 |
lokr | LoKr(KronA 低秩分解变体) | lokr_rank,默认 8 |
dislora | DisLoRA(可消除的 LoRA) | dislora_rank,默认 8 |
reft | ReFT(表征干预微调) | 由 ReftArgument 控制(见下) |
neftune | NEFTune(向 embedding 注入噪声提升微调效果) | neftune_noise_alpha,默认 5.0 |
ReFT 专项参数(ReftArgument)定义在 llm/utils/argument.py#L18-L26:layers(干预哪些层,默认all)、position(干预哪些位置的 token,默认f7+l7)、intervention_type(干预网络类型,默认LoreftIntervention)、rank(干预网络低秩,默认 8)、act_fn(激活函数,默认linear)、add_bias(是否加偏置,默认 False)、dropout(Dropout rate,默认 0.0)。
更多大模型精调使用文档、训练细节和各算法效果对比,请参见 大模型精调教程;PEFT 的完整 API 说明见 llm/docs/peft.md。
4. 精调后的权重保存与合并
训练结束后,run_finetune.py会把模型、tokenizer、训练指标与训练状态保存到output_dir指定的目录(llm/run_finetune.py#L517-L525)。
对于LoRA 等 PEFT 权重,为了后续的模型压缩和静态图推理方便,PaddleNLP 提供了参数合并脚本,可以将 LoRA 参数合并回主干模型并保存完整权重:
python tools/merge_lora_params.py \ --model_name_or_path ./base_model \ --lora_path ./checkpoints/lora_ckpts \ --output_path ./checkpoints/lora_merge \ --device "gpu" \ --safe_serialization True脚本参数说明(对应 llm/docs/finetune.md#L109-L116):
model_name_or_path(必填):主干模型参数路径;lora_path:LoRA 参数和配置路径(lora_model_state.pdparams+lora_config.json);output_path(必填):合并后权重保存路径;device:运行环境,默认gpu;safe_serialization:是否保存为 safetensors 格式,默认True。
同类合并脚本还包括tools/merge_vera_params.py(VeRA)、tools/merge_lokr_params.py(LoKr)、tools/merge_dislora_params.py(DisLoRA),用法一致。合并完成后即可使用 llm/predict/predictor.py 等推理入口进行动态图预测。
5. 进阶实践建议与常见坑位
结合 llm/docs/finetune.md 与源码实现,给出以下可直接落地的实践建议:
- 提升训练效率:将
zero_padding与greedy_zero_padding同时设为True(Zero Padding 数据流可减少 Padding 冗余计算、大幅提升有效 Token 计算效率)。此时建议per_device_train_batch_size=1,用gradient_accumulation_steps控制 batch size,并适当调整max_length。注意:eval_with_do_generation为 True 时评估过程不支持 Zero Padding(llm/docs/finetune.md#L273)。 - 注意力加速:将
use_flash_attention设为True使用 FlashAttention;在其基础上把flash_mask设为True使用 FlashMask(需要同时开启 zero padding 与 flash attention,否则脚本会自动开启,见 llm/run_finetune.py#L267-L270,且仅支持 DeepSeekV2/V3、Llama、Qwen2/Qwen2Moe 等系列模型)。 - 混合精度选择:0.5B 小模型用
fp16 + fp16_opt_level=O2即可;7B 及以上推荐bf16(BF16 动态范围更大,训练更稳定)。O2 级别下若未指定fp16或bf16会直接报错(llm/run_finetune.py#L158-L164)。 - LoRA 提速技巧:
use_quick_lora可加速 LoRA 训练;lora_alpha默认取2 * lora_rank(rslora开启时按 rsLoRA 规则调整)。LoRA 策略默认应用在所有 Linear 层。 - 主干模型量化 + LoRA:可通过
weight_quantize_algo(如weight_only_int4、weight_only_int8、nf4、fp4)将主干模型量化到低比特,搭配 LoRA 形成 QLoRA 训练,在显存受限时是可行方案(llm/docs/finetune.md#L94)。 - 并行策略:SFT 与 LoRA 均支持 4D 并行(
tensor_parallel_degree、pipeline_parallel_degree、sharding_parallel_degree、sharding),可扩展至单机 LoRA 微调千亿模型;但 MoSLoRA、LinChain、MoRA、VeRA、LoKr、DisLoRA、ReFT 等算法暂不支持张量模型并行,Prefix Tuning 不支持流水线并行,配置前需确认算法限制。 - LoRA 精度注意:LoRA 模式下目前不支持开启
sharding_stage1_overlap优化(llm/run_finetune.py#L594-L597)。
6. 完整学习路径:从入门到进阶
围绕精调主题,本仓库还提供了完整的配套资料,建议按以下顺序深入:
- 本文(入门实操):本指南对应的原文为 docs/zh/llm/docs/finetune_tutorial.md,同步在 Ai Studio 项目
9169303上开放了在线体验环境; - 精调完整文档:llm/docs/finetune.md(含全量精调、LoRA/QLoRA、Prefix Tuning、VeRA、LoKr、DisLoRA、ReFT 的完整启动命令与全部参数说明);
- PEFT API 详解:llm/docs/peft.md(LoRAConfig/LoRAModel/PrefixConfig/PrefixModelForCausalLM 的类与函数说明);
- 算法原理总览:llm/docs/algorithm_overview.md(LoRA+、PiSSA、rsLoRA、NEFTune、VeRA、MoRA、ReFT、MoSLoRA 等算法原理);
- 配置文件样板:Qwen 系配置见 llm/config/qwen,Llama 系配置见 llm/config/llama(含
lora_argument.json、qlora_argument.json、pt_argument.json、vera_argument.json、lokr_argument.json、dislora_argument.json、reft_argument.json等); - 源码入口:精调主脚本 llm/run_finetune.py、参数定义 llm/utils/argument.py、PEFT 实现 paddlenlp/peft。
环境要求:运行精调脚本需要 PaddlePaddle 3.0-beta 及以上、PaddleNLP 3.0.0b3 及以上;run_finetune.py启动时也会校验 paddlenlp 版本是否 ≥ 3.0.0b3(llm/run_finetune.py#L103-L110)。建议在配置好对应版本环境后,先跑通 0.5B 的 SFT / Prefix Tuning / LoRA 三个示例,再平滑迁移到 7B 及以上模型与多卡训练。
- 人工智能
- 大模型
- 预训练
- 微调
- LoRA
- RLHF
- 强化学习
- 分布式训练
【免费下载链接】PaddleNLP
Easy-to-use and powerful LLM and SLM library with awesome model zoo.
相关推荐
PaddleNLP 大模型微调实战指南:从全参数 SFT 到 LoRA/QLoRA 与多种 PEFT 策略
PaddleNLP 大模型微调实战指南:从全参数 SFT 到 LoRA/QLoRA 与多种 PEFT 策略 导读 本文基于 PaddleNLP 官方微调文档,系
人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLPPaddleNLP高效精调完全指南:SFT、Prefix Tuning、LoKr、ReFT等8种PEFT技术选型清单
PaddleNLP高效精调完全指南:SFT、Prefix Tuning、LoKr、ReFT等8种PEFT技术选型清单 PaddleNLP 是飞桨(PaddleP
人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLPPaddleNLP PEFT 实战指南:使用 LoRA 与 Prefix-Tuning 进行大模型低参数微调
PaddleNLP PEFT 实战指南:使用 LoRA 与 Prefix Tuning 进行大模型低参数微调 导读 本文聚焦 PaddleNLP 提供的 PEF
人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLP
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考