文章目录
- P Tuning微调概述
- 核心原理
- 实现步骤
- 优势与适用场景
- 代码注释
P Tuning微调概述
P Tuning是一种参数高效的微调方法,通过引入可训练的连续提示(prompt)参数来适配下游任务,避免直接修改预训练语言模型(PLM)的全部参数。其核心思想是将离散的自然语言提示替换为可优化的连续向量,显著降低计算成本。
核心原理
传统微调需要更新整个模型的参数,而P Tuning仅优化插入的连续提示向量。这些提示通常以可学习张量的形式嵌入输入层或中间层,引导模型输出适应特定任务。数学形式可表示为:
h = PLM ( [ P ; x ] ) h = \text{PLM}([P; x])h=PLM([P;x])
其中P PP为连续提示向量,x xx为输入文本,h hh为模型输出。
实现步骤
连续提示设计
在输入序列前或中间插入可训练的张量(如维度与词嵌入相同),替代传统离散提示。例如,在分类任务中,输入可能构造为[ P 1 , P 2 , . . . , P n ; 文本 ] [P_1, P_2, ..., P_n; \text{文本}][P1,P2,...,Pn;文本]。
参数冻结
保持预训练模型参数固定,仅更新提示向量P PP和任务特定头部(如分类器)。部分变体允许选择性微调部分模型层。
优势与适用场景
- 计算高效:仅训练少量参数,适合资源受限场景。
- 通用性:适用于文本分类、生成、问答等多种任务。
- 小样本适配:在低数据场景下表现优于全参数微调。
代码注释
importtorchimporttorch.nnasnn# 定义PromptEncoder类,继承自nn.ModuleclassPromptEncoder(nn.Module):def__init__(self,config):super(PromptEncoder,self).__init__()# 从config中获取模型参数self.token_dim=config.token_dim# token的维度self.input_size=self.token_dim# 输入维度self.output_size=self.token_dim# 输出维度self.hidden_size=config.encoder_hidden_size# LSTM隐藏层维度self.total_virtual_tokens=config.num_virtual_tokens*config.num_transformer_submodules# 虚拟token总数# 定义embedding层,将虚拟token映射到token_dim维度self.embedding=nn.Embedding(self.total_virtual_tokens,self.token_dim)# 如果不是推理模式,初始化LSTM和MLPifnotconfig.inference_mode:lstm_dropout=config.encoder_dropout# LSTM的dropout率num_layers=config.encoder_num_layers# LSTM层数# 定义双向LSTMself.lstm_head=nn.LSTM(input_size=self.input_size,hidden_size=self.hidden_size,num_layers=num_layers,dropout=lstm_dropout,bidirectional=True,batch_first=True)# 定义MLP,包含两个线性层和ReLU激活函数self.mlp_head=nn.Sequential(nn.Linear(self.hidden_size*2,self.hidden_size*2),# 双向LSTM输出维度翻倍nn.ReLU(),nn.Linear(self.hidden_size*2,self.output_size)# 输出维度与token_dim相同)defforward(self,indices):# 将输入的indices转换为embeddinginput_embeds=self.embedding(indices)# 将embedding输入LSTM,取输出结果输入MLPoutput_embeds=self.mlp_head(self.lstm_head(input_embeds)[0])returnoutput_embeds初始化部分
- 从配置中获取模型参数,包括token维度、隐藏层大小等。
- 定义embedding层,将虚拟token映射到指定维度。
- 在非推理模式下,初始化双向LSTM和MLP结构。
前向传播
- 将输入的虚拟token索引转换为embedding向量。
- 通过双向LSTM处理embedding向量。
- 使用MLP进一步处理LSTM输出,生成最终编码结果。
该模块通常用于prompt tuning或prefix tuning等场景,用于生成可学习的虚拟token表示。