Fine-tuning
Fine-tuning (微调)
- SFT (Supervised Fine-Tuning): 传统的微调,给数据对。
- PEFT (LoRA, Adapter): 怎么省钱地微调。
- Alignment (对齐技术):
- RLHF: 用强化学习微调(ChatGPT的核心)。
- DPO (Direct Preference Optimization): 最近很火的去掉了强化学习的简化版 RLHF。
迁移学习
迁移学习的核心思想是:将一个任务(源领域)中学到的知识,应用到另一个相关任务(目标领域)中。 迁移学习通常通过如下方式进行:
- 预训练(Pre-training):在大规模数据集上训练一个通用模型
- 微调(Fine-tuning):更新模型的全部或者部分参数
- Zero-Shot / Few-shot Learning
- Domain Adaptation,领域自适应,处理源数据和目标数据“分布不同”的问题。例如:用合成照片训练的模型,迁移到现实世界的照片中。
迁移学习适用于几乎所有的深度学习架构:
| 架构类型 | 迁移的具体对象 | 典型应用 |
|---|---|---|
| CNN (视觉) | 卷积核(提取边缘、形状、纹理的过滤器) | 医学影像识别、自动驾驶物体检测 |
| Transformer (NLP) | 注意力机制权重、语言表征能力 | 翻译、情感分析、代码生成、法律文档理解 |
| RNN (序列) | 隐藏状态的时间序列逻辑 | 语音识别、股票预测微调 |
| GNN (图神经网络) | 节点和边的结构特征嵌入 | 药物分子发现、社交网络推荐 |
迁移学习是现代AI的基石,因为数据是稀缺的、算力是昂贵的、预训练模型的泛化能力是更强大的。
全量微调
假设预训练模型参数为 \(\Theta\),我们将网络分为两部分:
- \(\theta_{backbone}\) :特征提取部分(如 ResNet 的卷积层)。
- \(\theta_{head}\) :分类输出部分(最后的全连接层)。
全量微调 (Full Fine-tuning)将整个模型的预训练权重作为初始值,并在新任务上更新所有参数:
(注:这里 \(\theta = \{\theta_{backbone}, \theta_{head}\}\),所有参数都参与梯度 \(\nabla\) 的计算)
底层逻辑 :认为源领域和目标领域存在较大差异,或者数据量足够大,允许模型“全身心”改变以适配新任务。
后端微调
后端微调 (Partial Fine-tuning)认为底层特征(边缘、纹理)是通用的,只需微调靠近输出的高层语义特征。
更新公式 :
底层逻辑 :通过设置 \(\frac{\partial L}{\partial \theta_{low}} = 0\)(手动阻断梯度流),强制保留通用特征提取能力,减少训练开销。
差分学习率微调
差分学习率微调 (Differential Learning Rates)对不同层应用不同的学习步长 \(\eta\)。通常:\(\eta_{backbone} \ll \eta_{head}\)。
更新公式 :
底层逻辑 :这是一种加权信任机制。我们极度信任基座已有的知识(所以改得极慢),同时允许新加的输出层快速适应新类别。
固定特征提取器
固定特征提取器 (Fixed Feature Extractor)完全不改变预训练层的权重,仅将模型视作一个“黑盒”转换器,只训练新接的分类头。
更新公式 :
底层逻辑 :在 PyTorch 中通过 param.requires_grad = False 实现。此时,计算图在反向传播时到分类头截止,不再向后传播梯度,计算效率最高。
LLM PEFT
LLM PEFT指的是2026年主流的LLM的高效微调(Parameter-Efficient Fine-Tuning, PEFT)。
大多数开发不再从零开始,而是基于现有模型进行:
- 预训练(Pretraining - 学生阶段): 学习通用语法和常识,具备预测下一个词的能力。
- 指令微调(SFT - 专家阶段): 让模型学会“听从指令”,通过问答对训练使其适应特定领域(如电子工程)。
- 对齐(Alignment - 抛光阶段): 使用 RLHF 等技术使回复更安全、更有用、更符合人类偏好。
技术工具栈
PEFT的技术栈和工具包括:
- 硬件层:CUDA,NVIDIA提供的引擎,可以将python代码翻译为GPU运算指令,并经过GPU完成矩阵乘法等深度学习计算任务。
- 计算引擎:PyTorch,当下主流的深度学习框架,可以自动求导等。
- 优化层:Unsloth,一个专门为 LoRA(低秩自适应) 优化的加速库。它通过手写更高效的数学算子,让显存占用降低 70% 以上,速度提升 2-3 倍。它让在普通消费级显卡(如 RTX 4090)上微调 7B 甚至 70B 模型成为可能。
- 管理层:Hugging Face Transformers: 它提供了一个统一的接口,无论你想用 Meta 的 Llama、Google 的 Gemma 还是阿里的 Qwen,代码几乎是一样的。
- Hugging Face Datasets: 提供了标准化的数据加载方式。不管你的原始数据是 JSON 还是 CSV,它都能快速转化成模型需要的格式。
- Python/Jupyter Notebook: 应用层。
训练流程
计算机无法理解文字,只能处理数字。因此,分词(Tokenization) 成为首要步骤,它通过算法将句子拆解为名为“Token”的最小单元(如将 "Learning" 拆分为 "Learn" 与 "ing"),并为每个单元分配唯一的数字 ID。不同模型的分词效率直接影响其对长文本的处理能力。
在训练阶段,损失函数(Loss) 充当了衡量模型表现的“标尺”。它利用数学公式计算预测结果与标准答案之间的差距。如果模型预测离谱(如将“电阻单位”预测为“香蕉”),Loss 就会大幅上升。训练的核心目标就是通过梯度下降算法,不断调整参数以最小化 Loss,使预测趋于准确。
当模型完成学习并投入使用时,这一过程称为 推理(Inference) 。与训练不同,推理无需更新参数或计算梯度,因此对计算资源和显存的需求更低。
为了让庞大的模型能在普通硬件甚至移动设备上运行,量化(Quantization) 技术至关重要。它将模型原有的高精度参数(如 16 位浮点数)压缩至 4 位甚至更低。虽然这会带来极微小的精度损失,但能显著降低显存占用,使原本需要高端显卡支持的大模型得以在平价硬件上流畅运行。
LoRA
LoRA 是 Low-Rank Adaptation 的缩写。
- Low-Rank (低秩):这是数学概念。指的是我们不需要更新模型那个巨大的、全功率的矩阵,而是将其简化为两个“窄”矩阵(Rank \(r\) 很小)。
- Adaptation (适配/微调):指的是它的用途。它不是为了从头训练一个模型,而是为了让已经训练好的模型去“适配”特定的新任务或新风格。
我们都很清楚,在深度学习中,模型其实就是一堆巨大的 权重矩阵 (Matrix)。当你训练一个大模型时,传统的微调(Fine-tuning)需要更新这些矩阵里的每一个数字。然而,现在的模型太大了。比如 Llama 3 70B,哪怕只是更新 1% 的参数,普通显卡也根本跑不动(因为训练时需要储存每个参数的“梯度”和“动量”,显存消耗是参数本身的数倍)。
人们很快发现,为了让模型学会一个新技能(比如学会写诗或写代码),其实并不需要改变所有的参数方向。模型修改的实质是低秩(Low-Rank)的。比如说,虽然模型有 1 万个维度,但真正起作用的可能只有那 8 个核心维度。LoRA 就是只去捕捉这核心的 8 个维度,而不去碰剩下的 9992 个。
数学原理
假设模型中有一个原始的权重矩阵 \(W_0\),它的维度是 \(d \times k\)。你要计算一个新的 \(\Delta W\)(权重变化量),然后得到训练后的权重 \(W = W_0 + \Delta W\)。这里 \(\Delta W\) 的大小和 \(W_0\) 一模一样。如果 \(W_0\) 是 \(4096 \times 4096\),那么 \(\Delta W\) 也有 1600 万个参数 。
LoRA 假设这个 \(\Delta W\) 可以被分解为两个极小的矩阵相乘:
其中:
- 矩阵 A 的维度是 \(d \times r\)
- 矩阵 B 的维度是 \(r \times k\)
这个 \(r\) 就是所谓的 LoRA Rank(秩)。
例如,假设 \(d=4096, k=4096\),我们取 \(r=8\) :
- 传统微调: 参数量 \(= 4096 \times 4096 = 16,777,216\)
- LoRA: 参数量 \(= (4096 \times 8) + (8 \times 4096) = 65,536\)
如果你把 \(r\) 从 8 增加到 64 甚至更高,显存占用增加 (Training Overhead 增加)是最直接的变化。\(r\) 越大,矩阵 \(A\) 和 \(B\) 就越宽,包含的参数就越多。
- 你需要更多的显存来存储这些参数的 梯度(Gradients)和优化器状态(Optimizer States) 。
- 如果你在 24GB 的卡上跑,原本 \(r=8\) 能跑,调到 \(r=256\) 可能就直接提示 OOM (Out of Memory) 了。
\(r\) 越高,意味着 \(\Delta W\) 能够捕捉到的细节越多。如果你的任务非常复杂(比如让模型学习一种完全不同的新语言),高 \(r\) 会更有帮助。如果任务简单(比如只是调整一下说话语气),低 \(r\) 就足够了。
\(r\) 越高,训练时间越长。虽然 LoRA 很快,但参数量翻倍后,GPU 每一轮计算所需的浮点运算次数(FLOPs)也会随之增加,训练会变慢。
\(r\) 越高,过拟合风险越大:这像是在一张小纸条上写不下太多东西,所以你只能记重点(泛化性好);但如果给你一块巨大的黑板(高 \(r\)),你可能会把训练集里一些没意义的噪声也背下来,导致模型在实际使用时变笨(过拟合)。
r的选择
当 \(r\) 增加时,LoRA 矩阵 \(A\) 和 \(B\) 的参数量变多,导致上述的梯度和优化器状态占用的空间也随之增大。不过,即使你把 \(r\) 开到 128 或 256,其显存占用通常依然比 Full Parameter Tuning(全参数微调) 低得多。因为全参数微调是针对每一个原始参数都要存梯度和优化器状态,而 LoRA 只针对那两个窄窄的矩阵。
虽然 LoRA 效果很好且省钱,但在以下三种核心场景下,全参数微调(即你图中 Scenario A 那种模式)依然是不可替代的:
- 注入全新的、大量的垂直领域知识
- 改变模型的输出格式或任务范式
- 数据量极大且算力极其充足