参数高效微调
参数高效微调简介
对于预训练数据涉及较少的垂直领域,大语言模型需要对这些领域及相应的下游任务进行适配。上下文学习和指令微调是进行下游任务适配的有效途径,但它们在效果或效率上存在缺陷。为弥补这些不足,参数高效微调(Parameter-EfficientFine-Tuning,
PEFT)技术应运而生。
下游任务适配
1. 上下文学习
它的核心思想是将不同类型的任务都转化为生成任务,通过设计 Prompt 来驱动大语言模型完成这些下游任务。
小样本上下文学习(Few-shot in-context learning)将数据集中的样本-标签对转化为自然语言指令(Instruction)和样例(Demonstrations),并拼接上需要测试的样本一同输入给大语言模型,将模型输出作为最终预测结果。
上下文学习不需要对模型进行参数更新,因此能快速将单个模型应用到多种不同的任务上。
缺点:
1)上下文学习的性能和微调依旧存在差距,并且 Prompt 设计需要花费大量的人力成本,不同 Prompt 的最终任务性能有较大差异;
2)上下文学习虽然完全不需要训练,但在推理阶段的代价会随 Prompt 中样例的增多快速增加。
2. 指令微调
指令微调(Instruction Tuning)是另一种进行下游任务适配的方法。指令微调旨在对模型进行任务指令的学习,使其能更好地理解和执行各种自然语言处理任务的指令。
指令微调的主要步骤包括:
- 确定目标:明确你希望模型达到的效果或行为。
- 准备数据:根据目标,准备相应的数据集,这些数据集包含任务描述和输入输出对。
- 微调:使用该数据集对模型进行微调,使其更好地理解和执行指令。
- 验证:使用独立的数据集验证微调后的模型的效果。
指令微调的优点包括:
- 提升性能:显著提升大型语言模型在学术NLP基准测试上的性能,同时也提升了小型模型的表现。
- 解锁CoT能力:通过Instruction Tuning,小型模型在未见过的任务上的表现也有所提升,甚至能够解锁连续性文本理解(CoT)的能力。
- 灵活适应各种任务:随着任务数量的增加,Instruction Tuning的效果也会相应提升,使得Language Model都能通过Instruction Tuning获得更好的处理效果。
- 提升LLM理解真实指令的能力:显著提升了大型语言模型(LLM)理解人类真实指令的能力,使得LLM在实际应用中更加实用和高效。
参数高效微调
参数高效微调(PEFT)是一种旨在提高大语言模型微调效率的方法,通过减少需要更新的参数数量和计算开销,从而实现更高效的模型适配。PEFT 技术的主要优势包括计算效率高、存储效率高和适应性强,能够有效适应不同任务而不需要对整个模型进行重训。
PEFT 方法分类
-
参数附加方法
这种方法在模型结构中添加新的、较小的可训练模块(适应层),在微调时冻结原始模型参数,仅更新这些新模块的参数。常见的参数附加方法包括适配器微调、提示微调、前缀微调等。 -
参数选择方法
仅选择模型的一部分参数进行微调,而其余参数则被冻结。这样可以利用模型中只有部分参数对特定任务至关重要的特性,有效降低计算负担并提升性能。典型的方法包括 BitFit、Child-tuning 和 FishMask 等。 -
低秩适配方法
通过使用低秩矩阵来近似原始权重的更新,冻结原始参数矩阵,仅微调低秩更新矩阵。LoRA 是经典的低秩适配方法,后续有多个变体不断改进其性能。
参数附加方法
参数附加方法(Additional Parameter Methods)通过增加和训练新的附加参数或模块来进行大语言模型的微调。这些方法可以按照附加参数的位置分为三类:加在输入、加在模型和加在输出。
加在输入
这一方法主要是将额外的参数附加到模型的输入嵌入中,最经典的例子是 Prompt-tuning。在此方法中,会引入可微分的软提示(Soft prompt),它们与文本数据一起作为模型的输入。
- Prompt-tuning
- 软提示作为输入的一部分,与原始的 token 嵌入拼接在一起,形成新的输入矩阵。
- 在训练过程中,只有软提示的参数被更新,原始模型参数保持不变。
- 软提示的长度通常在 1 到 200 之间,超过 20 的时候能保证一定的性能。
- 该方法具有以下优势:
- 内存效率高:例如,T5-XXL 模型只需 20480 个参数来适应特定任务,而不是整个 11B 参数的模型。
- 多任务能力:可以用于多任务适应,避免为每个任务保存完整的模型副本。
- 缩放特性:随着模型参数增大,Prompt-tuning 的性能也会增强。
加在模型
加在模型的方法通过将新的可学习参数或模块直接插入到预训练模型的隐藏层中。主要的代表性方法包括 Prefix-tuning、Adapter-tuning 和 AdapterFusion。
-
Prefix-tuning
- 这一方法将可训练前缀(Prefix)插入到输入嵌入和 Transformer 的注意力模块中。
- 同样引入可学习的向量,这些向量在注意力模块的键(K)和值(V)之前被添加,以此来增强模型的学习能力。
- 优势包括:
- 参数效率:仅更新前缀参数,大幅减少训练参数量。
- 任务适应性:前缀参数可以根据不同任务进行定制。
- 保持预训练知识:不更新原始模型的参数。
-
Adapter-tuning
- 通过在每个多头注意力层和全连接层之后插入适配器(Adapter)模块,以压缩和扩展特征信息。
- 适配器模块具有瓶颈结构,能有效减少所需参数。
- 在训练时仅微调适配器参数,从而保持预训练模型的知识。
-
AdapterFusion
旨在结合多个任务的知识,通过独立训练每个任务的适配器,然后进行参数融合。
第一阶段:知识提取
在这一阶段,首先对每个任务 N 进行适配器模块的训练,这有助于捕获每个任务特定的知识。这个阶段有两种主要的训练方式:
-
单任务适配器(Single-Task Adapters, ST-A):
- 每个任务的适配器模块独立训练,彼此之间没有干扰。这种方式确保了每个适配器能够专注于学习与对应任务相关的特定知识。
-
多任务适配器(Multi-Task Adapters, MT-A):
- 同时进行多个任务的训练,利用多任务学习的优势,通过共享知识来提升适配器的学习能力。这种方式可以帮助适配器捕获任务之间的潜在联系,并促进模型性能的整体提升。
这两个策略的选择取决于具体的任务需求和场景。
第二阶段:知识组合
在完成适配器训练后,进入知识组合阶段。这一阶段的目标是将各个任务的适配器模块融合,形成一个能够更好地适应多种任务的组合模型。
-
融合模块:
- 引入新的可学习的融合模块,该模块用于探寻和优化多个任务适配器的最优组合。
- 在这一阶段,所有的任务适配器和预训练模型的参数保持固定,仅优化融合模块的参数。这样做有效避免了对所有适配器参数的再训练,从而进一步提高了效率。
-
损失函数优化:
- 融合模块的优化目标是最小化以下损失函数:
Ψ ← arg min Ψ L n ( D n ; Θ , Φ 1 , … , Φ N , Ψ ) Ψ ← \arg\min_{Ψ} L_n(D_n; Θ, Φ_1, \ldots, Φ_N, Ψ) Ψ←argminΨLn(Dn;Θ,Φ1,…,ΦN,Ψ)
其中,(D_n) 是第 n 个任务的训练数据,(L_n) 是对应的损失函数,(Θ) 代表预训练模型的参数,(Φ_i) 是第 i 个任务的适配器模块参数,(Ψ) 是融合模块的参数。
- 融合模块的优化目标是最小化以下损失函数:
-
注意力机制:
- 在每层的 AdapterFusion 模块中,使用可学习的键(Key)、值(Value)和查询(Query)投影矩阵。这些矩阵帮助模型计算出多任务适配器的联合输出。
- 全连接层的输出作为 Query,适配器的输出作为 Key 和 Value,通过注意力机制合成最终的输出结果,从而实现知识的有效融合。
加在输出
这一方法是将可学习的参数添加到模型的输出层。常见方法包括使用线性层对适配器输出进行加权等。这些方法通常用于将适配器的功能扩展到输出,从而进一步提高模型的灵活性和性能。
代理微调(Proxy-tuning)
代理微调的基本思路是利用两个模型之间的输出进行调整,以实现高效的微调和定制。
-
模型设置:
- 设定待微调的 代理模型 M M M 和一个较小的 反专家模型 M − M^{-} M−。
- 这两个模型需要使用相同的词汇表,以确保它们的输出可以互相兼容。
-
专家模型的微调:
- 通过微调反专家模型 M − M^{-} M− 得到 专家模型 M + M^{+} M+。
- 专家模型是经过训练以适应特定任务的小型模型(例如,LLaMA-7B)。
-
输出分数的调整:
- 在生成内容时,代理微调算法计算代理模型 M M M、专家模型 M + M^{+} M+和反专家模型 M − M^{-} M− 的 logits分布。
- 在每一个自回归生成的时间步 (t),通过以下公式调整目标模型的输出分数:
s ~ = s M + s M + − s M − \tilde{s} = s_{M} + s_{M^{+}} - s_{M^{-}} s~=sM+sM+−sM− - 接着,使用 softmax 函数对调整后的输出分数进行归一化,得到最终的输出概率分布:
p M ( X t ∣ x < t ) = softmax ( s ~ ) p_{M}(\mathbf{X}_{t} | x_{<t}) = \text{softmax}(\tilde{s}) pM(Xt∣x<t)=softmax(s~) - 通过在这个概率分布中进行采样,生成下一个词的预测结果。
代理微调的优势
- 计算效率:通过使用较小的专家模型和反专家模型来产生调整信号,可以显著减少计算成本。
- 黑盒模型适配:由于只需要访问模型的输出分布,而不需要直接修改或访问大语言模型的权重,这种方法非常适合于黑盒模型。
- 知识迁移:代理微调允许将较小模型中学习到的知识以解码时的约束方式迁移到更大的模型中,从而实现增强的语言生成能力。
参数选择方法
基于规则的方法
基于规则的微调方法
基于规则的微调方法依赖于人类专家的专业知识,针对具体模型和任务,确定哪些参数应该被更新。其中,BitFit 是最具代表性的实例之一。
BitFit
-
方法概述:
- BitFit 的核心思想是仅优化神经网络中每一层的 偏置项(Biases) 以及任务特定的分类头。
- 偏置项在模型总参数中所占的比例极小,约为 0.08%-0.09%。因此,BitFit 在进行微调时具备极高的参数效率。
-
性能表现:
- 尽管仅微调少量参数,BitFit 在 GLUE Benchmark 上的表现与全量微调相媲美,甚至在某些任务上表现更优。
- 该方法的优势之一是能够使用更大的学习率,带来更稳定的整体优化过程。
-
适用范围:
- BitFit 的性能验证主要集中在小模型(如 BERT、RoBERT 等)上,关于其在更大模型(如 LLaMA 等)上的表现还有待探索。
其他基于规则的方法
除了 BitFit,还有其他基于规则的方法旨在通过微调特定的 Transformer 层提高参数效率:
-
分层微调:
- 例如,Lee 等人提出的方法仅微调 BERT 和 RoBERTa 模型的最后四分之一层。这种方法可以实现与全量微调相当的 90% 的效果。
- 通过选择性微调模型的后续层,可以减少计算开销,同时保持较高的模型性能。
-
PaFi:
- PaFi 方法选择具有最小绝对值的模型参数作为可训练参数。这种策略旨在识别对模型表现影响较小的参数,只微调那些可能产生显著效果的参数,进一步提高了参数效率。
基于学习的方法
通过选择可训练的参数子集,这些方法能够在不改变大部分参数的情况下有效地微调模型,从而减少计算开销和内存需求。
基于学习的方法概述
- Child-tuning 方法:通过梯度掩码矩阵选择性地更新子网络的参数。这种方法有助于实现参数的高效微调。
- 掩码矩阵 (M):用于选择在每次迭代中需要更新的子网络的参数。梯度更新公式如下:
W t + 1 = W t − η ( ∂ L ( W t ) ∂ W t ⊙ M t ) W_{t+1} = W_t - \eta \left( \frac{\partial L(W_t)}{\partial W_t} \odot M_t \right) Wt+1=Wt−η(∂Wt∂L(Wt)⊙Mt)
Child-tuning 的两种变体
-
Child-tuningF (任务无关的变体)
- 随机从伯努利分布中生成掩码,这样选择的子网络与任务无关。
- 通过添加噪声来避免小数据集上的过拟合,提高模型的泛化能力。
-
Child-tuningD (任务驱动的变体)
- 利用下游任务的数据,通过费舍尔信息矩阵 (FIM) 来估算参数的重要性。
- 确定选择子网络的步骤:
- 计算每个参数的费舍尔信息值
- 排序
- 选择比例最高的参数
优势与挑战
-
优势:
- 通过梯度屏蔽减少计算负担,降低过拟合风险。
- 尤其适用于训练数据有限的情况,并可以与其他参数高效微调(PEFT)方法结合。
-
挑战:
- 子网络选择需要额外的计算,尤其是在任务驱动的变体中计算费舍尔信息较为耗时。
- 如何选择最佳的参数子集,平衡参数更新数量与模型性能。
其他基于学习的方法
- FishMask 和 Fish-Dip:借助费舍尔信息计算掩码,后者在每个训练周期动态计算。
- LT-SFT:根据参数重要性形成掩码。
- SAM:提出了一个二阶逼近方法来帮助决定参数掩码。
低秩适配方法
低维固有维度假设表明:过参数化模型的固有维度是很低的;换言之,存在可以与全参数更新媲美的低维的参数更新。
基于这一假设,低秩适配方法(Low-rank Adaptation Methods)通过低秩矩阵来近似原始权重权更新矩阵,并仅微调低秩矩阵,以大幅降低模型参数量。
低秩适配(Low-rank Adaptation, LoRA)是一种高效的微调技术,通过低秩矩阵近似参数更新,以减少微调过程中的参数数量和计算开销。
LoRA
1. 方法实现
LoRA 的核心思想是将需要更新的参数矩阵进行低秩分解
-
参数更新矩阵的低秩分解:
- 给定一个神经网络层的原始参数矩阵 W 0 ∈ R d × k W_0 \in \mathbb{R}^{d \times k} W0∈Rd×k,我们通常需要学习参数更新矩阵 Δ W ∈ R d × k \Delta W \in \mathbb{R}^{d \times k} ΔW∈Rd×k。在全量微调中, Δ W \Delta W ΔW 的微调需要计算 d × k d \times k d×k 个参数的梯度,这要求较大的 GPU 内存。
- LoRA 利用低秩分解将更新矩阵表示为两个低秩矩阵
B
∈
R
d
×
r
B \in \mathbb{R}^{d \times r}
B∈Rd×r 和
A
∈
R
r
×
k
A \in \mathbb{R}^{r \times k}
A∈Rr×k,其中
r
≪
min
{
d
,
k
}
r \ll \min\{d, k\}
r≪min{d,k}。因此,参数更新可以简化为:
W = W 0 + α B A W = W_0 + \alpha BA W=W0+αBA
其中, α \alpha α 是用于控制 LoRA 权重的缩放因子。
-
微调过程:
- 在训练过程中,固定预训练模型的原始参数,仅优化矩阵 B B B 和 A A A。因此,需要微调的参数数量大幅减少,只有 r × ( d + k ) r \times (d + k) r×(d+k),远小于全量微调中的 d × k d \times k d×k。
-
应用场景:
- LoRA 可应用于多种神经网络层,尤其是在基于 Transformer 的模型中,包括注意力层的权重矩阵和前馈神经网络(FFN)模块中的投影层。
2. 参数效率
以下是 LoRA 在性能和资源使用上的优势分析:
-
案例分析:
- 以 LLaMA2-7B 为例,微调第一个 FFN 层的权重矩阵:
- 全量微调需要调整 11 , 008 × 4 , 096 = 45 , 088 , 768 11,008 \times 4,096 = 45,088,768 11,008×4,096=45,088,768 个参数。
- 当设定 r = 4 r = 4 r=4 时,LoRA 只需调整 ( 11 , 008 × 4 ) + ( 4 × 4 , 096 ) = 60 , 416 (11,008 \times 4) + (4 \times 4,096) = 60,416 (11,008×4)+(4×4,096)=60,416 个参数。与全量微调相比,LoRA 仅占原始参数量的千分之一。
- 以 LLaMA2-7B 为例,微调第一个 FFN 层的权重矩阵:
-
内存使用比较:
- LoRA 的微调涉及四个内存部分:
- 权重内存:存储模型权重。
- 激活内存:前向传播过程中中间激活的内存使用。
- 梯度内存:反向传播期间保存梯度的内存,仅针对可训练参数。
- 优化器内存:用于存储优化器状态(如 Adam 的一阶动量和二阶动量)。
- LoRA 的微调涉及四个内存部分:
-
实验对比:
- 在 LLaMA2-7B 模型上使用批量大小为 1 的情况下,单个 NVIDIA RTX4090 GPU(24GB)进行全量微调约需要 60GB 显存,而 LoRA 微调仅需约 23GB 显存。
- LoRA 显著减少了显存使用,使得在较小内存条件下微调大模型成为可能。即使考虑到额外的增量参数带来的激活内存和权重内存轻微增加(约 2GB),整体内存的显著减少仍使得这一方法可行。
-
加速效果:
- LoRA 由于减少了涉及的参数计算,成功加速了反向传播,与全量微调相比,LoRA 的训练速度提高了 1.9 倍。
LoRA 相关变体
1. 打破低秩瓶颈
LoRA 的低秩特性带来了参数效率,但同时也限制了模型记忆和适应新知识的能力。研究表明,全量微调的秩通常显著高于 LoRA,增加 LoRA 的秩可以减小这种性能差距。
- ReLoRA:
- ReLoRA 提出了 合并和重置(merge-and-reinit)的方法。在训练中,周期性地将 LoRA 模块合并入大语言模型,并重置 LoRA 的参数与优化状态。
- 合并过程:合并时会执行如下操作:
W i ← W i + α B i A i W_i \leftarrow W_i + \alpha B_i A_i Wi←Wi+αBiAi
其中 W i W_i Wi 是原始权重, B i B_i Bi 和 A i A_i Ai 是低秩分解得到的矩阵, α \alpha α 是缩放因子。 - 此后,重置步骤会将 B i B_i Bi(使用特定初始化方法,如 Kaiming 初始化)和 A i A_i Ai(设置为零)进行重置。这种方法允许通过多次低秩 LoRA 更新逐步接近高秩状态,从而提高模型性能。
2. 动态秩分配
LoRA 的秩并不总是越高越好,过高的秩可能导致性能和效率的下降。考虑到在不同层间权重的重要性差异,动态调整对每层的秩分配是一种有效策略。
- AdaLoRA:
- AdaLoRA 通过将参数更新矩阵参数化为奇异值分解(SVD)的形式,并在每层动态调整 LoRA 模块的秩。
- 具体来说,使用 SVD 重新表示权重更新
Δ
W
\Delta W
ΔW:
W = W 0 + Δ W = W 0 + P Λ Q W = W_0 + \Delta W = W_0 + P \Lambda Q W=W0+ΔW=W0+PΛQ
其中 P P P 和 Q Q Q 是正交矩阵, Λ \Lambda Λ 是包含奇异值的对角矩阵。 - 在训练中,固定 W 0 W_0 W0,对 P P P、 Λ \Lambda Λ、 Q Q Q 进行更新。通过对重要性得分进行剪枝,可以动态调整更新的维度。
- 为确保
P
P
P 与
Q
Q
Q 的正交性,AdaLoRA 引入了额外的惩罚项:
R ( P , Q ) = ∥ P T P − I ∥ F 2 + ∥ Q Q T − I ∥ F 2 R(P, Q) = \| P^T P - I \|_F^2 + \| QQ^T - I \|_F^2 R(P,Q)=∥PTP−I∥F2+∥QQT−I∥F2
3. 训练过程优化
LoRA 的训练过程相较于全量微调稳定性较差,收敛速度也较慢,因此对超参数非常敏感,并且容易过拟合。为了提升训练效率,以下方法进行了相应优化。
- DoRA:
- DoRA 通过约束梯度更新来提高训练稳定性。它将预训练权重 W 0 ∈ R d × k W_0 \in \mathbb{R}^{d \times k} W0∈Rd×k 分解为大小和方向两个组件,只对方向组件施加 LoRA。
- 具体表示为:
W 0 = m V / ∥ V ∥ c = ∥ W 0 ∥ c W 0 / ∥ W 0 ∥ c W_0 = m V / \| V \|_c = \| W_0 \|_c W_0 / \| W_0 \|_c W0=mV/∥V∥c=∥W0∥cW0/∥W0∥c
其中 m ∈ R 1 × k m \in \mathbb{R}^{1 \times k} m∈R1×k 是大小向量, V ∈ R d × k V \in \mathbb{R}^{d \times k} V∈Rd×k 是方向矩阵。 - 再通过应用 LoRA 更新于方向矩阵:
W ′ = m V + Δ V / ∥ V + Δ V ∥ c = m W 0 + B A / ∥ W 0 + B A ∥ c W' = m V + \Delta V / \| V + \Delta V \|_c = m W_0 + BA / \| W_0 + BA \|_c W′=mV+ΔV/∥V+ΔV∥c=mW0+BA/∥W0+BA∥c
其中 Δ V \Delta V ΔV 是由 LoRA 学习的增量方向更新。
基于 LoRA 插件的任务泛化
低秩适配(LoRA) 是一种在微调模型时通过低秩矩阵分解来减少训练参数量的有效策略。在 LoRA 微调结束后,可以将更新的参数模块 B 和 A 从模型中分离出来,封装成可插拔的 LoRA 插件。这些插件具有以下优势:
- 即插即用:可以灵活地在不同任务上使用,而无需修改原始模型的参数或结构。
- 参数共享:可以保存、共享和使用不同任务上训练的 LoRA 模块,方便复用已有的知识。
LoRAHub 框架
为了有效管理和使用这些 LoRA 插件,LoRAHub 提供了一种方法框架,允许组合多个任务的 LoRA 插件,以便在新任务中迁移能力。LoRAHub 的操作分为两个阶段:组合阶段和适应阶段。
-
组合阶段:
- 在此阶段,LoRAHub 将已经学习的多个 LoRA 模块(假设为 N 个模块)逐元素线性加权组合为一个单一模块。具体表达式如下:
m ^ = ( w 1 A 1 + w 2 A 2 + … + w N A N ) ( w 1 B 1 + w 2 B 2 + … + w N B N ) \hat{m} = (w_1A_1 + w_2A_2 + \ldots + w_NA_N)(w_1B_1 + w_2B_2 + \ldots + w_NB_N) m^=(w1A1+w2A2+…+wNAN)(w1B1+w2B2+…+wNBN)
其中,( w_i ) 是第 i 个 LoRA 模块的权重,( A_i ) 和 ( B_i ) 分别是 N 个 LoRA 模块的分解矩阵。
- 在此阶段,LoRAHub 将已经学习的多个 LoRA 模块(假设为 N 个模块)逐元素线性加权组合为一个单一模块。具体表达式如下:
-
适应阶段:
- 在适应阶段,给定新任务的相关示例,利用无梯度方法(例如 Shiwa)来自适应地学习权重组合。
- 这个过程会经过 k 次迭代,直到找到最优的权重组合,以实现对新任务的适应。
实践与应用
PEFT 实践
1. PEFT 主流框架
目前最流行的 PEFT 框架是 HF-PEFT,由 Hugging Face 开发。该框架旨在提供高效和灵活的参数微调方法,集成了多种先进的微调技术,如 LoRA、Adapter-tuning、Prompt-tuning 和 IA3。HF-PEFT 的特点包括:
- 与 Hugging Face 工具的兼容性:HF-PEFT 可以与 Transformers、Diffusers 和 Accelerate 等工具无缝集成,支持从单机到分布式的多样化训练场景。
- 适用于大模型的性能:能够在消费级硬件上实现高性能,并且与模型量化技术兼容,进一步降低内存需求。
- 易用性:提供详细文档、快速入门指南和示例代码,帮助用户快速理解如何训练和推理 PEFT 模型。
- 社区支持:活跃的社区鼓励用户贡献,确保库的功能强大并不断更新。
2. HF-PEFT 框架使用
使用 HF-PEFT 框架进行模型微调以提升模型在特定任务的性能,通常包括以下步骤:
-
安装与配置:
- 在你的环境中安装 HF-PEFT 及其依赖项,主要是 Hugging Face 的 Transformers 库。
pip install peft transformers
-
选择模型与数据:
- 根据具体任务选择适合的预训练模型,并准备相应的训练数据集。
-
确定微调策略:
- 根据任务需求,选择适合的微调方法,例如 LoRA 或适配器等。
-
模型准备:
- 加载预训练模型,并根据选定的微调方法进行配置,包括任务类型和参数设置。
-
模型训练:
- 定义完整的训练流程,包括损失函数、优化器设置,并执行训练过程中可以应用数据增强、学习率调度等技术。
通过上述步骤,可以高效地使用 HF-PEFT 框架进行模型微调,以满足特定任务的需求并提高模型性能。
3. PEFT 相关技巧
HF-PEFT 支持多种参数高效微调技术,每种技术都有其特定的参数设置。以下是一些常用的参数设置方法:
Prompt Tuning
num_virtual_tokens
: 代表为每个任务添加的虚拟 token 数量,通常设置在 10-20 之间。prompt_tuning_init
: 指定 prompt 参数的初始化方式,可以选择随机初始化、文本初始化等。
Prefix Tuning
num_virtual_tokens
: 与 Prompt Tuning 中相同,表示构造的虚拟 tokens 的数量。encoder_hidden_size
: 用于 Prefix 编码的多层感知机(MLP)层的大小,通常与模型的隐藏层大小相匹配。
LoRA
r
: 秩的大小,用于控制更新矩阵的复杂度,通常选择小值如 4、8、16。lora_alpha
: 缩放因子,用于控制 LoRA 权重的大小,通常与 r 成反比。lora_dropout
: LoRA 层的 dropout 比率,防止过拟合,可以设置为 0.01。target_modules
: 指定 LoRA 中要应用的模型模块,如注意力机制中的矩阵,灵活选择不同的模块进行微调。
需要注意的是,具体的参数设置可能会因模型、数据集和任务的不同而有所变化,因此在实际应用中可能需要基于实验结果进行适当调整。
PEFT 应用
1. 表格数据查询
-
背景:表格数据广泛应用于金融、医疗、商务等多个领域,但大多数大型语言模型在其预训练阶段接触的表格数据极为有限,导致其在表格查询任务上的性能欠佳。
-
Text-to-SQL 技术:为了降低表格数据查询的门槛,Text-to-SQL技术可以将自然语言自动转换为 SQL 代码,极大地提高了数据查询的效率。相较于传统编写 SQL 代码的复杂性,使用这一技术可以将查询时间从几分钟减少到几秒钟。
-
FinSQL 框架:
- 组成部分:
- 提示构造:增强原始数据并构建高效检索器,以检索相关表格和字段。
- 参数高效微调:使用 PEFT 技术对基座模型进行微调,通过整合多个 LoRA 模块提升少样本场景的性能。
- 输出校准:通过修正生成的 SQL 中的语法错误,并采用自一致性方法选择最一致的 SQL 结果。
- 组成部分:
- 优势:相比基线方法,FinSQL 显著提升了查询的准确性和效率,支持复杂的金融查询,为数据分析与决策提供了强有力的技术支撑。