资讯动态

Transformers 在 CPU 上的高效训练实战指南:bf16 混合精度、Intel MPI 多路/多机扩展与 Kubernetes 部署

发布时间:2026/9/9 20:45:48 来源:尧图企业网站定制
Transformers 在 CPU 上的高效训练实战指南bf16 混合精度、Intel MPI 多路/多机扩展与 Kubernetes 部署【免费下载链接】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本指南以当前仓库的 CPU 训练性能文档 为主线系统讲解在没有 GPU 的环境下如何使用 Transformers 的 [Trainer] 在 CPU 上完成高效训练从单机启用 bf16 混合精度、按 CPU socket 拆分进程、跨多节点扩展均基于 Intel MPI 与 DDP 策略再到通过 Kubeflow PyTorchJob 在 Kubernetes 集群上编排大规模 CPU 训练任务。读完本文你将能够独立把 SQuAD 问答微调等典型脚本无缝迁移到 CPU 环境并正确设置OMP_NUM_THREADS、线程亲和、内存分配器与混合精度等关键性能变量。什么时候适合用 CPU 训练为什么优先选 bf16CPU 训练在两类场景下是合理选择一是没有 GPU 可用二是希望以更低成本获得够用的训练吞吐。现代 Intel CPU 本身支持 bf16 混合精度训练——配合 PyTorch 针对 CPU 后端的 AMPAutomatic Mixed Precision既显著降低内存占用又提升训练速度。关于精度格式perf_train_cpu.md 明确建议CPU 训练优先使用 bf16 而不是 fp16因为 bf16 数值稳定性更好其指数位宽与 fp32 相同动态范围大不易溢出/下溢。这一点在仓库的TrainingArguments定义中也能看到一致的表述bf16字段的 help 文案明确写着Generally preferred over FP16 due to better numerical stabilitytraining_args.py。需要说明的是bf16 并不等于全程用 bf16 计算。混合精度训练中只有部分算子运行在 bf16梯度累积、参数更新等关键环节仍保持 fp32 精度因此通常不会带来精度损失却能换取内存占用下降与计算加速。单机单 CPU用Trainer一键启用 bf16 混合精度Trainer原生支持在 CPU 上做 bf16 混合精度训练。开启方式只有两个开关--bf16启用 PyTorch 针对 CPU 的 autocast 混合精度--use_cpu强制在 CPU 上训练否则Trainer会优先探测 GPU 等加速设备。下面以仓库自带的问答微调脚本 run_qa.py 为例在 SQuAD 数据集上微调google-bert/bert-base-uncasedpython run_qa.py \ --model_name_or_path google-bert/bert-base-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/ \ --bf16 \ --use_cpu各参数含义参数作用--model_name_or_path预训练模型 ID 或本地路径此处为 bert-base-uncased--dataset_name squad使用 Hub 上的 SQuAD 数据集--do_train / --do_eval训练与评估开关--per_device_train_batch_size每设备 batch size默认 8见 training_args.pyCPU 上需结合内存容量调整--learning_rate初始学习率默认 5e-5--num_train_epochs训练轮数默认 3.0--max_seq_length / --doc_stride问答任务的截断长度与滑窗步长--output_dir模型与 checkpoint 输出目录必填--bf16启用 bf16 混合精度--use_cpu强制 CPU 训练等价的中文编程式配置上述命令行参数与TrainingArguments一一对应因此完全可以跳过命令行、直接在 Python 脚本里声明训练配置from transformers import TrainingArguments training_args TrainingArguments( output_dir./outputs, bf16True, use_cpuTrue, )从源码理解这两个开关发生了什么use_cpu与bf16并不只是表面传参它们在 training_args.py 的初始化逻辑里有着具体行为混合精度解析在__post_init__中当bf16True时self.mixed_precision会被置为字符串bf16见 training_args.py。该值会传递给底层 Accelerate 库由 Accelerate 决定何时用 CPU autocast 包裹前向计算。设备选择TrainingArguments通过PartialState(cpuself.use_cpu)初始化分布式状态见 training_args.pyuse_cpuTrue时把训练设备解析为torch.device(cpu)。数据加载优化CPU 训练下dataloader_pin_memory会被自动置为False见 training_args.py因为锁页内存是为加速 CPU→GPU 拷贝设计的在纯 CPU 场景并无收益。autocast 的实际执行Trainer自身的autocast_smart_context_manager()直接返回nullcontext()并注明We rely on accelerate for autocast见 trainer.py即混合精度上下文由 Accelerate 依据前面解析出的bf16设置注入到训练循环中。扩展规模CPU 训练的三种形态当单个 CPU 的训练速度不满足要求时可以把规模扩展到多路 CPUmultiple sockets甚至多节点。文档给出了三种典型形态单 CPU单机单进程启用 bf16 即可单机多进程一台机器上每个 CPU socket 跑一个进程多机多进程跨多台机器扩展。文档中的分布式示例统一采用Intel MPI来自 Intel oneAPI HPC Toolkit作为通信库配合Trainer内置的DDPDistributedDataParallel策略。仓库中的run_qa.py通过HfArgumentParser同时解析模型、数据与TrainingArguments三类参数见 run_qa.py因此同一脚本无需改动即可被mpirun/torchrun拉起多个进程。单机多路每 socket 一个进程在双路dual-socketCPU 上推荐每个 socket 启动一个进程。原因是内存访问局部性NUMA 架构下进程只访问自己所在 socket 的内存带宽与 LLC 缓存吞吐远高于两个进程在任意 core 上漂移。示例在单机启动两个进程每 socket 一个模型换成了更大的bert-large-uncased[!TIP] 把OMP_NUM_THREADS设为单个 socket 的物理核数减 1留 1 个核给操作系统。例如 24 核 socket 设OMP_NUM_THREADS23。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/其中-n 2指定总进程数-genv OMP_NUM_THREADS23以全局环境变量方式把每个进程的 OpenMP 线程数限制为 23。MASTER_ADDR指向本机回环地址即可单机场景 rank 0 就是本机。Trainer会从进程环境自动识别分布式配置并切换为 DDP 模式。跨节点扩展两台 Xeon 机器、四个进程当单机资源不足时可将训练扩展到两台机器示例中为node0与node1每台机器 2 个进程每 socket 一个共 4 个进程。启动命令需在作为主节点的node0上执行。第一步编写 hostfilehostfile 中列出各节点的 IP 地址示例 IP 需替换为你的真实地址cat hostfile xxx.xxx.xxx.xxx #node0 ip xxx.xxx.xxx.xxx #node1 ip第二步执行训练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/ \ --use_cpu \ --bf16关键参数说明mpirun 参数含义-f hostfile指定节点列表文件-n 4总进程数4-ppn 2每节点进程数2即每 socket 一个-genv OMP_NUM_THREADS23把每个进程的 OpenMP 线程数设为 23同时把MASTER_ADDR指向node0的 IPnode0即分布式训练的主进程。相比单机示例这里显式补充了--use_cpu --bf16跨节点时全部按 CPU 场景训练并保持 bf16 混合精度。Kubernetes用 PyTorchJob 编排 CPU 分布式训练如果团队以 Kubernetes 为基础设施也可以用 PyTorchJobKubeflow 提供的自定义资源用于管理 PyTorch 分布式训练任务在集群上跑 CPU 分布式训练。部署前需要完成的四项准备拥有已安装Kubeflow的 Kubernetes 集群安装并配置kubectl以便操作集群准备一个PersistentVolumeClaimPVC用于存放数据集与模型文件为训练脚本及其依赖构建Docker 镜像。定制 Docker 镜像文档示例从 Intel 优化版 PyTorch 基础镜像出发——该镜像自带多节点 CPU 训练所需的 MPI 支持——并额外安装两个关键性能库google-perftoolslibtcmalloc相比系统默认分配器能显著降低内存分配开销libomp-devlibiomp5Intel 的 OpenMP 运行时线程管理优于 GNU OpenMP 默认实现。FROM intel/intel-optimized-pytorch:2.4.0-pip-multinode RUN apt-get update -y \ apt-get install -y --no-install-recommends --fix-missing \ google-perftools \ libomp-dev WORKDIR /workspace # Download and extract the transformers code ARG HF_TRANSFORMERS_VER4.46.0 RUN pip install --no-cache-dir \ transformers${HF_TRANSFORMERS_VER} \ mkdir transformers \ curl -sSL --retry 5 transformers 对应版本源码归档地址 | tar -C transformers --strip-components1 -xzf -镜像构建完成后需先推送到集群节点可访问的镜像仓库再执行部署。编写 PyTorchJob 资源清单PyTorchJob 负责 worker pod 的全生命周期管理创建、重启策略、进程协调等因此训练脚本只需关心模型与数据本身无需自行实现分布式协调逻辑。下面的 YAML 创建 4 个 worker全部运行仓库的 run_qa.py微调distilbert/distilbert-base-uncased并开启 bf16apiVersion: kubeflow.org/v1 kind: PyTorchJob metadata: name: transformers-pytorchjob spec: elasticPolicy: rdzvBackend: c10d minReplicas: 1 maxReplicas: 4 maxRestarts: 10 pytorchReplicaSpecs: Worker: replicas: 4 # The number of worker pods restartPolicy: OnFailure template: spec: containers: - name: pytorch image: image name:tag # Specify the docker image to use for the worker pods imagePullPolicy: IfNotPresent command: [/bin/bash, -c] args: - - cd /workspace/transformers; pip install -r /workspace/transformers/examples/pytorch/question-answering/requirements.txt; torchrun /workspace/transformers/examples/pytorch/question-answering/run_qa.py \ --model_name_or_path distilbert/distilbert-base-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/pvc-mount/output_$(date %Y%m%d_%H%M%S) \ --bf16; env: - name: LD_PRELOAD value: /usr/lib/x86_64-linux-gnu/libtcmalloc.so.4.5.9:/usr/local/lib/libiomp5.so - name: HF_HUB_CACHE value: /tmp/pvc-mount/hub_cache - name: HF_DATASETS_CACHE value: /tmp/pvc-mount/hf_datasets_cache - name: LOGLEVEL value: INFO - name: OMP_NUM_THREADS # Set to match the number of allocated CPU units value: 240 resources: limits: cpu: 240 # Update the CPU and memory limit values based on your nodes memory: 128Gi requests: cpu: 240 # Update the CPU and memory request values based on your nodes memory: 128Gi volumeMounts: - name: pvc-volume mountPath: /tmp/pvc-mount - mountPath: /dev/shm name: dshm restartPolicy: Never nodeSelector: # Optionally use nodeSelector to match a certain node label for the worker pods node-type: gnr volumes: - name: pvc-volume persistentVolumeClaim: claimName: transformers-pvc - name: dshm emptyDir: medium: Memory对该清单的几个关键设计点做深入解读弹性策略elasticPolicy采用 c10d 作为 rendezvous 后端minReplicas: 1、maxReplicas: 4允许 worker 数量在 1~4 间弹性伸缩maxRestarts: 10控制重启上限torchrun会自动适配该弹性语义。CPU 资源单位CPU unitsKubernetes 中 1 个 CPU 单位等于 1 个物理核或 vCPU。将limits与requests设为相同值240 CPU / 128Gi 内存可让 pod 获得Guaranteed级服务质量同时应留出部分核给 kubelet 与系统进程。OMP_NUM_THREADS与 CPU 配额对齐环境变量应等于分配的 CPU 单位数示例 240确保 PyTorch 的 OpenMP 线程池能覆盖全部可用核。LD_PRELOAD注入两个性能库把libtcmalloc内存分配与libiomp5Intel OpenMP 运行时以预加载方式挂入进程与前面 Dockerfile 中安装的google-perftools、libomp-dev相呼应。缓存与共享内存HF_HUB_CACHE、HF_DATASETS_CACHE指向 PVC 挂载路径/tmp/pvc-mount避免每次启动重新下载/dev/shm使用内存型emptyDir为 dataloader 多进程共享提供足够空间。nodeSelector可选可通过节点标签如node-type: gnr把 worker 调度到指定型号的 CPU 节点。注意该 YAML 需根据你的训练脚本与集群节点数做相应调整例如镜像名、CPU/内存配额、PVC 名称。部署与监控创建资源请先设置你的 namespaceexport NAMESPACEspecify your namespace kubectl create -f pytorchjob.yaml -n ${NAMESPACE}查看 pod 状态。Pod 在拉取镜像阶段处于Pending随后转为Runningkubectl get pods -n ${NAMESPACE} NAME READY STATUS RESTARTS AGE ... transformers-pytorchjob-worker-0 1/1 Running 0 7m37s transformers-pytorchjob-worker-1 1/1 Running 0 7m37s transformers-pytorchjob-worker-2 1/1 Running 0 7m37s transformers-pytorchjob-worker-3 1/1 Running 0 7m37s ...跟进某个 worker 的训练日志kubectl logs transformers-pytorchjob-worker-0 -n ${NAMESPACE} -f训练结束后从 PVC或你的存储位置取回训练好的模型然后删除 PyTorchJob 资源kubectl delete -f pytorchjob.yaml -n ${NAMESPACE}关键参数速查表以下参数贯穿全文汇总自 training_args.py 的字段定义参数默认值说明bf16/--bf16False启用 bf16 混合精度CPU 训练优先选 bf16training_args.pyfp16/--fp16Falsefp16 混合精度主要面向 GPUCPU 场景数值稳定性不如 bf16use_cpu/--use_cpuFalse强制使用 CPU为 True 时同时关闭dataloader_pin_memorytraining_args.pyper_device_train_batch_size8每设备训练 batch sizeCPU 上受内存限制需下调training_args.pylearning_rate5e-5初始学习率training_args.pynum_train_epochs3.0训练轮数training_args.pyoutput_dir必填checkpoint 与最终模型输出目录training_args.py下一步建议单机验证先跑通单 CPU bf16场景使用 run_qa.py再叠加多进程/多节点依赖清单见 requirements.txt。想要在Trainer之外做更精细的 CPU 调优如torch.compile、更细粒度线程绑定可结合仓库的 Dockerfile 体系 与性能相关文档继续深入。关于 bf16 在现代 Intel 硬件上的性能收益可阅读社区博客《Accelerating PyTorch Transformers with Intel Sapphire Rapids》一文获得更深入的背景知识。【免费下载链接】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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价