- DeepSpeed 教程
- DeepSpeed - 首页
- DeepSpeed - 快速入门
- DeepSpeed - 模型训练
- DeepSpeed - 优化器
- DeepSpeed - 学习率调度器
- DeepSpeed - 分布式训练
- DeepSpeed - 内存优化
- DeepSpeed - 混合精度训练
- DeepSpeed 有用资源
- DeepSpeed - 资源
- DeepSpeed - 讨论
使用 DeepSpeed 进行分布式训练
随着模型规模和数据集规模的增加,在大多数情况下,单GPU训练变得低效甚至不可行。因此,基于分布式训练,模型可以轻松地从单个GPU扩展到多个GPU和节点。结合优化这种训练方法,微软的DeepSpeed是最好的框架之一。它能够处理大型模型,并通过数据并行、模型并行和零冗余优化器 (ZeRO) 等重要技术来降低内存开销。
基础分布式训练
训练机器学习模型包含许多部分,通常会将这些部分分布到多个计算资源(例如GPU或集群节点)上。扩展数据和计算通常面临一项重要挑战,导致大型模型的轻松高效训练。
为什么选择分布式训练?
在处理大型深度学习模型时,需要考虑分布式训练的关键原因如下:
- 可扩展性 - 在单个GPU上训练具有数千万甚至数十亿参数的超大型模型非常困难。通过使用分布式训练,可以将此过程扩展到多个GPU上。
- 更快的收敛速度 - 将训练过程分散到多个GPU上可以加快收敛过程,从而加快模型开发速度。
- 资源效率 - 此类训练将充分利用您的可用硬件,从而节省时间和金钱。
- 数据并行 - 将一个模型分布在多个GPU上,每个GPU处理数据集的不同批次。
- 模型并行 - 模型在多个GPU上并行化;每个GPU计算模型操作的一部分。
- 混合并行 - 混合数据和模型并行。换句话说,将数据分割到GPU上,然后进一步分割模型。
数据并行
DeepSpeed 通过提供适应性强的模型和数据并发来促进分布式训练。让我们深入探讨这些方面。
使用数据并行时,每个GPU或工作器都会收到一部分数据进行处理。然后,在处理后对这些结果进行平均以更新模型权重。因此,可以在不耗尽内存的情况下使用更大的批量大小进行训练。
使用 DeepSpeed 的数据并行示例
以下是一个简单的 Python 示例,用于演示使用 DeepSpeed 进行数据并行:
import torch import deepspeed # Define a simple neural network model class SimpleModel(torch.nn.Module): def __init__(self): super(SimpleModel, self).__init__() self.fc1 = torch.nn.Linear(784, 128) self.fc2 = torch.nn.Linear(128, 10) def forward(self, x): x = torch.relu(self.fc1(x)) return self.fc2(x) # Initialize DeepSpeed configuration deepspeed_config = { "train_batch_size": 64, "optimizer": { "type": "Adam", "params": { "lr": 0.001 } } } # Initialize model model = SimpleModel() # Initialize DeepSpeed for distributed data parallelity model_engine, optimizer, _, _ = deepspeed.initialize( config=deepspeed_config, model=model ) # Dummy data inputs = torch.randn(64, 784) labels = torch.randint(0, 10, (64,)) # Forward pass outputs = model_engine(inputs) loss = torch.nn.functional.cross_entropy(outputs, labels) # Backward pass and optimization model_engine.backward(loss) model_engine.step()
现在神经网络将在多个GPU上进行训练;每个GPU负责一部分数据。
模型并行
模型并行处理将模型分割到多个GPU上。当单个模型不适合单个GPU的内存时,这将非常有用。
使用 DeepSpeed 的模型并行
它将模型分割到多个GPU上,模型的不同部分可以在不同的GPU上并发执行。
使用 DeepSpeed 的模型并行示例
以下是一个简单的Python程序,用于演示使用DeepSpeed进行模型并行的运行方式:
import torch import deepspeed from deepspeed.pipe import PipelineModule, LayerSpec # Define a simple pipeline model class SimpleLayer(torch.nn.Module): def __init__(self, input_size, output_size): super(SimpleLayer, self).__init__() self.fc = torch.nn.Linear(input_size, output_size) def forward(self, x): return torch.relu(self.fc(x)) # Two GPUs and two layers in a pipeline paradigm. layers = [ LayerSpec(SimpleLayer, 784, 128), LayerSpec(SimpleLayer, 128, 10) ] # We create a pipeline model, specifying the number of stages - 2 pipeline_model = PipelineModule(layers=layers, num_stages=2) # Initialize DeepSpeed for model parallelism model_engine, optimizer, _, _ = deepspeed.initialize( config=deepspeed_config, model=pipeline_model ) # Dummy inputs inputs = torch.randn(64, 784) # Forward pass through pipeline outputs = model_engine(inputs)
这将在多个GPU上分阶段处理前向传递。第一个GPU将处理到第一层,而第二个GPU将处理到倒数第二层。
零冗余优化器 (ZeRO)
DeepSpeed 最显著的特性也许是零冗余优化器 (Zero Redundancy Optimizer),更方便地称为 ZeRO,它旨在解决模型训练的内存消耗问题。它将各种状态分布在不同的GPU上,从而更有效地利用内存:优化器、梯度和参数。
ZeRO 包括三个阶段:
- 阶段 1 - 对优化器状态进行分区。
- 阶段 2 - 对梯度状态进行分区。
- 阶段 3 - 对参数状态进行分区。
零冗余优化器示例
以下是 Python 中零冗余优化器的简单示例:
import torch import deepspeed # Use ZeRO optimization to define the model and DeepSpeed settings deepspeed_config = { "train_batch_size": 64, "optimizer": { "type": "Adam", "params": { "lr": 0.001 } }, "zero_optimization": { "stage": 2 # Toggle gradient partitioning using ZeRO Stage 2 } } # Initialize model model = SimpleModel() # Initialize DeepSpeed with ZeRO optimization model_engine, optimizer, _, _ = deepspeed.initialize( config=deepspeed_config, model=model ) # Forward pass inputs = torch.randn(64, 784) outputs = model_engine(inputs) # Backward pass and optimization model_engine.backward(outputs) model_engine.step()
此代码在 ZeRO 阶段 2 上运行,该阶段是跨 GPU 分区的梯度状态,可在训练期间减少内存消耗。
跨多个GPU和节点扩展模型
DeepSpeed 通过利用混合并行策略和 DeepSpeed 的高级通信层来实现最佳扩展,从而跨多个 GPU 和节点扩展模型。
使用多个节点的扩展示例
NCCL 后端用于 GPU 间通信并将训练扩展到多个 GPU 和节点。我们可以进行以下调用以使用在多个 GPU 和节点上运行的 DeepSpeed
要使用 DeepSpeed 在多个 GPU 和节点上运行,可以使用以下命令
deepspeed --num_nodes 2 --num_gpus 8 train.py
这总共使用 8 个 GPU 和 2 个节点进行训练。
使用 DeepSpeed 在多个 GPU 上进行训练的示例
以下示例演示了如何使用 DeepSpeed 在多个 GPU 上进行训练:
import deepspeed # Training on multiple GPUs if torch.distributed.get_rank() == 0: print("Training on multiple GPUs with DeepSpeed") # Initialize DeepSpeed with ZeRO optimization for multi-GPU model_engine, optimizer, _, _ = deepspeed.initialize( model=model, config=deepspeed_config ) # Training loop for batch in train_loader: inputs, labels = batch outputs = model_engine(inputs) loss = torch.nn.functional.cross_entropy(outputs, labels) model_engine.backward(loss) model_engine.step()
此代码使用 DeepSpeed 在多个 GPU 上高效地训练模型,并采用 ZeRO 等方法进行优化。
总结
DeepSpeed 已经为扩展和优化深度学习模型中的分布式训练而强大地开发。通过集成 ZeRO 来进一步扩展到多个 GPU 和节点,并结合数据并行和模型并行,DeepSpeed 可以完全解决大型模型高效训练中的所有挑战。这意味着 DeepSpeed 的特性将同时确保分布式训练在增长时保持可访问性和性能增强。