練(DDP on CPU)實(shí)戰(zhàn)指南)
Hugging Face Transformers基于 Intel oneCCL 的多 CPU 分布式訓(xùn)練DDP on CPU實(shí)戰(zhàn)指南【免費(fèi)下載鏈接】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.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/tra/transformers本文聚焦 Transformers 官方文檔 多 CPU 高效訓(xùn)練指南當(dāng)單 CPU 訓(xùn)練速度無(wú)法滿(mǎn)足需求時(shí)如何通過(guò) Intel? oneCCL Bindings for PyTorch 與 Intel? MPI 庫(kù)使用 PyTorch DDP 在單機(jī)多進(jìn)程乃至雙機(jī)多進(jìn)程環(huán)境下完成 CPU 分布式訓(xùn)練。讀完本文你將能夠正確安裝并配置 oneCCL/Intel MPI 運(yùn)行環(huán)境、在 Trainer 示例腳本如 SQuAD 問(wèn)答任務(wù)中啟用--ddp_backend ccl多進(jìn)程訓(xùn)練、理解ddp_backend參數(shù)在 Transformers 源碼中的傳遞鏈路并掌握OMP_NUM_THREADS、CCL_WORKER_COUNT等關(guān)鍵調(diào)優(yōu)變量。1. 背景為什么需要多 CPU 分布式訓(xùn)練Transformers 的性能優(yōu)化文檔體系將多 CPU 訓(xùn)練作為單 CPU 訓(xùn)練的進(jìn)階路徑。其核心思路是使用 PyTorch 原生的 DDPDistributedDataParallel 一個(gè)針對(duì) Intel 架構(gòu)優(yōu)化的高性能集合通信后端oneCCL把一份模型復(fù)制到多個(gè)進(jìn)程每個(gè)進(jìn)程綁定一個(gè) CPU 插槽/一組核各進(jìn)程獨(dú)立前向/反向計(jì)算局部梯度再通過(guò)后端的 all-reduce 等集合通信完成梯度同步。該方案的三個(gè)關(guān)鍵組件是Intel? oneCCL集合通信庫(kù)實(shí)現(xiàn)了 allreduce、allgather、alltoall 等高效集合通信專(zhuān)為 Intel 架構(gòu)上的分布式深度學(xué)習(xí)訓(xùn)練優(yōu)化oneccl_bindings_for_pytorch模塊1.12 版本以前叫torch_ccl它實(shí)現(xiàn)了 PyTorch C10D 的 ProcessGroup API作為外部 ProcessGroup 動(dòng)態(tài)加載進(jìn) PyTorch因此無(wú)需修改 PyTorch 本身即可讓torch.distributed使用 CCL 后端目前僅在 Linux 平臺(tái)可用Intel? MPI 庫(kù)基于 Intel MPI 實(shí)現(xiàn)提供 Intel 架構(gòu)上靈活、高效、可擴(kuò)展的集群消息能力是 Intel? oneAPI HPC Toolkit 的組件之一。文檔中所有啟動(dòng)示例均通過(guò)它提供的mpirun來(lái)拉起多進(jìn)程而不是torchrun。注意oneCCL 與 PyTorch 的版本必須嚴(yán)格匹配這是該方案能否跑通的第一前提詳見(jiàn)下一節(jié)版本兼容表。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}需替換為你當(dāng)前安裝的 PyTorch 版本號(hào)例如1.13.0pip install oneccl_bind_pt{pytorch_version} -f https://developer.intel.com/ipex-whl-stable-cpu版本匹配規(guī)則重要oneCCL 與 PyTorch 版本必須一致。官方文檔特別給出了一條兼容性警告oneccl_bindings_for_pytorch的1.12.0預(yù)編譯 wheel 與PyTorch 1.12.1不兼容它是為 PyTorch 1.12.0 構(gòu)建的如果你使用的是 PyTorch 1.12.1請(qǐng)安裝oneccl_bindings_for_pytorch的1.12.100版本。3. 配置 Intel? MPI 運(yùn)行環(huán)境oneccl_bindings_for_pytorch會(huì)連同 MPI 工具集一起安裝但在運(yùn)行訓(xùn)練之前必須先 source 環(huán)境腳本。文檔按 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 時(shí)代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兩者的區(qū)別僅在于定位綁定模塊安裝路徑的方式不同新版模塊可直接from oneccl_bindings_for_pytorch import cwd獲取舊版需要通過(guò)torch_ccl.__file__推導(dǎo)。另外官方文檔建議配合IPEXIntel Extension for PyTorch以獲得 CPU 訓(xùn)練的性能優(yōu)化它同時(shí)支持 Float32 與 BFloat16 兩種精度路徑可參考同目錄的單 CPU 訓(xùn)練指南 perf_train_cpu.md。這也是后文啟動(dòng)命令中--use_ipex參數(shù)的來(lái)源。4. 在 Trainer 中啟用多 CPU DDP 訓(xùn)練要在 Trainer 中開(kāi)啟多 CPU 分布式訓(xùn)練只需在示例腳本的命令行參數(shù)中追加--ddp_backend ccl并用--no_cuda強(qiáng)制走 CPU 路徑。以下兩個(gè)示例均以倉(cāng)庫(kù)中的 SQuAD 問(wèn)答訓(xùn)練腳本 為載體。4.1 單機(jī)1 個(gè) Xeon 節(jié)點(diǎn)、2 個(gè)進(jìn)程以下命令在 1 個(gè) Xeon 節(jié)點(diǎn)上用 2 個(gè)進(jìn)程啟動(dòng)訓(xùn)練每個(gè)進(jìn)程綁定 1 個(gè) 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參數(shù)逐條解讀參數(shù)/變量作用export CCL_WORKER_COUNT1控制 CCL 內(nèi)部使用的 worker 線程數(shù)屬于性能調(diào)優(yōu)變量export MASTER_ADDR127.0.0.1DDP 主進(jìn)程地址單機(jī)場(chǎng)景直接指向本機(jī)mpirun -n 2由 Intel MPI 拉起 2 個(gè)進(jìn)程即 2 個(gè) DDP rank-genv OMP_NUM_THREADS23通過(guò) MPI 向每個(gè)子進(jìn)程注入 OpenMP 線程數(shù)避免 2 個(gè)進(jìn)程的線程互相爭(zhēng)搶物理核示例為 23 線程/進(jìn)程--no_cuda強(qiáng)制 Transformers 使用 CPU 設(shè)備--ddp_backend ccl指定分布式后端為 oneCCL--use_ipex啟用 IPEX 的 CPU 圖優(yōu)化路徑--per_device_train_batch_size 12每個(gè)進(jìn)程的 batch size全局 batch size 12 × 進(jìn)程數(shù)OMP_NUM_THREADS與CCL_WORKER_COUNT是文檔明確點(diǎn)名的兩個(gè)為獲得最佳性能而可調(diào)的變量前者決定每個(gè)進(jìn)程內(nèi)部 OpenMP 并行度后者決定 CCL 通信線程數(shù)二者需要根據(jù)節(jié)點(diǎn)的實(shí)際核數(shù)/插槽數(shù)組合調(diào)優(yōu)。4.2 雙機(jī)2 個(gè) Xeon 節(jié)點(diǎn)、共 4 個(gè)進(jìn)程第二個(gè)示例擴(kuò)展到node0 與 node1 兩個(gè)節(jié)點(diǎn)每節(jié)點(diǎn) 2 個(gè)進(jìn)程-ppn 2合計(jì) 4 個(gè) DDP 進(jìn)程并開(kāi)啟BF16 自動(dòng)混合精度--bf16。首先在node0上創(chuàng)建一個(gè)包含各節(jié)點(diǎn) IP 的hostfile配置文件cat hostfile xxx.xxx.xxx.xxx #node0 ip xxx.xxx.xxx.xxx #node1 ip然后在 node0 上執(zhí)行node0 承擔(dān)主進(jìn)程角色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與單機(jī)版相比多機(jī)版本的關(guān)鍵差異在于mpirun -f hostfile通過(guò) hostfile 聲明節(jié)點(diǎn)拓?fù)溆?Intel MPI 負(fù)責(zé)跨節(jié)點(diǎn)分發(fā)進(jìn)程-n 4 -ppn 2全局 4 進(jìn)程、每節(jié)點(diǎn) 2 進(jìn)程1 進(jìn)程/插槽MASTER_ADDR從127.0.0.1改為 node0 的真實(shí) IP所有節(jié)點(diǎn)據(jù)此找到主進(jìn)程追加--bf16利用 Intel 架構(gòu)AVX512_BF16的 BF16 硬件加速在保持?jǐn)?shù)值穩(wěn)定性的同時(shí)提升吞吐。5. 源碼縱深--ddp_backend在 Transformers 內(nèi)部如何生效結(jié)合倉(cāng)庫(kù)源碼可以看清這條參數(shù)鏈路的完整路徑。參數(shù)定義ddp_backend定義在 TrainingArguments 的 dataclass 字段 中默認(rèn)值為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], }, )參數(shù)傳遞在TrainingArguments初始化分布式狀態(tài)時(shí)ddp_backend會(huì)被透?jìng)鹘o 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也就是說(shuō)--no_cuda映射為use_cpu與--ddp_backend ccl兩個(gè)參數(shù)在源頭就是配套設(shè)計(jì)的前者把cpuTrue交給PartialState選定 CPU 設(shè)備與 CPU 分布式類(lèi)型后者把 CCL 作為torch.distributed的 ProcessGroup 后端名。最終在PartialState內(nèi)部調(diào)用torch.distributed.init_process_group(backendccl, ...)而 PyTorch 在初始化時(shí)通過(guò)動(dòng)態(tài)加載的oneccl_bindings_for_pytorch模塊完成 CCL ProcessGroup 的構(gòu)造——這正是第 3 節(jié)必須 sourcesetvars.sh的原因該腳本設(shè)置了 MPI 庫(kù)路徑等環(huán)境變量綁定模塊的運(yùn)行時(shí)依賴(lài)它。一點(diǎn)版本提示基于當(dāng)前倉(cāng)庫(kù)源碼的觀察從當(dāng)前倉(cāng)庫(kù) training_args.py 的字段 metadata 看choices白名單列出的是[nccl, gloo, mpi, xccl, hccl, cncl, mccl]并未包含字面量ccl而本文檔給出的命令使用--ddp_backend ccl。兩者存在出入可以推斷該文檔面向的是較早版本 Transformers當(dāng)時(shí) choices 中包含ccl。如果你在當(dāng)前倉(cāng)庫(kù)版本上復(fù)現(xiàn)本文命令建議先核對(duì)ddp_backend的可選值與所用 Transformers 版本的匹配關(guān)系若參數(shù)校驗(yàn)不通過(guò)可嘗試以 PyTorch 原生支持的gloo后端作為對(duì)照驗(yàn)證流程或查閱你所用版本對(duì)應(yīng)的文檔。這一點(diǎn)不影響理解 oneCCL 方案本身——CCL 后端是通過(guò)oneccl_bindings_for_pytorch以外部 ProcessGroup 形式動(dòng)態(tài)注冊(cè)進(jìn) PyTorch 的。6. 關(guān)鍵調(diào)優(yōu)要點(diǎn)與適用前提小結(jié)進(jìn)程與核的映射文檔的兩個(gè)示例都遵循1 進(jìn)程 / 1 CPU 插槽的部署約定單機(jī) 2 進(jìn)程 雙插槽 Xeon雙機(jī)-ppn 2同理OMP_NUM_THREADS應(yīng)設(shè)置為插槽內(nèi)物理核數(shù)量級(jí)避免超配線程通信線程獨(dú)立調(diào)優(yōu)CCL_WORKER_COUNT與OMP_NUM_THREADS正交——前者屬于 oneCCL 內(nèi)部通信線程后者屬于計(jì)算側(cè) OpenMP 線程最佳組合需要針對(duì)具體硬件實(shí)測(cè)精度策略BF16--bf16--use_ipex在支持 AVX512_BF16 的 Xeon 上可獲得顯著吞吐提升不支持時(shí)回退到 IPEX 優(yōu)化的 Float32 路徑適用前提與限制Linux 平臺(tái)oneCCL 與 PyTorch 版本嚴(yán)格匹配運(yùn)行前必須 source MPI 環(huán)境腳本跨節(jié)點(diǎn)場(chǎng)景需要 node0 可達(dá)各節(jié)點(diǎn) IP 的 hostfile 配置全局 batch size 語(yǔ)義--per_device_train_batch_size是按進(jìn)程計(jì)的多進(jìn)程下的全局 batch size 單進(jìn)程 batch × 進(jìn)程數(shù)例如雙機(jī)示例為 12 × 4 48調(diào)整進(jìn)程數(shù)時(shí)需相應(yīng)評(píng)估學(xué)習(xí)率與 epoch 數(shù)。7. 參考文件原始文檔docs/source/ja/perf_train_cpu_many.md單 CPU 訓(xùn)練指南IPEX 優(yōu)化細(xì)節(jié)docs/source/ja/perf_train_cpu.md分布式訓(xùn)練參數(shù)定義src/transformers/training_args.pyCPU 分布式分支與 backend 透?jìng)鱯rc/transformers/training_args.py問(wèn)答示例腳本examples/pytorch/question-answering/run_qa.py【免費(fèi)下載鏈接】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.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/tra/transformers創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考