本文翻譯了 Getting Started 和 Installation Details 和 CIFAR-10 Tutorial 三個(gè)教程,可以讓新手安裝和簡單使用上 DeepSpeed 來做模型訓(xùn)練。
0x0. 前言
這個(gè)系列是對DeepSpeed的教程做一下翻譯工作,在DeepSpeed的Tutorials中提供了34個(gè)Tutorials。這些Tutorials不僅包含配置DeepSpeed完成分布式訓(xùn)練的標(biāo)準(zhǔn)流程,還包含一些DeepSpeed支持的一些Feature比如低比特優(yōu)化器,Zero等等。最近有使用DeepSpeed做一些簡單的模型訓(xùn)練實(shí)驗(yàn)的需求,所以開一下這個(gè)專題,盡量翻譯完DeepSpeed的大多數(shù)Tutorials,不定期更新。這篇首先翻譯一下Getting Started 和 Installation Details,CIFAR-10 Tutorial 這三個(gè)Tutorials。基于 PyTorch 2.0 版本運(yùn)行 CIFAR-10 Tutorial 中碰到一些報(bào)錯(cuò)也給出了解決的方法。
0x1. Getting Started
安裝
安裝DeepSpeed非常簡單,只需運(yùn)行以下命令:pip install deepspeed。有關(guān)更多詳細(xì)信息,請參閱官方文檔,也就是稍后會(huì)翻譯的文檔。
要在AzureML上開始使用DeepSpeed,請參閱AzureML Examples GitHub。這里的鏈接404了。
DeepSpeed與HuggingFace Transformers和PyTorch Lightning進(jìn)行了直接集成。HuggingFace Transformers用戶現(xiàn)在可以通過簡單的--deepspeed標(biāo)志和配置文件輕松加速他們的模型。有關(guān)更多詳細(xì)信息,請參見官方文檔。PyTorch Lightning通過Lightning Trainer提供了對DeepSpeed的易于訪問。有關(guān)更多詳細(xì)信息,請參見官方文檔。
DeepSpeed在AMD上可通過我們的ROCm鏡像使用,例如docker pull deepspeed/rocm501:ds060_pytorch110。
編寫DeepSpeed模型
使用DeepSpeed引擎進(jìn)行模型訓(xùn)練。引擎可以包裝任何類型為torch.nn.module的模型,并具有一組最小的API來訓(xùn)練和保存模型檢查點(diǎn)。請參見教程以獲取詳細(xì)示例。
要初始化DeepSpeed引擎:
model_engine,optimizer,_,_=deepspeed.initialize(args=cmd_args, model=model, model_parameters=params)
deepspeed.initialize確保在底層適當(dāng)?shù)赝瓿闪怂璧姆植际綌?shù)據(jù)并行或混合精度訓(xùn)練所需的所有設(shè)置。除了包裝模型外,DeepSpeed還可以基于傳遞給deepspeed.initialize和DeepSpeed配置文件(https://www.deepspeed.ai/getting-started/#deepspeed-configuration)的參數(shù)構(gòu)建和管理訓(xùn)練優(yōu)化器、數(shù)據(jù)加載器和學(xué)習(xí)率調(diào)度器。請注意,DeepSpeed會(huì)在每個(gè)訓(xùn)練步驟自動(dòng)執(zhí)行學(xué)習(xí)率調(diào)度。
如果你已經(jīng)設(shè)置了分布式環(huán)境,則需要進(jìn)行以下替換:
torch.distributed.init_process_group(...)
替換為:
deepspeed.init_distributed()
默認(rèn)情況下,DeepSpeed使用已經(jīng)經(jīng)過充分測試的NCCL后端,但您也可以覆蓋默認(rèn)設(shè)置(https://deepspeed.readthedocs.io/en/latest/initialize.html#distributed-initialization)。但是,如果直到deepspeed.initialize()之后才需要設(shè)置分布式環(huán)境,則無需使用此函數(shù),因?yàn)镈eepSpeed將在其初始化期間自動(dòng)初始化分布式環(huán)境。無論如何,你都需要?jiǎng)h除torch.distributed.init_process_group。
訓(xùn)練
一旦DeepSpeed引擎被初始化,就可以使用三個(gè)簡單的API來進(jìn)行前向傳播(callable object)、反向傳播(backward)和權(quán)重更新(step)來訓(xùn)練模型。
forstep,batchinenumerate(data_loader): #forward()method loss=model_engine(batch) #runsbackpropagation model_engine.backward(loss) #weightupdate model_engine.step()
Gradient Averaging: 在分布式數(shù)據(jù)并行訓(xùn)練中,backward 確保在對一個(gè) train_batch_size 進(jìn)行訓(xùn)練后,梯度在數(shù)據(jù)并行進(jìn)程間進(jìn)行平均。
Loss Scaling: 在FP16/混合精度訓(xùn)練中, DeepSpeed 引擎會(huì)自動(dòng)處理縮放損失,以避免梯度中的精度損失。
Learning Rate Scheduler: 當(dāng)使用 DeepSpeed 的學(xué)習(xí)率調(diào)度器(在ds_config.json文件中指定)時(shí), DeepSpeed 會(huì)在每次訓(xùn)練步驟(執(zhí)行model_engine.step()時(shí))調(diào)用調(diào)度器的step()方法。當(dāng)不使用DeepSpeed的學(xué)習(xí)率調(diào)度器時(shí):
如果調(diào)度期望在每次訓(xùn)練步驟都執(zhí)行, 那么用戶可以在初始化 DeepSpeed 引擎時(shí)將調(diào)度器傳遞給 deepspeed.initialize, 讓 DeepSpeed 進(jìn)行管理、更新或保存/恢復(fù)。
如果調(diào)度應(yīng)該在任何其它間隔(例如訓(xùn)練周期)執(zhí)行,則用戶在初始化期間不應(yīng)將調(diào)度傳遞給 DeepSpeed,必須顯式地管理它。
模型檢查點(diǎn)
使用 DeepSpeed 中的 save_checkpoint 和 load_checkpoint API 處理訓(xùn)練狀態(tài)的保存和加載,需要提供兩個(gè)參數(shù)來唯一識別一個(gè)檢查點(diǎn):
ckpt_dir: 檢查點(diǎn)將保存到此目錄。
ckpt_id:在目錄中唯一標(biāo)識檢查點(diǎn)的標(biāo)識符。在下面的代碼片段中,我們使用損失值作為檢查點(diǎn)標(biāo)識符。
#loadcheckpoint _,client_sd=model_engine.load_checkpoint(args.load_dir,args.ckpt_id) step=client_sd['step'] #advancedataloadertockptstep dataloader_to_step(data_loader,step+1) forstep,batchinenumerate(data_loader): #forward()method loss=model_engine(batch) #runsbackpropagation model_engine.backward(loss) #weightupdate model_engine.step() #savecheckpoint ifstep%args.save_interval: client_sd['step']=step ckpt_id=loss.item() model_engine.save_checkpoint(args.save_dir,ckpt_id,client_sd=client_sd)
DeepSpeed 可以自動(dòng)保存和恢復(fù)模型、優(yōu)化器和學(xué)習(xí)率調(diào)度器的狀態(tài),同時(shí)隱藏這些細(xì)節(jié),使用戶無需關(guān)心。然而,用戶可能希望保存與給定模型訓(xùn)練相關(guān)的其他數(shù)據(jù)。為了支持這些項(xiàng)目,save_checkpoint 接受一個(gè)客戶端狀態(tài)字典 client_sd 用于保存。這些元素可以作為返回參數(shù)從 load_checkpoint 中檢索。在上面的示例中,步驟值 (step) 被存儲為 client_sd 的一部分。
重要提示:所有進(jìn)程都必須調(diào)用此方法,而不僅僅是rank 0的進(jìn)程。這是因?yàn)槊總€(gè)進(jìn)程都需要保存其主節(jié)點(diǎn)權(quán)重和調(diào)度器+優(yōu)化器狀態(tài)。如果僅為rank 0的進(jìn)程調(diào)用此方法,它將掛起等待與其它進(jìn)程同步。
DeepSpeed 配置
可以使用一個(gè)配置 JSON 文件來啟用、禁用或配置 DeepSpeed 功能,該文件應(yīng)該作為 args.deepspeed_config 指定。下面是一個(gè)示例配置文件。有關(guān)完整功能集,請參見 API 文檔(https://www.deepspeed.ai/docs/config-json/) 。
{ "train_batch_size": 8, "gradient_accumulation_steps": 1, "optimizer": { "type": "Adam", "params": { "lr": 0.00015 } }, "fp16": { "enabled": true }, "zero_optimization": true }
加載 DeepSpeed 訓(xùn)練
DeepSpeed 安裝了入口點(diǎn) deepspeed 以啟動(dòng)分布式訓(xùn)練。我們通過以下假設(shè)來說明 DeepSpeed 的一個(gè)示例用法:
你已將 DeepSpeed 集成到你的模型中了。
client_entry.py 是你的模型入口腳本。
client args 是 argparse 命令行參數(shù)。
ds_config.json 是 DeepSpeed 的配置參數(shù)。
資源配置
DeepSpeed 使用與 OpenMPI 和 Horovod 兼容的 hostfile 配置多節(jié)點(diǎn)計(jì)算資源。hostfile 是一個(gè)主機(jī)名(或 SSH 別名)列表,這些機(jī)器可以通過無密碼 SSH 訪問,并且還包括 slot counts,用于指定系統(tǒng)上可用的 GPU 數(shù)量。例如:
worker-1 slots=4 worker-2 slots=4
上述示例指定了兩個(gè)名為 worker-1 和 worker-2 的機(jī)器,每臺機(jī)器都有四個(gè) GPU 用于訓(xùn)練。
可以使用 --hostfile 命令行選項(xiàng)指定 hostfile。如果沒有指定 hostfile,則 DeepSpeed 會(huì)搜索 /job/hostfile 。如果沒有指定或找到 hostfile,則 DeepSpeed 查詢本地計(jì)算機(jī)上的 GPU 數(shù)量,以發(fā)現(xiàn)可用的本地 slot 數(shù)量。
下面的命令在 myhostfile 中指定的所有可用節(jié)點(diǎn)和 GPU 上啟動(dòng) PyTorch 訓(xùn)練工作:
deepspeed --hostfile=myhostfile--deepspeed --deepspeed_config ds_config.json
另外,DeepSpeed 允許您將模型的分布式訓(xùn)練限制在可用節(jié)點(diǎn)和 GPU 的子集上。此功能通過兩個(gè)命令行參數(shù)啟用:--num_nodes 和 --num_gpus。例如,可以使用以下命令將分布式訓(xùn)練限制為僅使用兩個(gè)節(jié)點(diǎn):
deepspeed--num_nodes=2--deepspeed--deepspeed_configds_config.json
您也可以使用 --include 和 --exclude 標(biāo)志來包含或排除特定的資源。例如,要使用除節(jié)點(diǎn) worker-2 上的 GPU 0 和節(jié)點(diǎn) worker-3 上的 GPU 0 和 1 之外的所有可用資源:
deepspeed --exclude="worker-2:0@worker-3:0,1"--deepspeed --deepspeed_config ds_config.json
類似地,可以僅在 worker-2 上使用 GPU 0 和 1:
deepspeed --include="worker-2:0,1"--deepspeed --deepspeed_config ds_config.json
多節(jié)點(diǎn)環(huán)境變量
當(dāng)在多個(gè)節(jié)點(diǎn)上進(jìn)行訓(xùn)練時(shí),我們發(fā)現(xiàn)支持傳播用戶定義的環(huán)境變量非常有用。默認(rèn)情況下,DeepSpeed 將傳播所有設(shè)置的 NCCL 和 PYTHON 相關(guān)環(huán)境變量。如果您想傳播其它變量,可以在名為 .deepspeed_env 的文件中指定它們,該文件包含一個(gè)行分隔的 VAR=VAL 條目列表。DeepSpeed 啟動(dòng)器將查找你執(zhí)行的本地路徑以及你的主目錄(~/)。
以一個(gè)具體的例子來說明,有些集群需要在訓(xùn)練之前設(shè)置特殊的 NCCL 變量。用戶可以簡單地將這些變量添加到其主目錄中的 .deepspeed_env 文件中,該文件如下所示:
NCCL_IB_DISABLE=1 NCCL_SOCKET_IFNAME=eth0
DeepSpeed 然后會(huì)確保在啟動(dòng)每個(gè)進(jìn)程時(shí)在整個(gè)訓(xùn)練工作的每個(gè)節(jié)點(diǎn)上設(shè)置這些環(huán)境變量。
MPI 和 AzureML 兼容性
如上所述,DeepSpeed 提供了自己的并行啟動(dòng)器來幫助啟動(dòng)多節(jié)點(diǎn)/多GPU訓(xùn)練作業(yè)。如果您喜歡使用MPI(例如 mpirun)啟動(dòng)訓(xùn)練作業(yè),則我們提供對此的支持。需要注意的是,DeepSpeed 仍將使用 torch 分布式 NCCL 后端,而不是 MPI 后端。
要使用 mpirun + DeepSpeed 或 AzureML(使用 mpirun 作為啟動(dòng)器后端)啟動(dòng)你的訓(xùn)練作業(yè),您只需要安裝 mpi4py Python 包。DeepSpeed 將使用它來發(fā)現(xiàn) MPI 環(huán)境,并將必要的狀態(tài)(例如 world size、rank 等)傳遞給 torch 分布式后端。
如果你正在使用模型并行,Pipline 并行或者在調(diào)用 deepspeed.initialize(..) 之前需要使用 torch.distributed 調(diào)用,我們?yōu)槟闾峁┝祟~外的 DeepSpeed API 調(diào)用以支持相同的 MPI。請將您的初始 torch.distributed.init_process_group(..) 調(diào)用替換為:
deepspeed.init_distributed()
資源配置(單節(jié)點(diǎn))
如果我們只在單個(gè)節(jié)點(diǎn)上運(yùn)行(具有一個(gè)或多個(gè)GPU),DeepSpeed不需要像上面描述的那樣使用 hostfile。如果沒有檢測到或傳遞 hostfile,則 DeepSpeed 將查詢本地計(jì)算機(jī)上的 GPU 數(shù)量來發(fā)現(xiàn)可用的插槽數(shù)。--include 和 --exclude 參數(shù)與正常工作相同,但用戶應(yīng)將“l(fā)ocalhost”指定為主機(jī)名。
另外需要注意的是,CUDA_VISIBLE_DEVICES 不能用于 DeepSpeed 來控制應(yīng)該使用哪些設(shè)備。例如,要僅使用當(dāng)前節(jié)點(diǎn)的 gpu1,請執(zhí)行以下操作:
deepspeed--includelocalhost:1...
0x2. Installation Details
對應(yīng)原文:https://www.deepspeed.ai/tutorials/advanced-install/
安裝細(xì)節(jié)
通過 pip 是最快捷的開始使用 DeepSpeed 的方式,這將安裝最新版本的 DeepSpeed,不會(huì)與特定的 PyTorch 或 CUDA 版本綁定。DeepSpeed 包含若干個(gè) C++/CUDA 擴(kuò)展,我們通常稱之為“ops”。默認(rèn)情況下,所有這些 extensions/ops 將使用 torch 的 JIT C++ 擴(kuò)展加載器即時(shí)構(gòu)建(JIT)(https://pytorch.org/docs/stable/cpp_extension.html) ,該加載器依賴 ninja 在運(yùn)行時(shí)進(jìn)行動(dòng)態(tài)鏈接。
pip install deepspeed
安裝完成后,你可以使用 ds_report 或 python -m deepspeed.env_report 命令查看 DeepSpeed 環(huán)境報(bào)告,以驗(yàn)證你的安裝并查看你的機(jī)器與哪些 ops 兼容。我們發(fā)現(xiàn),在調(diào)試 DeepSpeed 安裝或兼容性問題時(shí),這個(gè)報(bào)告很有用。
ds_report
預(yù)安裝DeepSpeed的Ops
注意:在預(yù)編譯任何 DeepSpeed 的 c++/cuda ops 之前,必須先安裝 PyTorch。但是,如果使用 ops 的默認(rèn) JIT 編譯模式,則不需要預(yù)編譯安裝。
有時(shí)我們發(fā)現(xiàn),將一些或全部 DeepSpeed C++/CUDA ops 預(yù)先安裝而不使用 JIT 編譯路徑是有用的。為了支持預(yù)安裝,我們引入了構(gòu)建環(huán)境標(biāo)志以打開/關(guān)閉特定 ops 的構(gòu)建。
您可以通過設(shè)置 DS_BUILD_OPS 環(huán)境變量為 1 來指示我們的安裝程序(install.sh 或 pip install)嘗試安裝所有 ops,例如:
DS_BUILD_OPS=1 pip install deepspeed
DeepSpeed 只會(huì)安裝與你的機(jī)器兼容的 ops。有關(guān)系統(tǒng)兼容性的更多詳細(xì)信息,請嘗試上面描述的 ds_report 工具。
如果你只想安裝特定的 op(例如 FusedLamb),你可以在安裝時(shí)使用 DS_BUILD 環(huán)境變量進(jìn)行切換。例如,要僅安裝帶有 FusedLamb op 的 DeepSpeed,請使用:
DS_BUILD_FUSED_LAMB=1 pip install deepspeed
可用的 DS_BUILD 選項(xiàng)包含:
DS_BUILD_OPS 切換所有 ops
DS_BUILD_CPU_ADAM 構(gòu)建 CPUAdam op
DS_BUILD_FUSED_ADAM 構(gòu)建 FusedAdam op (from apex)
DS_BUILD_FUSED_LAMB 構(gòu)建 FusedLamb op
DS_BUILD_SPARSE_ATTN 構(gòu)建 sparse attention op
DS_BUILD_TRANSFORMER 構(gòu)建 transformer op
DS_BUILD_TRANSFORMER_INFERENCE 構(gòu)建 transformer-inference op
DS_BUILD_STOCHASTIC_TRANSFORMER 構(gòu)建 stochastic transformer op
DS_BUILD_UTILS 構(gòu)建各種優(yōu)化工具
DS_BUILD_AIO 構(gòu)建異步 (NVMe) I/O op
為了加速 build-all 過程,您可以使用以下方式并行編譯:
DS_BUILD_OPS=1 pip install deepspeed --global-option="build_ext" --global-option="-j8"
這應(yīng)該可以使完整構(gòu)建過程加快 2-3 倍。您可以調(diào)整 -j 來指定在構(gòu)建過程中使用多少個(gè) CPU 核心。在此示例中,它設(shè)置為 8 個(gè)核心。
你還可以構(gòu)建二進(jìn)制 whell,并在具有相同類型的 GPU 和相同軟件環(huán)境(CUDA 工具包、PyTorch、Python 等)的多臺機(jī)器上安裝它。
DS_BUILD_OPS=1 python setup.py build_ext -j8 bdist_wheel
這將在 dist 目錄下創(chuàng)建一個(gè) PyPI 二進(jìn)制輪,例如 dist/deepspeed-0.3.13+8cd046f-cp38-cp38-linux_x86_64.whl,然后你可以直接在多臺機(jī)器上安裝它,在我們的示例中:
pip install dist/deepspeed-0.3.13+8cd046f-cp38-cp38-linux_x86_64.whl
源碼安裝 DeepSpeed
在從 GitHub 克隆 DeepSpeed 倉庫后,您可以通過 pip 在 JIT 模式下安裝 DeepSpeed(見下文)。由于不編譯任何 C++/CUDA 源文件,此安裝過程應(yīng)該很快完成。
pip install .
對于跨多個(gè)節(jié)點(diǎn)的安裝,我們發(fā)現(xiàn)使用 github 倉庫中的 install.sh (https://github.com/microsoft/DeepSpeed/blob/master/install.sh) 腳本安裝 DeepSpeed 很有用。這將在本地構(gòu)建一個(gè) Python whell,并將其復(fù)制到你的主機(jī)文件(通過 --hostfile 給出,或默認(rèn)為 /job/hostfile)中列出的所有節(jié)點(diǎn)上。
當(dāng)使用 DeepSpeed 的代碼首次運(yùn)行時(shí),它將自動(dòng)構(gòu)建僅運(yùn)行所需的 CUDA 擴(kuò)展,并默認(rèn)將它們放置在 ~/.cache/torch_extensions/ 目錄下。下一次執(zhí)行相同的程序時(shí),這些已預(yù)編譯的擴(kuò)展將從該目錄加載。
如果你使用多個(gè)虛擬環(huán)境,則可能會(huì)出現(xiàn)問題,因?yàn)槟J(rèn)情況下只有一個(gè) torch_extensions 目錄,但不同的虛擬環(huán)境可能使用不同的設(shè)置(例如,不同的 python 或 cuda 版本),然后加載另一個(gè)環(huán)境構(gòu)建的 CUDA 擴(kuò)展將失敗。因此,如果需要,你可以使用 TORCH_EXTENSIONS_DIR 環(huán)境變量覆蓋默認(rèn)位置。因此,在每個(gè)虛擬環(huán)境中,你可以將其指向一個(gè)唯一的目錄,并且 DeepSpeed 將使用它來保存和加載 CUDA 擴(kuò)展。
你還可以在特定運(yùn)行中更改它,使用:
TORCH_EXTENSIONS_DIR=./torch-extensions deepspeed ...
選擇正確的架構(gòu)進(jìn)行構(gòu)建
如果你在運(yùn)行 DeepSpeed 時(shí)遇到以下錯(cuò)誤:
RuntimeError: CUDA error: no kernel image is available for execution on the device
這意味著 CUDA 擴(kuò)展沒有為你嘗試使用的卡構(gòu)建。
從源代碼構(gòu)建 DeepSpeed 時(shí),DeepSpeed 將嘗試支持各種架構(gòu),但在 JIT 模式下,它只支持在構(gòu)建時(shí)可見的架構(gòu)。
你可以通過設(shè)置 TORCH_CUDA_ARCH_LIST 環(huán)境變量來專門為所需的一系列架構(gòu)構(gòu)建:
TORCH_CUDA_ARCH_LIST="6.1;7.5;8.6" pip install ...
當(dāng)你為更少的架構(gòu)構(gòu)建時(shí),這也會(huì)使構(gòu)建更快。
這也是為了確保使用你的確切架構(gòu)而建議的。由于各種技術(shù)原因,分布式的 PyTorch 二進(jìn)制文件沒有完全支持所有架構(gòu),跳過兼容的二進(jìn)制文件可能會(huì)導(dǎo)致未充分利用你的完整卡的計(jì)算能力。要查看 deepspeed 來源構(gòu)建中包含哪些架構(gòu) - 保存日志并搜索 -gencode 參數(shù)。
完整的 NVIDIA GPU 列表及其計(jì)算能力可以在這里 (https://developer.nvidia.com/cuda-gpus) 找到。
CUDA 版本不匹配
如果在運(yùn)行時(shí)碰到以下錯(cuò)誤:
Exception: >- DeepSpeed Op Builder: Installed CUDA version {VERSION} does not match the version torch was compiled with {VERSION}, unable to compile cuda/cpp extensions without a matching cuda version.
你安裝的 CUDA 版本與用于編譯 torch 的 CUDA 版本不匹配。我們僅需要主版本匹配(例如,11.1 和 11.8 是可以的)。但是,主版本不匹配可能會(huì)導(dǎo)致意外的行為和錯(cuò)誤。
解決此錯(cuò)誤的最簡單方法是更改已安裝的 CUDA 版本(使用 nvcc --version 檢查)或更新 torch 版本以匹配已安裝的 CUDA 版本(使用 python3 -c "import torch; print(torch.version)" 檢查)。
如果你想跳過此檢查并繼續(xù)使用不匹配的 CUDA 版本,請使用以下環(huán)境變量:
DS_SKIP_CUDA_CHECK=1
針對特定功能的依賴項(xiàng)
一些 DeepSpeed 功能需要 DeepSpeed 的一般依賴項(xiàng)之外的特定依賴項(xiàng)。
有關(guān)每個(gè)功能/op 的 Python 包依賴項(xiàng),請參閱我們的 requirements 目錄(https://github.com/microsoft/DeepSpeed/tree/master/requirements)。
我們盡力將系統(tǒng)級依賴項(xiàng)最小化,但某些功能需要特殊的系統(tǒng)級軟件包。請查看我們的 ds_report 工具輸出,以查看您是否缺少給定功能的系統(tǒng)級軟件包。
0x3. CIFAR-10 Tutorial
如果你還沒有閱讀入門指南,我們建議你先閱讀入門指南(就是上面2節(jié)),然后再按照本教程逐步操作。
在本教程中,我們將向 CIFAR-10 模型中添加 DeepSpeed,這是一個(gè)小型圖像分類模型。
首先,我們將介紹如何運(yùn)行原始的 CIFAR-10 模型。然后,我們將逐步啟用此模型以在 DeepSpeed 中運(yùn)行。
運(yùn)行原始的 CIFAR-10
CIFAR-10 教程的原始模型代碼見(https://github.com/pytorch/tutorials/blob/main/beginner_source/blitz/cifar10_tutorial.py)。我們已將其復(fù)制到 DeepSpeedExamples/training/cifar/ (https://github.com/microsoft/DeepSpeedExamples/tree/master/training/cifar)下,并作為子模塊提供。要下載,請執(zhí)行:
git clone git@github.com:microsoft/DeepSpeedExamples.git
安裝 CIFAR-10 模型的 requirements:
cd DeepSpeedExamples/training/cifar pip install -r requirements.txt
運(yùn)行 python cifar10_tutorial.py,它會(huì)在第一次運(yùn)行時(shí)下載訓(xùn)練數(shù)據(jù)集。
Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data/cifar-10-python.tar.gz 170500096it [00:02, 61124868.24it/s] Extracting ./data/cifar-10-python.tar.gz to ./data Files already downloaded and verified cat frog frog frog [1, 2000] loss: 2.170 [1, 4000] loss: 1.879 [1, 6000] loss: 1.690 [1, 8000] loss: 1.591 [1, 10000] loss: 1.545 [1, 12000] loss: 1.467 [2, 2000] loss: 1.377 [2, 4000] loss: 1.374 [2, 6000] loss: 1.363 [2, 8000] loss: 1.322 [2, 10000] loss: 1.295 [2, 12000] loss: 1.287 Finished Training GroundTruth: cat ship ship plane Predicted: cat ship plane plane Accuracy of the network on the 10000 test images: 53 % Accuracy of plane : 69 % Accuracy of car : 59 % Accuracy of bird : 56 % Accuracy of cat : 36 % Accuracy of deer : 37 % Accuracy of dog : 26 % Accuracy of frog : 70 % Accuracy of horse : 61 % Accuracy of ship : 51 % Accuracy of truck : 63 % cuda:0
我這里本地使用torch 2.0版本,運(yùn)行這個(gè)腳本會(huì)報(bào)錯(cuò)。AttributeError: '_MultiProcessingDataLoaderIter' object has no attribute 'next' 。這個(gè)錯(cuò)誤通常發(fā)生在使用 PyTorch 1.7 及更高版本時(shí),因?yàn)樵谶@些版本中,.next() 方法被棄用了,并被 .__next__() 方法取代了。因此,你可以把代碼中的2處 .next() 替換成 .next()來解決這個(gè)錯(cuò)誤。
使能 DeepSpeed
參數(shù)解析
使能 DeepSpeed 的第一步是向 CIFAR-10 模型添加 DeepSpeed 參數(shù),可以使用以下方式的 deepspeed.add_config_arguments() 函數(shù):
importargparse importdeepspeed defadd_argument(): parser=argparse.ArgumentParser(description='CIFAR') #Data. #Cuda. parser.add_argument('--with_cuda',default=False,action='store_true', help='useCPUincasethere'snoGPUsupport') parser.add_argument('--use_ema',default=False,action='store_true', help='whetheruseexponentialmovingaverage') #Train. parser.add_argument('-b','--batch_size',default=32,type=int, help='mini-batchsize(default:32)') parser.add_argument('-e','--epochs',default=30,type=int, help='numberoftotalepochs(default:30)') parser.add_argument('--local_rank',type=int,default=-1, help='localrankpassedfromdistributedlauncher') #IncludeDeepSpeedconfigurationarguments. parser=deepspeed.add_config_arguments(parser) args=parser.parse_args() returnargs
初始化
我們使用 deepspeed.initialize 創(chuàng)建 model_engine、optimizer 和 trainloader,deepspeed.initialize 的定義如下:
definitialize(args, model, optimizer=None, model_params=None, training_data=None, lr_scheduler=None, mpu=None, dist_init_required=True, collate_fn=None):
在這里,我們使用 CIFAR-10 模型(net)、args、parameters 和 trainset 初始化 DeepSpeed:
parameters=filter(lambdap:p.requires_grad,net.parameters()) args=add_argument() #InitializeDeepSpeedtousethefollowingfeatures #1)Distributedmodel. #2)Distributeddataloader. #3)DeepSpeedoptimizer. model_engine,optimizer,trainloader,_=deepspeed.initialize(args=args,model=net,model_parameters=parameters,training_data=trainset)
初始化 DeepSpeed 后,原始 device 和 optimizer 會(huì)被刪除:
#fromdeepspeed.acceleratorimportget_accelerator #device=torch.device(get_accelerator().device_name(0)ifget_accelerator().is_available()else"cpu") #net.to(device) #optimizer=optim.SGD(net.parameters(),lr=0.001,momentum=0.9)
訓(xùn)練API
deepspeed.initialize 返回的模型是 DeepSpeed 模型引擎,我們將使用它來使用 forward、backward 和 step API 訓(xùn)練模型。
fori,datainenumerate(trainloader): #Gettheinputs;dataisalistof[inputs,labels]. inputs=data[0].to(model_engine.device) labels=data[1].to(model_engine.device) outputs=model_engine(inputs) loss=criterion(outputs,labels) model_engine.backward(loss) model_engine.step()
在使用 mini-batch 更新權(quán)重之后,DeepSpeed 會(huì)自動(dòng)處理梯度清零。
配置
使用 DeepSpeed 的下一步是創(chuàng)建一個(gè)配置 JSON 文件 (ds_config.json)。該文件提供由用戶定義的 DeepSpeed 特定參數(shù),例如批2?大小、優(yōu)化器、調(diào)度器和其他參數(shù)。
{ "train_batch_size": 4, "steps_per_print": 2000, "optimizer": { "type": "Adam", "params": { "lr": 0.001, "betas": [ 0.8, 0.999 ], "eps": 1e-8, "weight_decay": 3e-7 } }, "scheduler": { "type": "WarmupLR", "params": { "warmup_min_lr": 0, "warmup_max_lr": 0.001, "warmup_num_steps": 1000 } }, "wall_clock_breakdown": false }
運(yùn)行啟用 DeepSpeed 的 CIFAR-10 模型
要使用 DeepSpeed 開始訓(xùn)練已應(yīng)用 DeepSpeed 的 CIFAR-10 模型,請執(zhí)行以下命令,默認(rèn)情況下它將使用所有檢測到的 GPU。
deepspeed cifar10_deepspeed.py --deepspeed_config ds_config.json
DeepSpeed 通常會(huì)打印更多的訓(xùn)練細(xì)節(jié)供用戶監(jiān)視,包括訓(xùn)練設(shè)置、性能統(tǒng)計(jì)和損失趨勢。
deepspeed.pt cifar10_deepspeed.py --deepspeed_config ds_config.json Warning: Permanently added '[192.168.0.22]:42227' (ECDSA) to the list of known hosts. cmd=['pdsh', '-w', 'worker-0', 'export NCCL_VERSION=2.4.2; ', 'cd /data/users/deepscale/test/ds_v2/examples/cifar;', '/usr/bin/python', '-u', '-m', 'deepspeed.pt.deepspeed_launch', '--world_info=eyJ3b3JrZXItMCI6IFswXX0=', '--node_rank=%n', '--master_addr=192.168.0.22', '--master_port=29500', 'cifar10_deepspeed.py', '--deepspeed', '--deepspeed_config', 'ds_config.json'] worker-0: Warning: Permanently added '[192.168.0.22]:42227' (ECDSA) to the list of known hosts. worker-0: 0 NCCL_VERSION 2.4.2 worker-0: WORLD INFO DICT: {'worker-0': [0]} worker-0: nnodes=1, num_local_procs=1, node_rank=0 worker-0: global_rank_mapping=defaultdict(, {'worker-0': [0]}) worker-0: dist_world_size=1 worker-0: Setting CUDA_VISIBLE_DEVICES=0 worker-0: Files already downloaded and verified worker-0: Files already downloaded and verified worker-0: bird car horse ship worker-0: DeepSpeed info: version=2.1, git-hash=fa937e7, git-branch=master worker-0: [INFO 2020-02-06 1949] Set device to local rank 0 within node. worker-0: 1 1 worker-0: [INFO 2020-02-06 1956] Using DeepSpeed Optimizer param name adam as basic optimizer worker-0: [INFO 2020-02-06 1956] DeepSpeed Basic Optimizer = FusedAdam ( worker-0: Parameter Group 0 worker-0: betas: [0.8, 0.999] worker-0: bias_correction: True worker-0: eps: 1e-08 worker-0: lr: 0.001 worker-0: max_grad_norm: 0.0 worker-0: weight_decay: 3e-07 worker-0: ) worker-0: [INFO 2020-02-06 1956] DeepSpeed using configured LR scheduler = WarmupLR worker-0: [INFO 2020-02-06 1956] DeepSpeed LR Scheduler = worker-0: [INFO 2020-02-06 1956] rank:0 step=0, skipped=0, lr=[0.001], mom=[[0.8, 0.999]] worker-0: DeepSpeedLight configuration: worker-0: allgather_size ............... 500000000 worker-0: allreduce_always_fp32 ........ False worker-0: disable_allgather ............ False worker-0: dump_state ................... False worker-0: dynamic_loss_scale_args ...... None worker-0: fp16_enabled ................. False worker-0: global_rank .................. 0 worker-0: gradient_accumulation_steps .. 1 worker-0: gradient_clipping ............ 0.0 worker-0: initial_dynamic_scale ........ 4294967296 worker-0: loss_scale ................... 0 worker-0: optimizer_name ............... adam worker-0: optimizer_params ............. {'lr': 0.001, 'betas': [0.8, 0.999], 'eps': 1e-08, 'weight_decay': 3e-07} worker-0: prescale_gradients ........... False worker-0: scheduler_name ............... WarmupLR worker-0: scheduler_params ............. {'warmup_min_lr': 0, 'warmup_max_lr': 0.001, 'warmup_num_steps': 1000} worker-0: sparse_gradients_enabled ..... False worker-0: steps_per_print .............. 2000 worker-0: tensorboard_enabled .......... False worker-0: tensorboard_job_name ......... DeepSpeedJobName worker-0: tensorboard_output_path ...... worker-0: train_batch_size ............. 4 worker-0: train_micro_batch_size_per_gpu 4 worker-0: wall_clock_breakdown ......... False worker-0: world_size ................... 1 worker-0: zero_enabled ................. False worker-0: json = { worker-0: "optimizer":{ worker-0: "params":{ worker-0: "betas":[ worker-0: 0.8, worker-0: 0.999 worker-0: ], worker-0: "eps":1e-08, worker-0: "lr":0.001, worker-0: "weight_decay":3e-07 worker-0: }, worker-0: "type":"Adam" worker-0: }, worker-0: "scheduler":{ worker-0: "params":{ worker-0: "warmup_max_lr":0.001, worker-0: "warmup_min_lr":0, worker-0: "warmup_num_steps":1000 worker-0: }, worker-0: "type":"WarmupLR" worker-0: }, worker-0: "steps_per_print":2000, worker-0: "train_batch_size":4, worker-0: "wall_clock_breakdown":false worker-0: } worker-0: [INFO 2020-02-06 1956] 0/50, SamplesPerSec=1292.6411179579866 worker-0: [INFO 2020-02-06 1956] 0/100, SamplesPerSec=1303.6726433398537 worker-0: [INFO 2020-02-06 1956] 0/150, SamplesPerSec=1304.4251022567403 ...... worker-0: [2, 12000] loss: 1.247 worker-0: [INFO 2020-02-06 2023] 0/24550, SamplesPerSec=1284.4954513975558 worker-0: [INFO 2020-02-06 2023] 0/24600, SamplesPerSec=1284.384033658866 worker-0: [INFO 2020-02-06 2023] 0/24650, SamplesPerSec=1284.4433482972925 worker-0: [INFO 2020-02-06 2023] 0/24700, SamplesPerSec=1284.4664449792422 worker-0: [INFO 2020-02-06 2023] 0/24750, SamplesPerSec=1284.4950124403447 worker-0: [INFO 2020-02-06 2023] 0/24800, SamplesPerSec=1284.4756105952233 worker-0: [INFO 2020-02-06 2024] 0/24850, SamplesPerSec=1284.5251526215386 worker-0: [INFO 2020-02-06 2024] 0/24900, SamplesPerSec=1284.531217073863 worker-0: [INFO 2020-02-06 2024] 0/24950, SamplesPerSec=1284.5125323220368 worker-0: [INFO 2020-02-06 2024] 0/25000, SamplesPerSec=1284.5698818883018 worker-0: Finished Training worker-0: GroundTruth: cat ship ship plane worker-0: Predicted: cat car car plane worker-0: Accuracy of the network on the 10000 test images: 57 % worker-0: Accuracy of plane : 61 % worker-0: Accuracy of car : 74 % worker-0: Accuracy of bird : 49 % worker-0: Accuracy of cat : 36 % worker-0: Accuracy of deer : 44 % worker-0: Accuracy of dog : 52 % worker-0: Accuracy of frog : 67 % worker-0: Accuracy of horse : 58 % worker-0: Accuracy of ship : 70 % worker-0: Accuracy of truck : 59 %
補(bǔ)充:你可以使用 --include localhost:1 類似的命令在單卡上運(yùn)行模型。此外,--num_gpus可以指定使用多少張GPU來運(yùn)行。
0x4. 總結(jié)
本文翻譯了 Getting Started 和 Installation Details 和 CIFAR-10 Tutorial 三個(gè)教程,可以讓新手安裝和簡單使用上 DeepSpeed 來做模型訓(xùn)練。
-
amd
+關(guān)注
關(guān)注
25文章
5421瀏覽量
133811 -
模型
+關(guān)注
關(guān)注
1文章
3112瀏覽量
48660 -
Docker
+關(guān)注
關(guān)注
0文章
453瀏覽量
11792
原文標(biāo)題:0x4. 總結(jié)
文章出處:【微信號:GiantPandaCV,微信公眾號:GiantPandaCV】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論