趋近智
在训练大型语言模型时,在单个加速器上处理所需的海量数据很快就会变得不可行。数据并行提供了一种基本策略,可将此工作负载分发到多个处理单元(通常是 GPU 或 TPU),从而更快地训练模型并处理更大的有效批处理大小。
数据并行的核心思想很简单:在每个可用工作器(设备)上复制整个模型,向每个工作器提供输入数据批次的不同片段(分片),然后在每一步之后合并结果。我们来分析一下典型的工作流程:
数据并行工作流程:全局批次被拆分,每个工作器使用模型副本在其分片上计算梯度。梯度通过 AllReduce 同步,并且每个工作器以相同方式更新其模型副本。
PyTorch (DistributedDataParallel 或 DDP)、TensorFlow (tf.distribute.Strategy) 和 Horovod 等框架抽离了大部分实现数据并行的复杂性。DeepSpeed 也建立在这些思想之上,并添加了额外的优化。
一个使用 PyTorch DDP 的典型结构可能如下所示(简化版):
import torch
import torch.distributed as dist
import torch.nn as nn
import torch.optim as optim
from torch.nn.parallel import DistributedDataParallel as DDP
def setup(rank, world_size):
# 初始化进程组(例如,使用 NCCL 后端用于 GPU)
dist.init_process_group("nccl", rank=rank, world_size=world_size)
torch.cuda.set_device(rank)
def cleanup():
dist.destroy_process_group()
def train_step(rank, world_size, model, data_loader, optimizer, criterion):
model.train()
# 如果 DataLoader 使用 DistributedSampler,DDP 会自动处理数据分片
for data, target in data_loader:
data, target = data.to(rank), target.to(rank) # 将数据移动到工作器的设备
optimizer.zero_grad()
output = model(data)
loss = criterion(output, target)
# loss.backward() 计算本地梯度
loss.backward()
# DDP 会在反向传播期间自动触发 AllReduce
# 梯度在此处在工作器之间同步
# optimizer.step() 使用同步梯度更新本地模型参数
optimizer.step()
def main_worker(rank, world_size, model_definition, dataset):
setup(rank, world_size)
model = model_definition().to(rank)
# 使用 DDP 包装模型
ddp_model = DDP(model, device_ids=[rank])
# 为 DataLoader 使用 DistributedSampler
sampler = torch.utils.data.distributed.DistributedSampler(dataset, num_replicas=world_size, rank=rank)
data_loader = torch.utils.data.DataLoader(dataset, batch_size=local_batch_size, sampler=sampler)
optimizer = optim.AdamW(ddp_model.parameters(), lr=learning_rate)
criterion = nn.CrossEntropyLoss() # 示例损失函数
for epoch in range(num_epochs):
train_step(rank, world_size, ddp_model, data_loader, optimizer, criterion)
# 添加验证、检查点等
cleanup()
# --- 主执行逻辑以启动进程 ---
# if __name__ == "__main__":
# world_size = torch.cuda.device_count()
# mp.spawn(main_worker, args=(world_size, model_def, dataset), nprocs=world_size, join=True)
在使用大规模数据并行时,会出现一些重要的操作点:
local_batch_size 来说需要比每个工作器可用内存更多的内存时,会使用梯度累积。工作器会按顺序处理多个更小的“微批次”,在执行 AllReduce 和优化器步骤之前在本地累积梯度。这模拟了更大的本地批次大小,同时不增加内存需求,通过计算时间来换取内存。AllReduce 同步仅在每 N 个微批次发生一次,其中 N 是累积步数。数据并行因其相对简单和有效,通常是分布式训练的起点,尤其当每个数据点的计算量很大时。然而,当模型对单个设备的内存来说变得太大时,您必须将数据并行与模型并行技术结合起来,我们接下来会讨论这些技术。
这部分内容有帮助吗?
© 2026 ApX Machine LearningAI伦理与透明度•