萱仔大模型学习记录3.2-BERT算法微调理论和实践Adapter Tuning、Prefix Tuning等

3.Adapter Tuning

原版论文:https://arxiv.org/pdf/1902.00751.pdf

原版代码:GitHub - google-research/adapter-bert

Adapter Tuning 是一种在预训练模型的基础上进行高效微调的方法。通过插入adapter modules,只需增加少量可训练参数,就能使模型在新任务上取得优异的性能。(我个人感觉这个在使用上和lora有点类似,lora是引入了两个矩阵,在外面训练微调,较低成本实现训练任务。这个是加入一个适配器的模块。Adapter Modules是插入到现有预训练模型中的小型网络层。由少量可训练参数组成,通常包括一个下采样层、一个ReLU之类的非线性激活层,以及一个上采样层。(这一点又和计算机视觉中有一点点像,上采样和下采样各有作用,然后加上激活函数的非线性函数,加入到神经网络中可以让网格拟合非线性映射。Adapter Modules插入位置通常在Transformer层之间。)

在适配器微调过程中,预训练模型的参数保持不变。只训练适配器模块的参数,从而实现参数高效的迁移学习。相比于传统的微调,适配器微调只需增加很少的新参数,但能够取得接近或甚至超越全量微调的效果。适配器模块可以独立于任务进行训练,适应多任务学习的需求。

import torch
from transformers import BertModel, BertTokenizer, BertForSequenceClassification, AdapterConfig

# 加载预训练BERT模型和Tokenizer
model_name = "bert-base-uncased"
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForSequenceClassification.from_pretrained(model_name)

# 冻结BERT主体模型的所有参数
for param in model.bert.parameters():
    param.requires_grad = False

# 添加适配器模块配置
adapter_config = AdapterConfig(
    hidden_size=64,  # 适配器模块的隐藏层大小
    adapter_non_linearity="relu",  # 非线性激活函数
    reduction_factor=16  # 下采样比例
)

# 为分类任务添加适配器
model.add_adapter("text_classification_adapter", config=adapter_config)
model.train_adapter("text_classification_adapter")

# 示例输入
inputs = tokenizer("This is a test sentence.", return_tensors="pt")

# 模型预测前向传播
outputs = model(**inputs)

# 打印模型输出
print(outputs.logits)

# 准备训练数据(以GLUE任务中的MRPC数据集为例)
from datasets import load_dataset
dataset = load_dataset("glue", "mrpc")
train_dataset = dataset['train']
validation_dataset = dataset['validation']

# 数据处理函数
def preprocess_function(examples):
    return tokenizer(examples['sentence1'], examples['sentence2'], truncation=True, padding=True)

# 预处理数据
train_dataset = train_dataset.map(preprocess_function, batched=True)
validation_dataset = validation_dataset.map(preprocess_function, batched=True)

# 数据加载器
from torch.utils.data import DataLoader
train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)
validation_loader = DataLoader(validation_dataset, batch_size=16)

# 定义优化器和损失函数
from transformers import AdamW
optimizer = AdamW(model.parameters(), lr=5e-5)
loss_fn = torch.nn.CrossEntropyLoss()

# 训练适配器
model.train()
for epoch in range(3):  # 训练3个epoch
    for batch in train_loader:
        inputs = {k: v.to(model.device) for k, v in batch.items() if k in tokenizer.model_input_names}
        labels = batch['label'].to(model.device)
        optimizer.zero_grad()
        outputs = model(**inputs)
        loss = loss_fn(outputs.logits, labels)
        loss.backward()
        optimizer.step()
    print(f"Epoch {epoch + 1}: Loss {loss.item()}")

# 验证模型
model.eval()
correct_predictions = 0
total_predictions = 0
with torch.no_grad():
    for batch in validation_loader:
        inputs = {k: v.to(model.device) for k, v in batch.items() if k in tokenizer.model_input_names}
        labels = batch['label'].to(model.device)
        outputs = model(**inputs)
        predictions = torch.argmax(outputs.logits, dim=-1)
        correct_predictions += (predictions == labels).sum().item()
        total_predictions += labels.size(0)
accuracy = correct_predictions / total_predictions
print(f"Validation Accuracy: {accuracy}")

# 保存适配器
model.save_adapter("text_classification_adapter", "output_adapter_directory")

4.Prefix Tuning输入增加可训练的上下文前缀

原版论文:https://arxiv.org/pdf/2101.00190.pdf
原版代码:

Fine-tuning是利用大型预训练语言模型来执行下游任务的默认方式。然而,微调会修改所有语言模型的参数,因此需要为每个任务存储一份完整的副本。本文提出了一种轻量级的微调替代方法——前缀调优prefix-tuning,专用于自然语言生成任务。前缀调优保持语言模型参数不变,仅优化一个小的任务特定的连续向量(称为前缀)。前缀调优受提示(prompting)的启发,允许后续的token关注这个前缀,仿佛它们是“虚拟token”。这篇论文将前缀调优应用于GPT-2进行表格到文本生成,以及BART进行摘要生成。结果表明,通过仅学习0.1%的参数,前缀调优在完整数据集环境中获得了与全量微调相当的性能,在低数据环境中表现优于微调,并且在训练时未见过主题的例子上具有更好的外推能力。

Prefix Tuning 是一种在预训练语言模型(如 BERT 或 GPT-2)基础上进行高效微调的方法。与传统的微调方式不同,Prefix Tuning 只调整少量的前缀参数,而不修改原始模型的参数,从而在多个任务之间实现高效迁移。

  1. 前缀参数(Prefix Parameters)
    • 前缀参数是在每层 Transformer 网络的输入前增加的一组可训练参数。
    • 这些参数在模型进行任务特定的微调时可以独立更新,而无需调整原始模型的参数。
  2. 冻结预训练模型
    • 在 Prefix Tuning 过程中,预训练模型的参数保持不变。
    • 只训练前缀参数,从而实现高效的参数更新和迁移学习。
  3. 高效微调
    • 相比于传统的微调,Prefix Tuning 只需调整少量的前缀参数,但能够取得接近或甚至超越全量微调的效果。
    • 前缀参数可以独立于任务进行训练,适应多任务学习的需求。

总结
  1. 传统微调的局限性

    • 修改所有语言模型参数,需要为每个任务存储一个完整的模型副本。
  2. 前缀调优的优势

    • 保持语言模型参数不变,仅优化前缀参数。
    • 通过仅学习0.1%的参数,前缀调优在全数据集设置中获得了可比的性能,在低数据设置中表现优于微调,并在训练中未见的主题上表现更好。
  3. 应用场景

    • 前缀调优适用于自然语言生成任务,如表格到文本生成和摘要生成。

        所有P-tuning都是基于优化连续的prefix或者prompt的思想。调整软提示优于先前对离散提示优化的工作。Prompt-tuning的工作表明全量微调和P*-tuning之间的性能差距随着模型的大小增大而消失。


5.Prompt Tuning输入增加可训练的嵌入向量提示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值