Transformers 文档
分布式CPU
并获得增强的文档体验
开始使用
分布式CPU
CPU是普遍可用的,并且在GPU不可用时可以作为一种经济高效的训练选项。当训练大型模型或单个CPU太慢时,使用CPU进行分布式训练有助于加快训练速度。
本指南演示了如何在使用 Trainer 的裸机上以及使用 Kubernetes 集群时,使用 DistributedDataParallel (DDP) 策略,通过多个 CPU 执行分布式训练。本指南中显示的所有示例都依赖于 Intel oneAPI HPC Toolkit。
您将需要 Intel oneAPI 中的两个工具包。
- oneCCL 包含深度学习中常用的高效集合操作实现,例如 all-gather、all-reduce 和 reduce-scatter。要从预构建的 wheel 安装,请务必始终使用最新版本。请参阅此处的表格,以检查 oneCCL 版本是否支持特定 Python 和 PyTorch 版本。
# installs oneCCL for PyTorch 2.4.0
pip install oneccl_bind_pt==2.4.0 -f https://developer.intel.com/ipex-whl-stable-cpu
有关更多详细信息,请参阅 oneCCL 安装。
- MPI 是用于硬件和网络之间通信的消息传递接口。oneCCL 工具包与 MPI 一起安装,但在使用前需要像下面这样配置环境变量。
oneccl_bindings_for_pytorch_path=$(python -c "from oneccl_bindings_for_pytorch import cwd; print(cwd)")
source $oneccl_bindings_for_pytorch_path/env/setvars.sh
最后,安装 适用于 PyTorch 的 Intel 扩展 (IPEX),它为 Intel 硬件提供额外的性能优化,例如权重共享和更好的线程运行时控制。
pip install intel_extension_for_pytorch==<version_name> -f https://developer.intel.com/ipex-whl-stable-cpu
有关更多详细信息,请参阅 IPEX 安装。
Trainer
Trainer 支持使用 oneCCL 后端进行 CPU 分布式训练。在命令行参数中添加 --ddp_backend ccl
参数即可启用。
下面的示例演示了 run_qa.py 脚本。它可以在一台 Xeon CPU 上启用两个进程的训练,每个套接字运行一个进程。
调整变量 OMP_NUM_THREADS/CCL_WORKER_COUNT
以获得最佳性能。
export CCL_WORKER_COUNT=1
export MASTER_ADDR=127.0.0.1
mpirun -n 2 -genv OMP_NUM_THREADS=23 \
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
Kubernetes
使用 PyTorchJob 也可以将 CPU 分布式训练部署到 Kubernetes 集群。在开始之前,您应该执行以下设置步骤。
- 确保您可以访问安装了 Kubeflow 的 Kubernetes 集群。
- 安装和配置 kubectl 以与集群交互。
- 设置 PersistentVolumeClaim (PVC) 以存储数据集和模型文件。有多种选项可供选择,包括 StorageClass 或云存储桶。
- 为训练脚本和所有必需的依赖项(如 PyTorch、Transformers、IPEX、oneCCL 和 OpenSSH)设置一个 Docker 容器,以方便容器之间的通信。
下面的 Dockerfile 示例使用了一个支持 CPU 分布式训练的基础镜像,并将 Transformers 提取到 `/workspace` 目录以在镜像中包含训练脚本。该镜像需要在部署之前构建并复制到集群节点或推送到容器注册表。
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_VER="4.46.0"
RUN pip install --no-cache-dir \
transformers==${HF_TRANSFORMERS_VER} && \
mkdir transformers && \
curl -sSL --retry 5 https://github.com/huggingface/transformers/archive/refs/tags/v${HF_TRANSFORMERS_VER}.tar.gz | tar -C transformers --strip-components=1 -xzf -
PyTorchJob
PyTorchJob 是 Kubernetes API 的一个扩展,用于在 Kubernetes 上运行 PyTorch 训练作业。它包含一个 yaml 文件,用于定义训练作业参数,例如 PyTorchJob 的名称、worker 数量、每个 worker 的资源类型等等。
卷挂载参数是 PVC 在每个 worker pod 的容器中挂载的路径。PVC 通常用于保存数据集、检查点文件以及训练完成后保存的模型。
下面的 yaml 文件示例在 run_qa.py 脚本上设置了四个 worker。根据您的训练脚本和集群中的节点数量调整 yaml 文件。
CPU 资源限制和请求以CPU 单位定义。一个 CPU 单位相当于一个物理 CPU 核心或虚拟核心。yaml 文件中定义的 CPU 单位应小于单台机器可用的 CPU 和内存容量,以便为 kubelet 和系统留下一些资源。对于 `Guaranteed` 服务质量,CPU 和内存的数量应在资源限制和请求中设置相同。
apiVersion: "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;
source /usr/local/lib/python3.10/dist-packages/oneccl_bindings_for_pytorch/env/setvars.sh;
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) \
--no_cuda \
--ddp_backend ccl \
--bf16;
env:
- name: LD_PRELOAD
value: "/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4.5.9:/usr/local/lib/libiomp5.so"
- name: TRANSFORMERS_CACHE
value: "/tmp/pvc-mount/transformers_cache"
- name: HF_DATASETS_CACHE
value: "/tmp/pvc-mount/hf_datasets_cache"
- name: LOGLEVEL
value: "INFO"
- name: CCL_WORKER_COUNT
value: "1"
- name: OMP_NUM_THREADS # Can be tuned for optimal performance
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
部署
在为您的集群和训练作业设置好 PyTorchJob yaml 文件后,使用以下命令将其部署到集群中。
export NAMESPACE=<specify your namespace>
kubectl create -f pytorchjob.yaml -n ${NAMESPACE}
使用 kubectl get pods -n ${NAMESPACE}
命令列出命名空间中的 Pod。最初,状态可能是“Pending”,但在容器被拉取并创建后,它应该会变为“Running”。
kubectl 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 的日志。添加 -f
以流式传输日志。
kubectl logs transformers-pytorchjob-worker-0 -n ${NAMESPACE} -f
训练完成后,训练好的模型可以从 PVC 或存储位置复制。使用以下命令从集群中删除 PyTorchJob 资源。
kubectl delete -f pytorchjob.yaml -n ${NAMESPACE}