ModeScope在线训练平台&服务器选配训练模型
模型微调的基本模式
- 全量微调
- 局部微调
- 增量微调
Model Scope 在线训练平台介绍
使用 Model Scope 在线训练 GPT2
选配AutoDL服务器并使用vscode远程连接
AutoDL网站地址: https://www.autodl.com/home
通过VSCode和SSH使用AutoDL服务器训练模型教程地址: https://www.autodl.com/home
混合精度训练(Mixed Precision Training)
介绍
优点
FP16和 FP32
FP16(16位浮点数)
FP32(32位浮点数)
基本流程
准备环境
GradScaler
- 模型微调的基本模式
全量微调
对所有参数进行微调。
要求较高的计算资源(算力和显存)。
效果最佳,适合复杂场景。
局部微调
仅微调模型的某些部分,如输出层或特定的Transformer 层。
计算资源需求较小,适合有限资源的情况。
增量微调
新增参数进行微调,将新知识存储在新增参数中。
计算资源需求最低,但效果不如全量微调。
- Model Scope 在线训练平台介绍
Model Scope 是一个在线的AI模型训练平台,支持GPT2、BERT等多种模型的训练与部署。其优势包括:
提供云端训练环境,降低本地计算资源压力。
支持丰富的预训练模型和数据集。
简化微调训练流程,适合快速迭代开发。
- 使用 Model Scope 在线训练 GPT2
可以使用 Model Scope 在线平台进行GPT2的模型微调,以下是具体步骤:
登录 Model Scope 平台,选择GPT2 模型。
上传或选择中文古诗词训练数据集。
配置模型微调参数(如学习率、训练轮数等)。
启动训练,并在训练完成后下载微调后的模型权重。
- 选配AutoDL服务器并使用vscode远程连接
AutoDL网站地址: https://www.autodl.com/home
通过VSCode和SSH使用AutoDL服务器训练模型教程地址: https://www.autodl.com/home - 混合精度训练(Mixed Precision Training)
介绍
混合精度训练(Mixed Precision Training)是一种在深度学习中提高训练速度和减少内存占用的技术。在PyTorch中,通过使用半精度浮点数(16位浮点数,FP16)和单精度浮点数(32位浮点数,FP32)的组合。
优点
在不改变模型、不降低模型训练精度的前提下,可以缩短训练时间,降低存储需求,因而能支持更大的batch size、更大模型和尺寸更大的输入的训练。
FP16 和 FP32
FP16和FP32 是两种不同的浮点数表示格式,它们表示浮点数的精度和范围。
FP16 (16位浮点数):
FP16 是一种半精度浮点数格式,它使用16位(2字节)来表示一个浮点数。
它的格式通常包括1位符号位、5位指数位和10位尾数位。
由于指数位较少,FP16能够表示的数值范围比FP32小,但它需要的内存和计算资源也更少。
FP16在深度学习中被用于加速计算和节省内存,尤其是在支持FP16运算的硬件上。
FP32(32位浮点数):
FP32 是一种单精度浮点数格式,它使用32位(4字节)来表示一个浮点数。
它的格式包括1位符号位、8位指数位和23位尾数位。
相比于FP16,FP32能够表示更大范围的数值,具有更高的精度,但也需要更多的内存和计算资源。
FP32是最常用的浮点数类型,适用于广泛的科学计算和工程应用。
在深度学习中,使用FP16进行训练可以显著减少模型的内存占用,加快数据传输和计算速度,尤其是在配备有Tensor Core的NVIDIA GPU上。然而,由于FP16的数值范围较小,可能会导致数值下溢(underflow)或精度损失,因此在训练过程中可能需要一些特殊的技术(如梯度缩放和混合精度训练)来确保模型的数值稳定性和最终精度。
基本流程
下面是一个使用PyTorch进行混合精度训练的例子:
- 准备环境:
首先,确保你的硬件和PyTorch版本支持FP16运算。然后,导入必要的库:
Python
import torch
import torch.nn as nn
import torch.optim as optim
from torch.cuda.amp import autocast, GradScaler
- 定义模型:
创建一个简单的神经网络模型,例如一个多层感知机(MLP):
Python
class SimpleMLP(nn.Module):
def init(self):
super(SimpleMLP, self).init()
self.fc1 = nn.Linear(10, 5)
self.fc2 = nn.Linear(5, 2)
def forward(self, x):
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
- 启用混合精度:
使用autocast()上下文管理器来指定哪些操作应该使用FP16执行:
Python
model = SimpleMLP().cuda()
model.train()
scaler = GradScaler()
for epoch in range(num_epochs):
for batch in data_loader:
x, y = batch
x, y = x.cuda(), y.cuda()
with autocast():
outputs = model(x)
loss = criterion(outputs, y)
# 反向传播和权重更新
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
在这个例子中,autocast()将模型的前向传播和损失计算转换为FP16格式。然而,反向传播仍然是在FP32精度下进行的,这是为了保持数值稳定性。
- 使用GradScaler:
由于FP16的数值范围较小,可能会导致梯度下溢(underflow)。GradScaler在反向传播之前将梯度的值放大,然后在权重更新之后将其缩放回来:
Python
scaler = GradScaler()
在计算梯度后,使用scaler.step(optimizer)来应用缩放后的梯度。
GradScaler
GradScaler 是 PyTorch 中 torch.cuda.amp 模块提供的一个工具,它用于帮助进行混合精度训练。在混合精度训练中,我们通常使用FP16来存储模型的权重和进行前向计算,以减少内存占用和加速计算。
然而,FP16的数值范围比FP32小,这可能导致在梯度计算和权重更新时出现数值下溢(underflow),即梯度的数值变得非常小,以至于在FP16格式下无法有效表示。
GradScaler 通过在反向传播之前自动放大(scale up)梯度的值来解决这个问题。然后,在执行权重更新之后,GradScaler 会将放大的梯度缩放(scale down)回原来的大小。这个过程确保了即使在FP16格式下,梯度的数值也能保持在可表示的范围内,从而避免了数值下溢的问题。
Python
scaler = torch.cuda.amp.GradScaler()
for inputs, targets in dataloader:
with autocast():
outputs = model(inputs)
loss = loss_fn(outputs, targets)
scaler.scale(loss).backward() # 放大梯度
scaler.step(optimizer) # 应用缩放后的梯度进行权重更新
scaler.update() # 更新缩放因子
保存和加载模型:
Python
torch.save(model.state_dict(), 'model.pth')
model.load_state_dict(torch.load('model.pth'))
在混合精度训练中,虽然模型的权重在训练过程中可能会被转换为FP16格式以节省内存和加速计算,但在保存模型时,我们通常会将权重转换回 FP32格式。这是因为FP32提供了更高的数值精度和更广泛的硬件支持,这使得模型在不同环境中的兼容性和可靠性更好。
在PyTorch 中,当你调用 model.state_dict()方法时,默认情况下它会返回一个包含权重的字典。即使你在训练时使用了FP16,这个字典也会包含FP32权重,因为PyTorch 会先转换为FP32 再保存。同样,当你使用 torch.load()加载模型时,如果模型权重是FP16格式,PyTorch 会自动将它们转换为FP32。
注意,如果你的模型是在GPU上训练的,加载模型时应该使用map_location 参数来指定加载到CPU,然后再将模型转换为FP32并移回 GPU。