新闻类的网站如何做优化、,计算机基础网站建设和网络安全,网站的后缀,跨境电商面试自我介绍范文1. 概述
在深度学习中#xff0c;微调#xff08;Fine-tuning#xff09;是一种重要的技术#xff0c;用于改进预训练模型的性能。在预训练模型的基础上#xff0c;针对特定任务#xff08;如文本分类、机器翻译、情感分析等#xff09;#xff0c;使用相对较小的有监…1. 概述
在深度学习中微调Fine-tuning是一种重要的技术用于改进预训练模型的性能。在预训练模型的基础上针对特定任务如文本分类、机器翻译、情感分析等使用相对较小的有监督数据集对模型进行进一步训练的过程。预训练模型学习到了语言的一般规律如语法、语义等知识通过微调模型可以利用预训练过程中学习到的知识并结合特定任务的数据在该任务上达到更好的准确率、召回率等性能指标。
在微调过程中通常会冻结预训练模型的一部分参数只训练模型的顶层或特定层以便模型能够针对新任务进行调整。所需的Fine-tuning量取决于预训练语料库和任务特定语料库之间的相似性。如果两者相似可能只需要少量的Fine tuning。如果两者不相似则可能需要更多的Fine tuning。 为什么需要微调
微调的价值可以帮助我们更好地利用预训练模型的知识加速和优化新任务的训练过程同时减少对新数据的需求和降低训练成本。减少对新数据的需求从头开始训练一个大型神经网络通常需要大量的数据和计算资源而在实际应用中我们可能只有有限的数据集。通过微调预训练模型我们可以利用预训练模型已经学到的知识减少对新数据的需求从而在小数据集上获得更好的性能。降低训练成本由于我们只需要调整预训练模型的部分参数而不是从头开始训练整个模型因此可以大大减少训练时间和所需的计算资源。这使得微调成为一种高效且经济的解决方案尤其适用于资源有限的环境。
2. 微调的分类 全微调Full Fine-tuning这是一种比较直接的方法使用特定任务的数据集对整个预训练模型的所有参数进行微调适用于任务和预训练模型之间存在较大差异的情况或任务需要模型具有高度灵活性和自适应能力的情况。这种方法需要较大的计算资源和时间但可以获得更好的性能。也可能会出现 “灾难性遗忘” 的问题即模型在微调过程中过度拟合特定任务的数据而忘记了预训练过程中学习到的一些通用知识。 参数高效微调Parameter-Efficient Fine-Tuning, PEFT为了解决全微调的问题参数高效微调方法应运而生。通过微调少量参数来达到接近微调全量参数的效果使得在GPU资源不足的情况下也可以微调大模型。PEFT技术包括LoRA、QLoRA、适配器调整(Adapter Tuning)、前缀调整(Prefix Tuning)、提示调整(Prompt Tuning)及P-Tuning v2等多种方法。
3. 常见的微调技术
3.1 LoRA
LoRALow-Rank Adaptation由微软在2021年提出通过在模型的关键层次中引入小型、低秩的矩阵来实现模型行为的微调而无需对整个模型结构进行大幅度修改。简单来说Lora的本质就是对所有权重矩阵套了一层“壳”这些壳会对原来的预训练权重矩阵进行加减使其更加适合下游任务即实现微调。他的假设前提是预训练模型具有低的内在维度因此认为在模型适配下游任务的过程中权重更新也应该具有低的“内在秩”。通常只需要全模型微调的 10%-20% 的计算资源。因此在资源受限的环境下LoRA 可以轻松实现大规模语言模型的微调。LoRA 通常与 Transformer 架构结合使用特别是在自注意力模块和前馈神经网络中。在实际应用中LoRA 可以与其他参数高效微调方法如适配器调整、前缀调整等结合使用以进一步提高微调效果。
具体来说权重矩阵会被分解成两个小矩阵的乘积。假设原始权重矩阵为 W尺寸为 d×d。LoRA 会将其更新为 W ′ WΔW其中 ΔWA×BA 和 B 是两个低秩矩阵。矩阵 A 用于降维从大维度到小维度矩阵 B 用于升维从小维度回到大维度B 和 A 的尺寸分别为 d×r 和 r×d而 r≪d。这种方法在训练时只更新 A 和 B而原始权重矩阵 W 保持不变从而大大减少了训练参数量提高了计算效率。矩阵 A 会使用高斯初始化矩阵 B 则初始化为零矩阵。这样在训练初期新增的通路对模型的影响为零训练开始时不会对原有模型的行为产生影响。
3.2 QLoRA
2023 年 5 月 23 日 QLoRA 的推出它代表具有低秩适配器的量化 LLM这是一种能够以最小的内存使用量高效微调大型语言模型的方法。QLoRA 不会从头开始重新训练整个模型而是向模型添加少量新参数这些参数专门针对新任务进行训练同时将原始预训练语言模型参数保持在 4 位量化状态。
QLoRA 背后的关键理念是通过减少内存使用量来提高 LLM 的效率同时保持可靠的性能。它通过几个步骤实现这一目标引入 4 位量化、一种称为 4 位 NormalFloat (NF4) 的新数据类型、双量化和分页优化器。
14 位量化 传统的深度学习模型通常使用 32 位浮点数float32或 16 位浮点数float16进行计算。这些数据类型占用较多内存尤其是在处理大型语言模型时内存需求会非常高。而 QLoRA 引入了 4 位量化即将模型的权重和激活值从 32 位或 16 位浮点数压缩到 4 位。这种量化可以显著减少内存占用从而提高模型的效率。
24位NormalFloat (NF4) 数据类型 在量化过程中选择合适的数据类型至关重要。不同的数据类型在精度和内存占用之间需要权衡。NF4 是一种针对正态分布权重优化的 4 位数据类型。与其他4位数据类型如INT4相比NF4 在实验中表现出更好的性能能够在量化后保持较高的精度。
3双量化 即使使用了 4 位量化量化过程中仍然会引入一些量化常数这些常数本身也需要占用内存。因此QLoRA 通过进一步量化这些量化常数进一步减少内存占用。
4分页优化器 在训练大型模型时梯度检查点gradient checkpointing是一种常用的技巧用于减少内存占用。然而这种方法在某些情况下会导致内存峰值问题。QLoRA 通过将模型参数划分为多个小组并分别处理每个小组从而避免了梯度检查点期间的内存峰值问题。此外它还使用NVIDIA统一内存Unified Memory来管理内存页面进一步优化内存使用。 3.3 Adapter Tuning
Adapter Tuning 方法由 Houlsby N 等人在2019年提出它涉及将称为适配器的小型神经网络模块整合到Transformer模型中这些适配器模块作为每个Transformer层内的附加组件。针对每一个 Transformer 层增加了两个 Adapter 结构分别是多头注意力的投影之后和第二个 feed-forward 层之后在训练时固定住原来预训练模型的参数不变只对新增的 Adapter 结构和 Layer Norm 层进行微调从而保证了训练的高效性。虽然通过增加模型层数来引入额外的灵活性但这也导致了额外的推理延迟。
什么是适配器模块
我们从三点来看一下适配器模块在 transformer 架构中的应用
适配器模块右首先将原始 d 维特征投影到较小的 m 维向量应用非线性然后将其投影回 d 维。可以看出该模块具有跳跃连接功能——有了它当投影层的参数初始化为接近零时最终导致模块的接近恒等初始化。这对于稳定的微调是必需的并且很直观因为有了它我们基本上不会干扰预训练的学习。在变压器块左中适配器直接应用于每个层注意力和前馈的输出。
如何确定m的值
适配器模块中的大小 m 决定了可优化参数的数量因此存在参数与性能的权衡。原始论文通过实验调查了不同适配器尺寸 m 的性能保持相当稳定因此对于给定模型所有下游任务都可以使用固定尺寸。
3.4 Prefix Tuning
前缀微调Prefix tuning是一种用于语言模型的技术其中在每个Transformer层中添加了一组可训练的连续向量序列这些向量被称为前缀。这些前缀是特定于任务的可以被视为虚拟的标记嵌入。在训练过程中仅更新这些前缀参数而模型的其余部分保持不变。
前缀向量的优化是通过一种重参数化技巧实现的。不是直接优化前缀而是学习一个MLP多层感知器函数它将一个较小的矩阵映射到前缀的参数矩阵。这种重参数化技巧有助于实现稳定的训练。优化完成后映射函数会被丢弃只保留推导出的前缀向量以增强特定任务的性能。这种方法专注于仅训练前缀参数使其成为一种参数高效的模型优化方法。
3.5 Prompt Tuning
提示微调Prompt tuning是一种与前缀微调不同的技术(也就是我们常说的P-Tuning)它侧重于在语言模型的输入层引入可训练的提示向量。该方法基于离散提示方法人工设计如文本模板并通过在输入文本中包含软提示标记以自由形式或前缀形式来扩展输入文本。在实现过程中特定任务的提示嵌入与输入文本嵌入相结合并输入到语言模型中。简单来说就是通过设计或学习一个固定的提示将其与输入文本结合引导模型生成期望的输出。
该方法在少样本或零样本学习中表现较好但对提示的设计依赖较强。
3.6 P-Tuning v2
P-Tuning v2 是 Prompt Tuning 的改进版本通过引入连续提示嵌入和多层提示机制提升提示的表达能力和模型性能。
连续提示嵌入将离散提示替换为可学习的连续向量增强了提示的灵活性。多层提示在模型的不同层引入提示嵌入捕捉多层次的语义信息。提示编码器使用双向 LSTM 或 Transformer 编码提示嵌入进一步提升提示的语义表达能力。通用性适用于多种预训练模型如BERT、GPT等且在少样本学习中表现更稳定。
4. 微调步骤
笔者重点介绍怎么使用参数高效微调方法微调视觉语言大模型。
VisualGLM-6B 是一个结合视觉和语言的多模态大模型支持图像和文本的联合理解与生成。对其进行参数高效微调Parameter-Efficient Fine-Tuning, PEFT可以显著降低计算和存储成本。以下是针对使用 GPU 对VisualGLM-6B 的高效微调步骤
1选择高效微调方法
笔者推荐使用 LoRA 或 Adapter因为它们在多模态任务中表现良好。
2环境部署
安装 PyTorch 和 Hugging Face Transformers。安装 PEFT 库如 peft和 VisualGLM-6B 相关依赖。笔者已经在之前的博客中介绍过 VisualGLM-6B 的环境部署与推理。注意GPU 需要至少 24GB 显存如 NVIDIA A100、RTX 3090 等。
conda create -n visualglm python3.8 -y
conda activate visualglm
conda install pytorch2.0.0 torchvision0.15.0 torchaudio2.0.0 pytorch-cuda11.7 -c pytorch -c nvidia
pip install transformers peft datasets accelerate2加载预训练模型
使用 Hugging Face 加载 VisualGLM-6B 的预训练模型和分词器。将模型移动到 GPU。同样笔者已经在之前的博客中介绍过如何加载本地模型。
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch# 加载模型和分词器
model_name THUDM/visualglm-6b
model AutoModelForCausalLM.from_pretrained(model_name, trust_remote_codeTrue)
tokenizer AutoTokenizer.from_pretrained(model_name, trust_remote_codeTrue)# 将模型移动到 GPU
device torch.device(cuda if torch.cuda.is_available() else cpu)
model.to(device)
3 应用高效微调方法
以 LoRA 为例使用 peft 库实现
配置 LoRA
from peft import get_peft_model, LoraConfig, TaskType# 配置 LoRA
lora_config LoraConfig(task_typeTaskType.CAUSAL_LM, # 任务类型r8, # 低秩矩阵的秩lora_alpha32, # 缩放因子lora_dropout0.1, # Dropout 概率target_modules[query_key_value], # 目标模块VisualGLM-6B 中的注意力层
)# 应用 LoRA
model get_peft_model(model, lora_config)
model.to(device) # 将 LoRA 模型移动到 GPU
4准备数据
加载多模态数据集如图像-文本对并对图像和文本进行预处理。
from datasets import load_dataset
from torchvision import transforms
from PIL import Image# 加载本地数据集
dataset load_dataset(json, data_filesdataset/annotations.json)# 图像预处理
image_transform transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor(),
])# 文本预处理
def preprocess_function(examples):examples[image] [image_transform(Image.open(img).convert(RGB)) for img in examples[image_path]]examples[text] tokenizer(examples[text], paddingmax_length, truncationTrue, return_tensorspt)return examplestokenized_dataset dataset.map(preprocess_function, batchedTrue)5设置训练参数
from transformers import TrainingArgumentstraining_args TrainingArguments(output_dir./results,per_device_train_batch_size4, # 根据 GPU 显存调整per_device_eval_batch_size4,num_train_epochs100,learning_rate1e-4,evaluation_strategyepoch,save_strategyepoch,logging_dir./logs,fp16True, # 启用混合精度训练以节省显存gradient_accumulation_steps2, # 梯度累积
)6训练模型
使用 Trainer 进行训练。
from transformers import Trainertrainer Trainer(modelmodel,argstraining_args,train_datasettokenized_dataset[train],eval_datasettokenized_dataset[test],
)# 开始训练
trainer.train()7评估模型
在测试集上评估模型性能。计算任务相关指标如生成文本的 BLEU 分数或图像-文本匹配准确率。
results trainer.evaluate()
print(results)8保存模型
保存微调后的模型和配置。
model.save_pretrained(./fine-tuned-visualglm-6b)
tokenizer.save_pretrained(./fine-tuned-visualglm-6b)9部署与推理
from transformers import pipeline
from PIL import Image# 加载微调后的模型
model AutoModelForCausalLM.from_pretrained(./fine-tuned-visualglm-6b, trust_remote_codeTrue)
tokenizer AutoTokenizer.from_pretrained(./fine-tuned-visualglm-6b, trust_remote_codeTrue)device torch.device(cuda if torch.cuda.is_available() else cpu)
model.to(device)# 推理示例
image Image.open(image.jpg).convert(RGB)
text Describe the image:
inputs tokenizer(text, return_tensorspt).to(device)
image_input image_transform(image).unsqueeze(0).to(device)outputs model.generate(inputs[input_ids], image_inputimage_input)
print(tokenizer.decode(outputs[0], skip_special_tokensTrue))5. 自定义数据集
数据集结构
图像文件存储图像的文件夹。标注文件存储图像-文本对的元数据如 JSON、CSV 文件。
示例
dataset/
├── images/
│ ├── 1.jpg
│ ├── 2.jpg
│ └── 3.jpg
└── annotations.json标注文件如 annotations.json通常包含以下信息
图像路径指向图像文件的路径。文本描述与图像相关的文本描述。
JSON 格式示例
[{image_path: images/1.jpg,text: A cat sitting on a wooden table.},{image_path: images/2.jpg,text: A group of people playing soccer in a field.},{image_path: images/3.jpg,text: A beautiful sunset over the mountains.}
]CSV 格式示例
image_path,text
images/1.jpg,A cat sitting on a wooden table.
images/2.jpg,A group of people playing soccer in a field.
images/3.jpg,A beautiful sunset over the mountains.