LoRA、AdaLoRA、Adapter Tuning、Prefix Tuning、Prompt Tuning、P-Tuning、P-Tuning V2、QLoRA、Ladder Side

本文探讨了多种针对预训练语言模型的微调技术,包括LoRA的低秩矩阵适应,PromptTuning的前缀添加,AdapterTuning的参数高效迁移学习,PrefixTuning的连续提示优化,以及P-Tuning的不同变体。这些方法旨在在保持模型推理效率的同时,提高特定任务的性能,且在参数量增加有限的情况下,能接近全微调的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PEFT(Parameter-Efficient Fine-Tuning)快速总结

针对矩阵分解的

  • LoRA:把W=W0+BAW=W_0+BAW=W0+BA分解,BA的参数量级远低于W
  • AdaLoRA:把LoRA换成SVD分解

针对prompt的

  • PREFIX_TUNING:给prompt增加前缀,前缀用mlp结构来训练,每个任务用相同的前缀
  • PROMPT_TUNING:是PREFIX_TUNING的简化,把mlp简化没了(只要预训练模型够大,难训练的问题就没有),只保留个embedding即可,每个任务用相同的前缀
  • P-Tuning:prefix和prompt都是加前缀,P-Tuning直接对整个Prompt过Encoder,Encoder论文中是lstm或者mlp的结构。P-Tuning要解决的是 [X] is located in [Y], [Y] is the country of [X]之类模版带来的问题
  • P-Tuning V2:只搞prompt还不够,要把Prompt token再给模型多传几层

针对self attention

  • (IA)^3:缩写是Infused Adapter by Inhibiting and Amplifying Inner Activations,方法是把标准的self-attention加一些参数。给标准self-attention的K,V各hadamard product一个参数,给position-wise feed-forward层的结果也hadamard product一个参数。最后相当于对每层Transformer block都hadamard product了三个参数;另外(IA)^3还贡献了unlikelihood loss(discourages the model from predicting tokens from incorrect target sequences,来自于Improving and Simplifying Pattern Exploiting Training这篇paper,实际上就是构造一个错误序列集合,1减去和错误集合匹配的概率,最后拼成一个cross entropy的形式)和length-normalized loss(把长度的因素也评成一个cross entropy的形式)

Adapter Tuning

来自Parameter-Efficient Transfer Learning for NLP,介绍了adapter结构:首先是一个down-project层将高维度特征映射到低维特征,然后过一个非线形层之后,再用一个up-project结构将低维特征映射回原来的高维特征;同时也设计了skip-connection结构,确保了在最差的情况下能够退化为identity。
在这里插入图片描述
从实验结果来看,该方法能够在只额外对增加的3.6%参数规模(相比原来预训练模型的参数量)的情况下取得和Full-finetuning接近的效果(GLUE指标在0.4%以内)

Prefix Tuning

来自Prefix-Tuning: Optimizing Continuous Prompts for Generation,在输入token之前构造一段任务相关的virtual tokens作为Prefix,然后训练的时候只更新Prefix部分的参数,而Transformer中的其他部分参数固定。该方法其实和构造Prompt类似,只是Prompt是人为构造的“显式”的提示,并且无法更新参数,而Prefix则是可以学习的“隐式”的提示。

同时,为了防止直接更新Prefix的参数导致训练不稳定的情况,他们在Prefix层前面加了MLP结构(相当于将Prefix分解为更小维度的Input与MLP的组合后输出的结果),训练完成后,只保留Prefix的参数。
在这里插入图片描述

Prompt Tuning

来自The Power of Scale for Parameter-Efficient Prompt Tuning

该方法可以看作是Prefix Tuning的简化版本,只在输入层加入prompt tokens,并不需要加入MLP进行调整来解决难训练的问题,主要在T5预训练模型上做实验。似乎只要预训练模型足够强大,其他的一切都不是问题。作者也做实验说明随着预训练模型参数量的增加,Prompt Tuning的方法会逼近Fine-tune的结果。
在这里插入图片描述

P-Tuning

下图说的比较明白,和Prefix-Tuning区别在于:

  • Prefix Tuning是将额外的embedding加在开头,看起来更像是模仿Instruction指令;而P-Tuning的位置则不固定。
  • Prefix Tuning通过在每个Attention层都加入Prefix Embedding来增加额外的参数,通过MLP来初始化;而P-Tuning只是在输入的时候加入Embedding,并通过LSTM+MLP来初始化。
    在这里插入图片描述
    P-Tuning方法的提出主要是为了解决这样一个问题:大模型的Prompt构造方式严重影响下游任务的效果。
    在这里插入图片描述

P-Tuning V2

来自P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks,相比Prompt Tuning和P-tuning的方法, P-tuning v2方法在多层加入了Prompts tokens作为输入,带来两个方面的好处:

  1. 带来更多可学习的参数(从P-tuning和Prompt Tuning的0.1%增加到0.1%-3%),同时也足够parameter-efficient。
  2. 加入到更深层结构中的Prompt能给模型预测带来更直接的影响。
几个关键设计因素

● Reparameterization:Prefix Tuning和P-tuning中都有MLP来构造可训练的embedding。本文发现在自然语言理解领域,面对不同的任务以及不同的数据集,这种方法可能带来完全相反的结论。
● Prompt Length: 不同的任务对应的最合适的Prompt Length不一样,比如简单分类任务下length=20最好,而复杂的任务需要更长的Prompt Length。
● Multi-task Learning 多任务对于P-Tuning v2是可选的,但可以利用它提供更好的初始化来进一步提高性能。
● Classification Head 使用LM head来预测动词是Prompt Tuning的核心,但我们发现在完整的数据设置中没有必要这样做,并且这样做与序列标记不兼容。P-tuning v2采用和BERT一样的方式,在第一个token处应用随机初始化的分类头。

LoRA

语言模型虽然参数众多,但是起到关键作用的还是其中低秩的本质维度(low instrisic dimension)。本文受到该观点的启发,提出了Low-Rank Adaption(LoRA),设计了如下所示的结构,在涉及到矩阵相乘的模块,引入A、B这样两个低秩矩阵模块去模拟Full-finetune的过程,相当于只对语言模型中起关键作用的低秩本质维度进行更新。矩阵秩的含义是矩阵中线性无关行或列的最大数量,秩的几何意义是线性变换后空间的维度
在这里插入图片描述
在这里插入图片描述
这么做就能完美解决以上存在的3个问题:
○ 相比于原始的Adapter方法“额外”增加网络深度,必然会带来推理过程额外的延迟,该方法可以在推理阶段直接用训练好的A、B矩阵参数与原预训练模型的参数相加去替换原有预训练模型的参数,这样的话推理过程就相当于和Full-finetune一样,没有额外的计算量,从而不会带来性能的损失。
○ 由于没有使用Prompt方式,自然不会存在Prompt方法带来的一系列问题。
○ 该方法由于实际上相当于是用LoRA去模拟Full-finetune的过程,几乎不会带来任何训练效果的损失,后续的实验结果也证明了这一点。还有苏神针对梯度的分析

LoRA的核心公式可表示为:
h=(W0+ΔW)⋅x=W0⋅x+αr⋅(A⋅B⋅x)ΔW=αr⋅A⋅B h = (W_0 + \Delta W) \cdot x = W_0 \cdot x + \frac{\alpha}{r} \cdot (A \cdot B \cdot x) \\ \Delta W = \frac{\alpha}{r} \cdot A \cdot B h=(W0+ΔW)x=W0x+rα(ABx)ΔW=rαAB
其中:

  • W0W_0W0 是原始预训练模型的权重矩阵;
  • A和B是低秩矩阵(维度分别为 d×rd \times rd×rr×dr \times dr×dr≪dr \ll drd );
  • α 是缩放因子(即 lora_alpha 参数);
  • r 是低秩矩阵的秩(即 r 参数)。

作用

  • α/r 的比例决定了低秩矩阵 ( A \cdot B ) 对权重更新的贡献程度。例如,若设置 ( \alpha=16 ) 且 ( r=8 ),则缩放因子为 ( 16/8=2 ),即低秩矩阵的更新会被放大2倍;
  • 若 ( \alpha=0 ),则LoRA的更新完全失效,模型退化为原始预训练权重;若 ( \alpha \gg r ),低秩调整的幅度可能过大,导致训练不稳定。
  • 平衡预训练知识与新任务适应
    α通过缩放因子调整低秩矩阵的影响力。较大的α值(如 ( \alpha=2r ))会增强低秩矩阵的更新幅度,使模型更关注新任务的特征;较小的α值则更依赖预训练权重,适合保留原有知识。
  • 初始化与训练稳定性
    在初始化时,矩阵 ( A ) 采用高斯分布(均值为0,标准差为 ( 1/\sqrt{r} )),矩阵 ( B ) 初始化为零矩阵。此时 ( \Delta W = 0 ),确保训练初期模型行为与原模型一致,避免随机噪声干扰。α通过后续梯度更新逐步调整低秩矩阵的贡献。

在这里插入图片描述

QLoRA

QLoRA: Efficient Finetuning of Quantized LLMs,实际上就是量化+LoRA

Towards a Unified View of PETL

有一大堆实验,就不展开写了,一些结论:

  • 哪种嵌入形式更好:Parallel or Sequencial? Parallel
  • 对哪块结构做修改更好?Attention or FFN? 当微调的参数量较多时,从结果来看,对FFN层进行修改更好。一种可能的解释是FFN层学到的是任务相关的文本模式,而Attention层学到的是成对的位置交叉关系,针对新任务并不需要进行大规模调整。 当微调参数量较少(0.1%)时,对Attention进行调整效果更好。
  • 哪种组合效果更好?论文里提到的Scaled PA效果更好

Ladder Side-Tuning(LST)

它是在原有大模型的基础上搭建了一个“旁支”(梯子),将大模型的部分层输出作为旁枝模型的输入,所有的训练参数尽在旁枝模型中,由于大模型仅提供输入,因此反向传播的复杂度取决于旁枝模型的规模,并不需要直接在原始大模型上执行反向传播,因此是可以明显提升训练效率的。
在这里插入图片描述
转载自:

  1. https://www.yuque.com/meta95/hmc3l4/ozgy13dx4akv7v17?singleDoc#miOqk
  2. https://kexue.fm/archives/9590/comment-page-1#comments
  3. https://kexue.fm/archives/9138
<think>嗯,用户现在想了解P-Tuning V2的实现或教程,特别是在NLP预训练和微调方法中的应用。首先,我需要回忆一下P-Tuning V2的基本概念。记得P-Tuning V2是P-Tuning的升级版,主要解决在自然语言处理中参数高效微调的问题。之前的P-Tuning可能在某些任务或模型规模上有局限性,而V2版本则扩展了适用性,比如支持更大的模型和更广泛的任务类型。 接下来,用户可能需要知道P-Tuning V2的核心原理。根据引用中的对比学习获得可学习的原型向量,这可能涉及到如何通过对比学习优化提示向量。另外,可能需要结合BERT等模型的微调方法,比如引用提到的Transformers和BERT Fine-tuning源码实现,这里需要确认P-Tuning V2在微调时的具体步骤,比如插入可训练的连续提示向量到各个Transformer层。 然后,用户可能关心具体的实现步骤。需要分点说明,比如模型结构修改部分,如何在每一层加入prompt embeddings,目标函数设计时如何结合对比学习或其他损失函数。同时,代码示例部分可能需要给出关键的代码片段,比如使用PyTorch和Hugging Face库定义提示向量,并在前向传播时将它们拼接到输入中。 还要注意用户的潜在需求,比如他们可能想知道如何在自己的数据集上应用P-Tuning V2,或者与LoRA等其他方法的对比。因此,相关问题部分需要覆盖这些方面,比如比较不同参数高效微调方法,调参技巧,以及实际应用案例。 另外,确保回答符合系统级指令,比如数学公式的正确格式,引用标识的添加。比如在讲对比学习时,如果有数学公式,需要用$$...$$格式,并正确引用相关文献。同时,检查是否有站内引用被正确使用,如引用[^1]和[^2]。 最后,要确保回答结构清晰,分点明确,帮助用户逐步理解P-Tuning V2的实现方法,并提供相关资源链接和进一步的问题引导他们深入学习。</think>### P-Tuning V2 原理与实现解析 P-Tuning V2是参数高效微调(Parameter-Efficient Fine-Tuning)方法的重要改进,其核心思想是通过可学习的连续提示向量(learnable prompt embeddings)引导模型适应下游任务。 #### 一、核心技术原理 1. **连续提示向量注入** - 在输入层和所有Transformer层插入可训练的连续提示向量 - 数学表达: $$ h_{i}^{'} = \text{TransformerLayer}([p_i; h_i]), \quad p_i \in \mathbb{R}^{k \times d} $$ 其中$p_i$为第$i$层的提示向量,$k$为提示长度,$d$为隐藏层维度 2. **对比学习优化**(基于引用[1]) - 通过对比正负样本优化提示向量空间分布 - 目标函数: $$ \mathcal{L}_{contrast} = -\log\frac{e^{s(q,p^+)}}{e^{s(q,p^+)} + \sum_{p^-}e^{s(q,p^-)}} $$ #### 二、实现步骤(基于PyTorch/Hugging Face) ```python from transformers import AutoModel import torch.nn as nn class PTuningV2(nn.Module): def __init__(self, model_name, prompt_length=20): super().__init__() self.backbone = AutoModel.from_pretrained(model_name) self.hidden_size = self.backbone.config.hidden_size # 初始化各层提示向量 self.prompt_embeddings = nn.ParameterList([ nn.Parameter(torch.randn(prompt_length, self.hidden_size)) for _ in range(self.backbone.config.num_hidden_layers + 1) ]) def forward(self, input_ids, attention_mask): embeddings = self.backbone.embeddings(input_ids) # 输入层提示拼接 inputs_embeds = torch.cat([ self.prompt_embeddings[0].expand(input_ids.size(0), -1, -1), embeddings ], dim=1) # 逐层处理 hidden_states = inputs_embeds for i, layer in enumerate(self.backbone.encoder.layer): # 添加层提示 prompt = self.prompt_embeddings[i+1].expand(hidden_states.size(0), -1, -1) hidden_states = torch.cat([prompt, hidden_states], dim=1) hidden_states = layer(hidden_states, attention_mask=attention_mask)[0] return hidden_states ``` #### 三、关键配置参数 | 参数 | 推荐值 | 作用 | |-------|---------|------| | `prompt_length` | 20-100 | 提示向量长度 | | `learning_rate` | 1e-4 | 提示向量学习率 | | `contrastive_weight` | 0.2 | 对比损失权重 | #### 四、应用场景 1. 少样本学习(<100训练样本) 2. 多任务联合微调 3. 领域适应(医疗/法律等专业领域)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值