ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Hugging Face Transformers:基于 Intel oneCCL 的多 CPU 分布式训练(DDP on CPU)实战指南

Hugging Face Transformers:基于 Intel oneCCL 的多 CPU 分布式训练(DDP on CPU)实战指南 Hugging Face Transformers基于 Intel oneCCL 的多 CPU 分布式训练DDP on CPU实战指南【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers本文聚焦 Transformers 官方文档 多 CPU 高效训练指南当单 CPU 训练速度无法满足需求时如何通过 Intel® oneCCL Bindings for PyTorch 与 Intel® MPI 库使用 PyTorch DDP 在单机多进程乃至双机多进程环境下完成 CPU 分布式训练。读完本文你将能够正确安装并配置 oneCCL/Intel MPI 运行环境、在 Trainer 示例脚本如 SQuAD 问答任务中启用--ddp_backend ccl多进程训练、理解ddp_backend参数在 Transformers 源码中的传递链路并掌握OMP_NUM_THREADS、CCL_WORKER_COUNT等关键调优变量。1. 背景为什么需要多 CPU 分布式训练Transformers 的性能优化文档体系将多 CPU 训练作为单 CPU 训练的进阶路径。其核心思路是使用 PyTorch 原生的 DDPDistributedDataParallel 一个针对 Intel 架构优化的高性能集合通信后端oneCCL把一份模型复制到多个进程每个进程绑定一个 CPU 插槽/一组核各进程独立前向/反向计算局部梯度再通过后端的 all-reduce 等集合通信完成梯度同步。该方案的三个关键组件是Intel® oneCCL集合通信库实现了 allreduce、allgather、alltoall 等高效集合通信专为 Intel 架构上的分布式深度学习训练优化oneccl_bindings_for_pytorch模块1.12 版本以前叫torch_ccl它实现了 PyTorch C10D 的 ProcessGroup API作为外部 ProcessGroup 动态加载进 PyTorch因此无需修改 PyTorch 本身即可让torch.distributed使用 CCL 后端目前仅在 Linux 平台可用Intel® MPI 库基于 Intel MPI 实现提供 Intel 架构上灵活、高效、可扩展的集群消息能力是 Intel® oneAPI HPC Toolkit 的组件之一。文档中所有启动示例均通过它提供的mpirun来拉起多进程而不是torchrun。注意oneCCL 与 PyTorch 的版本必须严格匹配这是该方案能否跑通的第一前提详见下一节版本兼容表。2. 安装 Intel® oneCCL Bindings for PyTorchWheel 包按 PyTorch 版本提供文档给出了如下兼容性矩阵原样继承自官方文档Extension VersionPython 3.6Python 3.7Python 3.8Python 3.9Python 3.101.13.0√√√√1.12.100√√√√1.12.0√√√√1.11.0√√√√1.10.0√√√√安装命令如下其中{pytorch_version}需替换为你当前安装的 PyTorch 版本号例如1.13.0pip install oneccl_bind_pt{pytorch_version} -f https://developer.intel.com/ipex-whl-stable-cpu版本匹配规则重要oneCCL 与 PyTorch 版本必须一致。官方文档特别给出了一条兼容性警告oneccl_bindings_for_pytorch的1.12.0预编译 wheel 与PyTorch 1.12.1不兼容它是为 PyTorch 1.12.0 构建的如果你使用的是 PyTorch 1.12.1请安装oneccl_bindings_for_pytorch的1.12.100版本。3. 配置 Intel® MPI 运行环境oneccl_bindings_for_pytorch会连同 MPI 工具集一起安装但在运行训练之前必须先 source 环境脚本。文档按 oneCCL 版本给出了两套做法Intel® oneCCL 1.12.0oneccl_bindings_for_pytorch_path$(python -c from oneccl_bindings_for_pytorch import cwd; print(cwd)) source $oneccl_bindings_for_pytorch_path/env/setvars.shIntel® oneCCL 1.12.0即 torch_ccl 时代torch_ccl_path$(python -c import torch; import torch_ccl; import os; print(os.path.abspath(os.path.dirname(torch_ccl.__file__)))) source $torch_ccl_path/env/setvars.sh两者的区别仅在于定位绑定模块安装路径的方式不同新版模块可直接from oneccl_bindings_for_pytorch import cwd获取旧版需要通过torch_ccl.__file__推导。另外官方文档建议配合IPEXIntel Extension for PyTorch以获得 CPU 训练的性能优化它同时支持 Float32 与 BFloat16 两种精度路径可参考同目录的单 CPU 训练指南 perf_train_cpu.md。这也是后文启动命令中--use_ipex参数的来源。4. 在 Trainer 中启用多 CPU DDP 训练要在 Trainer 中开启多 CPU 分布式训练只需在示例脚本的命令行参数中追加--ddp_backend ccl并用--no_cuda强制走 CPU 路径。以下两个示例均以仓库中的 SQuAD 问答训练脚本 为载体。4.1 单机1 个 Xeon 节点、2 个进程以下命令在 1 个 Xeon 节点上用 2 个进程启动训练每个进程绑定 1 个 CPU 插槽export CCL_WORKER_COUNT1 export MASTER_ADDR127.0.0.1 mpirun -n 2 -genv OMP_NUM_THREADS23 \ python3 run_qa.py \ --model_name_or_path google-bert/bert-large-uncased \ --dataset_name squad \ --do_train \ --do_eval \ --per_device_train_batch_size 12 \ --learning_rate 3e-5 \ --num_train_epochs 2 \ --max_seq_length 384 \ --doc_stride 128 \ --output_dir /tmp/debug_squad/ \ --no_cuda \ --ddp_backend ccl \ --use_ipex参数逐条解读参数/变量作用export CCL_WORKER_COUNT1控制 CCL 内部使用的 worker 线程数属于性能调优变量export MASTER_ADDR127.0.0.1DDP 主进程地址单机场景直接指向本机mpirun -n 2由 Intel MPI 拉起 2 个进程即 2 个 DDP rank-genv OMP_NUM_THREADS23通过 MPI 向每个子进程注入 OpenMP 线程数避免 2 个进程的线程互相争抢物理核示例为 23 线程/进程--no_cuda强制 Transformers 使用 CPU 设备--ddp_backend ccl指定分布式后端为 oneCCL--use_ipex启用 IPEX 的 CPU 图优化路径--per_device_train_batch_size 12每个进程的 batch size全局 batch size 12 × 进程数OMP_NUM_THREADS与CCL_WORKER_COUNT是文档明确点名的两个为获得最佳性能而可调的变量前者决定每个进程内部 OpenMP 并行度后者决定 CCL 通信线程数二者需要根据节点的实际核数/插槽数组合调优。4.2 双机2 个 Xeon 节点、共 4 个进程第二个示例扩展到node0 与 node1 两个节点每节点 2 个进程-ppn 2合计 4 个 DDP 进程并开启BF16 自动混合精度--bf16。首先在node0上创建一个包含各节点 IP 的hostfile配置文件cat hostfile xxx.xxx.xxx.xxx #node0 ip xxx.xxx.xxx.xxx #node1 ip然后在 node0 上执行node0 承担主进程角色MASTER_ADDR指向 node0 的 IPexport CCL_WORKER_COUNT1 export MASTER_ADDRxxx.xxx.xxx.xxx #node0 ip mpirun -f hostfile -n 4 -ppn 2 \ -genv OMP_NUM_THREADS23 \ python3 run_qa.py \ --model_name_or_path google-bert/bert-large-uncased \ --dataset_name squad \ --do_train \ --do_eval \ --per_device_train_batch_size 12 \ --learning_rate 3e-5 \ --num_train_epochs 2 \ --max_seq_length 384 \ --doc_stride 128 \ --output_dir /tmp/debug_squad/ \ --no_cuda \ --ddp_backend ccl \ --use_ipex \ --bf16与单机版相比多机版本的关键差异在于mpirun -f hostfile通过 hostfile 声明节点拓扑由 Intel MPI 负责跨节点分发进程-n 4 -ppn 2全局 4 进程、每节点 2 进程1 进程/插槽MASTER_ADDR从127.0.0.1改为 node0 的真实 IP所有节点据此找到主进程追加--bf16利用 Intel 架构AVX512_BF16的 BF16 硬件加速在保持数值稳定性的同时提升吞吐。5. 源码纵深--ddp_backend在 Transformers 内部如何生效结合仓库源码可以看清这条参数链路的完整路径。参数定义ddp_backend定义在 TrainingArguments 的 dataclass 字段 中默认值为Noneddp_backend: str | None field( defaultNone, metadata{ help: The backend to use for distributed training. Must be one of nccl, mpi, xccl, gloo, hccl., choices: [nccl, gloo, mpi, xccl, hccl, cncl, mccl], }, )参数传递在TrainingArguments初始化分布式状态时ddp_backend会被透传给 Accelerate 的PartialState。从 CPU 分支的处理逻辑 看if self.use_cpu or strtobool(os.environ.get(ACCELERATE_USE_CPU, False)): accelerator_state_kwargs[cpu] True accelerator_state_kwargs[backend] self.ddp_backend self._n_gpu 0也就是说--no_cuda映射为use_cpu与--ddp_backend ccl两个参数在源头就是配套设计的前者把cpuTrue交给PartialState选定 CPU 设备与 CPU 分布式类型后者把 CCL 作为torch.distributed的 ProcessGroup 后端名。最终在PartialState内部调用torch.distributed.init_process_group(backendccl, ...)而 PyTorch 在初始化时通过动态加载的oneccl_bindings_for_pytorch模块完成 CCL ProcessGroup 的构造——这正是第 3 节必须 sourcesetvars.sh的原因该脚本设置了 MPI 库路径等环境变量绑定模块的运行时依赖它。一点版本提示基于当前仓库源码的观察从当前仓库 training_args.py 的字段 metadata 看choices白名单列出的是[nccl, gloo, mpi, xccl, hccl, cncl, mccl]并未包含字面量ccl而本文档给出的命令使用--ddp_backend ccl。两者存在出入可以推断该文档面向的是较早版本 Transformers当时 choices 中包含ccl。如果你在当前仓库版本上复现本文命令建议先核对ddp_backend的可选值与所用 Transformers 版本的匹配关系若参数校验不通过可尝试以 PyTorch 原生支持的gloo后端作为对照验证流程或查阅你所用版本对应的文档。这一点不影响理解 oneCCL 方案本身——CCL 后端是通过oneccl_bindings_for_pytorch以外部 ProcessGroup 形式动态注册进 PyTorch 的。6. 关键调优要点与适用前提小结进程与核的映射文档的两个示例都遵循1 进程 / 1 CPU 插槽的部署约定单机 2 进程 双插槽 Xeon双机-ppn 2同理OMP_NUM_THREADS应设置为插槽内物理核数量级避免超配线程通信线程独立调优CCL_WORKER_COUNT与OMP_NUM_THREADS正交——前者属于 oneCCL 内部通信线程后者属于计算侧 OpenMP 线程最佳组合需要针对具体硬件实测精度策略BF16--bf16--use_ipex在支持 AVX512_BF16 的 Xeon 上可获得显著吞吐提升不支持时回退到 IPEX 优化的 Float32 路径适用前提与限制Linux 平台oneCCL 与 PyTorch 版本严格匹配运行前必须 source MPI 环境脚本跨节点场景需要 node0 可达各节点 IP 的 hostfile 配置全局 batch size 语义--per_device_train_batch_size是按进程计的多进程下的全局 batch size 单进程 batch × 进程数例如双机示例为 12 × 4 48调整进程数时需相应评估学习率与 epoch 数。7. 参考文件原始文档docs/source/ja/perf_train_cpu_many.md单 CPU 训练指南IPEX 优化细节docs/source/ja/perf_train_cpu.md分布式训练参数定义src/transformers/training_args.pyCPU 分布式分支与 backend 透传src/transformers/training_args.py问答示例脚本examples/pytorch/question-answering/run_qa.py【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表