Transformers 文件

分散式CPU

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

分散式CPU

CPU是普遍可用的,並且在GPU不可用時可以作為一種經濟高效的訓練選項。當訓練大型模型或單個CPU太慢時,使用CPU進行分散式訓練有助於加快訓練速度。

本指南演示瞭如何在使用 Trainer 的裸機上以及使用 Kubernetes 叢集時,使用 DistributedDataParallel (DDP) 策略,透過多個 CPU 執行分散式訓練。本指南中顯示的所有示例都依賴於 Intel oneAPI HPC Toolkit

您將需要 Intel oneAPI 中的兩個工具包。

  1. 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 安裝

  1. 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 叢集。在開始之前,您應該執行以下設定步驟。

  1. 確保您可以訪問安裝了 Kubeflow 的 Kubernetes 叢集。
  2. 安裝和配置 kubectl 以與叢集互動。
  3. 設定 PersistentVolumeClaim (PVC) 以儲存資料集和模型檔案。有多種選項可供選擇,包括 StorageClass 或雲端儲存桶。
  4. 為訓練指令碼和所有必需的依賴項(如 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}
< > 在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.