SayMeeveTime

ModeScope在线训练平台&服务器选配训练模型

avatar

Chester

模型微调的基本模式

  • 全量微调
  • 局部微调
  • 增量微调
    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

  1. 模型微调的基本模式
    全量微调
    对所有参数进行微调。
    要求较高的计算资源(算力和显存)。
    效果最佳,适合复杂场景。

局部微调
仅微调模型的某些部分,如输出层或特定的Transformer 层。
计算资源需求较小,适合有限资源的情况。

增量微调
新增参数进行微调,将新知识存储在新增参数中。
计算资源需求最低,但效果不如全量微调。

  1. Model Scope 在线训练平台介绍
    Model Scope 是一个在线的AI模型训练平台,支持GPT2、BERT等多种模型的训练与部署。其优势包括:

提供云端训练环境,降低本地计算资源压力。
支持丰富的预训练模型和数据集。
简化微调训练流程,适合快速迭代开发。

  1. 使用 Model Scope 在线训练 GPT2
    可以使用 Model Scope 在线平台进行GPT2的模型微调,以下是具体步骤:

登录 Model Scope 平台,选择GPT2 模型。
上传或选择中文古诗词训练数据集。
配置模型微调参数(如学习率、训练轮数等)。
启动训练,并在训练完成后下载微调后的模型权重。

  1. 选配AutoDL服务器并使用vscode远程连接
    AutoDL网站地址: https://www.autodl.com/home
    通过VSCode和SSH使用AutoDL服务器训练模型教程地址: https://www.autodl.com/home
  2. 混合精度训练(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进行混合精度训练的例子:

  1. 准备环境:

首先,确保你的硬件和PyTorch版本支持FP16运算。然后,导入必要的库:

Python

import torch
import torch.nn as nn
import torch.optim as optim
from torch.cuda.amp import autocast, GradScaler

  1. 定义模型:

创建一个简单的神经网络模型,例如一个多层感知机(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
  1. 启用混合精度:

使用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精度下进行的,这是为了保持数值稳定性。

  1. 使用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。

2024056667
powered by SayMeeveTime