尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

从单卡到多卡:分布式训练启动前的 6 项 GPU 检查

从单卡到多卡:分布式训练启动前的 6 项 GPU 检查 单卡训练能跑通不代表多卡训练可以直接启动。从单卡切换到多卡后问题往往不再只是显存大小还会涉及 GPU 是否被正确枚举、驱动和 CUDA 是否一致、进程之间能否通信、数据是否被重复读取以及多卡带来的吞吐是否真的抵消了通信成本。本文给出一套适合个人开发者的启动前检查流程先把环境和启动参数验证清楚再开始长时间训练。一、为什么多卡训练不能只看 GPU 数量多卡训练至少有四个条件同时成立系统能看到预期数量的 GPU每个进程都能绑定到正确的 GPU进程之间能通过 NCCL 或其他后端正常通信数据、梯度和 checkpoint 的处理方式适合分布式执行。只要其中一个条件不满足就可能出现进程卡住、只有一张卡工作、NCCL 报错、数据重复训练甚至任务刚启动就退出。二、启动前的 6 项 GPU 检查1. 检查 GPU 数量、型号和显存先确认系统看到的 GPU 数量nvidia-smi-Lnvidia-smi需要记录GPU 数量每张卡的型号和显存驱动版本当前是否有其他进程占用显存。多卡训练时尽量确认卡的型号和显存规格一致。混用不同显存容量的 GPU可能导致某个进程先 OOM或者整体只能按最小显存来设计 batch。2. 检查卡之间的拓扑和通信条件可以查看 GPU 之间的连接关系nvidia-smi topo-m这一步不能简单理解为“有 NVLink 就一定更快”。实际效率还取决于主板 PCIe 拓扑、CPU NUMA、网络、通信库版本和训练框架。如果是跨机器训练还要额外确认节点之间的内网延迟节点之间的带宽防火墙和端口是否放行所有节点是否能访问相同的数据和代码版本。3. 固定驱动、CUDA 和 PyTorch 版本每张卡都能被 nvidia-smi 看到并不代表所有进程使用的是同一套运行环境。建议在每个节点、每个 Python 环境中记录importtorchprint(PyTorch:,torch.__version__)print(CUDA runtime:,torch.version.cuda)print(CUDA available:,torch.cuda.is_available())print(GPU count:,torch.cuda.device_count())forindexinrange(torch.cuda.device_count()):print(index,torch.cuda.get_device_name(index))还要确认驱动版本满足当前 CUDA 运行时要求所有节点的 Python 依赖一致模型、配置文件和训练代码版本一致NCCL 或其他通信库没有被错误的环境变量覆盖。4. 检查 rank、world size 和端口分布式训练中每个进程都需要知道自己的 rank、总进程数和对应 GPU。常见环境变量包括LOCAL_RANK当前节点上的 GPU 编号RANK全局进程编号WORLD_SIZE总进程数MASTER_ADDR主节点地址MASTER_PORT进程通信端口。单机双卡可以先用最小启动命令验证torchrun--standalone--nproc_per_node2train.py如果提示端口已被占用不要一味重复启动。先检查旧进程是否仍在运行再更换端口或清理残留进程。5. 检查程序是否正确绑定 GPU训练脚本中不能让所有进程默认使用 cuda:0。一个最小的设备绑定示例是importosimporttorchimporttorch.distributedasdist local_rankint(os.environ[LOCAL_RANK])torch.cuda.set_device(local_rank)dist.init_process_group(backendnccl)devicetorch.device(cuda,local_rank)print(rank:,dist.get_rank())print(world size:,dist.get_world_size())print(device:,device)如果日志里所有进程都显示同一张 GPU通常说明 LOCAL_RANK 没有正确读取或者设备绑定发生在错误的位置。6. 检查数据、采样器和 checkpoint多卡训练最容易被忽略的不是 GPU而是数据处理。如果每个进程都从数据集头部开始读取相同样本就会出现重复训练GPU 利用率可能很高但有效训练进度并没有按预期增加。使用 PyTorch DDP 时通常需要为每个进程配置 DistributedSampler并在每个 epoch 开始时设置 sampler 的 epoch。保存 checkpoint 时也要避免所有进程同时写同一个文件。建议提前确认每个进程是否拿到不同的数据切片每个 epoch 是否正确调用 sampler.set_epoch只有主进程负责保存日志和 checkpoint中断后能否从正确的全局状态恢复。三、一个最小的 DDP 启动验证流程不要一开始就运行完整模型。可以先写一个只做通信和随机张量计算的小脚本importosimporttorchimporttorch.distributedasdist local_rankint(os.environ[LOCAL_RANK])torch.cuda.set_device(local_rank)dist.init_process_group(nccl)rankdist.get_rank()world_sizedist.get_world_size()devicetorch.device(cuda,local_rank)valuetorch.tensor([rank1.0],devicedevice)dist.all_reduce(value)print({rank:rank,world_size:world_size,device:str(device),reduced_value:value.item()})dist.destroy_process_group()使用torchrun--standalone--nproc_per_node2ddp_smoke_test.py如果两个进程都能打印 rank、world size 和相同的规约结果说明最基本的进程组和 GPU 通信已经跑通。之后再加入模型、数据集和优化器定位问题会容易很多。四、常见问题应该怎么判断1. 只有一张 GPU 利用率高先检查 nvidia-smi 是否显示多个 Python 进程再检查每个进程的 LOCAL_RANK 和 device。不要先假设是 GPU 性能问题。2. 程序启动后一直不动优先检查MASTER_ADDR 和 MASTER_PORT防火墙和网络连通性是否有旧的 torchrun 进程每个节点的 WORLD_SIZE 是否一致NCCL_DEBUGINFO 日志中最后停在哪一步。3. 多卡速度没有接近线性提升多卡吞吐通常不会简单等于单卡吞吐乘以卡数。通信、梯度同步、数据加载、I/O 和 batch 切分都会产生开销。如果单卡已经被数据加载限制多加 GPU 并不会自动解决问题。应该同时观察 GPU、CPU、磁盘和网络而不是只看某一张卡的利用率。4. 多卡比单卡更容易 OOM多卡并不一定自动减少单卡显存占用。普通 DDP 通常会在每张 GPU 上复制一份模型模型权重和部分状态仍然存在于每张卡上。如果目标是把一个放不进单卡的模型拆到多张卡需要评估模型并行、流水线并行、ZeRO 或其他分片方案不能只把 nproc_per_node 调大。五、启动前的检查清单在启动长任务前建议确认nvidia-smi -L 显示的 GPU 数量符合预期每张卡的型号和显存满足任务要求所有节点的驱动、CUDA、PyTorch 和代码版本一致torch.cuda.device_count() 和实际进程数匹配LOCAL_RANK、RANK、WORLD_SIZE 都能正确读取DDP smoke test 能完成 all_reduce数据采样器不会让多个进程读取同一批样本只有主进程负责保存 checkpoint 和日志任务失败后实例和数据不会一直占用资源。结语从单卡切换到多卡真正增加的不是一个 nproc_per_node 参数而是一整套设备、进程、通信、数据和保存逻辑。最稳妥的顺序是先检查 GPU 和软件环境再跑通信 smoke test之后验证数据切分最后才启动完整训练。这样即使出现问题也能判断它到底发生在硬件、通信、代码还是数据环节。如果你准备验证不同的 GPU 数量和区域可以先访问起源算力官网查看资源与使用入口官网https://origpu.com控制台https://origpu.com/app
返回列表