Accelerate 文件

快速教程

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

快速入門

啟動和執行程式碼的方式有很多,具體取決於您的訓練環境(torchrunDeepSpeed 等)和可用的硬體。Accelerate 提供了一個統一的介面,用於在不同的分散式設定上啟動和訓練,讓您可以專注於 PyTorch 訓練程式碼,而不是將程式碼適應這些不同設定的複雜性。這使您可以輕鬆地擴充套件您的 PyTorch 程式碼,以便在 GPU 和 TPU 等硬體的分散式設定上進行訓練和推理。Accelerate 還提供了大模型推理功能,使載入和執行通常無法裝入記憶體的大型模型的推理變得更加容易。

本快速入門介紹了 Accelerate 的三個主要功能

  • 用於分散式訓練指令碼的統一命令列啟動介面
  • 一個用於使 PyTorch 訓練程式碼適應不同分散式設定的訓練庫
  • 大模型推理

統一啟動介面

Accelerate 透過由 accelerate config 命令生成的統一配置檔案,為任何給定的分散式訓練框架(DeepSpeed、FSDP 等)自動選擇適當的配置值。您也可以將配置值顯式地傳遞給命令列,這在某些情況下(例如使用 SLURM 時)很有幫助。

但在大多數情況下,您應該始終先執行 accelerate config 來幫助 Accelerate 瞭解您的訓練設定。

accelerate config

accelerate config 命令會在 Accelerate 的快取資料夾中建立並儲存一個 default_config.yaml 檔案。該檔案儲存了您的訓練環境配置,幫助 Accelerate 根據您的機器正確啟動訓練指令碼。

在配置完您的環境後,您可以使用 accelerate test 測試您的設定,該命令會啟動一個簡短的指令碼來測試分散式環境。

accelerate test

如果配置檔案儲存在非預設位置(如快取),請將 --config_file 新增到 accelerate testaccelerate launch 命令中以指定配置檔案的位置。

一旦您的環境設定完畢,就可以使用 accelerate launch 啟動您的訓練指令碼!

accelerate launch path_to_script.py --args_for_the_script

要了解更多資訊,請檢視 啟動分散式程式碼 教程以獲取有關啟動指令碼的更多資訊。

我們還有一個 配置示例集,其中展示了許多為各種設定預製的**最小**配置示例。

適配訓練程式碼

Accelerate 的下一個主要功能是 Accelerator 類,它能讓您的 PyTorch 程式碼適應不同的分散式設定。

您只需在訓練指令碼中新增幾行程式碼,就可以讓它在多個 GPU 或 TPU 上執行。

+ from accelerate import Accelerator
+ accelerator = Accelerator()

+ device = accelerator.device
+ model, optimizer, training_dataloader, scheduler = accelerator.prepare(
+     model, optimizer, training_dataloader, scheduler
+ )

  for batch in training_dataloader:
      optimizer.zero_grad()
      inputs, targets = batch
-     inputs = inputs.to(device)
-     targets = targets.to(device)
      outputs = model(inputs)
      loss = loss_function(outputs, targets)
+     accelerator.backward(loss)
      optimizer.step()
      scheduler.step()
  1. 在訓練指令碼的開頭匯入並例項化 Accelerator 類。Accelerator 類會初始化分散式訓練所需的一切,並根據程式碼的啟動方式自動檢測您的訓練環境(例如,單 GPU 的機器、多 GPU 的機器、多臺多 GPU 的機器或 TPU)。
from accelerate import Accelerator

accelerator = Accelerator()
  1. 移除模型和輸入資料上的 .cuda() 等呼叫。Accelerator 類會自動將這些物件放置到適當的裝置上。

這一步是**可選的**,但被認為是最佳實踐,讓 Accelerate 來處理裝置放置。您也可以在初始化 Accelerator 時傳遞 device_placement=False 來停用自動裝置放置。如果您想使用 .to(device) 顯式地將物件放置在裝置上,請確保使用 accelerator.device。例如,如果在將模型放置到 accelerator.device 之前建立最佳化器,在 TPU 上的訓練會失敗。

Accelerate 預設情況下不對其自動裝置放置使用非阻塞傳輸,這可能導致不希望的 CUDA 同步。您可以透過在初始化 Accelerator 時,傳遞一個將 non_blocking=True 設定為 dataloader_configDataLoaderConfiguration 來啟用非阻塞傳輸。像往常一樣,非阻塞傳輸只有在 dataloader 也設定了 pin_memory=True 時才能工作。請注意,從 GPU 到 CPU 使用非阻塞傳輸可能會導致不正確的結果,如果這導致 CPU 操作在未準備好的張量上執行。

device = accelerator.device
  1. 將所有相關的 PyTorch 訓練物件(最佳化器、模型、資料載入器、學習率排程器)在建立後立即傳遞給 prepare() 方法。該方法會將模型包裝在一個為您的分散式設定最佳化的容器中,使用 Accelerate 版本的最佳化器和排程器,併為您的資料載入器建立一個分片版本,以便在 GPU 或 TPU 之間分發。
model, optimizer, train_dataloader, lr_scheduler = accelerator.prepare(
    model, optimizer, train_dataloader, lr_scheduler
)
  1. loss.backward() 替換為 backward(),以使用適合您訓練設定的正確 backward() 方法。
accelerator.backward(loss)

閱讀 Accelerate 的內部機制 指南,瞭解更多關於 Accelerate 如何適配您的程式碼的詳細資訊。

分散式評估

要執行分散式評估,請將您的驗證資料載入器傳遞給 prepare() 方法。

validation_dataloader = accelerator.prepare(validation_dataloader)

分散式設定中的每個裝置只接收一部分評估資料,這意味著您應該使用 gather_for_metrics() 方法將您的預測結果彙總在一起。該方法要求每個程序上的所有張量大小相同,因此如果您的張量在每個程序上的大小不同(例如,在一個批次中動態填充到最大長度),您應該使用 pad_across_processes() 方法將您的張量填充到所有程序中的最大尺寸。請注意,張量需要是 1D 的,並且我們沿第一個維度連線張量。

for inputs, targets in validation_dataloader:
    predictions = model(inputs)
    # Gather all predictions and targets
    all_predictions, all_targets = accelerator.gather_for_metrics((predictions, targets))
    # Example of use with a *Datasets.Metric*
    metric.add_batch(all_predictions, all_targets)

對於更復雜的情況(例如 2D 張量、不想連線張量、包含 3D 張量的字典),您可以在 gather_for_metrics 中傳遞 use_gather_object=True。這將返回收集後的物件列表。請注意,在 GPU 張量上使用它支援不佳且效率低下。

資料集末尾的資料可能會被複制,以便批次可以平均分配給所有工作程序。gather_for_metrics() 方法會自動刪除重複的資料,以計算更準確的指標。

大模型推理

Accelerate 的大模型推理有兩個主要功能,init_empty_weights()load_checkpoint_and_dispatch(),用於載入通常無法裝入記憶體的大型模型進行推理。

請檢視處理大模型推理指南,以更好地瞭解大模型推理的內部工作原理。

空權重初始化

init_empty_weights() 上下文管理器透過建立一個*模型骨架*,並在每次建立引數時將其移動和放置到 PyTorch 的 **meta** 裝置上,來初始化任意大小的模型。這樣,並非所有權重都立即載入,每次只有一小部分模型載入到記憶體中。

例如,載入一個空的 Mixtral-8x7B 模型比在 CPU 上完全載入模型和權重所需的記憶體要少得多。

from accelerate import init_empty_weights
from transformers import AutoConfig, AutoModelForCausalLM

config = AutoConfig.from_pretrained("mistralai/Mixtral-8x7B-Instruct-v0.1")
with init_empty_weights():
    model = AutoModelForCausalLM.from_config(config)

載入並分派權重

load_checkpoint_and_dispatch() 函式將完整的或分片的檢查點載入到空模型中,並自動將權重分佈到所有可用的裝置上。

device_map 引數決定了每個模型層的放置位置,指定為 "auto" 會首先將它們放置在 GPU 上,然後是 CPU,如果記憶體仍然不足,則最後作為記憶體對映張量放置在硬碟上。使用 no_split_module_classes 引數來指示哪些模組不應跨裝置拆分(通常是那些具有殘差連線的模組)。

from accelerate import load_checkpoint_and_dispatch

model_checkpoint = "your-local-model-folder"
model = load_checkpoint_and_dispatch(
    model, checkpoint=model_checkpoint, device_map="auto", no_split_module_classes=['Block']
)

下一步

既然您已經瞭解了 Accelerate 的主要功能,您的下一步可以包括

  • 檢視教程,以溫和地瞭解 Accelerate。如果您是分散式訓練和該庫的新手,這將特別有用。
  • 深入研究指南,瞭解如何在特定用例中使用 Accelerate。
  • 透過閱讀概念指南,加深對 Accelerate 內部工作原理的理解。
  • API 參考中查詢類和命令,以檢視可用的引數和選項。
< > 在 GitHub 上更新

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