type
Post
date
Dec 17, 2025
slug
unsloth/learning
summary
“微调没有单一的“最佳”方法,只有针对不同场景的最佳实践。重要的是尝试不同的方法和配置,以找到最适合您的数据集和用例的方法。QLoRA (4 位)是一个很好的起点,它提供了一种非常经济高效、资源友好的模型微调方法,且无需繁重的计算要求。”
status
Published
tags
AI
LLM
category
技术茶点
icon
password
哪些业务情景可能需要实施 LLM Fine-tuning?
FAQ + Is Fine-tuning Right For Me? | Unsloth Documentation
- 更新知识:引入新的特定领域信息。
- 自定义行为:调整模型的语气、个性或反应风格。
- 针对任务进行优化:提高特定用例的准确性和相关性。

FAQ + Is Fine-tuning Right For Me? | Unsloth Documentation
If you're stuck on if fine-tuning is right for you, see here! Learn about fine-tuning misconceptions, how it compared to RAG and more:
1. 基础笔记
- Unsloth
Unsloth 是一款专为参数高效微调(PEFT)设计的工具包,它通过优化 CUDA 内核,让 LoRA 微调速度比 Hugging Face 快 2 到 5 倍,同时显著减少显存占用。它支持主流的开源模型,让开发者能在消费级显卡上更轻松、更快速地完成大模型的微调任务。
- VRAM
VRAM(Video Random Access Memory),即显存,是显卡上专门用于存储图像数据和计算任务的内存。对于大模型(LLM)而言,VRAM 的作用至关重要,它决定了模型推理和微调的上限,因为它直接存储了模型本身的参数、中间计算结果以及优化器状态等所有数据。

- SFT
SFT(Supervised Fine-tuning),即有监督微调,是一种利用标注好的“问答对”数据集来训练预训练大模型的技术。这就像给一个知识渊博的学生提供一本带有标准答案的习题集,使其学习如何根据特定的指令(问题)产生预期的、符合人类偏好的回答(答案)。这种方法是大多数微调工作的基础,旨在让模型在特定任务或领域上,如客服问答、代码生成或写作风格模仿,表现得更精准和专业。
例如:GPT-4作为基础模型;然而,OpenAI 对其进行了微调,以更好地理解指令和提示,从而创建了今天每个人都在使用的 ChatGPT-4。
- LoRA
LoRA(Low-Rank Adaptation)是一种参数高效微调(PEFT)技术,它通过在预训练大模型的特定层中注入少量可训练的“适配器”来工作。这些适配器利用低秩矩阵分解来表示,因此参数量极小,只占原始模型参数的不到百分之一。通过冻结原始模型的大部分参数,只训练这些小型的适配器,LoRA 显著降低了微调所需的计算资源和显存,同时能够实现与全量微调相近的性能,让开发者能轻松地在消费级硬件上对大型语言模型进行定制化训练。
- PEFT
- LoRA(低秩自适应) ——仅对一小部分额外的“适配器”权重矩阵(16 位精度)进行微调,同时保持原始模型的大部分不变。这显著减少了训练期间需要更新的参数数量。
- QLoRA(量化 LoRA) ——将 LoRA 与模型权重的 4 位量化相结合,能够在极小的硬件上高效地微调超大型模型。通过尽可能使用 4 位精度,可以显著降低内存使用量和计算开销。
- LoRA Hyperparameters(LoRA微调中较为关键的一些超参数)
- LoRA Rank (
r) - LoRA Alpha (
lora_alpha) - 作用:lora_alpha 决定了低秩更新的“强度”。较高的lora_alpha值会放大低秩矩阵的贡献,使模型更倾向于适应新任务;较低的lora_alpha值则使更新更加保守,减少对原始预训练权重的偏离。
- 与r的关系:通过除以秩r(lora_alpha / r),LoRA确保缩放因子与低秩矩阵的维度无关,从而在不同秩大小下保持更新幅度的一致性。
- 实际应用:例如,设置lora_alpha=16和r=8,缩放因子为16/8=2,这意味着低秩更新的影响会被放大2倍。选择合适的lora_alpha值需要在实验中权衡任务性能和模型稳定性,通常与r一起调整。
- LoRA Dropout
- 作用:LoRA Dropout 通过随机丢弃低秩矩阵中的部分权重,减少过拟合风险,尤其在微调数据量较小或任务复杂度较高时效果显著。它有助于模型在保持低秩更新高效性的同时,提高泛化性能。
- 参数设置:LoRA Dropout 通常以概率值表示(例如 0.1 表示 10% 的权重会被随机丢弃)。具体值需要在实验中调整,过高的 Dropout 率可能导致模型学习不足,而过低的 Dropout 率可能无法有效正则化。
- 与全参数微调的区别:与传统的 Dropout(应用于整个模型的权重或激活)不同,LoRA Dropout 仅作用于低秩更新矩阵,影响范围更小,因此可以在微调时以较低的计算成本实现正则化。
- Weight Decay
- 作用:权重衰减通过限制权重大小,减少模型对训练数据噪声的敏感性,提高对未见过数据的泛化能力。它在一定程度上模拟了“简单模型更优”的思想。
- 与 Dropout 的区别:权重衰减通过直接惩罚权重大小实现正则化,而 Dropout 通过随机丢弃神经元输出实现正则化。两者常结合使用以进一步提高泛化性能。
- 实际应用:在优化算法(如 SGD 或 Adam)中,权重衰减通常作为优化器的超参数直接设置。例如,在 PyTorch 中,可以通过优化器的 weight_decay 参数指定 λ。例如,设置 weight_decay=0.01 表示对权重施加中等强度的 L2 正则化。
- 在 LoRA 上下文中的应用:当结合 LoRA(Low-Rank Adaptation)微调时,权重衰减可以应用于低秩矩阵 A 和 B 的更新,防止这些矩阵的权重过大,从而进一步增强 LoRA 微调的稳定性和泛化能力。
- Warmup Steps
- 作用:Warmup Steps有助于在训练早期避免梯度计算不稳定,尤其在大型模型(如Transformer)或大批量训练中效果显著。它可以减少初始损失的剧烈波动,提高整体训练效率,并改善最终模型性能。
- 参数设置:Warmup Steps通常设置为总训练步数的比例,例如总步数为10,000时,Warmup Steps=500(5%)。具体值取决于数据集大小、模型复杂度及优化器(如AdamW),需通过实验调优。过长的Warmup可能延迟有效学习,过短则可能无法充分稳定训练。
- 与LoRA的结合:在LoRA(Low-Rank Adaptation)微调中,Warmup Steps常用于低秩矩阵的更新过程,结合权重衰减和学习率调度,确保高效适应特定任务而不会过度扰动预训练权重。
- 实际应用:在框架如PyTorch或Hugging Face Transformers中,可通过学习率调度器(如LinearWarmup)设置Warmup Steps。例如,num_warmup_steps=1000 表示前1000步线性增加学习率。这种策略广泛用于BERT、GPT等模型的训练和微调。
- Scheduler Type
- 恒定学习率(Constant Scheduler)
- 学习率在整个训练过程中保持不变。简单但可能导致训练后期收敛缓慢或不稳定。
- 适用场景:简单的模型或短训练周期。
- 线性衰减(Linear Decay Scheduler)
- 学习率从初始值线性下降到0或某个最小值。常与Warmup Steps结合使用,先增加再线性下降。
- 适用场景:需要逐渐减小学习率以细化模型参数的场景,如微调任务。
- 余弦退火(Cosine Annealing Scheduler)
- 学习率按照余弦函数曲线平滑下降,可能在训练末期接近零或周期性重启。提供平滑的收敛特性。
- 适用场景:大型语言模型(如Transformer)的训练或微调,常用于LoRA微调以平衡探索和收敛。
- 指数衰减(Exponential Decay Scheduler)
- 学习率以指数形式快速下降,适合快速收敛但可能过早降低学习率。
- 适用场景:训练初期需要快速调整权重的场景。
- 分段恒定(Step Scheduler)
- 每隔固定步数(或epoch)将学习率降低固定比例(如乘以0.1)。简单但可能不够平滑。
- 适用场景:传统深度学习任务,如CNN训练。
- ReduceLROnPlateau
- 当验证集上的性能(如损失或指标)停止改善时,动态降低学习率。灵活但依赖验证集表现。
- 适用场景:需要根据模型表现自适应调整学习率的场景。
- 作用:调度器类型决定了学习率如何随训练过程变化,直接影响模型的收敛速度、稳定性和最终性能。合理选择调度器类型可以避免过拟合或欠拟合,提高泛化能力。
- 与Warmup Steps的结合:许多调度器(如余弦退火或线性衰减)会结合Warmup Steps,在训练初期逐渐增加学习率,随后按调度器策略衰减。例如,Hugging Face Transformers中常使用linear或cosine调度器与Warmup配合。
- 在LoRA中的应用:在LoRA(Low-Rank Adaptation)微调中,调度器类型(如余弦退火)常用于控制低秩矩阵(A和B)的学习率变化,结合Warmup Steps和权重衰减,确保高效且稳定的任务适配。
- 实际应用:在PyTorch或Hugging Face中,调度器类型通过优化器配置指定。例如,scheduler_type="cosine"表示使用余弦退火调度器。选择合适的调度器类型需要根据任务、模型规模和训练时长实验调优。
- Seed (
random_state) - 作用:控制随机性,保证实验可重复。例如,设置 random_state=42 后,数据分割或参数初始化每次都相同。
- 在LoRA中的应用:在LoRA微调中,种子可用于初始化低秩矩阵(A和B)或控制Dropout等随机操作,确保微调结果一致。
- 实际应用:在框架如PyTorch或scikit-learn中,通过 torch.manual_seed(42) 或 random_state=42 设置。未设置种子时,随机结果不可控。
- Target Modules
- 作用:通过选择目标模块,LoRA只更新特定部分的权重(如query、key、value矩阵),减少计算和内存需求,同时保持微调效果。
- 常见设置:在Transformer模型中,目标模块常包括q_proj(查询投影)、k_proj(键投影)、v_proj(值投影)或dense(全连接层)。例如,设置为["q_proj", "v_proj"]表示只对查询和值投影矩阵应用LoRA。
- 实际应用:在Hugging Face Transformers中,通过target_modules=["q", "v"]指定。选择哪些模块需要根据任务和模型结构实验确定。
- Gradient Accumulation and Batch Size equivalency(梯度累积与批次大小等效性)
- Batch Size (
batch_size) - 作用:较大的batch_size提供更稳定的梯度估计,但需要更多显存;较小的batch_size节省显存,但可能导致梯度波动。LoRA因只更新低秩矩阵,内存需求较低,允许稍大的batch_size。
- 在LoRA中的应用:batch_size影响低秩更新的质量。例如,batch_size=4表示每次处理4个样本,累积梯度后更新A和B。结合梯度累积(Gradient Accumulation),可在小batch_size下模拟大批量效果。
- 实际应用:在Hugging Face Transformers中,设置per_device_train_batch_size=8表示每设备处理8个样本。需根据显存和任务调优。
- Gradient Accumulation (
gradient_accumulation_steps) - 作用:允许使用小batch_size降低内存需求,同时通过累积梯度模拟大batch_size的稳定训练效果。例如,batch_size=4,gradient_accumulation_steps=4,相当于有效batch_size=16。
- 在LoRA中的应用:LoRA本身已减少参数更新量,梯度累积进一步优化显存使用,确保微调稳定性和性能,尤其适合大型模型在低资源设备上训练。
- 实际应用:在Hugging Face Transformers中,设置gradient_accumulation_steps=4表示累积4次小批次梯度后更新参数。需根据显存和任务调优。
- Effective Batch Size (Calculated)
- 计算公式: 有效批次大小 = batch_size × gradient_accumulation_steps 例如,若batch_size=4,gradient_accumulation_steps=4,则有效批次大小=16,相当于一次更新使用了16个样本的梯度。
- 作用:有效批次大小决定了梯度估计的稳定性。较大的有效批次大小提供更稳定的梯度,但需要更多计算或内存(通过梯度累积实现)。在LoRA中,它帮助在显存受限时模拟大批量训练效果。
- 在LoRA中的应用:由于LoRA只更新低秩矩阵,内存需求低,有效批次大小可通过增加gradient_accumulation_steps灵活调整,以提高微调稳定性和性能。
- 实际应用:在Hugging Face Transformers中,若设置per_device_train_batch_size=8和gradient_accumulation_steps=2,则有效批次大小=16。需根据任务和硬件调优。
batch_size = 32, gradient_accumulation_steps = 1batch_size = 16, gradient_accumulation_steps = 2batch_size = 8, gradient_accumulation_steps = 4batch_size = 4, gradient_accumulation_steps = 8batch_size = 2, gradient_accumulation_steps = 16batch_size = 1, gradient_accumulation_steps = 32
参数高效微调(PEFT),是针对大型语言模型(LLM)的一种训练策略,其核心在于只更新模型参数中的一小部分,甚至是在不修改原始模型参数的前提下,实现模型在特定任务上的微调。与需要更新模型所有参数的全量微调相比,PEFT 大大降低了对计算资源和存储空间的需求。这使得开发者能够在消费级硬件上进行大模型的微调,从而降低了进入门槛,让更多人能参与到大模型的定制化应用开发中。LoRA、QLoRA、Prefix-Tuning 等都属于 PEFT 技术。

LoRA(Low-Rank Adaptation)秩(rank,简称r)是LoRA技术中的一个关键超参数,表示在模型参数微调时使用的低秩矩阵分解的秩大小。LoRA是一种高效的微调方法,通过在预训练模型的权重矩阵上添加低秩更新矩阵来适应特定任务,而不需要调整整个模型的参数。
具体来说,LoRA假设对模型权重的更新可以表示为低秩矩阵的形式,即通过两个较小的矩阵(通常记为A和B)的乘积来近似权重变化,形式为ΔW = A·B,其中A和B的维度由秩r决定。秩r控制了这些矩阵的“宽度”,即表示更新矩阵的复杂度或自由度。较低的r值意味着更少的参数和更低的计算成本,但可能限制模型的表达能力;较高的r值则允许更复杂的更新,但会增加计算和内存开销。
例如,在微调一个大型语言模型时,选择r=8可能足以捕捉任务特定的模式,而无需修改全部权重。r的选择需要在模型性能和计算效率之间权衡,通常通过实验确定最优值。LoRA的低秩特性使其在资源受限的场景下非常高效,同时保持与全参数微调相当的性能。
LoRA Alpha(lora_alpha)是LoRA(Low-Rank Adaptation)微调技术中的一个超参数,用于控制低秩更新矩阵对模型权重更新的影响幅度。具体来说,lora_alpha 是一个缩放因子,用于调整低秩分解矩阵(A和B的乘积)对模型参数更新的贡献程度。
在LoRA中,模型权重的更新表示为ΔW = A·B,其中A和B是两个低秩矩阵,秩由参数r决定。为了控制更新的强度,实际的权重更新会乘以一个缩放因子,即ΔW' = (lora_alpha / r) * A·B。这个缩放因子的引入使得LoRA可以灵活地调节低秩更新的影响,而不直接依赖于矩阵A和B的数值大小。
通过合理设置lora_alpha,LoRA可以在保持低内存占用的同时,高效地适应特定任务,广泛应用于大型语言模型的微调场景。
LoRA Dropout 是 LoRA(Low-Rank Adaptation)微调技术中的一个超参数,指在低秩更新矩阵的训练过程中引入的 Dropout 机制,用于防止过拟合并提高模型的泛化能力。Dropout 是一种正则化技术,通过在训练时随机“丢弃”(即将某些神经元的输出置为零)一部分计算单元来减少模型对特定参数的依赖。
在 LoRA 的上下文中,LoRA Dropout 具体指的是在低秩矩阵 A 和 B(用于表示权重更新 ΔW = A·B)的计算或更新过程中,随机丢弃一部分元素或连接。通常,Dropout 会被应用于矩阵 A 和 B 的某些权重,以避免低秩更新过于依赖特定的模式或特征,从而增强模型对新数据的适应能力。
通过合理设置 LoRA Dropout,结合 LoRA 的其他超参数(如秩 r 和 lora_alpha),可以在资源受限的环境下实现高效且稳定的模型微调,广泛应用于大型语言模型的特定任务适配。
权重衰减(Weight Decay)是一种在深度学习模型训练中常用的正则化技术,通过在损失函数中添加权重参数的惩罚项来防止模型过拟合,从而提高其泛化能力。权重衰减通常通过在优化过程中对模型的权重施加一个 L2 正则化项(即权重的平方和)来实现。
具体来说,权重衰减通过在损失函数中加入一个正则化项,形如 λ⋅∑wi2 \lambda \cdot \sum w_i^2 λ⋅∑wi2,其中 λ \lambda λ 是权重衰减系数(一个超参数,通常为小值,如 0.01 或 0.001),wi w_i wi 是模型的权重参数。优化器在最小化损失函数时,不仅要优化原始任务的损失,还要考虑权重的 L2 范数,从而倾向于使权重保持较小的值。这种机制可以有效减少模型对训练数据的过拟合,防止权重变得过大而导致模型过于复杂。
λ \lambda
通过合理设置权重衰减系数,模型可以在训练过程中保持较好的稳定性,尤其在数据量有限或模型复杂时,能够有效提升性能。权重衰减的强度需要通过实验调优,过高的值可能导致模型欠拟合,过低的则可能不足以防止过拟合。
Warmup Steps(预热步骤)是深度学习模型训练中一种学习率调度策略的超参数,指在训练开始阶段逐步增加学习率(从一个较小的初始值线性或指数增长到目标学习率)的步数或迭代次数。这种方法旨在解决训练初期模型参数随机初始化导致的学习不稳定问题,提高训练的收敛性和稳定性。
在优化过程中,学习率决定了参数更新的步长。如果从一开始就使用较高的学习率,可能会导致梯度爆炸或训练振荡;反之,Warmup 通过“预热”阶段让模型逐步适应训练动态。具体实现通常是将学习率从0(或很小的值)线性增加到预设的最大学习率,持续Warmup Steps个迭代步骤(例如,总训练步数的5-10%)。之后,学习率可能保持恒定、余弦退火或线性衰减。
通过合理设置Warmup Steps,训练过程更平滑,尤其在资源受限或大规模数据场景下,能显著提升模型的鲁棒性和泛化能力。
调度器类型(Scheduler Type)是深度学习训练中用于控制学习率变化策略的超参数,指的是在训练过程中如何动态调整学习率的算法或方法。学习率调度器(Learning Rate Scheduler)通过在不同训练阶段调整学习率,帮助模型更好地收敛,避免陷入局部最优或训练不稳定。不同的调度器类型适合不同的任务和模型需求。
常见的调度器类型包括以下几种:
通过选择合适的调度器类型,结合Warmup Steps、权重衰减等超参数,训练过程可以在效率和性能之间取得平衡,尤其在资源受限或微调大型模型(如LoRA场景)时效果显著。
种子(Seed,或称为 random_state)是深度学习或机器学习中用于初始化随机数生成器的超参数。它确保随机操作(如权重初始化、数据打乱、Dropout等)的结果可重现。设置相同的种子值,模型在每次运行时会产生一致的随机结果,便于调试、比较实验或复现研究。
简单来说,种子就像一个“随机规则书”,固定它就能让随机过程变得可预测,方便实验复现。
目标模块(Target Modules)是LoRA(Low-Rank Adaptation)微调中指定的神经网络模型中需要应用低秩更新的部分(通常是特定层或权重矩阵)。它决定了哪些模块(如Transformer中的注意力层或全连接层的权重)会被LoRA修改,而不是对整个模型进行全参数微调。
简单来说,目标模块是LoRA微调时“重点关注”的网络部分,精准修改以高效适应任务。
梯度累积(Gradient Accumulation)是一种在深度学习训练中使用的技术,旨在通过多次较小的批次(mini-batch)计算梯度并累积,模拟使用较大批次大小(Batch Size)的训练效果。这种方法主要用于解决显存不足的问题。
在深度学习中,批次大小直接影响模型训练的稳定性和效率。较大的批次大小通常能提供更稳定的梯度估计,但需要更多的显存。如果硬件限制无法支持大的批次,梯度累积通过多次前向和反向传播计算小批次的梯度,并将这些梯度累积起来,直到达到等效于目标批次大小的梯度总和,再进行一次参数更新。这样可以在不增加显存需求的情况下,模拟大批量训练的效果。
例如,假设目标批次大小为32,但显存只能支持批次大小为8。通过梯度累积,可以分4次处理批次大小为8的数据,累积4次梯度后再更新模型参数,其效果等价于一次性处理批次大小为32。这种等效性使得梯度累积成为在资源受限环境中实现大批量训练的重要技术,同时保持训练的稳定性和模型性能。
Effective Batch Size =
batch_size * gradient_accumulation_steps
批次大小(batch_size)是深度学习训练中一次前向和反向传播处理的数据样本数量。在LoRA(Low-Rank Adaptation)微调中,batch_size 决定了每次更新低秩矩阵(A和B)时使用的数据量,直接影响训练的内存需求、梯度估计的稳定性和收敛速度。
简单来说,batch_size是LoRA微调中每次处理的数据量,平衡内存与训练稳定性,需实验选择合适值。
梯度累积(gradient_accumulation_steps)是深度学习训练中一种技术,指在更新模型参数前,将多个小批次(mini-batch)的梯度累积起来,模拟大批量训练的效果。在LoRA(Low-Rank Adaptation)微调中,它用于在显存受限时,通过多次小批次计算梯度,累积到指定步数后再更新低秩矩阵(A和B)。
简单来说,gradient_accumulation_steps是LoRA微调中通过多次小批次梯度累积模拟大批量训练的技术,平衡内存与效果。
有效批次大小(Effective Batch Size)是在深度学习训练中,通过批次大小(batch_size)和梯度累积步数(gradient_accumulation_steps)计算得到的等效批次大小,表示一次参数更新实际使用的样本总数。在LoRA(Low-Rank Adaptation)微调中,它反映了低秩矩阵(A和B)更新时考虑的总样本量。
简单来说,有效批次大小是LoRA微调中batch_size和梯度累积步数的乘积,表示一次参数更新使用的样本量,影响训练稳定性。
假设你希望每个训练步骤有 32 个数据样本。那么你可以使用以下任意配置:
虽然所有这些对于模型的权重更新都是等效的,但它们对硬件的要求却大不相同。
第一个配置(
batch_size = 32)占用最多的 VRAM,在大多数 GPU 上可能会失败。最后一个配置(batch_size = 1)占用最少的 VRAM,但代价是训练速度会略慢。为避免 OOM(内存不足)错误,请始终优先设置较小的batch_size,并逐渐增加gradient_accumulation_steps以达到目标有效批次大小。- RLHF
- PPO
RLHF,即基于人类反馈的强化学习,是一种让大型语言模型(LLM)的回答与人类价值观、偏好和指令保持一致的训练技术。它是一个复杂的多步骤过程,其核心思想是让人类标注员对模型生成的不同回答进行排名,并用这些数据训练一个奖励模型。这个奖励模型学会评估一个回答的“好坏”,然后作为“老师”来指导主模型,通过强化学习算法(如PPO)不断优化自己的生成策略,最终让模型的行为变得更安全、更有帮助、更符合人类的预期。
近端策略优化(PPO)是一种在强化学习领域被广泛应用的算法,尤其在RLHF(基于人类反馈的强化学习)中扮演着核心角色。它的主要目的是在更新模型的策略时,确保新的策略不会与旧的策略相差太远。这就像是在训练一只小狗,你不希望它在一次训练后就完全忘记之前的指令,而是希望它在不断学习新技巧的同时,能稳定地逐步进步。
PPO 通过引入一个“近端约束”来控制策略更新的幅度,从而防止训练过程中的不稳定或崩溃。这使得它在训练大型、复杂的语言模型时更加可靠和高效。在RLHF的流程中,PPO就是那个负责将奖励模型给出的分数转化为模型参数更新,从而让模型生成更“好”答案的关键算法。
- RL
纯强化学习(Pure Reinforcement Learning)是一种机器学习范式,与我们之前讨论的 RLHF 略有不同,它不依赖人类反馈,而是通过与环境的互动来学习。在这种模式下,一个“智能体”(Agent)会观察环境,做出行动,并从环境中获得奖励或惩罚信号。它的目标是学习一个最优的策略,以最大化其累积奖励。在 LLM 领域,这种方法通常用于更复杂的任务,比如让模型学会玩游戏、控制机器人或完成多步推理任务,而不需要预先准备好人类标注的数据集。
- GRPO
群体相对策略优化 (GRPO) 是一种用于训练大模型的先进强化学习方法,它的核心思想是通过比较模型自己生成的多个答案来学习。与传统的强化学习方法不同,GRPO 巧妙地省去了额外的价值网络,从而显著减少了训练所需的计算资源和显存。它让模型为同一个问题生成一组不同的回答,并利用一个奖励模型对这些回答进行评分。模型随后通过对比每个回答与这组回答平均分数的差距来优化自己的策略,从而高效地学习如何生成更好的答案,尤其在数学和代码这类需要复杂推理的任务上表现出色。
如果您想创建一个带有奖励的定制模型(例如法律、医学等领域),那么 GRPO 可以提供帮助。
如果您有输入和输出数据(例如问题和答案),但没有思路或推理过程,GRPO 可以神奇地为您创建推理过程!
- Multi-GPU Training
多卡训练(Multi-GPU Training)是一种利用多张显卡并行处理计算任务的技术,旨在解决单个 GPU 显存不足和训练时间过长的问题。其核心思想是将模型和/或数据分布到多张显卡上,通过数据并行、张量并行或流水线并行等策略协同工作。这使得开发者能够训练那些无法放入单张显卡的巨大模型,并能显著缩短训练周期,是如今大型语言模型开发中不可或缺的关键技术。
- Distillation
蒸馏 (Distillation) 是一种模型压缩和加速的技术,其核心思想是让一个**小型模型(学生模型)去学习一个性能更强、参数量更大的大型模型(教师模型)**的行为。学生模型并不直接学习原始任务的标注数据,而是学习教师模型对于这些数据的输出(比如预测的概率分布)。这种方法使得学生模型能够在保持较高性能的同时,大幅减小体积、降低计算成本,特别适用于将一个复杂的、巨大的模型部署到移动设备或边缘计算等资源受限的环境中。
例如:DeepSeek-R1-Distill-Llama-8B是 Llama-3.1-8B 的微调版本。DeepSeek 利用 DeepSeek-R1 生成的数据对 Llama-3.1-8B 进行了微调。这个过程被称为“蒸馏”(微调的一个子类别),它将数据注入 Llama 模型,以学习其推理能力。
- Learning Rate
- 学习率过大,就像一步迈得太远,可能会直接跨过最低点,导致模型在最优解附近来回震荡,甚至无法收敛。
- 学习率过小,则像迈着小碎步,虽然能确保找到最低点,但会使训练过程变得非常缓慢,耗费大量时间。
学习率(Learning Rate)是深度学习中一个至关重要的超参数,它决定了模型在每次迭代中更新参数的幅度大小。你可以将其类比为一个人在下山时每一步迈出的距离:
因此,选择一个合适的学习率至关重要。开发者通常会采用**学习率调度(Learning Rate Scheduling)**等技术,在训练过程中动态调整学习率,以实现更稳定、高效的模型训练。
- Epochs
- 1 Epoch:模型看到了所有训练数据一次。
- 多个 Epochs:模型反复学习整套训练数据,比如 10 个 epochs 意味着模型完整地学习了这套数据 10 遍。
Epochs(周期)是训练神经网络时的一个核心概念,它指代将整个训练数据集完整地向前和向后传递一次。
可以把训练模型比作学生学习一本教科书:一个 epoch 就相当于学生从头到尾把整本书学完一遍。
通常,为了让模型更好地掌握知识和模式,需要进行多个 epochs 的训练。然而,训练周期过多可能会导致过拟合(Overfitting),即模型过度记忆了训练数据中的细节和噪声,导致在新数据上的表现变差。因此,选择合适的 epochs 数量是一个需要根据模型和任务来权衡的超参数。
- continued pretraining
- 预训练 (Pretraining):一个学生(模型)通过阅读海量百科全书、新闻、小说等(通用语料库),获得了广泛的通识知识。
- 继续预训练 (Continued Pretraining):这个学生现在去医学院(特定领域数据)继续学习,掌握了大量的医学术语、病例和专业知识。
继续预训练 (Continued Pretraining) 是一种训练大型语言模型(LLM)的方法,它是在一个已经通过海量通用数据预训练好的模型基础上,再利用特定领域或特定格式的数据集进行第二阶段的训练。
你可以把这个过程想象成:
这种方法与微调(Fine-tuning)不同,它不是为了让模型遵循指令或模仿某种风格,而是为了让模型深入学习新的知识,比如某个垂直行业的专业术语、事实性信息,或者新的语言。在继续预训练后,模型会**“知道”更多东西,而微调则更多地是让模型“会做”**某件事。
- Alpaca style
instruction(指令):用户提出的具体任务或问题,例如“写一封感谢信。”input(输入):可选字段,用于提供额外背景信息或上下文,例如“收件人是张总。”output(输出):模型应给出的期望回答或响应。
“Alpaca 风格”是一种非常流行的微调格式,它指的是一种简单、易于理解的指令微调数据格式,旨在教会大模型如何遵循人类的指令。
它的核心是使用三个明确的字段来构建训练数据:
这种格式的优势在于其清晰性,它通过明确地将指令、上下文和期望输出分离,使得模型能够高效地学习如何将人类语言中的意图转化为具体的行动或回答。许多开源模型,如 Llama、Mistral 和 Phi,都曾被使用类似 Alpaca 风格的数据集进行指令微调,以提升它们的对话和指令遵循能力。
- ShareGPT format
ShareGPT 格式是一种流行的、用于微调对话型语言模型的数据格式。它源于一个名为 ShareGPT.com 的网站,该网站允许用户分享他们与大型语言模型(如 ChatGPT)的对话记录。
这种格式的核心在于,它将整个对话过程表示为一个由**“
human”(人类)和“gpt”(模型)角色交替发言组成的列表**。这种格式的优势在于,它能够完整地保留多轮对话的上下文和角色信息,这对于训练模型理解对话的流向、保持连贯性以及扮演特定角色至关重要。许多开源的指令微调数据集,尤其是那些旨在训练像 ChatGPT 那样能进行多轮对话的模型,都采用了这种 ShareGPT 格式。
- OpenAI's ChatML format
- 摘抄
- LoRA:对 16 位小型可训练矩阵进行微调,无需更新所有模型权重。
- QLoRA:将 LoRA 与 4 位量化相结合,以最少的资源处理非常大的模型。
- 模型名称以 结尾
unsloth-bnb-4bit表示它们是Unsloth 动态 4 位量化模型。这些模型比标准 BitsAndBytes 4 位模型消耗的 VRAM 略多,但精度明显更高。 - 如果模型名称以 结尾
bnb-4bit,而没有“unsloth”,则它指的是标准 BitsAndBytes 4 位量化。 - 无后缀的模型采用其原始的16 位或 8 位格式。虽然它们是来自官方模型创建者的原始模型,但我们有时会包含重要的修复,例如聊天模板或标记器修复。因此,建议在可用时使用我们的版本。
max_seq_length = 2048– 控制上下文长度。虽然 Llama-3 支持 8192 字节,但我们建议测试时使用 2048 字节。Unsloth 支持 4 倍长的上下文微调。dtype = None– 默认为无;对于较新的 GPU使用torch.float16或。torch.bfloat16load_in_4bit = True– 启用 4 位量化,将微调所需的内存占用减少 4 倍。禁用此功能可启用 LoRA 16 位微调。- 要启用完全微调(FFT),请设置
full_finetuning = True。对于 8 位微调,请设置load_in_8bit = True。注意:True一次只能将一种训练方法设置为。 - 1,000+ 行数据:如果您拥有超过 1,000 行的大型数据集,通常最好对基础模型进行微调。
- 300-1,000 行高质量数据:使用中等规模、高质量的数据集,微调基础或指导模型都是可行的选择。
- 少于 300 行:对于较小的数据集,Instruct 模型通常是更好的选择。对 Instruct 模型进行微调可以使其在保留其内置指令功能的同时满足特定需求。这确保了它无需额外输入即可遵循一般指令,除非您打算大幅更改其功能。
- 有关数据集应该有多大的信息,请参见此处
- 模型名称以 结尾
unsloth-bnb-4bit表示它们是Unsloth 动态 4 位量化模型。这些模型比标准 BitsAndBytes 4 位模型消耗的 VRAM 略多,但精度明显更高。 - 如果模型名称以 结尾
bnb-4bit,而没有“unsloth”,则它指的是标准 BitsAndBytes 4 位量化。 - 无后缀的模型采用其原始的16 位或 8 位格式。虽然它们是来自官方模型创建者的原始模型,但我们有时会包含重要的修复,例如聊天模板或标记器修复。因此,建议在可用时使用我们的版本。
- 调整学习率:高学习率常导致过拟合,尤其在短训练中。对于较长的训练,较高的学习率可能更有效。建议实验两种设置以找到最佳表现。
- 减少训练轮数:在1、2或3轮后停止训练。
- 增加权重衰减:从0.01或0.1开始是一个好的起点。
- 增加LoRA Dropout:使用0.1等值来增加正则化。
- 增加批次大小或梯度累积步数。
- 扩展数据集:通过合并或拼接开源数据集与你的数据集来扩大数据集规模,选择高质量数据集。
- 评估早停:启用评估,当评估损失连续几步增加时停止训练。
- LoRA Alpha缩放:在训练和推理时将alpha值下调,这会使微调效果不那么显著。
- 权重平均:将原始指令模型和微调模型的权重相加后除以2。
- 调整学习率:如果当前学习率过低,增加它可加速收敛,尤其在短训练中。对于长训练,尝试降低学习率。测试两种方法以找到最佳效果。
- 增加训练轮数:训练更多轮,但需监控验证损失以避免过拟合。
- 增加LoRA秩(r)和alpha:秩应至少等于alpha值,对于较小模型或复杂数据集,秩应更大,通常在4到64之间。
- 使用更相关的领域数据集:确保训练数据高质量且与目标任务直接相关。
- 将批次大小减小到1:这会使模型更新更剧烈。
1、以上 2、选择正确的模型+方法如果您是初学者,最好从 Llama 3.1 (8B) 这样的小型指导模型开始,然后再进行实验。您还需要在 QLoRA 和 LoRA 训练之间做出选择:
您可以将模型名称更改为您喜欢的任何模型,方法是将其与 Hugging Face 上的模型名称进行匹配,例如“unsloth/llama-3.1-8b-unsloth-bnb-4bit”。我们建议从Instruct 模型开始,因为它们允许使用对话聊天模板(ChatML、ShareGPT 等)直接进行微调,并且与Base 模型(使用 Alpaca、Vicuna 等)相比,所需数据更少。点击此处了解更多关于 Instruct 模型和 Base 模型之间的区别。
您还可以切换其他设置:
我们建议从 QLoRA 入手,因为它是最便捷、最有效的模型训练方法之一。我们的动态 4 位量化模型显示,QLoRA 相对于 LoRA 的准确率损失现已基本恢复。我应该选择指导还是基础?
该决定通常取决于数据的数量、质量和类型:
您可以将模型名称更改为您喜欢的任何模型,方法是将其与 Hugging Face 上的模型名称进行匹配,例如“unsloth/llama-3.1-8b-unsloth-bnb-4bit”。我们建议从Instruct 模型开始,因为它们允许使用对话聊天模板(ChatML、ShareGPT 等)直接进行微调,并且与Base 模型(使用 Alpaca、Vicuna 等)相比,所需数据更少。点击此处了解更多关于 Instruct 模型和 Base 模型之间的区别。
Unsloth 中的 LoRA 超参数
以下演示了标准配置。虽然 Unsloth 提供了优化的默认值,但理解这些参数是手动调整的关键。
微调过程的秩 (r)。秩越高,占用的内存越多,速度越慢,但可以提高复杂任务的准确率。我们建议秩为 8 或 16(用于快速微调),最高可达 128。使用过大的秩可能会导致过度拟合,损害模型质量。
为了获得最佳性能,LoRA 应应用于所有主要线性层。研究表明,针对所有主要层对于达到完全微调的性能至关重要。虽然可以移除模块以减少内存使用量,但我们强烈建议不要这样做,因为这样做节省的内存空间非常小,因此为了保持最佳质量,我们强烈建议不要这样做。
控制微调强度的比例因子。将其设置为等于秩 (r) 是一个可靠的基准。一种流行且有效的启发式方法是将其设置为秩 (r * 2) 的两倍,这会使模型通过赋予 LoRA 更新更大的权重来更积极地学习。更多详情,请点击此处。
保留此项"none"可加快训练速度并减少内存占用。此设置可避免在线性层中训练偏差项,这会增加可训练参数,但实际收益却微乎其微。
选项包括True、False和"unsloth"。🦥我们推荐使用"unsloth",因为它可以额外减少 30% 的内存使用量,并支持超长上下文微调。您可以在 我们关于长上下文训练的博客文章中阅读更多内容。
种子用于确保确定性、可重复的运行。训练涉及随机数,因此设置固定种子对于保持一致的实验至关重要。
一项实现Rank-Stabilized LoRA 的高级功能。如果设置为True,则有效缩放比例将变为 ,lora_alpha / sqrt(r)而不是标准缩放比例lora_alpha / r。这有时可以提高稳定性,尤其是对于较高等级的情况。更多详情请见。
LoftQ中提出了一种先进的技术,利用预训练权重的前“r”个奇异向量初始化 LoRA 矩阵。这可以提高准确率,但可能会导致训练开始时内存消耗大幅增加。过拟合(泛化能力差/过于特化)
翻译:模型记住了训练数据,包括其统计噪声,因此无法泛化到未见过的数据。如果训练损失降到0.2以下,模型很可能过拟合——意味着它在未见过任务上的表现可能较差。一个简单的技巧是LoRA alpha缩放——只需将每个LoRA矩阵的alpha值乘以0.5。这有效地降低了微调的影响。这与权重合并/平均密切相关。你可以取原始基础(或指令)模型,添加LoRA权重,然后将结果除以2。这会得到一个平均模型——功能上等同于将alpha值减半。解决方案:
解释:过拟合是指模型过于贴合训练数据,连噪声都学会了,导致在新数据上表现不佳。在LoRA微调中,可通过调整alpha(控制低秩更新强度)、增加正则化(如权重衰减和Dropout)、扩大批次大小或数据集,以及权重平均等方法缓解。Unsloth等工具通过优化这些参数(如自动设置alpha或Dropout)来简化操作。欠拟合(过于泛化)
翻译:模型无法捕捉训练数据的潜在模式,通常是由于模型复杂性不足或训练时间不够。解决方案:
解释:欠拟合意味着模型未能学到数据的关键模式,可能因LoRA秩(r)过低、alpha不足或数据不匹配。在LoRA微调中,增加秩和alpha可提升模型表达能力,减少批次大小可加快参数更新,而更相关的数据则确保任务适配性。总结
微调没有单一的“最佳”方法,只有最佳实践。实验是找到适合你具体需求的关键。我们的笔记本根据大量研究和实验自动设置了最优参数,为你提供了一个很好的起点。祝微调愉快!微调(如LoRA)需要根据任务和数据调整超参数(如学习率、秩、alpha、批次大小等)。Unsloth等工具通过自动化参数设置降低实验门槛,但仍需针对具体场景优化。
2. 初试
2.1 DeepSeek_R1_0528_Qwen3_(8B)_GRPO
2.1.1 使用 Colab L4 资源快速测试。

2.1.2 Installation
- 代码解释
%%capture:是 Jupyter/Colab 的魔法命令,用来隐藏输出(不让安装日志刷屏)。
os.environ["UNSLOTH_VLLM_STANDBY"] = "1":设置一个环境变量,让 Unsloth 的 vLLM 支持 额外 30% 的上下文长度。
- 判断你是不是在 Colab 环境:
- 如果不是,就直接
pip install unsloth vllm。 - 如果是,就走下面写好的特殊安装步骤(因为 Colab 的显卡驱动、依赖环境和本地不同)。
- 给 Colab 写的安装逻辑。
uv是一个更快的包管理器,比pip装包快。
- 如果不是 Colab → 直接装。
- 如果是 Colab → 根据当前环境检查
numpy的版本,避免冲突。
- 检查你用的 GPU 是不是 Tesla T4(Colab 免费常见卡)。
- 不同显卡安装的
vllm版本不一样。
- 如果是 T4 卡,就装
vllm==0.9.2和固定版本的triton。
- 如果是别的卡,就装更新的版本。
- 额外装上:
torchvision:PyTorch 的图像库(有些功能要用到)。bitsandbytes:8bit/4bit 量化库,显存省很多。xformers:加速 Transformer。
- 固定 HuggingFace
transformers版本到 4.55.4(避免新版本不兼容)。
- 安装
trl(Transformers Reinforcement Learning),但不用自动装依赖,避免冲突。
2.1.3 Unsloth 部分
1. 安装依赖
- 安装
langid,这是一个语言检测工具。
- 作用:后面会用它来判断模型输出是不是印尼语(作为奖励函数的一部分)。
2. 导入和基础配置
FastLanguageModel:Unsloth 提供的高效模型加载器。
max_seq_length:模型能处理的最大上下文长度(这里设置 1024)。
lora_rank:控制 LoRA 参数的大小。32表示折中,既能提升性能,又不会太耗显存。
3. 加载预训练模型
- 这里加载的模型是 DeepSeek-R1-0528-Qwen3-8B。
load_in_4bit=True→ 启用 4bit 量化,省显存(适合消费级 GPU)。
fast_inference=True→ 使用 vLLM 加速推理。
gpu_memory_utilization=0.9→ 最大化利用 GPU 显存(但有 OOM 风险)。
4. 给模型加 LoRA 适配层
get_peft_model:为原始大模型加上 LoRA 训练层,只训练一小部分参数,节省显存。
target_modules:指定要加 LoRA 的模块(主要是 Transformer 的注意力和前馈层)。
lora_alpha:缩放因子(这里设为lora_rank*2,能加快训练)。
use_gradient_checkpointing="unsloth":节省显存,但训练速度略慢。
把
DeepSeek-R1-0528-Qwen3-8B 模型加载进来,并通过 LoRA 微调 方式,准备好做 印尼语推理模型训练(GRPO 强化微调)。- langid → 语言检测,用来定义奖励函数。
- LoRA rank=32 → 训练参数适中,性能和速度平衡。
- 4bit 量化 + vLLM → 节省显存、提升推理速度。
2.1.4 GRPO Chat Template
代码解释
1. 初始化变量
- 先定义几个变量,用来存放 特殊 token:
reasoning_start:推理开始标记(通常是<think>)。reasoning_end:推理结束标记(通常是</think>)。user_token:表示用户输入的特殊 token。assistant_token:表示助手输出的特殊 token。
2. 从词表里找出特殊 token
tokenizer.get_added_vocab()→ 获取额外添加的词表(里面就有<think>、</think>、<user>、<assistant>等特殊 token)。
- 根据规则:
- 如果 token 包含
"think"且带/→ 那就是</think>(推理结束)。 - 如果只是
"think"→ 那就是<think>(推理开始)。 - 如果包含
"user"→ 用户标记。 - 如果包含
"assistant"→ 助手标记。
👉 这一步完成后,四个特殊 token 就自动获取到了。
3. 定义系统提示词
- 系统提示词(system prompt):告诉模型必须用 印尼语 思考并写出推理步骤。
4. 测试 chat 模板
tokenizer.apply_chat_template(...):用 Qwen3 内置的 chat 模板 来格式化对话数据。
- 输入了一个模拟对话:
- 用户问:
What is 1+1? - 助手答:
<think>I think it's 2.2</think>2(先写思考,再给最终答案)。 - 用户再问一次。
- 助手再答一次。
tokenize = False→ 输出纯文本格式,不转 token id。
add_generation_prompt = True→ 在最后加一个提示,让模型继续生成。
自动获取 chat 模板的特殊 token,并验证 Qwen3 的对话模板格式是否能正确工作。
- 用户输入会被包裹在
<user>相关格式里。
- 助手输出会带
<think> ... </think>(推理过程)+ 最终答案。
- 系统提示词要求 → 必须用印尼语进行推理。
2.1.5 Data Prep
1. 导入数据工具
from datasets import load_dataset- 这是 Hugging Face 的
datasets库,可以方便地加载各种公开数据集。
2. 加载数据集
load_dataset("open-r1/DAPO-Math-17k-Processed", "en", split = "train")- 这里用的是 OpenR1 的数学推理数据集,名字叫:
DAPO-Math-17k-Processed。 - 第二个参数
"en"→ 表示选择英语版本。 split="train"→ 加载训练集部分。
3. 输出数据集对象
dataset会显示数据集的基本信息,比如:- 一共有多少条样本。
- 每条样本包含哪些字段(比如
question,answer,solution)。
背景说明
- 这个 Open-R1 Math 数据集 是专门用来训练推理模型的,里面有数学题和对应的解答过程。
- 你也可以替换成更常用的 GSM8K 数据集(OpenAI 出的小学数学推理 benchmark)。
👉 这段代码就是:
- 从 Hugging Face 拉取 数学推理训练数据(OpenR1 Math)。
- 为后面做 GRPO 强化微调 做准备。
代码解析
1.
dataset.map(...)- Hugging Face 的 map 函数 → 用来对数据集里的每一条样本做转换。
- 会返回一个新的数据集对象。
2. 转换逻辑
- 每条数据
x会变成一个字典,包含两个字段:
① prompt
- 这里构造了一个 对话格式的输入:
- 第一条 →
system,内容是固定的system_prompt(要求模型用印尼语推理)。 - 第二条 →
user,内容是数据集中原始的x["prompt"](就是数学题目)。
👉 这样就和前面说的 chat template 格式统一了。
② answer
- 取
solution字段(题目的答案和解法)。
- 用
extract_hash_answer处理一下: - 如果是 Open R1 → 直接返回完整解答。
- 如果是 GSM8K → 提取
####后的答案。
3. 查看第一条数据
- 会显示处理后的第一条样本,大概是这样的:
这一步就是把原始数据集转成 对话训练格式:
- prompt = 系统提示词 + 用户问题。
- answer = 标准答案(带推理过程)。
这样数据就能直接喂进 Unsloth + GRPO 训练流程里了。
1. 定义正则表达式
- 目标:提取
<think> ... </think>后面的部分(也就是最终答案)。
- 具体含义:
</think>→ 匹配推理过程的结束标签。(.*)→ 匹配后面所有内容(就是答案)。re.DOTALL→ 让.也能匹配换行符(跨行匹配)。re.UNICODE→ 支持 Unicode 字符(比如中文、印尼语)。
👉 所以这个正则会捕获:“
</think> 后的所有内容”。2. 测试正则是否生效
示例 1
输出:
✅ 说明它成功提取到了
<think> ... </think> 后的答案。示例 2
输出:
✅ 即使答案前有换行符,正则也能完整提取。
总结
👉 这段代码的作用:
- 训练和推理时,模型输出会有:
- 这里的正则能帮我们 自动分离“最终答案”部分。
1.
match_format_exactly👉 解释:
- 这个函数检查模型输出
response是否完全符合我们定义的格式(即<think> ... </think>后面有答案)。
- 如果格式完全正确,就加 3 分。
- 否则不给分(0)。
- 最后返回一个
scores列表,每个 completion 一个分数。
2.
match_format_approximately👉 解释:
- 这个函数是 “近似匹配”奖励。
- 它不要求完全正确,只要输出里有
<think>和</think>这些符号,就给分。
- 如果刚好出现一次 → +0.5 分。
- 如果没有,或者次数不对 → 1 分。
- 这样保证模型即使格式不完全正确,也能因为“部分遵守规则”得到小奖励。
3.
check_answer👉 解释:
- 这个函数是真正检查 模型输出的答案对不对。
match_format.search(r)先提取出<think> ... </think>后面的答案部分。
- 然后和正确答案
true_answer对比: - 完全相同 → +5 分
- 只差空格 → +3.5 分
- 数值接近(比如正确答案是 100,模型答 95 或 105) → 给 1.5~2 分
- 错得离谱 → -2.5 分
- 完全没找到答案 → -2 分
- 根本无法解析成数字(比如答案写了文字) → -4.5 分
总结:
- 第一个函数:严格格式奖励(+3 分)。
- 第二个函数:部分格式奖励(+0.5 或 -1 分)。
- 第三个函数:答案正确性奖励(最高 +5 分,错了会扣分)。
- Author:沈林曦
- URL:https://blog.aibhtt.com/article/unsloth/learning
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts












