Transformers 文件

DeepSpeed

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

DeepSpeed

DeepSpeed 旨在最佳化大型模型的分散式訓練,支援資料並行、模型並行、流水線並行,甚至三者的組合等多種並行策略,以提供更好的記憶體效率和更快的訓練速度。這透過零冗餘最佳化器(ZeRO)實現,該最佳化器包含三個階段。

ZeRO 階段 描述
1 劃分最佳化器狀態
2 劃分最佳化器和梯度狀態
3 劃分最佳化器、梯度和引數

每個階段逐步節省更多記憶體,允許真正大型的模型在單個 GPU 上進行擬合和訓練。所有 ZeRO 階段,包括將最佳化器記憶體和計算從 GPU 解除安裝到 CPU,都已整合到 Trainer 中。向 Trainer 提供配置檔案或其中一個示例模板,以啟用 DeepSpeed 功能。

本指南將引導您完成 DeepSpeed 配置檔案的設定、如何在 Trainer 中啟用其功能以及部署進行訓練。

從 PyPI 或 Transformers 安裝 DeepSpeed。有關更詳細的安裝說明,請參閱 DeepSpeed 安裝或 GitHub README

PyPI
Transformers
pip install deepspeed

如果您的安裝遇到問題,請參閱DeepSpeed CUDA 安裝。儘管 DeepSpeed 有一個可透過 pip 安裝的包,但強烈建議從原始碼安裝,以確保它與您的硬體匹配並支援 PyPI 分發中不可用的某些功能。

DeepSpeed 提供了一個工具,用於估算引數、最佳化器和梯度狀態所需的 CPU 和 GPU 記憶體。您還需要為 CUDA 核心和啟用保留一些記憶體。

執行以下命令以檢查 bigscience/T0_3B 在單個 GPU 上的記憶體需求。

$ python -c 'from transformers import AutoModel; \
from deepspeed.runtime.zero.stage3 import estimate_zero3_model_states_mem_needs_all_live; \
model = AutoModel.from_pretrained("bigscience/T0_3B"); \
estimate_zero3_model_states_mem_needs_all_live(model, num_gpus_per_node=1, num_nodes=1)'
[...]
Estimated memory needed for params, optim states and gradients for a:
HW: Setup with 1 node, 1 GPU per node.
SW: Model with 2783M total params, 65M largest layer params.
  per CPU  |  per GPU |   Options
   70.00GB |   0.25GB | offload_param=cpu , offload_optimizer=cpu , zero_init=1
   70.00GB |   0.25GB | offload_param=cpu , offload_optimizer=cpu , zero_init=0
   62.23GB |   5.43GB | offload_param=none, offload_optimizer=cpu , zero_init=1
   62.23GB |   5.43GB | offload_param=none, offload_optimizer=cpu , zero_init=0
    0.37GB |  46.91GB | offload_param=none, offload_optimizer=none, zero_init=1
   15.56GB |  46.91GB | offload_param=none, offload_optimizer=none, zero_init=0

如果您有足夠的 GPU 記憶體,請停用 CPU 和 NVMe 解除安裝以加快所有操作。

選擇 ZeRO 階段

請參考下表選擇適合您訓練的 ZeRO 階段,因為訓練速度和記憶體使用之間存在權衡。下表按從快到慢以及從最少記憶體使用到最多記憶體使用的順序排列 ZeRO 階段。

最快 最少記憶體使用
ZeRO-1 ZeRO-3 + 解除安裝
ZeRO-2 ZeRO-3
ZeRO-2 + 解除安裝 ZeRO-2 + 解除安裝
ZeRO-3 ZeRO-2
ZeRO-3 + 解除安裝 ZeRO-1

根據您要最佳化的效能型別(速度或記憶體)進行決定,然後反向推導,找出最適合您用例的 ZeRO 階段。例如,如果您要最佳化速度,請從最快的 ZeRO 階段開始,如果記憶體不足,請嘗試下一個階段,它會較慢但更節省記憶體。

配置檔案

決定 ZeRO 階段後,設定配置檔案以啟用 Trainer 中的 DeepSpeed。配置檔案包含所有配置和設定訓練的引數。執行訓練指令碼時,DeepSpeed 會將 Trainer 的配置記錄到控制檯,以便您準確檢視正在使用的內容。

您可以在 DeepSpeed 配置 JSON 參考中找到 DeepSpeed 配置選項的完整列表。在 DeepSpeedExamplesDeepSpeed 儲存庫中也有各種 DeepSpeed 配置示例的實際例子。執行以下命令以快速查詢特定示例。

git clone https://github.com/microsoft/DeepSpeedExamples
cd DeepSpeedExamples
find . -name '*json'
# find examples with the Lamb optimizer
grep -i Lamb $(find . -name '*json')

如果您從命令列介面進行訓練,配置檔案將作為 JSON 檔案的路徑傳遞;如果您在 Jupyter Notebook 中使用 Trainer,則作為巢狀字典物件傳遞。

檔案路徑
巢狀字典
TrainingArguments(
    deepspeed="path/to/deepspeed_config.json",
    ...,
)

DeepSpeed 與 Trainer 引數

配置引數有三種類型。

  1. 一些配置引數由 DeepSpeed 和 Trainer 共享,在存在衝突定義時,難以識別錯誤。在這種情況下,請從 Trainer 命令列引數配置這些引數。
  2. 一些配置引數會自動從模型配置中匯出,無需手動配置。Trainer 使用配置值 `auto` 來設定最正確或最有效的選項。您可以明確定義這些引數,但必須注意確保 Trainer 和 DeepSpeed 配置引數匹配。不匹配可能會導致訓練以非常難以檢測的方式失敗。
  3. 有些配置引數是 DeepSpeed 特有的,應根據您的訓練要求手動設定。

有兩種方法可以修改配置引數。

某些值,例如 scheduler.params.total_num_steps,由 Trainer 在訓練期間計算。

  1. 建立或載入 DeepSpeed 配置作為主配置。
  2. 根據 DeepSpeed 配置值建立 TrainingArguments 物件。

ZeRO 階段

每個 ZeRO 階段配置都在 zero_optimization 中定義。

有關每個引數的更詳細解釋,請參閱 DeepSpeed 配置 JSON 參考。這些引數必須與 DeepSpeed 一起設定,因為 Trainer 不提供等效的命令列引數。

DeepSpeed 不會驗證引數名稱,任何拼寫錯誤都將回退到引數的預設設定。觀察 DeepSpeed 引擎啟動日誌訊息,以檢視正在使用的值。

ZeRO-1
ZeRO-2
ZeRO-3

ZeRO-1 將最佳化器狀態分片到各個 GPU 上,您可以期望獲得少量加速。

{
    "zero_optimization": {
        "stage": 1
    }
}

NVMe

ZeRO-Infinity 將模型狀態解除安裝到 CPU 和/或 NVMe,以節省更多記憶體。智慧分割槽和平鋪演算法允許每個 GPU 在解除安裝期間傳送和接收極少量資料,從而使現代 NVMe 能夠容納比訓練過程可用記憶體池更大的總記憶體池。ZeRO-Infinity 需要 ZeRO-3。

根據可用的 CPU 和 NVMe 記憶體,您可以解除安裝最佳化器狀態引數,或僅解除安裝其中之一,或都不解除安裝。請確保 `nvme_path` 指向 NVMe 裝置,因為雖然它仍然適用於普通硬碟或固態硬碟,但速度會明顯變慢。使用現代 NVMe,您可以預期讀取操作的峰值傳輸速度約為 3.5GB/s,寫入操作的峰值傳輸速度約為 3GB/s。

考慮在您的訓練設定上執行基準測試,以確定最佳的 aio 配置。

下面的 ZeRO-3 和 ZeRO-Infinity 配置示例將大多數引數值設定為 auto,但您也可以手動配置這些值。

{
    "fp16": {
        "enabled": "auto",
        "loss_scale": 0,
        "loss_scale_window": 1000,
        "initial_scale_power": 16,
        "hysteresis": 2,
        "min_loss_scale": 1
    },

    "optimizer": {
        "type": "AdamW",
        "params": {
            "lr": "auto",
            "betas": "auto",
            "eps": "auto",
            "weight_decay": "auto"
        }
    },

    "scheduler": {
        "type": "WarmupLR",
        "params": {
            "warmup_min_lr": "auto",
            "warmup_max_lr": "auto",
            "warmup_num_steps": "auto"
        }
    },

    "zero_optimization": {
        "stage": 3,
        "offload_optimizer": {
            "device": "nvme",
            "nvme_path": "/local_nvme",
            "pin_memory": true,
            "buffer_count": 4,
            "fast_init": false
        },
        "offload_param": {
            "device": "nvme",
            "nvme_path": "/local_nvme",
            "pin_memory": true,
            "buffer_count": 5,
            "buffer_size": 1e8,
            "max_in_cpu": 1e9
        },
        "aio": {
            "block_size": 262144,
            "queue_depth": 32,
            "thread_count": 1,
            "single_submit": false,
            "overlap_events": true
        },
        "overlap_comm": true,
        "contiguous_gradients": true,
        "sub_group_size": 1e9,
        "reduce_bucket_size": "auto",
        "stage3_prefetch_bucket_size": "auto",
        "stage3_param_persistence_threshold": "auto",
        "stage3_max_live_parameters": 1e9,
        "stage3_max_reuse_distance": 1e9,
        "stage3_gather_16bit_weights_on_model_save": true
    },

    "gradient_accumulation_steps": "auto",
    "gradient_clipping": "auto",
    "steps_per_print": 2000,
    "train_batch_size": "auto",
    "train_micro_batch_size_per_gpu": "auto",
    "wall_clock_breakdown": false
}

訓練功能

DeepSpeed 支援許多可以在配置檔案中配置的訓練功能。本節介紹一些最重要的功能。

梯度檢查點

梯度檢查點透過僅儲存部分中間啟用而不是儲存所有中間啟用來節省記憶體。它有助於在 GPU 上擬合更大的模型而不會記憶體不足,或增加批大小以獲得更好的效能。不過,訓練速度會變慢。

  • 對於 Transformers 模型,設定 `model.gradient_checkpointing_enable()` 或在 TrainingArguments 中新增 `--gradient_checkpointing`。
  • 對於非 Transformers 模型,請使用 DeepSpeed 啟用檢查點 API。用 DeepSpeed API 替換 Transformers 模型程式碼和 torch.utils.checkpoint 可以提供更大的靈活性,因為您可以將前向啟用解除安裝到 CPU 記憶體而不是重新計算它們。

批次大小

批次大小可以自動配置或手動設定。當您選擇 `“auto”` 選項時,Trainer 會將 `train_micro_batch_size_per_gpu` 和 `train_batch_size` 設定為 `world_size * per_device_train_batch_size * gradient_accumulation_steps` 的值。

{
    "train_micro_batch_size_per_gpu": "auto",
    "train_batch_size": "auto"
}

通訊資料型別

對於歸約、收集和散射操作等通訊集合,使用了單獨的資料型別。

所有收集和散射操作均以資料所用的相同資料型別執行。例如,如果您以 bf16 進行訓練,資料也將以 bf16 收集,因為收集是非有損操作。

歸約操作是有損的,例如,當梯度在多個 GPU 之間平均時。當通訊以 fp16 或 bf16 完成時,它更有可能是有損的,因為在低精度下新增多個數字並不精確。bf16 尤其如此,它的精度低於 fp16。因此,fp16 是歸約操作的預設值,因為在對梯度進行平均時損失最小。

透過在配置檔案中設定 `communication_data_type` 引數來選擇通訊資料型別。例如,選擇 fp32 會增加少量開銷,但確保歸約操作以 fp32 累積,並在準備好時下轉換為您正在訓練的半精度資料型別。

{
    "communication_data_type": "fp32"
}

梯度累積

梯度累積在更新引數之前,會在多個小批次資料上累積梯度。它儲存的梯度較少,並允許使用更大的*有效批次大小*進行訓練。不過,訓練速度會變慢,但對於克服記憶體限制很有用。

梯度累積可以自動配置或手動設定。當您選擇 `“auto”` 選項時,Trainer 會將其設定為 `gradient_accumulation_steps` 的值。

{
    "gradient_accumulation_steps": "auto"
}

梯度裁剪

梯度裁剪有助於防止梯度爆炸,這可能導致訓練期間的不穩定性。它設定了一個最大閾值,如果梯度範數超過該閾值,則重新縮放梯度。

梯度裁剪可以自動配置或手動設定。當您選擇 `“auto”` 選項時,Trainer 會將其設定為 `max_grad_norm` 的值。

{
    "gradient_clipping": "auto"
}

混合精度訓練

混合精度透過將部分計算以半精度執行來加速訓練速度,同時保持部分計算以全精度執行以保持準確性。DeepSpeed 支援 fp32、fp16 和 bf16 資料型別。

fp32
fp16
bf16

如果模型未在混合精度下進行預訓練,請以 fp32 訓練,因為它可能導致下溢或上溢錯誤。在這種情況下,停用預設的 fp16。

{
    "fp16": {
        "enabled": false
    }
}

對於 Ampere GPU 和 PyTorch 1.7+,更高效的 tf32 模式會自動為某些操作啟用,但結果仍為 fp32。在 Trainer 中配置它,透過設定 `--tf32` 啟用,透過設定 `--tf32 0` 或 `--no_tf32` 停用。

最佳化器和排程器

如果未啟用 offload_optimizer,DeepSpeed 和 Transformers 最佳化器和排程器可以混搭。當啟用 offload_optimizer 時,只要它具有 CPU 和 GPU 實現,就可以使用非 DeepSpeed 最佳化器(LAMB 除外)。

透過命令列設定配置檔案的最佳化器和排程器引數,以避免難以發現的錯誤。例如,如果學習率在其他地方設定為不同的值,您可以透過命令列覆蓋它。

最佳化器
排程器

DeepSpeed 提供了多種最佳化器(Adam、AdamW、OneBitAdam 和 LAMB),但您也可以從 PyTorch 匯入其他最佳化器。如果您未在配置中配置最佳化器,Trainer 會自動選擇 AdamW,並使用提供的或以下命令列引數的預設值:lradam_beta1adam_beta2adam_epsilonweight_decay

您可以將引數設定為 "auto" 或手動輸入自己的值。

{
   "optimizer": {
       "type": "AdamW",
       "params": {
         "lr": "auto",
         "betas": "auto",
         "eps": "auto",
         "weight_decay": "auto"
       }
   }
}

透過在頂級配置中新增以下內容來使用不支援的最佳化器。

{
   "zero_allow_untested_optimizer": true
}

從 DeepSpeed 0.8.3+ 開始,如果您想使用解除安裝,還需要將以下內容新增到頂級配置中,因為解除安裝與 DeepSpeed 的 CPU Adam 最佳化器配合得最好。

{
   "zero_force_ds_cpu_optimizer": false
}

通用檢查點

通用檢查點可跨不同模型架構、並行技術和訓練配置儲存和載入模型、最佳化器和訓練排程器狀態。透過以通用格式儲存它們,可以更輕鬆地繼續模型訓練和微調。

透過將配置檔案中的 `load_universal` 設定為 `true` 來恢復通用檢查點訓練。

{
    "checkpoint": {
        "load_universal": true
    }
}

部署

DeepSpeed 可以使用其原生啟動器 torchrunAccelerate 進行部署。

在命令列中向 Trainer 新增 `--deepspeed ds_config.json` 引數。建議使用 DeepSpeed 的 add_config_arguments 工具向程式碼中新增任何其他命令列引數。

多 GPU
單 GPU

要將 DeepSpeed 部署到多個 GPU 上,請新增 `--num_gpus`。如果您打算使用所有可用的 GPU,則無需新增 `--num_gpus`。

deepspeed --num_gpus=2 examples/pytorch/translation/run_translation.py \
--deepspeed tests/deepspeed/ds_config_zero3.json \
--model_name_or_path google-t5/t5-small --per_device_train_batch_size 1 \
--output_dir output_dir --overwrite_output_dir --fp16 \
--do_train --max_train_samples 500 --num_train_epochs 1 \
--dataset_name wmt16 --dataset_config "ro-en" \
--source_lang en --target_lang ro

多節點

多節點設定由多個節點組成,每個節點都有一個或多個 GPU 執行工作負載。DeepSpeed 期望有一個共享儲存系統,但如果不是這種情況,您需要調整配置檔案以包含一個 檢查點,以便在沒有共享檔案系統的情況下載入。

{
  "checkpoint": {
    "use_node_local_storage": true
  }
}

您還可以使用 TrainingArguments 中的 `--save_on_each_node` 引數,自動將上述 `checkpoint` 新增到您的配置中。

以下 torchrun 和 DeepSpeed 啟動器示例展示瞭如何部署兩個節點,每個節點有八個 GPU。透過 `ssh hostname1` 訪問第一個節點,透過 `ssh hostname2` 訪問第二個節點。兩個節點必須能夠透過 ssh 在本地無需密碼進行通訊。

torchrun
DeepSpeed

使用 torchrun,ssh 到每個節點並在它們上執行以下命令。啟動器會等待兩個節點同步後才啟動訓練。

torchrun --nproc_per_node=8 --nnode=2 --node_rank=0 --master_addr=hostname1 \
--master_port=9901 your_program.py <normal cl args> --deepspeed ds_config.json

Slurm

Slurm 是一個叢集管理和作業排程系統。下面顯示了一個 Slurm 指令碼示例。

#SBATCH --job-name=test-nodes        # name
#SBATCH --nodes=2                    # nodes
#SBATCH --ntasks-per-node=1          # crucial - only 1 task per dist per node!
#SBATCH --cpus-per-task=10           # number of cores per tasks
#SBATCH --gres=gpu:8                 # number of gpus
#SBATCH --time 20:00:00              # maximum execution time (HH:MM:SS)
#SBATCH --output=%x-%j.out           # output file name

export GPUS_PER_NODE=8
export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1)
export MASTER_PORT=9901

srun --jobid $SLURM_JOBID bash -c 'python -m torch.distributed.run \
 --nproc_per_node $GPUS_PER_NODE --nnodes $SLURM_NNODES --node_rank $SLURM_PROCID \
 --master_addr $MASTER_ADDR --master_port $MASTER_PORT \
your_program.py <normal cl args> --deepspeed ds_config.json'

使用以下命令在所有節點上同時啟動訓練。

sbatch launch.slurm

Jupyter Notebook

要在 Jupyter Notebook 中使用 DeepSpeed,您需要模擬分散式環境,因為啟動器不支援從 Notebook 部署。這僅支援單個 GPU。要使用多個 GPU,您必須使用多程序環境,這意味著您必須使用 DeepSpeed 啟動器,而這無法像此處所示進行模擬。

# emulate a launcher in the notebook
import os

os.environ["MASTER_ADDR"] = "localhost"
os.environ["MASTER_PORT"] = "9994"  # modify if RuntimeError: Address already in use
os.environ["RANK"] = "0"
os.environ["LOCAL_RANK"] = "0"
os.environ["WORLD_SIZE"] = "1"

training_args = TrainingArguments(..., deepspeed="ds_config_zero3.json")
trainer = Trainer(...)
trainer.train()

在 Notebook 的當前目錄中,透過專用單元格即時建立配置檔案。

%%bash
cat <<'EOT' > ds_config_zero3.json
{
    "fp16": {
        "enabled": "auto",
        "loss_scale": 0,
        "loss_scale_window": 1000,
        "initial_scale_power": 16,
        "hysteresis": 2,
        "min_loss_scale": 1
    },

    "optimizer": {
        "type": "AdamW",
        "params": {
            "lr": "auto",
            "betas": "auto",
            "eps": "auto",
            "weight_decay": "auto"
        }
    },

    "scheduler": {
        "type": "WarmupLR",
        "params": {
            "warmup_min_lr": "auto",
            "warmup_max_lr": "auto",
            "warmup_num_steps": "auto"
        }
    },

    "zero_optimization": {
        "stage": 3,
        "offload_optimizer": {
            "device": "cpu",
            "pin_memory": true
        },
        "offload_param": {
            "device": "cpu",
            "pin_memory": true
        },
        "overlap_comm": true,
        "contiguous_gradients": true,
        "sub_group_size": 1e9,
        "reduce_bucket_size": "auto",
        "stage3_prefetch_bucket_size": "auto",
        "stage3_param_persistence_threshold": "auto",
        "stage3_max_live_parameters": 1e9,
        "stage3_max_reuse_distance": 1e9,
        "stage3_gather_16bit_weights_on_model_save": true
    },

    "gradient_accumulation_steps": "auto",
    "gradient_clipping": "auto",
    "steps_per_print": 2000,
    "train_batch_size": "auto",
    "train_micro_batch_size_per_gpu": "auto",
    "wall_clock_breakdown": false
}
EOT

如果訓練指令碼在檔案中而不是在 notebook 單元格中,則從 notebook 單元格中的 shell 啟動 DeepSpeed。

!git clone https://github.com/huggingface/transformers
!cd transformers; deepspeed examples/pytorch/translation/run_translation.py ...

另一種選擇是使用 `%%bash` 執行 shell 程式,而不模擬分散式環境。但是,在訓練完成之前,您將無法檢視日誌。

%%bash

git clone https://github.com/huggingface/transformers
cd transformers
deepspeed examples/pytorch/translation/run_translation.py ...

儲存模型權重

DeepSpeed 將主要的 fp32 權重儲存在自定義檢查點最佳化器檔案(`global_step*/*optim_states.pt`)中,這些檔案儲存在普通檢查點下。

fp16

ZeRO-2 以 fp16 格式儲存模型權重。對於 ZeRO-3,如果模型權重分佈在多個 GPU 上,請在配置檔案中設定 `"stage3_gather_16bit_weights_on_model_save": true` 以 fp16 格式儲存權重。

如果您不這樣做,Trainer 將不會以 fp16 格式儲存權重,並且不會建立 `pytorch_model.bin` 檔案。這是因為 DeepSpeed 的 `state_dict` 包含一個佔位符而不是實際權重,因此您將無法載入它。

{
    "zero_optimization": {
        "stage": 3,
        "stage3_gather_16bit_weights_on_model_save": true
    }
}

fp32

除非您有大量空閒 CPU 記憶體,否則訓練期間不應儲存 fp32 權重,因為它可能需要大量記憶體。通常最好在訓練完成後離線儲存 fp32 權重。

離線
線上

DeepSpeed 在頂級檢查點資料夾中提供了一個 zero_to_fp32.py 指令碼,用於隨時提取權重。這是一個獨立的指令碼,您不需要配置檔案或 Trainer

例如,如果您的檢查點資料夾如下圖所示,那麼您可以執行以下命令,從多個 GPU 建立併合並 fp32 權重到一個 `pytorch_model.bin` 檔案中。該指令碼會自動發現包含檢查點的子資料夾 `global_step1`。

$ ls -l output_dir/checkpoint-1/
-rw-rw-r-- 1 stas stas 1.4K Mar 27 20:42 config.json
drwxrwxr-x 2 stas stas 4.0K Mar 25 19:52 global_step1/
-rw-rw-r-- 1 stas stas   12 Mar 27 13:16 latest
-rw-rw-r-- 1 stas stas 827K Mar 27 20:42 optimizer.pt
-rw-rw-r-- 1 stas stas 231M Mar 27 20:42 pytorch_model.bin
-rw-rw-r-- 1 stas stas  623 Mar 27 20:42 scheduler.pt
-rw-rw-r-- 1 stas stas 1.8K Mar 27 20:42 special_tokens_map.json
-rw-rw-r-- 1 stas stas 774K Mar 27 20:42 spiece.model
-rw-rw-r-- 1 stas stas 1.9K Mar 27 20:42 tokenizer_config.json
-rw-rw-r-- 1 stas stas  339 Mar 27 20:42 trainer_state.json
-rw-rw-r-- 1 stas stas 2.3K Mar 27 20:42 training_args.bin
-rwxrw-r-- 1 stas stas 5.5K Mar 27 13:16 zero_to_fp32.py*

執行 `python zero_to_fp32.py -h` 以獲取更多用法詳情。該指令碼需要最終 fp32 權重兩倍的通用 RAM。

python zero_to_fp32.py . pytorch_model.bin

非 Trainer 整合

DeepSpeed 也可以與 Transformers 一起使用,而無需 Trainer。當呼叫 from_pretrained() 時,HfDeepSpeedConfig 負責收集 ZeRO-3 引數並將模型分割槽到多個 GPU。

您必須在載入模型之前例項化 HfDeepSpeedConfig,以高效部署 ZeRO-3。

預訓練模型
非預訓練模型
from transformers.integrations import HfDeepSpeedConfig
from transformers import AutoModel
import deepspeed

# DeepSpeed config object or path to the file
ds_config = {...}
# must run before instantiating the model to detect ZeRO-3
dschf = HfDeepSpeedConfig(ds_config)  # keep this object alive
model = AutoModel.from_pretrained("openai-community/gpt2")
engine = deepspeed.initialize(model=model, config_params=ds_config, ...)

故障排除

當您遇到錯誤時,首先要檢查的事情之一就是 DeepSpeed 是否是原因(因為它通常不是)。在不使用 DeepSpeed 的情況下重試您的設定,如果錯誤仍然存在,請報告問題。如果問題與 Transformers 整合無關,請在 DeepSpeed 儲存庫中提出問題。

對於與 Transformers 整合相關的問題,請提供以下資訊。

  • 完整的 DeepSpeed 配置檔案。

  • 命令列引數 TrainerTrainingArguments(如果您自己編寫 Trainer 設定指令碼)(請勿轉儲包含許多不相關條目的整個 TrainingArguments)。

  • 以下命令的輸出。

    python -c 'import torch; print(f"torch: {torch.__version__}")'
    python -c 'import transformers; print(f"transformers: {transformers.__version__}")'
    python -c 'import deepspeed; print(f"deepspeed: {deepspeed.__version__}")'
  • 指向 Google Colab 筆記本的連結,以重現此問題。

  • 一個標準或非自定義資料集或一個現有示例來重現此問題。

以下部分提供瞭解決兩個最常見問題的指南。

程序在啟動時被殺死

當 DeepSpeed 程序在啟動時被殺死而沒有堆疊跟蹤時,這通常意味著程式試圖分配的 CPU 記憶體超過了系統可用記憶體。或者,程序可能試圖分配超過允許的 CPU 記憶體,導致作業系統核心終止該程序。

在這種情況下,檢查您的配置檔案中是否配置了 `offload_optimizer`、`offload_param` 或兩者都解除安裝到 CPU。

如果您設定了 NVM3 和 ZeRO-3,可以嘗試將解除安裝到 NVMe(首先估算模型的記憶體需求)。

NaN 損失

NaN 損失通常發生在模型以 bf16 預訓練而您嘗試將其與 fp16 一起使用時(尤其與 TPU 訓練的模型相關)。要解決此問題,如果您的硬體(TPU、Ampere GPU 或更新版本)支援,請使用 fp32 或 bf16。

fp16也可能導致溢位。例如,如果您的配置檔案如下所示,您可能會在日誌中看到以下溢位錯誤。

{
    "fp16": {
        "enabled": "auto",
        "loss_scale": 0,
        "loss_scale_window": 1000,
        "initial_scale_power": 16,
        "hysteresis": 2,
        "min_loss_scale": 1
    }
}

下面的 `OVERFLOW!` 錯誤是 DeepSpeed 損失縮放器無法找到縮放係數來克服損失溢位的結果。在這種情況下,請嘗試更高的 `initial_scale_power` 值(通常 32 即可)。

0%|                                                                                                                             | 0/189 [00:00<?, ?it/s]
 [deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 262144, reducing to 262144
  1%|▌                                                                                                                    | 1/189 [00:00<01:26,  2.17it/s]
 [deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 262144, reducing to 131072.0
  1%|█▏
 [...]
 [deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 1, reducing to 1
 14%|████████████████▌                                                                                                   | 27/189 [00:14<01:13,  2.21it/s]
 [deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 1, reducing to 1
 15%|█████████████████▏                                                                                                  | 28/189 [00:14<01:13,  2.18it/s]
 [deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 1, reducing to 1
 15%|█████████████████▊                                                                                                  | 29/189 [00:15<01:13,  2.18it/s]
 [deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 1, reducing to 1
[...]

資源

DeepSpeed 是一種強大的技術,用於擴充套件大型模型訓練。要了解更多關於 DeepSpeed 的資訊,請查閱他們的部落格文章文件GitHub

以下論文提供了有關 ZeRO 的更多詳細資訊。

< > 在 GitHub 上更新

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