huggingface--transformers
e06fe8e8c6
Secret Leaks / trufflehog (push) Failing after 1s
Build documentation / build (push) Failing after 1s
Build documentation / build_other_lang (push) Failing after 0s
CodeQL Security Analysis / CodeQL Analysis (push) Failing after 0s
PR CI / pr-ci (push) Failing after 1s
Slow tests on important models (on Push - A10) / Get all modified files (push) Failing after 1s
Slow tests on important models (on Push - A10) / Model CI (push) Has been skipped
Self-hosted runner (benchmark) / Benchmark (aws-g5-4xlarge-cache) (push) Has been cancelled
New model PR merged notification / Notify new model (push) Has been cancelled
Update Transformers metadata / build_and_package (push) Has been cancelled
1209 ่ก
64 KiB
Markdown
1209 ่ก
64 KiB
Markdown
<!--Copyright 2024 The HuggingFace Team. All rights reserved.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
specific language governing permissions and limitations under the License.
|
|
|
|
โ ๏ธ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be
|
|
rendered properly in your Markdown viewer.
|
|
|
|
-->
|
|
|
|
# DeepSpeed[[deepspeed]]
|
|
|
|
[DeepSpeed](https://www.deepspeed.ai/)๋ ๋ถ์ฐ ํ์ต ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํจ์จ์ ์ด๊ณ ๋น ๋ฅด๊ฒ ๋ง๋๋ PyTorch ์ต์ ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์
๋๋ค. ๊ทธ ํต์ฌ์ ๋๊ท๋ชจ ๋ชจ๋ธ์ ๊ท๋ชจ์ ๋ง๊ฒ ํ๋ จํ ์ ์๋ [Zero Redundancy Optimizer(ZeRO)](https://hf.co/papers/1910.02054)์
๋๋ค. ZeRO๋ ์ฌ๋ฌ ๋จ๊ณ๋ก ์๋ํฉ๋๋ค:
|
|
|
|
* ZeRO-1, GPU ๊ฐ ์ต์ ํ ์ํ ๋ถํ
|
|
* ZeRO-2, GPU ๊ฐ ๊ทธ๋ ์ด๋์ธํธ ๋ถํ
|
|
* ZeRO-3, GPU ๊ฐ ๋งค๊ฐ๋ณ์ ๋ถํ
|
|
|
|
GPU๊ฐ ์ ํ๋ ํ๊ฒฝ์์ ZeRO๋ ์ต์ ํ ๋ฉ๋ชจ๋ฆฌ์ ๊ณ์ฐ์ GPU์์ CPU๋ก ์คํ๋ก๋ํ์ฌ ๋จ์ผ GPU์ ๋๊ท๋ชจ ๋ชจ๋ธ์ ์ฅ์ฐฉํ๊ณ ํ๋ จํ ์ ์์ต๋๋ค. DeepSpeed๋ ๋ชจ๋ ZeRO ๋จ๊ณ ๋ฐ ์คํ๋ก๋ฉ์ ์ํด Transformers [`Trainer`] ํด๋์ค์ ํตํฉ๋์ด ์์ต๋๋ค. ๊ตฌ์ฑ ํ์ผ์ ์ ๊ณตํ๊ฑฐ๋ ์ ๊ณต๋ ํ
ํ๋ฆฟ์ ์ฌ์ฉํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ์ถ๋ก ์ ๊ฒฝ์ฐ, Transformers๋ ๋์ฉ๋ ๋ชจ๋ธ์ ๊ฐ์ ธ์ฌ ์ ์์ผ๋ฏ๋ก ZeRO-3 ๋ฐ ์คํ๋ก๋ฉ์ ์ง์ํฉ๋๋ค.
|
|
|
|
์ด ๊ฐ์ด๋์์๋ DeepSpeed ํธ๋ ์ด๋์ ๋ฐฐํฌํ๋ ๋ฐฉ๋ฒ, ํ์ฑํํ ์ ์๋ ๊ธฐ๋ฅ, ๋ค์ํ ZeRO ๋จ๊ณ์ ๋ํ ๊ตฌ์ฑ ํ์ผ ์ค์ ๋ฐฉ๋ฒ, ์คํ๋ก๋ฉ, ์ถ๋ก ๋ฐ [`Trainer`] ์์ด DeepSpeed๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์๋ดํด ๋๋ฆฝ๋๋ค.
|
|
|
|
## ์ค์น[[installation]]
|
|
|
|
DeepSpeed๋ PyPI ๋๋ Transformers์์ ์ค์นํ ์ ์์ต๋๋ค(์์ธํ ์ค์น ์ต์
์ DeepSpeed [์ค์น ์์ธ์ฌํญ](https://www.deepspeed.ai/tutorials/advanced-install/) ๋๋ GitHub [README](https://github.com/deepspeedai/DeepSpeed#installation)๋ฅผ ์ฐธ์กฐํ์ธ์).
|
|
|
|
<Tip>
|
|
|
|
DeepSpeed๋ฅผ ์ค์นํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์๋ ๊ฒฝ์ฐ [DeepSpeed CUDA ์ค์น](../debugging#deepspeed-cuda-installation) ๊ฐ์ด๋๋ฅผ ํ์ธํ์ธ์. DeepSpeed์๋ pip ์ค์น ๊ฐ๋ฅํ PyPI ํจํค์ง๋ก ์ค์นํ ์ ์์ง๋ง, ํ๋์จ์ด์ ๊ฐ์ฅ ์ ๋ง๊ณ PyPI ๋ฐฐํฌํ์์๋ ์ ๊ณต๋์ง ์๋ 1๋นํธ Adam๊ณผ ๊ฐ์ ํน์ ๊ธฐ๋ฅ์ ์ง์ํ๋ ค๋ฉด [์์ค์์ ์ค์นํ๊ธฐ](https://www.deepspeed.ai/tutorials/advanced-install/#install-deepspeed-from-source)๋ฅผ ์ ๊ทน ๊ถ์ฅํฉ๋๋ค.
|
|
|
|
</Tip>
|
|
|
|
<hfoptions id="install">
|
|
<hfoption id="PyPI">
|
|
|
|
```bash
|
|
pip install deepspeed
|
|
```
|
|
|
|
</hfoption>
|
|
<hfoption id="Transformers">
|
|
|
|
```bash
|
|
pip install transformers[deepspeed]
|
|
```
|
|
|
|
</hfoption>
|
|
</hfoptions>
|
|
|
|
## ๋ฉ๋ชจ๋ฆฌ ์๊ตฌ๋[[memory-requirements]]
|
|
|
|
์์ํ๊ธฐ ์ ์ ๋ชจ๋ธ์ ๋ง๋ ์ถฉ๋ถํ GPU ๋ฐ CPU ๋ฉ๋ชจ๋ฆฌ๊ฐ ์๋์ง ํ์ธํ๋ ๊ฒ์ด ์ข์ต๋๋ค. DeepSpeed๋ ํ์ํ CPU/GPU ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ถ์ ํ ์ ์๋ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋จ์ผ GPU์์ [bigscience/T0_3B](bigscience/T0_3B) ๋ชจ๋ธ์ ๋ฉ๋ชจ๋ฆฌ ์๊ตฌ ์ฌํญ์ ์ถ์ ํ ์ ์์ต๋๋ค:
|
|
|
|
```bash
|
|
$ 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
|
|
```
|
|
|
|
์ฆ, CPU ์คํ๋ก๋๊ฐ ์๋ ๋จ์ผ 80GB GPU ๋๋ ์คํ๋ก๋ ํ 8GB GPU์ ์ต๋ 60GB CPU๊ฐ ํ์ํฉ๋๋ค (์ด๋ ๋งค๊ฐ๋ณ์, ์ต์ ํ ์ํ ๋ฐ ๊ทธ๋ ์ด๋์ธํธ์ ๋ํ ๋ฉ๋ชจ๋ฆฌ ์๊ตฌ ์ฌํญ์ผ ๋ฟ์ด๋ฉฐ CUDA ์ปค๋ ๋ฐ ํ์ฑํ์๋ ์กฐ๊ธ ๋ ํ์ํฉ๋๋ค). ๋ํ ๋ ์์ GPU๋ฅผ ๋์ฌํ๊ฑฐ๋ ๊ตฌ์
ํ๋ ๊ฒ์ด ๋ ์ ๋ ดํ์ง๋ง ๋ชจ๋ธ์ ํ๋ จํ๋ ๋ฐ ์๊ฐ์ด ๋ ์ค๋ ๊ฑธ๋ฆฌ๋ฏ๋ก ๋น์ฉ๊ณผ ์๋ ๊ฐ์ ๊ท ํ์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
|
|
|
|
GPU ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ถฉ๋ถํ๋ค๋ฉด CPU/NVMe ์คํ๋ก๋๋ฅผ ๋นํ์ฑํํ์ฌ ๋ชจ๋ ์์
์ ๋ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํ์ธ์.
|
|
|
|
## ZeRO ๋จ๊ณ ์ค์ ํ๊ธฐ[[select-a-zero-stage]]
|
|
|
|
DeepSpeed๋ฅผ ์ค์นํ๊ณ ๋ฉ๋ชจ๋ฆฌ ์๊ตฌ ์ฌํญ์ ๋ ์ ํ์
ํ๋ค๋ฉด ๋ค์ ๋จ๊ณ๋ ์ฌ์ฉํ ZeRO ์คํ
์ด์ง๋ฅผ ์ ํํ๋ ๊ฒ์
๋๋ค. ๊ฐ์ฅ ๋น ๋ฅด๊ณ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ด ๋์ ์์๋๋ก ์ ๋ ฌํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
|
|
|
|
| ์๋ | ๋ฉ๋ชจ๋ฆฌ ํจ์จ |
|
|
|------------------|------------------|
|
|
| ZeRO-1 | ZeRO-3 + offload |
|
|
| ZeRO-2 | ZeRO-3 |
|
|
| ZeRO-2 + offload | ZeRO-2 + offload |
|
|
| ZeRO-3 | ZeRO-2 |
|
|
| ZeRO-3 + offload | ZeRO-1 |
|
|
|
|
์์ ์๊ฒ ๊ฐ์ฅ ์ ํฉํ ๋ฐฉ๋ฒ์ ์ฐพ์ผ๋ ค๋ฉด ๊ฐ์ฅ ๋น ๋ฅธ ๋ฐฉ๋ฒ๋ถํฐ ์์ํ๊ณ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ๋ฉด ๋ ๋๋ฆฌ์ง๋ง ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ด ๋์ ๋ค์ ๋จ๊ณ๋ฅผ ์๋ํ์ธ์. ์๋์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ฌ์ด์ ์ ์ ํ ๊ท ํ์ ์ฐพ๊ธฐ ์ํด (๊ฐ์ฅ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ด๊ฑฐ๋ ๊ฐ์ฅ ๋น ๋ฅธ ๊ฒ๋ถํฐ ์์ํ์ฌ) ์ํ๋ ๋ฐฉํฅ์ผ๋ก ์์ ๋กญ๊ฒ ์์
ํ์ธ์.
|
|
|
|
์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ ํ๋ก์ธ์ค๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค(๋ฐฐ์น ํฌ๊ธฐ 1๋ก ์์):
|
|
|
|
1. ๊ทธ๋ ์ด๋์ธํธ ์ฒดํฌํฌ์ธํ
ํ์ฑํ
|
|
2. ZeRO-2 ์๋
|
|
3. ZeRO-2์ ๋งค๊ฐ๋ณ์ ์คํ๋ก๋ ์๋
|
|
4. ZeRO-3 ์๋
|
|
5. ZeRO-3๊ณผ ๋งค๊ฐ๋ณ์ CPU ์คํ๋ก๋ ์๋
|
|
6. ZeRO-3, ๋งค๊ฐ๋ณ์์ ์ตํฐ๋ง์ด์ CPU ์คํ๋ก๋ ์๋
|
|
7. [`~GenerationMixin.generate`] ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ ์ข์ ๋น ์์น ๊ฒ์ ๋ฒ์์ ๊ฐ์ ๋ค์ํ ๊ธฐ๋ณธ๊ฐ์ ๋ฎ์ถฐ๋ณด๊ธฐ
|
|
8. ์ ์ฒด ์ ๋ฐ๋ ๊ฐ์ค์น๋ณด๋ค ๋ฐ์ ๋ฐ๋(๊ตฌํ GPU ๊ตฌ์กฐ์ ๊ฒฝ์ฐ fp16, ์ํ์ด ์ดํ GPU์ ๊ฒฝ์ฐ bf16)๋ฅผ ํผํฉํด๋ณด๊ธฐ
|
|
9. ๊ฐ๋ฅํ๋ฉด ํ๋์จ์ด๋ฅผ ๋ ์ถ๊ฐํ๊ฑฐ๋ Infinity๊ฐ ๋งค๊ฐ๋ณ์์ ์ตํฐ๋ง์ด์ ๋ฅผ NVMe๋ก ์คํ๋ก๋ํ๋๋ก ํ์ฑํ
|
|
10. ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ์ง ์์ผ๋ฉด ์ ํจ ์ฒ๋ฆฌ๋์ ์ธก์ ํ ๋ค์ ๋ฐฐ์น ํฌ๊ธฐ๋ฅผ ์ต๋ํ ํฌ๊ฒ ๋๋ ค GPU ํจ์จ์ฑ์ ๊ทน๋ํ
|
|
11. ๋ง์ง๋ง์ผ๋ก ์ผ๋ถ ์คํ๋ก๋ ๊ธฐ๋ฅ์ ๋นํ์ฑํํ๊ฑฐ๋ ๋ ๋น ๋ฅธ ZeRO ์คํ
์ด์ง๋ฅผ ์ฌ์ฉํ๊ณ ๋ฐฐ์น ํฌ๊ธฐ๋ฅผ ๋๋ฆฌ๊ฑฐ๋ ์ค์ฌ ์๋์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๊ฐ์ ์ต์ ์ ๊ท ํ์ ์ฐพ์ ํธ๋ ์ด๋ ์ค์ ์ ์ต์ ํ
|
|
|
|
|
|
## DeepSpeed ๊ตฌ์ฑ ํ์ผ[[deepspeed-configuration-file]]
|
|
|
|
DeepSpeed๋ ํธ๋ ์ด๋ ์คํ ๋ฐฉ๋ฒ์ ๊ตฌ์ฑํ๋ ๋ชจ๋ ๋งค๊ฐ๋ณ์๊ฐ ํฌํจ๋ ๊ตฌ์ฑ ํ์ผ์ ํตํด [`Trainer`] ํด๋์ค์ ํจ๊ป ์๋ํฉ๋๋ค. ํธ๋ ์ด๋ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ฉด DeepSpeed๋ [`Trainer`]๋ก๋ถํฐ ๋ฐ์ ๊ตฌ์ฑ์ ์ฝ์์ ๊ธฐ๋กํ๋ฏ๋ก ์ด๋ค ๊ตฌ์ฑ์ด ์ฌ์ฉ๋์๋์ง ์ ํํ ํ์ธํ ์ ์์ต๋๋ค.
|
|
|
|
<Tip>
|
|
|
|
DeepSpeed ๊ตฌ์ฑ ์ต์
์ ์ ์ฒด ๋ชฉ๋ก์ [DeepSpeed Configuration JSON](https://www.deepspeed.ai/docs/config-json/)์์ ํ์ธํ ์ ์์ต๋๋ค. ๋ํ [DeepSpeedExamples](https://github.com/deepspeedai/DeepSpeedExamples) ๋ฆฌํฌ์งํ ๋ฆฌ ๋๋ ๊ธฐ๋ณธ [DeepSpeed](https://github.com/deepspeedai/DeepSpeed) ๋ฆฌํฌ์งํ ๋ฆฌ์์ ๋ค์ํ DeepSpeed ๊ตฌ์ฑ ์์ ์ ๋ํ ๋ณด๋ค ์ค์ฉ์ ์ธ ์์ ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. ๊ตฌ์ฒด์ ์ธ ์์ ๋ฅผ ๋น ๋ฅด๊ฒ ์ฐพ์ผ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ์ธ์:
|
|
|
|
```bash
|
|
git clone https://github.com/deepspeedai/DeepSpeedExamples
|
|
cd DeepSpeedExamples
|
|
find . -name '*json'
|
|
# Lamb ์ตํฐ๋ง์ด์ ์ํ ์ฐพ๊ธฐ
|
|
grep -i Lamb $(find . -name '*json')
|
|
```
|
|
|
|
</Tip>
|
|
|
|
๋ช
๋ น์ค ์ธํฐํ์ด์ค์์ ํธ๋ ์ด๋ํ๋ ๊ฒฝ์ฐ DeepSpeed ๊ตฌ์ฑ ํ์ผ์ JSON ํ์ผ์ ๊ฒฝ๋ก๋ก ์ ๋ฌ๋๊ฑฐ๋ ๋
ธํธ๋ถ ์ค์ ์์ [`Trainer`]๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ค์ฒฉ๋ `dict` ๊ฐ์ฒด๋ก ์ ๋ฌ๋ฉ๋๋ค.
|
|
|
|
<hfoptions id="pass-config">
|
|
<hfoption id="path to file">
|
|
|
|
```py
|
|
TrainingArguments(..., deepspeed="path/to/deepspeed_config.json")
|
|
```
|
|
|
|
</hfoption>
|
|
<hfoption id="nested dict">
|
|
|
|
```py
|
|
ds_config_dict = dict(scheduler=scheduler_params, optimizer=optimizer_params)
|
|
args = TrainingArguments(..., deepspeed=ds_config_dict)
|
|
trainer = Trainer(model, args, ...)
|
|
```
|
|
|
|
</hfoption>
|
|
</hfoptions>
|
|
|
|
### DeepSpeed์ Trainer ๋งค๊ฐ๋ณ์[[deepspeed-and-trainer-parameters]]
|
|
|
|
๊ตฌ์ฑ ๋งค๊ฐ๋ณ์์๋ ์ธ ๊ฐ์ง ์ ํ์ด ์์ต๋๋ค:
|
|
|
|
1. ์ผ๋ถ ๊ตฌ์ฑ ๋งค๊ฐ๋ณ์๋ [`Trainer`]์ DeepSpeed๊ฐ ๊ณต์ ํ๋ฉฐ, ์ ์๊ฐ ์ถฉ๋ํ๋ ๊ฒฝ์ฐ ์ค๋ฅ๋ฅผ ์๋ณํ๊ธฐ ์ด๋ ค์ธ ์ ์์ต๋๋ค. ์ด๋ฌํ ๊ณต์ ๊ตฌ์ฑ ๋งค๊ฐ๋ณ์๋ [`Trainer`] ๋ช
๋ น์ค ์ธ์์์ ์ฝ๊ฒ ์ค์ ํ ์ ์์ต๋๋ค.
|
|
|
|
2. ๋ชจ๋ธ ์ค์ ์์ ์๋์ผ๋ก ๋์ถ๋๋ ์ผ๋ถ ์ค์ ๋งค๊ฐ๋ณ์๋ ์๋์ผ๋ก ๊ฐ์ ์กฐ์ ํ ํ์๊ฐ ์์ต๋๋ค. [`Trainer`]๋ ๊ตฌ์ฑ ๊ฐ `auto`๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฅ ์ ํํ๊ฑฐ๋ ํจ์จ์ ์ธ ๊ฐ์ ์ค์ ํฉ๋๋ค. ์ง์ ๊ตฌ์ฑ ๋งค๊ฐ๋ณ์๋ฅผ ๋ช
์์ ์ผ๋ก ์ค์ ํ ์๋ ์์ง๋ง, [`Trainer`] ์ธ์์ DeepSpeed ์ค์ ๋งค๊ฐ๋ณ์๊ฐ ์ผ์นํ๋๋ก ์ฃผ์ํด์ผ ํฉ๋๋ค. ์ผ์นํ์ง ์์ผ๋ฉด ๊ฐ์งํ๊ธฐ ๋งค์ฐ ์ด๋ ค์ด ๋ฐฉ์์ผ๋ก ํ๋ จ์ด ์คํจํ ์ ์์ต๋๋ค!
|
|
|
|
3. ๊ต์ก ์๊ตฌ ์ฌํญ์ ๋ฐ๋ผ ์๋์ผ๋ก ์ค์ ํด์ผ ํ๋ ์ผ๋ถ ์ค์ ๋งค๊ฐ๋ณ์๋ DeepSpeed์๋ง ํด๋น๋ฉ๋๋ค.
|
|
|
|
DeepSpeed ๊ตฌ์ฑ์ ์์ ํ๊ณ [`TrainingArguments`]๋ฅผ ํธ์งํ ์๋ ์์ต๋๋ค:
|
|
|
|
1. ๊ธฐ๋ณธ ๊ตฌ์ฑ์ผ๋ก ์ฌ์ฉํ DeepSpeed ๊ตฌ์ฑ ํ์ผ์ ์์ฑํ๊ฑฐ๋ ๋ก๋ํฉ๋๋ค.
|
|
2. ๋ค์ DeepSpeed ๊ตฌ์ฑ์ ๊ธฐ๋ฐ์ผ๋ก [`TrainingArguments`] ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค.
|
|
|
|
`scheduler.params.total_num_steps`์ ๊ฐ์ ์ผ๋ถ ๊ฐ์ ํธ๋ ์ด๋ ์ค [`Trainer`]์ ์ํด ๊ณ์ฐ๋ฉ๋๋ค.
|
|
|
|
### ZeRO ๊ตฌ์ฑ[[zero-configuration]]
|
|
|
|
์ธ ๊ฐ์ง ๊ตฌ์ฑ์ด ์์ผ๋ฉฐ, ๊ฐ ๊ตฌ์ฑ์ ์๋ก ๋ค๋ฅธ ZeRO ๋จ๊ณ์ ํด๋นํฉ๋๋ค. 1๋จ๊ณ๋ ํ์ฅ์ฑ ์ธก๋ฉด์์ ๊ทธ๋ค์ง ๋์ฌ๊ฒจ๋ณผ๋งํ์ง ์์ผ๋ฏ๋ก ์ด ๊ฐ์ด๋์์๋ 2๋จ๊ณ์ 3๋จ๊ณ์ ์ค์ ์ ๋ก๋๋ค. `zero_optimization` ๊ตฌ์ฑ์๋ ํ์ฑํํ ํญ๋ชฉ๊ณผ ๊ตฌ์ฑ ๋ฐฉ๋ฒ์ ๋ํ ๋ชจ๋ ์ต์
์ด ํฌํจ๋์ด ์์ต๋๋ค. ๊ฐ ๋งค๊ฐ๋ณ์์ ๋ํ ์์ธํ ์ค๋ช
์ [DeepSpeed ๊ตฌ์ฑ JSON](https://www.deepspeed.ai/docs/config-json/) ์ฐธ์กฐ๋ฅผ ์ฐธ์กฐํ์ธ์.
|
|
|
|
<Tip warning={true}>
|
|
DeepSpeed๋ ๋งค๊ฐ๋ณ์ ์ด๋ฆ์ ์ ํจ์ฑ์ ๊ฒ์ฌํ์ง ์์ผ๋ฉฐ ์คํ๊ฐ ์์ผ๋ฉด ๋งค๊ฐ๋ณ์์ ๊ธฐ๋ณธ ์ค์ ์ผ๋ก ๋์ฒดํฉ๋๋ค. DeepSpeed ์์ง ์์ ๋ก๊ทธ ๋ฉ์์ง๋ฅผ ๋ณด๊ณ ์ด๋ค ๊ฐ์ ์ฌ์ฉํ ์ง ํ์ธํ ์ ์์ต๋๋ค.
|
|
|
|
</Tip>
|
|
|
|
[`Trainer`]๋ ๋๋ฑํ ๋ช
๋ น์ค ์ธ์๋ฅผ ์ ๊ณตํ์ง ์์ผ๋ฏ๋ก ๋ค์ ๊ตฌ์ฑ์ DeepSpeed๋ก ์ค์ ํด์ผ ํฉ๋๋ค.
|
|
|
|
<hfoptions id="zero-config">
|
|
<hfoption id="ZeRO-1">
|
|
|
|
ZeRO-1์ ์ตํฐ๋ง์ด์ ์ํ๋ฅผ GPU์ ๋ถํ ํ์ฌ ์ฝ๊ฐ์ ์๋ ํฅ์์ ๊ธฐ๋ํ ์ ์์ต๋๋ค. ZeRO-1 ๊ตฌ์ฑ์ ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํ ์ ์์ต๋๋ค:
|
|
|
|
```yml
|
|
{
|
|
"zero_optimization": {
|
|
"stage": 1
|
|
}
|
|
}
|
|
```
|
|
|
|
</hfoption>
|
|
<hfoption id="ZeRO-2">
|
|
|
|
ZeRO-2๋ GPU์์ ์ตํฐ๋ง์ด์ ์ ๊ทธ๋ ์ด๋์ธํธ๋ฅผ ๋ถํ ํฉ๋๋ค. ์ด ๋จ๊ณ๋ ์ถ๋ก ๊ณผ ๊ด๋ จ์ด ์๋ ๊ธฐ๋ฅ์ด๊ธฐ ๋๋ฌธ์ ์ฃผ๋ก ํ๋ จ์ ์ฌ์ฉ๋ฉ๋๋ค. ๋ ๋์ ์ฑ๋ฅ์ ์ํด ๊ตฌ์ฑํด์ผ ํ ๋ช ๊ฐ์ง ์ค์ํ ๋งค๊ฐ๋ณ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
|
|
|
|
* GPU ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ค์ด๋ ค๋ฉด `offload_optimizer`๋ฅผ ํ์ฑํํด์ผ ํฉ๋๋ค.
|
|
* `true`๋ก ์ค์ ๋ ๊ฒฝ์ฐ `overlap_comm`์ GPU ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ฆ๊ฐ๋ฅผ ์์ํ์ฌ ์ง์ฐ ์๊ฐ์ ์ค์
๋๋ค. ์ด ๊ธฐ๋ฅ์ 4.5๋ฐฐ์ `allgather_bucket_size` ๋ฐ `reduce_bucket_size`๊ฐ์ ์ฌ์ฉํฉ๋๋ค. ์ด ์์์๋ `5e8`๋ก ์ค์ ๋์ด ์์ผ๋ฏ๋ก 9GB์ GPU ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค. GPU ๋ฉ๋ชจ๋ฆฌ๊ฐ 8GB ์ดํ์ธ ๊ฒฝ์ฐ, ๋ฉ๋ชจ๋ฆฌ ์๊ตฌ๋์ ๋ฎ์ถ๊ณ ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ(OOM) ์ค๋ฅ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด `overlap_comm`์ ์ค์ฌ์ผ ํฉ๋๋ค.
|
|
* `allgather_bucket_size`์ `reduce_bucket_size`๋ ์ฌ์ฉ ๊ฐ๋ฅํ GPU ๋ฉ๋ชจ๋ฆฌ์ ํต์ ์๋๋ฅผ ์ ์ถฉํฉ๋๋ค. ๊ฐ์ด ์์์๋ก ํต์ ์๋๊ฐ ๋๋ ค์ง๊ณ ๋ ๋ง์ GPU ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ฐฐ์น ํฌ๊ธฐ๊ฐ ํฐ ๊ฒ์ด ์ฝ๊ฐ ๋๋ฆฐ ํ๋ จ ์๊ฐ๋ณด๋ค ๋ ์ค์ํ์ง ๊ท ํ์ ๋ง์ถ ์ ์์ต๋๋ค.
|
|
* DeepSpeed 0.4.4์์๋ CPU ์คํ๋ก๋ฉ์ ์ํด `round_robin_gradients`๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ์ธ๋ถํ๋ ๊ทธ๋ ์ด๋์ธํธ ํํฐ์
๋์ ํตํด ๋ฑ๊ธ ๊ฐ ๊ทธ๋ ์ด๋์ธํธ ๋ณต์ฌ๋ฅผ CPU ๋ฉ๋ชจ๋ฆฌ๋ก ๋ณ๋ ฌํํฉ๋๋ค. ์ฑ๋ฅ ์ด์ ์ ๊ทธ๋ ์ด๋์ธํธ ๋์ ๋จ๊ณ(์ต์ ํ ๋จ๊ณ ๊ฐ ๋ณต์ฌ ํ์ ์ฆ๊ฐ) ๋๋ GPU ์(๋ณ๋ ฌ ์ฒ๋ฆฌ ์ฆ๊ฐ)์ ๋ฐ๋ผ ์ฆ๊ฐํฉ๋๋ค.
|
|
|
|
```yml
|
|
{
|
|
"zero_optimization": {
|
|
"stage": 2,
|
|
"offload_optimizer": {
|
|
"device": "cpu",
|
|
"pin_memory": true
|
|
},
|
|
"allgather_partitions": true,
|
|
"allgather_bucket_size": 5e8,
|
|
"overlap_comm": true,
|
|
"reduce_scatter": true,
|
|
"reduce_bucket_size": 5e8,
|
|
"contiguous_gradients": true,
|
|
"round_robin_gradients": true
|
|
}
|
|
}
|
|
```
|
|
|
|
</hfoption>
|
|
<hfoption id="ZeRO-3">
|
|
|
|
ZeRO-3๋ ์ตํฐ๋ง์ด์ , ๊ทธ๋๋์ธํธ, ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ๋ฌ GPU์ ๊ฑธ์ณ ๋ถํ ํฉ๋๋ค. ZeRO-2์ ๋ฌ๋ฆฌ ZeRO-3๋ ์ฌ๋ฌ GPU์ ๋๊ท๋ชจ ๋ชจ๋ธ์ ๊ฐ์ ธ์ฌ ์ ์๊ธฐ ๋๋ฌธ์ ํ๋ จ ์ธ์๋ ์ถ๋ก ์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ตฌ์ฑํด์ผ ํ ๋ช ๊ฐ์ง ์ค์ํ ๋งค๊ฐ๋ณ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
|
|
|
|
* `device: "cpu"` ๋ GPU ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ๊ณ ์ฌ์ฉ ๊ฐ๋ฅํ CPU ๋ฉ๋ชจ๋ฆฌ๊ฐ ์๋ ๊ฒฝ์ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๋ชจ๋ธ ๋งค๊ฐ๋ณ์๋ฅผ CPU๋ก ์คํ๋ก๋ํ ์ ์์ต๋๋ค.
|
|
* `pin_memory: true` ๋ ์ฒ๋ฆฌ๋์ ํฅ์์ํฌ ์ ์์ง๋ง, ํ ๋ฉ๋ชจ๋ฆฌ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์์ฒญํ ํน์ ํ๋ก์ธ์ค๋ฅผ ์ํด ์์ฝ๋์ด ์๊ณ ์ผ๋ฐ์ ์ผ๋ก ์ผ๋ฐ CPU ๋ฉ๋ชจ๋ฆฌ๋ณด๋ค ํจ์ฌ ๋น ๋ฅด๊ฒ ์ก์ธ์ค๋๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ํ๋ก์ธ์ค์์ ์ฌ์ฉํ ์ ์๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ค์ด๋ญ๋๋ค.
|
|
* `stage3_max_live_parameters` ๋ ํน์ ์๊ฐ์ GPU์ ์ ์งํ๋ ค๋ ์ ์ฒด ๋งค๊ฐ๋ณ์์ ์ํ๊ฐ์
๋๋ค. OOM ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์ด ๊ฐ์ ์ค์ด์ธ์.
|
|
* `stage3_max_reuse_distance` ๋ ํฅํ ๋งค๊ฐ๋ณ์๋ฅผ ๋ค์ ์ฌ์ฉํ ์๊ธฐ๋ฅผ ๊ฒฐ์ ํ๋ ๊ฐ์ผ๋ก, ๋งค๊ฐ๋ณ์๋ฅผ ๋ฒ๋ฆด์ง ์ ์งํ ์ง ๊ฒฐ์ ํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฌ์ฉํ ๊ฒฝ์ฐ(`stage3_max_reuse_distance`๋ณด๋ค ์์ ๊ฐ์ธ ๊ฒฝ์ฐ) ํต์ ์ค๋ฒํค๋๋ฅผ ์ค์ด๊ธฐ ์ํด ๋งค๊ฐ๋ณ์๋ฅผ ์ ์งํฉ๋๋ค. ์ด ๊ธฐ๋ฅ์ ํ์ฑํ ์ฒดํฌํฌ์ธํ
์ด ํ์ฑํ๋์ด ์๊ณ ์ญ์ ํ ๊ณ์ฐ์๊น์ง ์์ ํ ์์ ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ์งํ๋ ค๋ ๊ฒฝ์ฐ์ ๋งค์ฐ ์ ์ฉํฉ๋๋ค. ๊ทธ๋ฌ๋ OOM ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์ด ๊ฐ์ ์ค์ด์ธ์.
|
|
* ๋ชจ๋ธ ์ ์ฅ ์ `stage3_gather_16bit_weights_on_model_save`๋ fp16 ๊ฐ์ค์น๋ฅผ ํตํฉํฉ๋๋ค. ๋๊ท๋ชจ ๋ชจ๋ธ์ ํ์ตํ๊ฑฐ๋ ์ฌ๋ฌ GPU๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ๋ฉ๋ชจ๋ฆฌ์ ์๋ ์ธก๋ฉด์์ ๋น์ฉ์ด ๋ง์ด ๋ญ๋๋ค. ํ๋ จ์ ์ฌ๊ฐํ ๊ณํ์ด๋ผ๋ฉด ์ด ์ต์
์ ํ์ฑํํด์ผ ํฉ๋๋ค.
|
|
* `sub_group_size` ๋ ์ต์ ํ ๋จ๊ณ์์ ์
๋ฐ์ดํธ๋๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ ์ดํฉ๋๋ค. ๋งค๊ฐ๋ณ์๋ `sub_group_size`์ ๋ฒํท์ผ๋ก ๊ทธ๋ฃนํ๋๋ฉฐ ๊ฐ ๋ฒํท์ ํ ๋ฒ์ ํ๋์ฉ ์
๋ฐ์ดํธ๋ฉ๋๋ค. NVMe ์คํ๋ก๋์ ํจ๊ป ์ฌ์ฉํ๋ ๊ฒฝ์ฐ `sub_group_size`๋ ์ต์ ํ ๋จ๊ณ ์ค ๋ชจ๋ธ ์ํ๊ฐ CPU ๋ฉ๋ชจ๋ฆฌ๋ก ์ด๋ํ๋ ์์ ์ ๊ฒฐ์ ํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋งค์ฐ ํฐ ๋ชจ๋ธ์ CPU ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค. NVMe ์คํ๋ก๋๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ `sub_group_size`๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋ ์ ์์ง๋ง, ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ณ๊ฒฝํ๋ ๊ฒ์ด ์ข์ต๋๋ค:
|
|
|
|
1. ์ตํฐ๋ง์ด์ ๋จ๊ณ์์ OOM ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด ๊ฒฝ์ฐ, ์์ ๋ฒํผ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ค์ด๋ ค๋ฉด `sub_group_size`๋ฅผ ์ค์ด์ธ์.
|
|
2. ์ตํฐ๋ง์ด์ ๋จ๊ณ์์ ์๊ฐ์ด ๋๋ฌด ์ค๋ ๊ฑธ๋ฆฝ๋๋ค. ์ด ๊ฒฝ์ฐ ๋ฐ์ดํฐ ๋ฒํผ ์ฆ๊ฐ๋ก ์ธํ ๋์ญํญ ์ฌ์ฉ๋ฅ ์ ๊ฐ์ ํ๊ธฐ ์ํด `sub_group_size`๋ฅผ ๋๋ฆฌ์ธ์.
|
|
|
|
* `reduce_bucket_size`, `stage3_prefetch_bucket_size`, `stage3_param_persistence_threshold`๋ ๋ชจ๋ธ์ ์จ๊ฒจ์ง ํฌ๊ธฐ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. ์ด ๊ฐ๋ค์ `auto`์ผ๋ก ์ค์ ํ๊ณ [`Trainer`]๊ฐ ์๋์ผ๋ก ๊ฐ์ ํ ๋นํ๋๋ก ํ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
|
|
|
|
```yml
|
|
{
|
|
"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
|
|
}
|
|
}
|
|
```
|
|
|
|
[`deepspeed.zero.Init`](https://deepspeed.readthedocs.io/en/latest/zero3.html#deepspeed.zero.Init) ์ปจํ
์คํธ ๋งค๋์ ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ชจ๋ธ์ ๋ ๋น ๋ฅด๊ฒ ์ด๊ธฐํํ ์ ์์ต๋๋ค:
|
|
|
|
```py
|
|
from transformers import T5ForConditionalGeneration, T5Config
|
|
import deepspeed
|
|
|
|
with deepspeed.zero.Init():
|
|
config = T5Config.from_pretrained("google-t5/t5-small")
|
|
model = T5ForConditionalGeneration(config)
|
|
```
|
|
|
|
์ฌ์ ํ์ต๋ ๋ชจ๋ธ์ ๊ฒฝ์ฐ, ๋ฅ์คํผ๋ ๊ตฌ์ฑ ํ์ผ์ `is_deepspeed_zero3_enabled: true`๊ฐ [`TrainingArguments`]์ ์ค์ ๋์ด ์์ด์ผ ํ๋ฉฐ, ZeRO ๊ตฌ์ฑ์ด ํ์ฑํ๋์ด ์์ด์ผ ํฉ๋๋ค. ํ๋ จ๋ ๋ชจ๋ธ [`~PreTrainedModel.from_pretrained`]์ ํธ์ถํ๊ธฐ **์ ์** [`TrainingArguments`] ๊ฐ์ฒด๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
|
|
|
|
```py
|
|
from transformers import AutoModel, Trainer, TrainingArguments
|
|
|
|
training_args = TrainingArguments(..., deepspeed=ds_config)
|
|
model = AutoModel.from_pretrained("google-t5/t5-small")
|
|
trainer = Trainer(model=model, args=training_args, ...)
|
|
```
|
|
|
|
fp16 ๊ฐ์ค์น๊ฐ ๋จ์ผ GPU์ ๋ง์ง ์๋ ๊ฒฝ์ฐ ZeRO-3์ด ํ์ํฉ๋๋ค. fp16 ๊ฐ์ค์น๋ฅผ ๋ก๋ํ ์ ์๋ ๊ฒฝ์ฐ, [`~PreTrainedModel.from_pretrained`]์ `dtype=torch.float16`์ ์ง์ ํด์ผ ํฉ๋๋ค.
|
|
|
|
ZeRO-3์ ๋ ๋ค๋ฅธ ๊ณ ๋ ค ์ฌํญ์ ์ฌ๋ฌ ๊ฐ์ GPU๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ํ์ฌ ์คํ ์ค์ธ ๋ ์ด์ด์ ๋งค๊ฐ๋ณ์๊ฐ ์๋ ํ ๋จ์ผ GPU์ ๋ชจ๋ ๋งค๊ฐ๋ณ์๊ฐ ์๋ค๋ ๊ฒ์
๋๋ค. ์ฌ์ ํ๋ จ๋ ๋ชจ๋ธ ๊ฐ์ค์น๋ฅผ [`~PreTrainedModel.from_pretrained`]์ ๋ก๋ํ๋ ๋ฑ ๋ชจ๋ ๋ ์ด์ด์ ๋ชจ๋ ๋งค๊ฐ๋ณ์์ ํ ๋ฒ์ ์ก์ธ์คํ๋ ค๋ฉด ํ ๋ฒ์ ํ๋์ ๋ ์ด์ด๋ฅผ ๋ก๋ํ๊ณ ์ฆ์ ๋ชจ๋ GPU์ ํํฐ์
๋ํฉ๋๋ค. ์ด๋ ๋งค์ฐ ํฐ ๋ชจ๋ธ์ ๊ฒฝ์ฐ ๋ฉ๋ชจ๋ฆฌ ์ ํ์ผ๋ก ์ธํด ํ๋์ GPU์ ๊ฐ์ค์น๋ฅผ ๋ก๋ํ ๋ค์ ๋ค๋ฅธ GPU์ ๋ถ์ฐํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
|
|
|
|
๋ค์๊ณผ ๊ฐ์ด ๋ณด์ด๋ ๋ชจ๋ธ ๋งค๊ฐ๋ณ์ ๊ฐ์ค์น(์ฌ๊ธฐ์ `tensor([1.])`) ๋๋ ๋งค๊ฐ๋ณ์ ํฌ๊ธฐ๊ฐ ๋ ํฐ ๋ค์ฐจ์ ํํ ๋์ 1์ธ ๊ฒฝ์ฐ, ์ด๋ ๋งค๊ฐ๋ณ์๊ฐ ๋ถํ ๋์ด ์์ผ๋ฉฐ ์ด๊ฒ์ด ZeRO-3 ํ๋ ์ด์คํ๋์ธ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
|
|
|
|
```py
|
|
tensor([1.0], device="cuda:0", dtype=torch.float16, requires_grad=True)
|
|
```
|
|
|
|
<Tip>
|
|
|
|
ZeRO-3๋ก ๋๊ท๋ชจ ๋ชจ๋ธ์ ์ด๊ธฐํํ๊ณ ๋งค๊ฐ๋ณ์์ ์ก์ธ์คํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์์ธํ ๋ด์ฉ์ [Constructing Massive Models](https://deepspeed.readthedocs.io/en/latest/zero3.html#constructing-massive-models) ๋ฐ [Gathering Parameters](https://deepspeed.readthedocs.io/en/latest/zero3.html#gathering-parameters) ๊ฐ์ด๋๋ฅผ ์ฐธ์กฐํ์ธ์.
|
|
|
|
</Tip>
|
|
|
|
</hfoption>
|
|
</hfoptions>
|
|
|
|
### NVMe ์ค์ [[nvme-configuration]]
|
|
|
|
[ZeRO-Infinity](https://hf.co/papers/2104.07857)๋ฅผ ์ฌ์ฉํ๋ฉด ๋ชจ๋ธ ์ํ๋ฅผ CPU ๋ฐ/๋๋ NVMe๋ก ์คํ๋ก๋ํ์ฌ ๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํ ์ ์์ต๋๋ค. ์ค๋งํธ ํํฐ์
๋ ๋ฐ ํ์ผ๋ง ์๊ณ ๋ฆฌ์ฆ์ ํตํด ๊ฐ GPU๋ ์คํ๋ก๋ฉ ์ค์ ๋งค์ฐ ์ ์ ์์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์์ผ๋ฏ๋ก ์ต์ NVMe๋ ํ๋ จ ํ๋ก์ธ์ค์ ์ฌ์ฉํ ์ ์๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋ ํฐ ์ด ๋ฉ๋ชจ๋ฆฌ ํ์ ๋ง์ถ ์ ์์ต๋๋ค. ZeRO-Infinity์๋ ZeRO-3๊ฐ ํ์ํฉ๋๋ค.
|
|
|
|
์ฌ์ฉ ๊ฐ๋ฅํ CPU ๋ฐ/๋๋ NVMe ๋ฉ๋ชจ๋ฆฌ์ ๋ฐ๋ผ [์ตํฐ๋ง์ด์ ](https://www.deepspeed.ai/docs/config-json/#optimizer-offloading)์ [๋งค๊ฐ๋ณ์](https://www.deepspeed.ai/docs/config-json/#parameter-offloading) ์ค ํ๋๋ง ์คํ๋ก๋ํ๊ฑฐ๋ ์๋ฌด๊ฒ๋ ์คํ๋ก๋ํ์ง ์์ ์ ์์ต๋๋ค. ๋ํ ์ผ๋ฐ ํ๋ ๋๋ผ์ด๋ธ๋ ์๋ฆฌ๋ ์คํ
์ดํธ ๋๋ผ์ด๋ธ์์๋ ์๋ํ์ง๋ง ์๋๊ฐ ํ์ ํ ๋๋ ค์ง๋ฏ๋ก `nvme_path`๊ฐ NVMe ์ฅ์น๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ์ต์ NVMe๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๊ธฐ ์์
์ ๊ฒฝ์ฐ ์ต๋ 3.5GB/s, ์ฐ๊ธฐ ์์
์ ๊ฒฝ์ฐ ์ต๋ 3GB/s์ ์ ์ก ์๋๋ฅผ ๊ธฐ๋ํ ์ ์์ต๋๋ค. ๋ง์ง๋ง์ผ๋ก, ํธ๋ ์ด๋ ์ค์ ์์ [๋ฒค์น๋งํฌ ์คํํ๊ธฐ](https://github.com/deepspeedai/DeepSpeed/issues/998)์ ํตํด ์ต์ ์ 'aio' ๊ตฌ์ฑ์ ๊ฒฐ์ ํฉ๋๋ค.
|
|
|
|
์๋ ์์ ZeRO-3/Infinity ๊ตฌ์ฑ ํ์ผ์ ๋๋ถ๋ถ์ ๋งค๊ฐ๋ณ์ ๊ฐ์ `auto`์ผ๋ก ์ค์ ํ๊ณ ์์ง๋ง, ์๋์ผ๋ก ๊ฐ์ ์ถ๊ฐํ ์๋ ์์ต๋๋ค.
|
|
|
|
```yml
|
|
{
|
|
"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
|
|
},
|
|
"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
|
|
},
|
|
"aio": {
|
|
"block_size": 262144,
|
|
"queue_depth": 32,
|
|
"thread_count": 1,
|
|
"single_submit": false,
|
|
"overlap_events": 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 ๊ตฌ์ฑ[[deepspeed-features]]
|
|
|
|
์ด ์น์
์์ ๊ฐ๋ตํ๊ฒ ์ค๋ช
ํ๋ ๋ช ๊ฐ์ง ์ค์ํ ๋งค๊ฐ๋ณ์๋ฅผ DeepSpeed ๊ตฌ์ฑ ํ์ผ์ ์ง์ ํ ์ ์์ต๋๋ค.
|
|
|
|
### ํ์ฑํ/๊ทธ๋ ์ด๋์ธํธ ์ฒดํฌํฌ์ธํ
[[activationgradient-checkpointing]]
|
|
|
|
ํ์ฑํ ๋ฐ ๊ทธ๋ ์ด๋์ธํธ ์ฒดํฌํฌ์ธํ
์ ์๋๋ฅผ ๋ ๋ง์ GPU ๋ฉ๋ชจ๋ฆฌ์ ๊ตํํ์ฌ GPU ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ ์ํฉ์ ๊ทน๋ณตํ๊ฑฐ๋ ๋ฐฐ์น ํฌ๊ธฐ๋ฅผ ๋๋ ค ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ํ์ฑํํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ์ธ์:
|
|
|
|
1. ํ๊น
ํ์ด์ค ๋ชจ๋ธ์ ๊ฒฝ์ฐ, [`Trainer`]์์ `model.gradient_checkpointing_enable()` ๋๋ `--gradient_checkpointing`์ ์ค์ ํฉ๋๋ค.
|
|
2. ํ๊น
ํ์ด์ค๊ฐ ์๋ ๋ชจ๋ธ์ ๊ฒฝ์ฐ, ๋ฅ์คํผ๋ [Activation Checkpointing API](https://deepspeed.readthedocs.io/en/latest/activation-checkpointing.html)๋ฅผ ์ฌ์ฉํฉ๋๋ค. ํธ๋์คํฌ๋จธ ๋ชจ๋ธ๋ง ์ฝ๋๋ฅผ ๋์ฒดํ๊ณ `torch.utils.checkpoint`๋ฅผ DeepSpeed API๋ก ๋์ฒดํ ์๋ ์์ต๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ์๋ฐฉํฅ ํ์ฑํ๋ฅผ ๋ค์ ๊ณ์ฐํ๋ ๋์ CPU ๋ฉ๋ชจ๋ฆฌ๋ก ์คํ๋ก๋ํ ์ ์์ผ๋ฏ๋ก ๋ ์ ์ฐํฉ๋๋ค.
|
|
|
|
### ์ตํฐ๋ง์ด์ ์ ์ค์ผ์ค๋ฌ[[optimizer-and-scheduler]]
|
|
|
|
`offload_optimizer`๋ฅผ ํ์ฑํํ์ง ์๋ ํ DeepSpeed์ ํธ๋์คํฌ๋จธ ์ตํฐ๋ง์ด์ ๋ฐ ์ค์ผ์ค๋ฌ๋ฅผ ํผํฉํ์ฌ ์ฌ์ฉํ ์ ์์ต๋๋ค. `offload_optimizer`๋ฅผ ํ์ฑํํ๋ฉด CPU์ GPU ๊ตฌํ์ด ๋ชจ๋ ์๋ ๊ฒฝ์ฐ DeepSpeed๊ฐ ์๋ ์ต์ ํ๊ธฐ(LAMB ์ ์ธ)๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
|
|
|
|
<Tip warning={true}>
|
|
|
|
๊ตฌ์ฑ ํ์ผ์ ์ต์ ํ ํ๋ก๊ทธ๋จ ๋ฐ ์ค์ผ์ค๋ฌ ๋งค๊ฐ๋ณ์๋ ๋ช
๋ น์ค์์ ์ค์ ํ ์ ์์ผ๋ฏ๋ก ์ค๋ฅ๋ฅผ ์ฐพ๊ธฐ ์ด๋ ต์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ํ์ต ์๋๊ฐ ๋ค๋ฅธ ๊ณณ์์ ๋ค๋ฅธ ๊ฐ์ผ๋ก ์ค์ ๋ ๊ฒฝ์ฐ ๋ช
๋ น์ค์์ ์ด๋ฅผ ์ฌ์ ์ํ ์ ์์ต๋๋ค. ์ต์ ํ ํ๋ก๊ทธ๋จ ๋ฐ ์ค์ผ์ค๋ฌ ๋งค๊ฐ๋ณ์ ์ธ์๋ [`Trainer`] ๋ช
๋ น์ค ์ธ์๊ฐ DeepSpeed ๊ตฌ์ฑ๊ณผ ์ผ์นํ๋์ง ํ์ธํด์ผ ํฉ๋๋ค.
|
|
|
|
</Tip>
|
|
|
|
<hfoptions id="opt-sched">
|
|
<hfoption id="optimizer">
|
|
|
|
DeepSpeed๋ ์ฌ๋ฌ [์ตํฐ๋ง์ด์ ](https://www.deepspeed.ai/docs/config-json/#optimizer-parameters)๋ฅผ ์ ๊ณตํ์ง๋ง(Adam, AdamW, OneBitAdam ๋ฐ LAMB) PyTorch์์ ๋ค๋ฅธ ์ตํฐ๋ง์ด์ ๋ฅผ ๊ฐ์ ธ์ฌ ์๋ ์์ต๋๋ค. ์ค์ ์์ ์ตํฐ๋ง์ด์ ๋ฅผ ๊ตฌ์ฑํ์ง ์์ผ๋ฉด [`Trainer`]๊ฐ ์๋์ผ๋ก AdamW๋ฅผ ์ ํํ๊ณ ๋ช
๋ น์ค์์ ์ ๊ณต๋ ๊ฐ ๋๋ ๊ธฐ๋ณธ๊ฐ์ ์ฌ์ฉํฉ๋๋ค: `lr`, `adam_beta1`, `adam_beta2`, `adam_epsilon`, `weight_decay`.
|
|
|
|
๋งค๊ฐ๋ณ์๋ฅผ `"auto"`์ผ๋ก ์ค์ ํ๊ฑฐ๋ ์ํ๋ ๊ฐ์ ์ง์ ์๋์ผ๋ก ์
๋ ฅํ ์ ์์ต๋๋ค.
|
|
|
|
```yaml
|
|
{
|
|
"optimizer": {
|
|
"type": "AdamW",
|
|
"params": {
|
|
"lr": "auto",
|
|
"betas": "auto",
|
|
"eps": "auto",
|
|
"weight_decay": "auto"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
์ต์์ ๊ตฌ์ฑ์ ๋ค์์ ์ถ๊ฐํ์ฌ ์ง์๋์ง ์๋ ์ตํฐ๋ง์ด์ ๋ฅผ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
|
|
|
|
```yaml
|
|
{
|
|
"zero_allow_untested_optimizer": true
|
|
}
|
|
```
|
|
|
|
DeepSpeed==0.8.3๋ถํฐ ์คํ๋ก๋๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ์คํ๋ก๋๊ฐ DeepSpeed์ CPU Adam ์ตํฐ๋ง์ด์ ์์ ๊ฐ์ฅ ์ ์๋ํ๋ฏ๋ก ์ต์์ ์์ค ๊ตฌ์ฑ์ ๋ค์ ์ฌํญ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
|
|
|
|
```yaml
|
|
{
|
|
"zero_force_ds_cpu_optimizer": false
|
|
}
|
|
```
|
|
|
|
</hfoption>
|
|
<hfoption id="scheduler">
|
|
|
|
DeepSpeed๋ LRRangeTest, OneCycle, WarmupLR ๋ฐ WarmupDecayLR learning rate[schedulers](https://www.deepspeed.ai/docs/config-json/#scheduler-parameters)๋ฅผ ์ง์ํฉ๋๋ค.
|
|
|
|
ํธ๋์คํฌ๋จธ์ DeepSpeed๋ ๋์ผํ ๋ ๊ฐ์ง ์ค์ผ์ค๋ฌ๋ฅผ ์ ๊ณตํฉ๋๋ค:
|
|
|
|
* WarmupLR์ Transformers์ `--lr_scheduler_type constant_warmup`๊ณผ ๋์ผํฉ๋๋ค.
|
|
* WarmupDecayLR์ Transformers์ `--lr_scheduler_type linear`์ ๋์ผํฉ๋๋ค(Transformers์์ ์ฌ์ฉ๋๋ ๊ธฐ๋ณธ ์ค์ผ์ค๋ฌ์
๋๋ค).
|
|
|
|
์ค์ ์์ ์ค์ผ์ค๋ฌ๋ฅผ ๊ตฌ์ฑํ์ง ์์ผ๋ฉด[`Trainer`]๋ ์๋์ผ๋ก WarmupDecayLR์ ์ ํํ๊ณ ๋ช
๋ น์ค์์ ์ ๊ณต๋ ๊ฐ ๋๋ ๊ธฐ๋ณธ๊ฐ์ ์ฌ์ฉํฉ๋๋ค: `warmup_min_lr`, `warmup_max_lr`, `warmup_num_steps`, `total_num_steps` (`max_steps`๊ฐ ์ ๊ณต๋์ง ์์ผ๋ฉด ๋ฐํ์ ์ค์ ์๋์ผ๋ก ๊ณ์ฐ๋จ).
|
|
|
|
๋งค๊ฐ๋ณ์๋ฅผ `"auto"`์ผ๋ก ์ค์ ํ๊ฑฐ๋ ์ํ๋ ๊ฐ์ ์ง์ ์๋์ผ๋ก ์
๋ ฅํ ์ ์์ต๋๋ค.
|
|
|
|
```yaml
|
|
{
|
|
"scheduler": {
|
|
"type": "WarmupDecayLR",
|
|
"params": {
|
|
"total_num_steps": "auto",
|
|
"warmup_min_lr": "auto",
|
|
"warmup_max_lr": "auto",
|
|
"warmup_num_steps": "auto"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
</hfoption>
|
|
</hfoptions>
|
|
|
|
### ์ ๋ฐ๋[[precision]]
|
|
|
|
DeepSpeed๋ fp32, fp16 ๋ฐ bf16 ํผํฉ ์ ๋ฐ๋๋ฅผ ์ง์ํฉ๋๋ค.
|
|
|
|
<hfoptions id="precision">
|
|
<hfoption id="fp32">
|
|
|
|
๋ชจ๋ธ์ด ํผํฉ ์ ๋ฐ๋๋ก ์ฌ์ ํ์ต๋์ง ์์ ๊ฒฝ์ฐ์ ๊ฐ์ด ํผํฉ ์ ๋ฐ๋๋ก ์ ์๋ํ์ง ์๋ ๊ฒฝ์ฐ NaN ์์ค์ ์ ๋ฐํ ์ ์๋ ์ค๋ฒํ๋ก ๋๋ ์ธ๋ํ๋ก ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ์๋ ๊ธฐ๋ณธ fp16 ๋ชจ๋๋ฅผ ๋ช
์์ ์ผ๋ก ๋นํ์ฑํํ์ฌ ์ ์ฒด fp32 ์ ๋ฐ๋๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
|
|
|
|
```yaml
|
|
{
|
|
"fp16": {
|
|
"enabled": false
|
|
}
|
|
}
|
|
```
|
|
|
|
Ampere GPU ๋ฐ PyTorch 1.7 ์ด์์ ๊ฒฝ์ฐ ์ผ๋ถ ์ฐ์ฐ์ ๋ํด ๋ ํจ์จ์ ์ธ [tf32](https://pytorch.org/docs/stable/notes/cuda.html#tensorfloat-32-tf32-on-ampere-devices) ํ์์ผ๋ก ์๋ ์ ํ๋์ง๋ง ๊ฒฐ๊ณผ๋ ์ฌ์ ํ fp32๋ก ํ์๋ฉ๋๋ค. [`Trainer`]์์ `--tf32`๋ฅผ ์ค์ ํ์ฌ ํ์ฑํํ๊ณ `--tf32 0` ๋๋ `--no_tf32`๋ฅผ ๋นํ์ฑํํ๋ฉด ์ ์ดํ ์ ์์ต๋๋ค.
|
|
|
|
</hfoption>
|
|
<hfoption id="fp16">
|
|
|
|
fp16 ํผํฉ ์ ๋ฐ๋๋ฅผ ๊ตฌ์ฑํ๋ ค๋ฉด ์๋์ ๊ฐ์ด `"auto"` ๋๋ ์ง์ ๊ฐ์ ์ค์ ํ์ธ์. [`Trainer`]๋ `fp16` ๋๋ `fp16_full_eval` ๊ฐ์ ๋ฐ๋ผ fp16์ ์๋์ผ๋ก ํ์ฑํ ๋๋ ๋นํ์ฑํํ๋ฉฐ, ๋๋จธ์ง ๊ตฌ์ฑ์ ์ฌ์ฉ์๊ฐ ์ค์ ํ ์ ์์ต๋๋ค. ๋ช
๋ น์ค์์ `--fp16` ๋๋ `--fp16_full_eval` ์ธ์๋ฅผ ์ ๋ฌํ๋ฉด fp16์ด ํ์ฑํ๋ฉ๋๋ค.
|
|
|
|
```yaml
|
|
{
|
|
"fp16": {
|
|
"enabled": "auto",
|
|
"loss_scale": 0,
|
|
"loss_scale_window": 1000,
|
|
"initial_scale_power": 16,
|
|
"hysteresis": 2,
|
|
"min_loss_scale": 1
|
|
}
|
|
}
|
|
```
|
|
|
|
์ถ๊ฐ ๋ฅ์คํผ๋ fp16 ํ๋ จ ์ต์
์ [fp16 ํ๋ จ ์ต์
](https://www.deepspeed.ai/docs/config-json/#fp16-training-options) ์ฐธ์กฐ๋ฅผ ์ฐธ์กฐํ์ธ์.
|
|
|
|
</hfoption>
|
|
<hfoption id="bf16">
|
|
|
|
bf16์ ์ฌ์ฉํ๋ ค๋ฉด DeepSpeed==0.6.0 ์ด์์ด ํ์ํฉ๋๋ค. bf16์ fp32์ ๋์ ๋ฒ์๊ฐ ๋์ผํ๋ฉฐ ์์ค ์ค์ผ์ผ๋ง์ด ํ์ํ์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ [gradient accumulation](#gradient-accumulation)์ bf16๊ณผ ํจ๊ป ์ฌ์ฉํ๋ฉด ์ด ํ์์ ๋ฎ์ ์ ๋ฐ๋๋ก ์ธํด ์์ค์ด ๋ฐ์ํ ์ ์์ผ๋ฏ๋ก ์ํ์ง ์๋ ๊ทธ๋ ์ด๋์ธํธ๊ฐ bf16์ ๋์ ๋ ์ ์์ต๋๋ค.
|
|
|
|
bf16์ ์ค์ ํ์ผ์์ ์ค์ ํ๊ฑฐ๋ ๋ค์ ์ธ์๋ฅผ ์ ๋ฌํ๋ฉด ๋ช
๋ น์ค์์ ํ์ฑํํ ์ ์์ต๋๋ค: `--bf16` ๋๋ `--bf16_full_eval`.
|
|
|
|
```yaml
|
|
{
|
|
"bf16": {
|
|
"enabled": "auto"
|
|
}
|
|
}
|
|
```
|
|
|
|
</hfoption>
|
|
</hfoptions>
|
|
|
|
### ๋ฐฐ์น ํฌ๊ธฐ[[batch-size]]
|
|
|
|
๋ฐฐ์น ํฌ๊ธฐ๋ ์๋์ผ๋ก ๊ตฌ์ฑํ๊ฑฐ๋ ๋ช
์์ ์ผ๋ก ์ค์ ํ ์ ์์ต๋๋ค. `"auto"` ์ต์
์ ์ฌ์ฉํ๋๋ก ์ ํํ๋ฉด [`Trainer`]๋ `train_micro_batch_size_per_gpu`๋ฅผ args.`per_device_train_batch_size`์ ๊ฐ์ผ๋ก, `train_batch_size`๋ฅผ `args.world_size * args.per_device_train_batch_size * args.gradient_accumulation_steps`๋ก ์ค์ ํฉ๋๋ค.
|
|
|
|
```yaml
|
|
{
|
|
"train_micro_batch_size_per_gpu": "auto",
|
|
"train_batch_size": "auto"
|
|
}
|
|
```
|
|
|
|
### ๊ทธ๋ ์ด๋์ธํธ ๋์ [[gradient-accumulation]]
|
|
|
|
๊ทธ๋ ์ด๋์ธํธ ๋์ ์ ์๋์ผ๋ก ๊ตฌ์ฑํ๊ฑฐ๋ ๋ช
์์ ์ผ๋ก ์ค์ ํ ์ ์์ต๋๋ค. `"auto"` ์ต์
์ ์ฌ์ฉํ๋๋ก ์ ํํ๋ฉด [`Trainer`]๊ฐ `args.gradient_accumulation_steps`์ ๊ฐ์ผ๋ก ์ค์ ํฉ๋๋ค.
|
|
|
|
```yaml
|
|
{
|
|
"gradient_accumulation_steps": "auto"
|
|
}
|
|
|
|
```
|
|
|
|
### ๊ทธ๋ ์ด๋์ธํธ ํด๋ฆฌํ[[gradient-clipping]]
|
|
|
|
๊ทธ๋ ์ด๋์ธํธ ํด๋ฆฌํ์ ์๋์ผ๋ก ๊ตฌ์ฑํ๊ฑฐ๋ ๋ช
์์ ์ผ๋ก ์ค์ ํ ์ ์์ต๋๋ค. `"auto"` ์ต์
์ ์ฌ์ฉํ๋๋ก ์ ํํ๋ฉด [`Trainer`]๊ฐ `args.max_grad_norm`์ ๊ฐ์ผ๋ก ์ค์ ํฉ๋๋ค.
|
|
|
|
```yaml
|
|
{
|
|
"gradient_clipping": "auto"
|
|
}
|
|
```
|
|
|
|
### ํต์ ๋ฐ์ดํฐ ์ ํ(Communication data type)[[communication-data-type]]
|
|
|
|
์ถ์, ์์ง ๋ฐ ๋ถ์ฐ ์์
๊ณผ ๊ฐ์ ํต์ ์งํฉ์ฒด์ ๊ฒฝ์ฐ ๋ณ๋์ ๋ฐ์ดํฐ ์ ํ์ด ์ฌ์ฉ๋ฉ๋๋ค.
|
|
|
|
๋ชจ๋ ์์ง ๋ฐ ๋ถ์ฐ ์์
์ ๋ฐ์ดํฐ์ ๋์ผํ ๋ฐ์ดํฐ ์ ํ์ผ๋ก ์ํ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด bf16์ผ๋ก ํ๋ จํ๋ ๊ฒฝ์ฐ, ์์ง์ ๋น์์ค ์ฐ์ฐ์ด๋ฏ๋ก ๋ฐ์ดํฐ๋ bf16์ผ๋ก ์์ง๋ฉ๋๋ค.
|
|
|
|
์๋ฅผ ๋ค์ด ๊ทธ๋ ์ด๋์ธํธ๊ฐ ์ฌ๋ฌ GPU์ ๊ฑธ์ณ ํ๊ท ํ๋๋ ๊ฒฝ์ฐ์ ๊ฐ์ด ๊ฐ์ ์ฐ์ฐ์ ์์ค์ด ๋ฐ์ํฉ๋๋ค. ํต์ ์ด fp16 ๋๋ bf16์ผ๋ก ์ํ๋๋ ๊ฒฝ์ฐ, ๋ฎ์ ์ ๋ฐ๋๋ก ์ฌ๋ฌ ์ซ์๋ฅผ ๋ํ๋ฉด ์ ํํ์ง ์๊ธฐ ๋๋ฌธ์ ์์ค์ด ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ๋ ๋์ต๋๋ค. ํนํ fp16๋ณด๋ค ์ ๋ฐ๋๊ฐ ๋ฎ์ bf16์ ๊ฒฝ์ฐ ๋์ฑ ๊ทธ๋ ์ต๋๋ค. ์ด๋ฌํ ์ด์ ๋ก ๊ธฐ์ธ๊ธฐ๋ฅผ ํ๊ท ํํ ๋ ์์ค์ด ์ต์ํ๋๋ฏ๋ก ๊ฐ์ ์ฐ์ฐ์๋ fp16์ด ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.
|
|
|
|
ํต์ ๋ฐ์ดํฐ ์ ํ์ ์ค์ ํ์ผ์์ `communication_data_type` ๋งค๊ฐ๋ณ์๋ฅผ ์ค์ ํ์ฌ ์ ํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, fp32๋ฅผ ์ ํํ๋ฉด ์ฝ๊ฐ์ ์ค๋ฒํค๋๊ฐ ์ถ๊ฐ๋์ง๋ง ๊ฐ์ ์ฐ์ฐ์ด fp32์ ๋์ ๋๊ณ ์ค๋น๊ฐ ๋๋ฉด ํ๋ จ ์ค์ธ ๋ฐ์ ๋ฐ dtype์ผ๋ก ๋ค์ด์บ์คํธ๋ฉ๋๋ค.
|
|
|
|
```yaml
|
|
{
|
|
"communication_data_type": "fp32"
|
|
}
|
|
```
|
|
|
|
## ๋ชจ๋ธ ๋ฐฐํฌ[[deployment]]
|
|
|
|
[torchrun](https://pytorch.org/docs/stable/elastic/run.html), `deepspeed` ๋ฐ์ฒ ๋๋ [Accelerate](https://huggingface.co/docs/accelerate/basic_tutorials/launch#using-accelerate-launch) ๋ฑ ๋ค์ํ ๋ฐ์ฒ๋ฅผ ํตํด DeepSpeed๋ฅผ ๋ฐฐํฌํ ์ ์์ต๋๋ค. ๋ฐฐํฌํ๋ ค๋ฉด [`Trainer`] ๋ช
๋ น์ค์ `--deepspeed ds_config.json`์ ์ถ๊ฐํฉ๋๋ค. ํ์ํ ๋ช
๋ น์ค ์ธ์๋ฅผ ์ฝ๋์ ์ถ๊ฐํ๋ ค๋ฉด DeepSpeed์ [`add_config_arguments`](https://deepspeed.readthedocs.io/en/latest/initialize.html#argument-parsing) ์ ํธ๋ฆฌํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
|
|
|
|
์ด ๊ฐ์ด๋์์๋ ๋ค์ํ ํธ๋ ์ด๋ ์ค์ ์ ๋ํด `deepspeed` ๋ฐ์ฒ๋ก DeepSpeed๋ฅผ ๋ฐฐํฌํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ๋๋ฆฝ๋๋ค. ๋ณด๋ค ์ค์ฉ์ ์ธ ์ฌ์ฉ ์์ ๋ ์ด [post](https://github.com/huggingface/transformers/issues/8771#issuecomment-759248400)์์ ํ์ธํ ์ ์์ต๋๋ค.
|
|
|
|
<hfoptions id="deploy">
|
|
<hfoption id="multi-GPU">
|
|
|
|
์ฌ๋ฌ GPU์ DeepSpeed๋ฅผ ๋ฐฐํฌํ๋ ค๋ฉด `--num_gpus` ๋งค๊ฐ๋ณ์๋ฅผ ์ถ๊ฐํ์ธ์. ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ GPU๋ฅผ ์ฌ์ฉํ๋ ค๋ ๊ฒฝ์ฐ `--num_gpus`๋ฅผ ์ถ๊ฐํ ํ์๊ฐ ์์ต๋๋ค. ์๋ ์์ ์์๋ 2๊ฐ์ GPU๋ฅผ ์ฌ์ฉํฉ๋๋ค.
|
|
|
|
```bash
|
|
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 --fp16 \
|
|
--do_train --max_train_samples 500 --num_train_epochs 1 \
|
|
--dataset_name wmt16 --dataset_config "ro-en" \
|
|
--source_lang en --target_lang ro
|
|
```
|
|
|
|
</hfoption>
|
|
<hfoption id="single-GPU">
|
|
|
|
๋จ์ผ GPU์ DeepSpeed๋ฅผ ๋ฐฐํฌํ๋ ค๋ฉด `--num_gpus` ๋งค๊ฐ๋ณ์๋ฅผ ์ถ๊ฐํ์ธ์. GPU๊ฐ 1๊ฐ๋ง ์๋ ๊ฒฝ์ฐ ์ด ๊ฐ์ ๋ช
์์ ์ผ๋ก ์ค์ ํ ํ์๋ ์์ต๋๋ค. DeepSpeed๋ ์ง์ ๋ ๋
ธ๋์์ ๋ณผ ์ ์๋ ๋ชจ๋ GPU๋ฅผ ๋ฐฐํฌํ๋ฏ๋ก ์ด ๊ฐ์ ๋ช
์์ ์ผ๋ก ์ค์ ํ ํ์๋ ์์ต๋๋ค.
|
|
|
|
```bash
|
|
deepspeed --num_gpus=1 examples/pytorch/translation/run_translation.py \
|
|
--deepspeed tests/deepspeed/ds_config_zero2.json \
|
|
--model_name_or_path google-t5/t5-small --per_device_train_batch_size 1 \
|
|
--output_dir 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
|
|
```
|
|
|
|
DeepSpeed๋ ๋จ ํ๋์ GPU๋ก๋ ์ฌ์ ํ ์ ์ฉํฉ๋๋ค:
|
|
|
|
1. ์ผ๋ถ ๊ณ์ฐ๊ณผ ๋ฉ๋ชจ๋ฆฌ๋ฅผ CPU๋ก ์คํ๋ก๋ํ์ฌ ๋ ํฐ ๋ฐฐ์น ํฌ๊ธฐ๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ์ผ๋ฐ์ ์ผ๋ก ๋ง์ง ์๋ ๋งค์ฐ ํฐ ๋ชจ๋ธ์ ๋ง์ถ๊ธฐ ์ํด ๋ชจ๋ธ์ ๋ ๋ง์ GPU ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ํฉ๋๋ค.
|
|
2. ์ค๋งํธ GPU ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ์์คํ
์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ์กฐ๊ฐํ๋ฅผ ์ต์ํํ์ฌ ๋ ํฐ ๋ชจ๋ธ๊ณผ ๋ฐ์ดํฐ ๋ฐฐ์น์ ๋ง์ถ ์ ์์ต๋๋ค.
|
|
|
|
<Tip>
|
|
|
|
๋จ์ผ GPU์์ ๋ ๋์ ์ฑ๋ฅ์ ์ป์ผ๋ ค๋ฉด [ZeRO-2](#zero-configuration) ๊ตฌ์ฑ ํ์ผ์์ `allgather_bucket_size` ๋ฐ `reduce_bucket_size` ๊ฐ์ 2e8๋ก ์ค์ ํ์ธ์.
|
|
|
|
</Tip>
|
|
|
|
</hfoption>
|
|
</hfoptions>
|
|
|
|
### ๋ค์ค ๋
ธ๋ ํ๊ฒฝ์์์ ๋ชจ๋ธ ๋ฐฐํฌ[[multi-node-deployment]]
|
|
|
|
๋
ธ๋๋ ์ํฌ๋ก๋๋ฅผ ์คํํ๊ธฐ ์ํ ํ๋ ์ด์์ GPU์
๋๋ค. ๋ ๊ฐ๋ ฅํ ์ค์ ์ ๋ฉํฐ ๋
ธ๋ ์ค์ ์ผ๋ก, `deepspeed` ๋ฐ์ฒ๋ก ์คํํ ์ ์์ต๋๋ค. ์ด ๊ฐ์ด๋์์๋ ๊ฐ๊ฐ 8๊ฐ์ GPU๊ฐ ์๋ ๋ ๊ฐ์ ๋
ธ๋๊ฐ ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋
ธ๋๋ `ssh hostname1`๋ก, ๋ ๋ฒ์งธ ๋
ธ๋๋ `ssh hostname2`๋ก ์ ์ํ ์ ์์ต๋๋ค. ๋ ๋
ธ๋ ๋ชจ๋ ๋น๋ฐ๋ฒํธ ์์ด ssh๋ฅผ ํตํด ๋ก์ปฌ๋ก ์๋ก ํต์ ํ ์ ์์ด์ผ ํฉ๋๋ค.
|
|
|
|
๊ธฐ๋ณธ์ ์ผ๋ก DeepSpeed๋ ๋ฉํฐ๋
ธ๋ ํ๊ฒฝ์์ ๊ณต์ ์ ์ฅ์๋ฅผ ์ฌ์ฉํ ๊ฒ์ผ๋ก ์์ํฉ๋๋ค. ๊ทธ๋ ์ง ์๊ณ ๊ฐ ๋
ธ๋๊ฐ ๋ก์ปฌ ํ์ผ ์์คํ
๋ง ๋ณผ ์ ์๋ ๊ฒฝ์ฐ, ๊ณต์ ํ์ผ ์์คํ
์ ๋ํ ์ก์ธ์ค ์์ด ๋ก๋ฉํ ์ ์๋๋ก [`checkpoint`](https://www.deepspeed.ai/docs/config-json/#checkpoint-options)๋ฅผ ํฌํจํ๋๋ก ๊ตฌ์ฑ ํ์ผ์ ์กฐ์ ํด์ผ ํฉ๋๋ค:
|
|
|
|
```yaml
|
|
{
|
|
"checkpoint": {
|
|
"use_node_local_storage": true
|
|
}
|
|
}
|
|
```
|
|
|
|
[`Trainer`]์ ``--save_on_each_node` ์ธ์๋ฅผ ์ฌ์ฉํ์ฌ ์์ `checkpoint`๋ฅผ ๊ตฌ์ฑ์ ์๋์ผ๋ก ์ถ๊ฐํ ์๋ ์์ต๋๋ค.
|
|
|
|
<hfoptions id="multinode">
|
|
<hfoption id="torchrun">
|
|
|
|
[torchrun](https://pytorch.org/docs/stable/elastic/run.html)์ ๊ฒฝ์ฐ, ๊ฐ ๋
ธ๋์ ssh๋ก ์ ์ํ ํ ๋ ๋
ธ๋ ๋ชจ๋์์ ๋ค์ ๋ช
๋ น์ ์คํํด์ผ ํฉ๋๋ค. ๋ฐ์ฒ๋ ๋ ๋
ธ๋๊ฐ ๋๊ธฐํ๋ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ ํธ๋ ์ด๋์ ์์ํฉ๋๋ค.
|
|
|
|
```bash
|
|
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
|
|
```
|
|
|
|
</hfoption>
|
|
<hfoption id="deepspeed">
|
|
|
|
`deepspeed` ๋ฐ์ฒ์ ๊ฒฝ์ฐ, ๋จผ์ `hostfile`์ ์์ฑํฉ๋๋ค.
|
|
|
|
```bash
|
|
hostname1 slots=8
|
|
hostname2 slots=8
|
|
```
|
|
|
|
๊ทธ๋ฐ ๋ค์ ๋ค์ ๋ช
๋ น์ด๋ก ํธ๋ ์ด๋์ ์์ํ ์ ์์ต๋๋ค. `deepspeed` ๋ฐ์ฒ๋ ๋ ๋
ธ๋์์ ๋์์ ๋ช
๋ น์ ์๋์ผ๋ก ์คํํฉ๋๋ค.
|
|
|
|
```bash
|
|
deepspeed --num_gpus 8 --num_nodes 2 --hostfile hostfile --master_addr hostname1 --master_port=9901 \
|
|
your_program.py <normal cl args> --deepspeed ds_config.json
|
|
```
|
|
|
|
๋ค์ค ๋
ธ๋ ์ปดํจํ
๋ฆฌ์์ค ๊ตฌ์ฑ์ ๋ํ ์์ธํ ๋ด์ฉ์ [Resource Configuration (multi-node)](https://www.deepspeed.ai/getting-started/#resource-configuration-multi-node) ๊ฐ์ด๋๋ฅผ ์ฐธ์กฐํ์ธ์.
|
|
|
|
</hfoption>
|
|
</hfoptions>
|
|
|
|
### SLURM[[slurm]]
|
|
|
|
SLURM ํ๊ฒฝ์์๋ ํน์ SLURM ํ๊ฒฝ์ ๋ง๊ฒ SLURM ์คํฌ๋ฆฝํธ๋ฅผ ์กฐ์ ํด์ผ ํฉ๋๋ค.SLURM ์คํฌ๋ฆฝํธ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
|
|
|
|
```bash
|
|
#SBATCH --job-name=test-nodes # ์์
์ด๋ฆ
|
|
#SBATCH --nodes=2 # ๋
ธ๋ ์
|
|
#SBATCH --ntasks-per-node=1 # ์ค์ - ๋
ธ๋๋น ๋ถ์ฐ ์์
1๊ฐ!
|
|
#SBATCH --cpus-per-task=10 # ์์
๋น CPU ์ฝ์ด ์
|
|
#SBATCH --gres=gpu:8 # gpu ์
|
|
#SBATCH --time 20:00:00 # ์ต๋ ์คํ ์๊ฐ (HH:MM:SS)
|
|
#SBATCH --output=%x-%j.out # ์ถ๋ ฅ ํ์ผ ์ด๋ฆ
|
|
|
|
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'
|
|
```
|
|
|
|
๊ทธ๋ฐ ๋ค์ ๋ชจ๋ ๋
ธ๋์์ ๋์์ ํ์ต์ ์์ํ๋ ๋ค์ ๋ช
๋ น์ ์ฌ์ฉํ์ฌ ๋ค์ค ๋
ธ๋ ๋ฐฐํฌ๋ฅผ ์์ฝํ ์ ์์ต๋๋ค.
|
|
|
|
```bash
|
|
sbatch launch.slurm
|
|
```
|
|
|
|
### ๋
ธํธ๋ถ[[notebook]]
|
|
|
|
`deepspeed` ๋ฐ์ฒ๋ ๋
ธํธ๋ถ์์์ ๋ฐฐํฌ๋ฅผ ์ง์ํ์ง ์์ผ๋ฏ๋ก ๋ถ์ฐ ํ๊ฒฝ์ ์๋ฎฌ๋ ์ด์
ํด์ผ ํฉ๋๋ค. ํ์ง๋ง ์ด๋ 1๊ฐ์ GPU์์๋ง ์๋ํฉ๋๋ค. 1๊ฐ ์ด์์ GPU๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๋ฅ์คํผ๋๊ฐ ์๋ํ ์ ์๋ ๋ค์ค ํ๋ก์ธ์ค ํ๊ฒฝ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ฆ, ์ฌ๊ธฐ์ ํ์๋ ๊ฒ์ฒ๋ผ ์๋ฎฌ๋ ์ด์
ํ ์ ์๋ `deepspeed` ๋ฐ์ฒ๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
|
|
|
|
```py
|
|
# DeepSpeed๋ ๋จ์ผ ํ๋ก์ธ์ค๋ง ์ฌ์ฉํ๋๋ผ๋ ๋ถ์ฐ ํ๊ฒฝ์ ํ์๋ก ํฉ๋๋ค.
|
|
# ์ด ์ฝ๋๋ก ๋ถ์ฐ ํ๊ฒฝ์ ๋ชจ๋ฐฉํฉ๋๋ค.
|
|
import os
|
|
|
|
os.environ["MASTER_ADDR"] = "localhost"
|
|
os.environ["MASTER_PORT"] = "9994" # RuntimeError: Address already in use ์ค๋ฅ ๋ฐ์ ์ ์์
|
|
os.environ["RANK"] = "0"
|
|
os.environ["LOCAL_RANK"] = "0"
|
|
os.environ["WORLD_SIZE"] = "1"
|
|
|
|
# ์ด์ ํ์์ ๊ฐ์ด ์งํํ๋, DeepSpeed ์ค์ ํ์ผ์ ์ ๋ฌํฉ๋๋ค.
|
|
training_args = TrainingArguments(..., deepspeed="ds_config_zero3.json")
|
|
trainer = Trainer(...)
|
|
trainer.train()
|
|
```
|
|
|
|
ํ์ฌ ๋๋ ํฐ๋ฆฌ์ ๋
ธํธ๋ถ์ ๊ตฌ์ฑ ํ์ผ์ ์ฆ์์์ ๋ง๋ค๊ณ ์ถ๋ค๋ฉด ์ ์ฉ ์
์ ๋ง๋ค ์ ์์ต๋๋ค.
|
|
|
|
```py
|
|
%%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
|
|
```
|
|
|
|
ํธ๋ ์ด๋ ์คํฌ๋ฆฝํธ๊ฐ ๋
ธํธ๋ถ ์
์ด ์๋ ํ์ผ์ ์๋ ๊ฒฝ์ฐ, ๋
ธํธ๋ถ ์
์ ์
ธ์์ `deepspeed`๋ฅผ ์ ์์ ์ผ๋ก ์คํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด `run_translation.py`๋ฅผ ์์ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ์ธ์.:
|
|
|
|
```py
|
|
!git clone https://github.com/huggingface/transformers
|
|
!cd transformers; deepspeed examples/pytorch/translation/run_translation.py ...
|
|
```
|
|
|
|
๋ํ `%%bash` ๋งค์ง์ ์ฌ์ฉํ์ฌ ์ฌ๋ฌ ์ค์ ์ฝ๋๋ฅผ ์์ฑํ์ฌ ์
ธ ํ๋ก๊ทธ๋จ์ ์คํํ ์๋ ์์ง๋ง ๊ต์ก์ด ์๋ฃ๋ ๋๊น์ง ๋ก๊ทธ๋ฅผ ๋ณผ ์ ์์ต๋๋ค. `%%bash` ๋งค์ง์ผ๋ก ๋ถ์ฐ ํ๊ฒฝ์ ์๋ฎฌ๋ ์ด์
ํ ํ์๋ ์์ต๋๋ค.
|
|
|
|
```py
|
|
%%bash
|
|
|
|
git clone https://github.com/huggingface/transformers
|
|
cd transformers
|
|
deepspeed examples/pytorch/translation/run_translation.py ...
|
|
```
|
|
|
|
## ๋ชจ๋ธ ๊ฐ์ค์น ์ ์ฅํ๊ธฐ[[save-model-weights]]
|
|
|
|
๋ฅ์คํผ๋๋ ๊ธฐ๋ณธ ๊ณ ์ ๋ฐ fp32 ๊ฐ์ค์น๋ฅผ ์ฌ์ฉ์ ์ง์ ์ฒดํฌํฌ์ธํธ ์ต์ ํ ํ์ผ(glob ํจํด์ `global_step*/*optim_states.pt`์ฒ๋ผ ๋ณด์
๋๋ค)์ ์ ์ฅํ๊ณ ์ผ๋ฐ ์ฒดํฌํฌ์ธํธ ์๋์ ์ ์ฅํฉ๋๋ค.
|
|
|
|
<hfoptions id="save">
|
|
<hfoption id="fp16">
|
|
|
|
ZeRO-2๋ก ํ๋ จ๋ ๋ชจ๋ธ์ pytorch_model.bin ๊ฐ์ค์น๋ฅผ fp16์ ์ ์ฅํฉ๋๋ค. ZeRO-3์ผ๋ก ํ๋ จ๋ ๋ชจ๋ธ์ ๋ชจ๋ธ ๊ฐ์ค์น๋ฅผ fp16์ ์ ์ฅํ๋ ค๋ฉด ๋ชจ๋ธ ๊ฐ์ค์น๊ฐ ์ฌ๋ฌ GPU์ ๋ถํ ๋์ด ์์ผ๋ฏ๋ก `โstage3_gather_16bit_weights_on_model_saveโ: true`๋ฅผ ์ค์ ํด์ผ ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด [`Trainer`]๊ฐ ๊ฐ์ค์น๋ฅผ fp16์ ์ ์ฅํ์ง ์๊ณ pytorch_model.bin ํ์ผ์ ์์ฑํ์ง ์์ต๋๋ค. ์ด๋ DeepSpeed์ state_dict์ ์ค์ ๊ฐ์ค์น ๋์ ํ๋ ์ด์คํ๋๊ฐ ํฌํจ๋์ด ์์ด ์ด๋ฅผ ๋ก๋ํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
|
|
|
|
```yaml
|
|
{
|
|
"zero_optimization": {
|
|
"stage3_gather_16bit_weights_on_model_save": true
|
|
}
|
|
}
|
|
```
|
|
|
|
</hfoption>
|
|
<hfoption id="fp32">
|
|
|
|
์ ์ฒด ์ ๋ฐ ๊ฐ์ค์น๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ์ํ ์ ์์ผ๋ฏ๋ก ํธ๋ ์ด๋ ์ค์ ์ ์ฅํด์๋ ์ ๋ฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ํ๋ จ์ด ์๋ฃ๋ ํ ์คํ๋ผ์ธ์ผ๋ก fp32 ๊ฐ์ค์น๋ฅผ ์ ์ฅํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค. ๊ทธ๋ฌ๋ ์ฌ์ CPU ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ง์ ๊ฒฝ์ฐ ํ๋ จ ์ค์ fp32 ๊ฐ์ค์น๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค. ์ด ์น์
์์๋ ์จ๋ผ์ธ๊ณผ ์คํ๋ผ์ธ ๋ฐฉ์์ ๋ชจ๋ ๋ค๋ฃน๋๋ค.
|
|
|
|
### ์จ๋ผ์ธ ํ๊ฒฝ[[online]]
|
|
|
|
๋ค์๊ณผ ๊ฐ์ด ์ต์ ์ฒดํฌํฌ์ธํธ๋ฅผ ๋ก๋ํ๋ ค๋ฉด ์ฒดํฌํฌ์ธํธ๋ฅผ ํ๋ ์ด์ ์ ์ฅํด์ผ ํฉ๋๋ค:
|
|
|
|
```py
|
|
from transformers.trainer_utils import get_last_checkpoint
|
|
from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint
|
|
|
|
checkpoint_dir = get_last_checkpoint(trainer.args.output_dir)
|
|
fp32_model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir)
|
|
```
|
|
|
|
`--load_best_model_at_end` ๋งค๊ฐ๋ณ์๋ฅผ ํ์ฑํํ์ฌ [`TrainingArguments`]์์ ์ต์ ์ ์ฒดํฌํฌ์ธํธ๋ฅผ ์ถ์ ํ๋ ๊ฒฝ์ฐ, ๋จผ์ ํ์ต์ ์๋ฃํ๊ณ ์ต์ข
๋ชจ๋ธ์ ๋ช
์์ ์ผ๋ก ์ ์ฅํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ์๋์ ๊ฐ์ด ๋ค์ ๋ก๋ํ ์ ์์ต๋๋ค:
|
|
|
|
```py
|
|
from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint
|
|
|
|
checkpoint_dir = os.path.join(trainer.args.output_dir, "checkpoint-final")
|
|
trainer.deepspeed.save_checkpoint(checkpoint_dir)
|
|
fp32_model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir)
|
|
```
|
|
|
|
<Tip>
|
|
|
|
`load_state_dict_from_zero_checkpoint`๊ฐ ์คํ๋๋ฉด ๋์ผํ ์ ํ๋ฆฌ์ผ์ด์
์ ์ปจํ
์คํธ์์ ๋ชจ๋ธ์ ๋ ์ด์ DeepSpeed์์ ์ฌ์ฉํ ์ ์์ต๋๋ค. `model.load_state_dict(state_dict)`๋ ๋ชจ๋ ๋ฅ์คํผ๋ ๋ง๋ฒ์ ์ ๊ฑฐํ๋ฏ๋ก ๋ฅ์คํผ๋ ์์ง์ ๋ค์ ์ด๊ธฐํํด์ผ ํฉ๋๋ค. ์ด ๊ธฐ๋ฅ์ ํ๋ จ์ด ๋๋ ๋๋ง ์ฌ์ฉํ์ธ์.
|
|
|
|
</Tip>
|
|
|
|
fp32 ๊ฐ์ค์น์ state_dict๋ฅผ ์ถ์ถํ์ฌ ๋ก๋ํ ์๋ ์์ต๋๋ค:
|
|
|
|
```py
|
|
from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint
|
|
|
|
state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # cpu์ ์ด๋ฏธ ์กด์ฌํจ
|
|
model = model.cpu()
|
|
model.load_state_dict(state_dict)
|
|
```
|
|
|
|
### ์คํ๋ผ์ธ ํ๊ฒฝ[[offline]]
|
|
|
|
DeepSpeed๋ ์ธ์ ๋ ์ง ๊ฐ์ค์น๋ฅผ ์ถ์ถํ ์ ์๋๋ก ์ฒดํฌํฌ์ธํธ ํด๋์ ์ต์์ ๋ ๋ฒจ์ zero_to_fp32.py ์คํฌ๋ฆฝํธ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ์คํฌ๋ฆฝํธ๋ ๋
๋ฆฝํ ์คํฌ๋ฆฝํธ๋ก ๊ตฌ์ฑ ํ์ผ์ด๋ [`Trainer`]๊ฐ ํ์ํ์ง ์์ต๋๋ค.
|
|
|
|
์๋ฅผ ๋ค์ด ์ฒดํฌํฌ์ธํธ ํด๋๊ฐ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์
๋๋ค:
|
|
|
|
```bash
|
|
$ 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*
|
|
```
|
|
|
|
๋ฅ์คํผ๋ ์ฒดํฌํฌ์ธํธ(ZeRO-2 ๋๋ ZeRO-3) ํ์ ํด๋ `global_step1`์์ fp32 ๊ฐ์ค์น๋ฅผ ์ฌ๊ตฌ์ฑํ๋ ค๋ฉด ๋ค์ ๋ช
๋ น์ ์คํํ์ฌ ์ฌ๋ฌ GPU์ ์ ์ฒด fp32 ๊ฐ์ค์น๋ฅผ ๋จ์ผ pytorch_model.bin ํ์ผ๋ก ์์ฑํ๊ณ ํตํฉํฉ๋๋ค. ์คํฌ๋ฆฝํธ๋ ์๋์ผ๋ก ์ฒดํฌํฌ์ธํธ๊ฐ ํฌํจ๋ ํ์ ํด๋๋ฅผ ์ฐพ์ต๋๋ค.
|
|
|
|
```py
|
|
python zero_to_fp32.py . pytorch_model.bin
|
|
```
|
|
|
|
<Tip>
|
|
|
|
์์ธํ ์ฌ์ฉ๋ฒ์ `python zero_to_fp32.py -h`๋ฅผ ์คํํ์ธ์. ์ด ์คํฌ๋ฆฝํธ์๋ ์ต์ข
fp32 ๊ฐ์ค์น์ 2๋ฐฐ์ ์ผ๋ฐ RAM์ด ํ์ํฉ๋๋ค.
|
|
|
|
</Tip>
|
|
|
|
</hfoption>
|
|
</hfoptions>
|
|
|
|
## ZeRO Inference[[zero-inference]]
|
|
|
|
[ZeRO Inference](https://www.deepspeed.ai/2022/09/09/zero-inference.html)๋ ๋ชจ๋ธ ๊ฐ์ค์น๋ฅผ CPU ๋๋ NVMe ๋ฉ๋ชจ๋ฆฌ์ ๋ฐฐ์นํ์ฌ GPU์ ๋ถ๋ด์ ์ฃผ์ง ์์ผ๋ฏ๋ก GPU์์ ๋๊ท๋ชจ ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ์ถ๋ก ์ ์คํํ ์ ์์ต๋๋ค. ์ถ๋ก ์ ์ต์ ํ ์ํ ๋ฐ ๊ทธ๋ ์ด๋์ธํธ์ ๋ง์ ์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ถ๊ฐ๋ก ํ์๋ก ํ์ง ์์ผ๋ฏ๋ก ๋์ผํ ํ๋์จ์ด์ ํจ์ฌ ๋ ํฐ ๋ฐฐ์น ๋ฐ/๋๋ ์ํ์ค ๊ธธ์ด๋ฅผ ๋ง์ถ ์ ์์ต๋๋ค.
|
|
|
|
ZeRO Inference๋ [ZeRO-3](#zero-configuration)์ ๋์ผํ ๊ตฌ์ฑ ํ์ผ์ ๊ณต์ ํ๋ฉฐ, ZeRO-2 ๋ฐ ZeRO-1 ๊ตฌ์ฑ์ ์ถ๋ก ์ ์๋ฌด๋ฐ ์ด์ ์ ์ ๊ณตํ์ง ์์ผ๋ฏ๋ก ์๋ํ์ง ์์ต๋๋ค.
|
|
|
|
ZeRO Inference๋ฅผ ์คํํ๋ ค๋ฉด ์ผ๋ฐ์ ์ธ ํ๋ จ ์ธ์๋ฅผ [`TrainingArguments`] ํด๋์ค์ ์ ๋ฌํ๊ณ `--do_eval` ์ธ์๋ฅผ ์ถ๊ฐํฉ๋๋ค.
|
|
|
|
```bash
|
|
deepspeed --num_gpus=2 your_program.py <normal cl args> --do_eval --deepspeed ds_config.json
|
|
```
|
|
|
|
## Trainer ์์ด DeepSpeed ์ฌ์ฉํ๊ธฐ[[non-trainer-deepspeed-integration]]
|
|
|
|
DeepSpeed๋ [`Trainer`] ํด๋์ค๊ฐ ์๋ ํธ๋์คํฌ๋จธ์์๋ ์๋ํฉ๋๋ค. ์ด๋ [`~PreTrainedModel.from_pretrained`]๋ฅผ ํธ์ถํ ๋ ZeRO-3 ๋งค๊ฐ๋ณ์๋ฅผ ์์งํ๊ณ ๋ชจ๋ธ์ ์ฌ๋ฌ GPU์ ๋ถํ ํ๋ ์์
๋ง ์ฒ๋ฆฌํ๋ [`HfDeepSpeedConfig`]๊ฐ ์ฒ๋ฆฌํฉ๋๋ค.
|
|
|
|
<Tip>
|
|
|
|
๋ชจ๋ ๊ฒ์ด ์๋์ผ๋ก ์ฒ๋ฆฌ๋๊ธฐ๋ฅผ ์ํ๋ค๋ฉด, [`Trainer`]์ ํจ๊ป DeepSpeed๋ฅผ ์ฌ์ฉํด ๋ณด์ธ์! [DeepSpeed ๋ฌธ์](https://www.deepspeed.ai/)๋ฅผ ์ฐธ์กฐํ์ฌ ์ค์ ํ์ผ์์ ๋งค๊ฐ๋ณ์ ๊ฐ์ ์๋์ผ๋ก ๊ตฌ์ฑํด์ผ ํฉ๋๋ค(`"auto"` ๊ฐ์ ์ฌ์ฉํ ์ ์์).
|
|
|
|
</Tip>
|
|
|
|
ZeRO-3๋ฅผ ํจ์จ์ ์ผ๋ก ๋ฐฐํฌํ๋ ค๋ฉด ๋ชจ๋ธ ์์ [`HfDeepSpeedConfig`] ๊ฐ์ฒด๋ฅผ ์ธ์คํด์คํํ๊ณ ํด๋น ๊ฐ์ฒด๋ฅผ ์ ์งํด์ผ ํฉ๋๋ค:
|
|
|
|
<hfoptions id="models">
|
|
<hfoption id="pretrained model">
|
|
|
|
```py
|
|
from transformers.integrations import HfDeepSpeedConfig
|
|
from transformers import AutoModel
|
|
import deepspeed
|
|
|
|
ds_config = {...} # deepspeed ์ค์ ๊ฐ์ฒด ๋๋ ํ์ผ ๊ฒฝ๋ก
|
|
# Zero 3๋ฅผ ๊ฐ์งํ๊ธฐ ์ํด ๋ชจ๋ธ์ ์ธ์คํด์คํํ๊ธฐ ์ ์ ๋ฐ๋์ ์คํํด์ผ ํฉ๋๋ค
|
|
dschf = HfDeepSpeedConfig(ds_config) # ์ด ๊ฐ์ฒด๋ฅผ ์ ์งํ์ธ์.
|
|
model = AutoModel.from_pretrained("openai-community/gpt2")
|
|
engine = deepspeed.initialize(model=model, config_params=ds_config, ...)
|
|
```
|
|
|
|
</hfoption>
|
|
<hfoption id="non-pretrained model">
|
|
|
|
[`HfDeepSpeedConfig`] is not required for ZeRO-1 or ZeRO-2.
|
|
|
|
```py
|
|
from transformers.integrations import HfDeepSpeedConfig
|
|
from transformers import AutoModel, AutoConfig
|
|
import deepspeed
|
|
|
|
ds_config = {...} # deepspeed ์ค์ ๊ฐ์ฒด ๋๋ ํ์ผ ๊ฒฝ๋ก
|
|
# Zero 3๋ฅผ ๊ฐ์งํ๊ธฐ ์ํด ๋ชจ๋ธ์ ์ธ์คํด์คํํ๊ธฐ ์ ์ ๋ฐ๋์ ์คํํด์ผ ํฉ๋๋ค
|
|
dschf = HfDeepSpeedConfig(ds_config) # ์ด ๊ฐ์ฒด๋ฅผ ์ ์งํ์ธ์.
|
|
config = AutoConfig.from_pretrained("openai-community/gpt2")
|
|
model = AutoModel.from_config(config)
|
|
engine = deepspeed.initialize(model=model, config_params=ds_config, ...)
|
|
```
|
|
|
|
</hfoption>
|
|
</hfoptions>
|
|
|
|
### Trainer ์์ด ZeRO Inference ์ฌ์ฉํ๊ธฐ[[non-trainer-zero-inference]]
|
|
|
|
๋จ์ผ GPU์ ๋ชจ๋ธ์ ๋ง์ถ ์ ์๋ ๊ฒฝ์ฐ [`Trainer`]์์ด ZeRO ์ถ๋ก ์ ์คํํ๋ ค๋ฉด ์ถ๊ฐ GPU๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ CPU ๋ฉ๋ชจ๋ฆฌ๋ก ์คํ๋ก๋๋ฅผ ์๋ํ์ธ์. ์ฌ๊ธฐ์ ์ดํดํด์ผ ํ ์ค์ํ ๋์์ค๋ ZeRO๊ฐ ์ค๊ณ๋ ๋ฐฉ์์ ๋ฐ๋ผ ์๋ก ๋ค๋ฅธ GPU์์ ์๋ก ๋ค๋ฅธ ์
๋ ฅ์ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ ์ ์๋ค๋ ๊ฒ์
๋๋ค.
|
|
|
|
๋ฐ๋์ ํ์ธํ์ธ์:
|
|
|
|
* GPU ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ถฉ๋ถํ ๊ฒฝ์ฐ CPU ์คํ๋ก๋๋ฅผ ๋นํ์ฑํํฉ๋๋ค(์๋๊ฐ ๋๋ ค์ง๋ฏ๋ก).
|
|
* Ampere ์ด์์ GPU๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ bf16์ ํ์ฑํํ๋ฉด ์๋๊ฐ ๋นจ๋ผ์ง๋๋ค. ์ด๋ฌํ GPU๊ฐ ์๋ ๊ฒฝ์ฐ ์ค๋ฒํ๋ก ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ผ๋ฏ๋ก bf16์ผ๋ก ์ฌ์ ํ์ต๋ ๋ชจ๋ธ(T5 ๋ชจ๋ธ)์ ์ฌ์ฉํ์ง ์๋ ํ fp16์ ํ์ฑํํ ์ ์์ต๋๋ค.
|
|
|
|
๋จ์ผ GPU์ ๋ง์ง ์๋ ๋ชจ๋ธ์์ [`Trainer`] ์์ด ZeRO ์ถ๋ก ์ ์คํํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ ๋์ ์์ด๋์ด๋ฅผ ์ป์ผ๋ ค๋ฉด ๋ค์ ์คํฌ๋ฆฝํธ๋ฅผ ์ดํด๋ณด์๊ธฐ ๋ฐ๋๋๋ค.
|
|
|
|
```py
|
|
#!/usr/bin/env python
|
|
|
|
# ์ด ์คํฌ๋ฆฝํธ๋ ๋จ์ผ GPU์ ๋ชจ๋ธ์ ๋ง์ถ ์ ์์ ๋ ์ถ๋ก ๋ชจ๋์์ Deepspeed ZeRO๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
|
|
#
|
|
# 1. CPU ์คํ๋ก๋์ ํจ๊ป 1๊ฐ์ GPU ์ฌ์ฉ
|
|
# 2. ๋๋ ์ฌ๋ฌ GPU ์ฌ์ฉ
|
|
#
|
|
# ๋จผ์ deepspeed๋ฅผ ์ค์นํด์ผ ํฉ๋๋ค: pip install deepspeed
|
|
#
|
|
# ์ฌ๊ธฐ์๋ ์ฝ 15GB์ GPU RAM์ด ํ์ํ 3B "bigscience/T0_3B" ๋ชจ๋ธ์ ์ฌ์ฉํฉ๋๋ค - ๋ฐ๋ผ์ 1๊ฐ์ ํฐ GPU๋ 2๊ฐ์
|
|
# ์์ GPU๋ก ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ๋๋ 1๊ฐ์ ์์ GPU์ ๋ง์ CPU ๋ฉ๋ชจ๋ฆฌ๋ก๋ ๊ฐ๋ฅํฉ๋๋ค.
|
|
#
|
|
# ์ฝ 50GB๊ฐ ํ์ํ "bigscience/T0"์ ๊ฐ์ ๋ ํฐ ๋ชจ๋ธ์ ์ฌ์ฉํ๋ ค๋ฉด, 80GB GPU๊ฐ ์๋ ํ
|
|
# 2-4๊ฐ์ GPU๊ฐ ํ์ํ ๊ฒ์
๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ๋ฌ ์
๋ ฅ์ ํ ๋ฒ์ ์ฒ๋ฆฌํ๊ณ ์ถ๋ค๋ฉด
|
|
# ์คํฌ๋ฆฝํธ๋ฅผ ์์ ํ์ฌ ๋ ๋ง์ GPU๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
|
|
#
|
|
# ์ ๊ณต๋ deepspeed ์ค์ ์ CPU ๋ฉ๋ชจ๋ฆฌ ์คํ๋ก๋ฉ๋ ํ์ฑํํ๋ฏ๋ก, ์ฌ์ฉ ๊ฐ๋ฅํ CPU ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ง๊ณ
|
|
# ์๋ ์ ํ๋ฅผ ๊ฐ์ํ ์ ์๋ค๋ฉด ์ผ๋ฐ์ ์ผ๋ก ๋จ์ผ GPU์ ๋ง์ง ์๋ ๋ชจ๋ธ์ ๋ก๋ํ ์ ์์ ๊ฒ์
๋๋ค.
|
|
# GPU ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ถฉ๋ถํ๋ค๋ฉด CPU๋ก์ ์คํ๋ก๋๋ฅผ ์ํ์ง ์์ ๋ ํ๋ก๊ทธ๋จ์ด ๋ ๋น ๋ฅด๊ฒ ์คํ๋ ๊ฒ์
๋๋ค - ๊ทธ๋ด ๋๋ ํด๋น ์น์
์ ๋นํ์ฑํํ์ธ์.
|
|
#
|
|
# 1๊ฐ์ GPU์ ๋ฐฐํฌํ๋ ค๋ฉด:
|
|
#
|
|
# deepspeed --num_gpus 1 t0.py
|
|
# ๋๋:
|
|
# python -m torch.distributed.run --nproc_per_node=1 t0.py
|
|
#
|
|
# 2๊ฐ์ GPU์ ๋ฐฐํฌํ๋ ค๋ฉด:
|
|
#
|
|
# deepspeed --num_gpus 2 t0.py
|
|
# ๋๋:
|
|
# python -m torch.distributed.run --nproc_per_node=2 t0.py
|
|
|
|
from transformers import AutoTokenizer, AutoConfig, AutoModelForSeq2SeqLM
|
|
from transformers.integrations import HfDeepSpeedConfig
|
|
import deepspeed
|
|
import os
|
|
import torch
|
|
|
|
os.environ["TOKENIZERS_PARALLELISM"] = "false" # ํ ํฌ๋์ด์ ์ ๋ณ๋ ฌ ์ฒ๋ฆฌ์ ๊ดํ ๊ฒฝ๊ณ ๋ฅผ ํผํ๊ธฐ ์ํจ์
๋๋ค.
|
|
|
|
# ๋ถ์ฐ ํ๊ฒฝ ์ค์
|
|
local_rank = int(os.getenv("LOCAL_RANK", "0"))
|
|
world_size = int(os.getenv("WORLD_SIZE", "1"))
|
|
torch.cuda.set_device(local_rank)
|
|
deepspeed.init_distributed()
|
|
|
|
model_name = "bigscience/T0_3B"
|
|
|
|
config = AutoConfig.from_pretrained(model_name)
|
|
model_hidden_size = config.d_model
|
|
|
|
# ๋ฐฐ์น ํฌ๊ธฐ๋ world_size๋ก ๋๋์ด ๋จ์ด์ ธ์ผ ํ์ง๋ง, world_size๋ณด๋ค ํด ์ ์์ต๋๋ค
|
|
train_batch_size = 1 * world_size
|
|
|
|
# ds_config ์ฐธ๊ณ ์ฌํญ
|
|
#
|
|
# - Ampere ์ด์์ GPU๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ bf16์ ํ์ฑํํ์ธ์ - ์ด๋ ํผํฉ ์ ๋ฐ๋๋ก ์คํ๋์ด
|
|
# ๋ ๋น ๋ฅผ ๊ฒ์
๋๋ค.
|
|
#
|
|
# - ์ค๋๋ GPU์ ๊ฒฝ์ฐ fp16์ ํ์ฑํํ ์ ์์ง๋ง, bf16์ผ๋ก ์ฌ์ ํ๋ จ๋์ง ์์ ๋ชจ๋ธ์์๋ง ์๋ํฉ๋๋ค - ์๋ฅผ ๋ค์ด
|
|
# ๋ชจ๋ ๊ณต์ t5 ๋ชจ๋ธ์ bf16์ผ๋ก ์ฌ์ ํ๋ จ๋์์ต๋๋ค
|
|
#
|
|
# - CPU ์คํ๋ก๋๋ฅผ ์ํ์ง ์๋๋ค๋ฉด offload_param.device๋ฅผ "none"์ผ๋ก ์ค์ ํ๊ฑฐ๋ `offload_param` ์น์
์
|
|
# ์์ ํ ์ ๊ฑฐํ์ธ์
|
|
#
|
|
# - `offload_param`์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, stage3_param_persistence_threshold๋ฅผ ์๋์ผ๋ก ๋ฏธ์ธ ์กฐ์ ํ์ฌ
|
|
# ์ด๋ค ๋งค๊ฐ๋ณ์๊ฐ GPU์ ๋จ์์์ด์ผ ํ๋์ง ์ ์ดํ ์ ์์ต๋๋ค - ๊ฐ์ด ํด์๋ก ์คํ๋ก๋ ํฌ๊ธฐ๊ฐ ์์์ง๋๋ค
|
|
#
|
|
# Deepspeed ์ค์ ์ ๋ํ ์์ธํ ์ ๋ณด๋ ๋ค์์ ์ฐธ์กฐํ์ธ์
|
|
# https://huggingface.co/docs/transformers/main/main_classes/deepspeed
|
|
|
|
# ์ผ๊ด์ฑ์ ์ํด json๊ณผ ๋์ผํ ํ์์ ์ ์งํ๋, true/false์๋ ์๋ฌธ์๋ฅผ ์ฌ์ฉํฉ๋๋ค
|
|
# fmt: off
|
|
ds_config = {
|
|
"fp16": {
|
|
"enabled": False
|
|
},
|
|
"bf16": {
|
|
"enabled": False
|
|
},
|
|
"zero_optimization": {
|
|
"stage": 3,
|
|
"offload_param": {
|
|
"device": "cpu",
|
|
"pin_memory": True
|
|
},
|
|
"overlap_comm": True,
|
|
"contiguous_gradients": True,
|
|
"reduce_bucket_size": model_hidden_size * model_hidden_size,
|
|
"stage3_prefetch_bucket_size": 0.9 * model_hidden_size * model_hidden_size,
|
|
"stage3_param_persistence_threshold": 10 * model_hidden_size
|
|
},
|
|
"steps_per_print": 2000,
|
|
"train_batch_size": train_batch_size,
|
|
"train_micro_batch_size_per_gpu": 1,
|
|
"wall_clock_breakdown": False
|
|
}
|
|
# fmt: on
|
|
|
|
# ๋ค์ ์ค์ ๋ชจ๋ธ์ `from_pretrained` ๋ฉ์๋๊ฐ ํธ์ถ๋ ๋
|
|
# deepspeed.zero.Init๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ธ์ ์ฌ๋ฌ GPU์ ์ง์ ๋ถํ ํ๋๋ก transformers์ ์ง์ํฉ๋๋ค.
|
|
#
|
|
# **์ด๋ AutoModelForSeq2SeqLM.from_pretrained(model_name)๋ก ๋ชจ๋ธ์ ๋ก๋ํ๊ธฐ ์ ์ ์คํ๋์ด์ผ ํฉ๋๋ค**
|
|
#
|
|
# ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ชจ๋ธ์ด ๋จผ์ ์ ์์ ์ผ๋ก ๋ก๋๋ ํ ํฌ์๋ ์์๋ง ๋ถํ ๋๋๋ฐ, ์ด๋
|
|
# ๋ ํจ์จ์ ์ด๋ฉฐ CPU RAM์ด ๋ถ์กฑํ ๊ฒฝ์ฐ ์คํจํ ์ ์์ต๋๋ค
|
|
dschf = HfDeepSpeedConfig(ds_config) # ์ด ๊ฐ์ฒด๋ฅผ ์ ์งํ์ธ์
|
|
|
|
# ์ด์ ๋ชจ๋ธ์ ๋ก๋ํ ์ ์์ต๋๋ค.
|
|
model = AutoModelForSeq2SeqLM.from_pretrained(model_name)
|
|
|
|
# Deepspeed ZeRO๋ฅผ ์ด๊ธฐํํ๊ณ ์์ง ๊ฐ์ฒด๋ง ์ ์ฅ
|
|
ds_engine = deepspeed.initialize(model=model, config_params=ds_config)[0]
|
|
ds_engine.module.eval() # inference
|
|
|
|
# Deepspeed ZeRO๋ ๊ฐ GPU์์ ์๋ก ๊ด๋ จ ์๋ ์
๋ ฅ์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ 2๊ฐ์ GPU๋ฅผ ์ฌ์ฉํ๋ฉด ํ ๋ฒ์ 2๊ฐ์ ์
๋ ฅ์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
|
|
# GPU๋ฅผ ๋ ๋ง์ด ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๊ทธ์ ๋ง๊ฒ ์กฐ์ ํ์ธ์.
|
|
|
|
# ๋ฌผ๋ก ์ฒ๋ฆฌํ ์
๋ ฅ์ด ํ๋๋ฟ์ด๋ผ๋ฉด ๋ GPU์ ๋์ผํ ๋ฌธ์์ด์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
|
|
# GPU๋ฅผ ํ๋๋ง ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ rank 0๋ง ๊ฐ๊ฒ ๋ฉ๋๋ค.
|
|
rank = torch.distributed.get_rank()
|
|
if rank == 0:
|
|
text_in = "Is this review positive or negative? Review: this is the best cast iron skillet you will ever buy"
|
|
elif rank == 1:
|
|
text_in = "Is this review positive or negative? Review: this is the worst restaurant ever"
|
|
|
|
tokenizer = AutoTokenizer.from_pretrained(model_name)
|
|
inputs = tokenizer.encode(text_in, return_tensors="pt").to(device=local_rank)
|
|
with torch.no_grad():
|
|
outputs = ds_engine.module.generate(inputs, synced_gpus=True)
|
|
text_out = tokenizer.decode(outputs[0], skip_special_tokens=True)
|
|
print(f"rank{rank}:\n in={text_in}\n out={text_out}")
|
|
```
|
|
|
|
์คํฌ๋ฆฝํธ๋ฅผ t0.py๋ก ์ ์ฅํ๊ณ ์คํํฉ๋๋ค:
|
|
|
|
```bash
|
|
$ deepspeed --num_gpus 2 t0.py
|
|
rank0:
|
|
in=Is this review positive or negative? Review: this is the best cast iron skillet you will ever buy
|
|
out=Positive
|
|
rank1:
|
|
in=Is this review positive or negative? Review: this is the worst restaurant ever
|
|
out=negative
|
|
```
|
|
|
|
์ด๊ฒ์ ๋งค์ฐ ๊ธฐ๋ณธ์ ์ธ ์์์ด๋ฏ๋ก ์ฌ์ฉ ์ฌ๋ก์ ๋ง๊ฒ ์กฐ์ ํ ์ ์์ต๋๋ค.
|
|
|
|
### ์์ฑ[[generate]]
|
|
|
|
์์ฑ์ ZeRO-3์ ํจ๊ป ์ฌ๋ฌ ๊ฐ์ GPU๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด [`~GenerationMixin.generate`] ๋ฉ์๋์์ `synced_gpus=True`๋ฅผ ์ค์ ํ์ฌ GPU๋ฅผ ๋๊ธฐํํด์ผ ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ํ GPU๊ฐ ๋ค๋ฅธ GPU๋ณด๋ค ๋จผ์ ์์ฑ์ ์๋ฃํ๋ฉด ๋๋จธ์ง GPU๊ฐ ๋จผ์ ์๋ฃํ GPU๋ก๋ถํฐ ๊ฐ์ค์น ์ค๋๋ฅผ ๋ฐ์ง ๋ชปํ์ฌ ์ ์ฒด ์์คํ
์ด ์ค๋จ๋ฉ๋๋ค.
|
|
|
|
ํธ๋์คํฌ๋จธ>=4.28์ ๊ฒฝ์ฐ, ์์ฑ ์ค์ ์ฌ๋ฌ ๊ฐ์ GPU๊ฐ ๊ฐ์ง๋๋ฉด `synced_gpus`๊ฐ ์๋์ผ๋ก `True`๋ก ์ค์ ๋ฉ๋๋ค.
|
|
|
|
## ํธ๋ฌ๋ธ์ํ
[[troubleshoot]]
|
|
|
|
๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฉด DeepSpeed๊ฐ ๋ฌธ์ ์ ์์ธ์ด ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ผ๋ฏ๋ก(์์ฃผ ๋ช
๋ฐฑํ๊ณ ์์ธ์ ์ผ๋ก DeepSpeed ๋ชจ๋์ ๋ณผ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ผ๋ฉด) DeepSpeed๊ฐ ๋ฌธ์ ์ ์์ธ์ธ์ง ๊ณ ๋ คํด์ผ ํฉ๋๋ค! ์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ DeepSpeed ์์ด ์ค์ ์ ๋ค์ ์๋ํ๊ณ ๋ฌธ์ ๊ฐ ์ง์๋๋ฉด ๋ฌธ์ ๋ฅผ ์ ๊ณ ํ๋ ๊ฒ์
๋๋ค. ๋ฌธ์ ๊ฐ ํต์ฌ์ ์ธ DeepSpeed ๋ฌธ์ ์ด๊ณ transformers์ ๊ด๋ จ์ด ์๋ ๊ฒฝ์ฐ, [DeepSpeed ๋ฆฌํฌ์งํ ๋ฆฌ](https://github.com/deepspeedai/DeepSpeed)์์ ์ด์๋ฅผ ๊ฐ์คํ์ธ์.
|
|
|
|
transformers์ ๊ด๋ จ๋ ์ด์๋ฅผ ๊ฐ์คํ ๋์๋ ๋ค์ ์ ๋ณด๋ฅผ ์ ๊ณตํด ์ฃผ์ธ์:
|
|
|
|
* ์ ์ฒด DeepSpeed ๊ตฌ์ฑ ํ์ผ
|
|
|
|
*[`Trainer`]์ ๋ช
๋ น์ค ์ธ์, ๋๋[`Trainer`] ์ค์ ์ ์ง์ ์์ฑํ๋ ๊ฒฝ์ฐ[`TrainingArguments`] ์ธ์(๊ด๋ จ ์๋ ํญ๋ชฉ์ด ์์ญ ๊ฐ ์๋ [`TrainingArguments`]๋ ๋คํํ์ง ๋ง์ธ์).
|
|
|
|
* ๋ค์ ์ฝ๋์ ์ถ๋ ฅ ๊ฒฐ๊ณผ:
|
|
|
|
```bash
|
|
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 ํ๋ก์ธ์ค๊ฐ ์์ ๋จ๊ณ์์ ์ข
๋ฃ๋์์ ๊ฒฝ์ฐ[[deepspeed-process-killed-at-startup]]
|
|
|
|
์คํ ์ค์ ํธ๋ ์ด์ค๋ฐฑ ์์ด DeepSpeed ํ๋ก์ธ์ค๊ฐ ์ข
๋ฃ๋๋ฉด ์ผ๋ฐ์ ์ผ๋ก ํ๋ก๊ทธ๋จ์ด ์์คํ
๋ณด๋ค ๋ง์ CPU ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๋ ค๊ณ ์๋ํ๊ฑฐ๋ ํ๋ก์ธ์ค๊ฐ ํ์ฉ๋ ๊ฒ๋ณด๋ค ๋ง์ CPU ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๋ ค๊ณ ์๋ํ์ฌ OS ์ปค๋์ด ํ๋ก์ธ์ค๋ฅผ ์ข
๋ฃํ์์ ์๋ฏธํฉ๋๋ค. ์ด ๊ฒฝ์ฐ ๊ตฌ์ฑ ํ์ผ์ `offload_optimizer`, `offload_param` ๋๋ ๋ ๋ค CPU๋ก ์คํ๋ก๋ํ๋๋ก ๊ตฌ์ฑ๋์ด ์๋์ง ํ์ธํ์ธ์.
|
|
|
|
NVMe ๋ฐ ZeRO-3๋ฅผ ์ค์ ํ ๊ฒฝ์ฐ NVMe๋ก ์คํ๋ก๋๋ฅผ ์คํํด ๋ณด์ธ์(๋ชจ๋ธ์ ๋ฉ๋ชจ๋ฆฌ ์๊ตฌ ์ฌํญ์ [ํ์ธ](https://deepspeed.readthedocs.io/en/latest/memory.html)ํ์ธ์).
|
|
|
|
### NaN ์์ค[[nan-loss]]
|
|
|
|
๋ชจ๋ธ์ bf16์ผ๋ก ์ฌ์ ํ๋ จํ ๋ค์ fp16์ผ๋ก ์ฌ์ฉํ๋ ค๊ณ ํ ๋ NaN ์์ค์ด ๋ฐ์ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค(ํนํ TPU ํ๋ จ ๋ชจ๋ธ์ ํด๋น). ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ํ๋์จ์ด๊ฐ ์ด๋ฅผ ์ง์ํ๋ ๊ฒฝ์ฐ(TPU, Ampere GPU ์ด์) fp32 ๋๋ bf16์ ์ฌ์ฉํ์ธ์.
|
|
|
|
๋ค๋ฅธ ๋ฌธ์ ๋ fp16 ์ฌ์ฉ๊ณผ ๊ด๋ จ์ด ์์ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์ด๊ฒ์ด fp16 ๊ตฌ์ฑ์ธ ๊ฒฝ์ฐ์
๋๋ค:
|
|
|
|
```yaml
|
|
{
|
|
"fp16": {
|
|
"enabled": "auto",
|
|
"loss_scale": 0,
|
|
"loss_scale_window": 1000,
|
|
"initial_scale_power": 16,
|
|
"hysteresis": 2,
|
|
"min_loss_scale": 1
|
|
}
|
|
}
|
|
```
|
|
|
|
๋ก๊ทธ์ ๋ค์๊ณผ ๊ฐ์ `OVERFLOW!` ๋ฉ์์ง๊ฐ ํ์๋ ์ ์์ต๋๋ค:
|
|
|
|
```bash
|
|
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 ์์ค ์ค์ผ์ผ๋ฌ๊ฐ ์์ค ์ค๋ฒํ๋ก๋ฅผ ๊ทน๋ณตํ ์ ์๋ ์ค์ผ์ผ๋ง ๊ณ์๋ฅผ ์ฐพ์ ์ ์์์ ์๋ฏธํฉ๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด `initial_scale_power` ๊ฐ์ ๋ ๋๊ฒ ์ค์ ํ์ธ์(์ผ๋ฐ์ ์ผ๋ก 32๊ฐ ์ ์ ํฉ๋๋ค).
|
|
|
|
## ๋ฆฌ์์ค[[resources]]
|
|
|
|
DeepSpeed ZeRO๋ ์ ํ๋ GPU ๋ฆฌ์์ค๋ก ์ถ๋ก ์ ์ํด ๋งค์ฐ ํฐ ๋ชจ๋ธ์ ํ๋ จํ๊ณ ๋ก๋ํ๋ ๊ฐ๋ ฅํ ๊ธฐ์ ๋ก, ๋๊ตฌ๋ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค. DeepSpeed์ ๋ํด ์์ธํ ์์๋ณด๋ ค๋ฉด [๋ธ๋ก๊ทธ ํฌ์คํธ](https://www.microsoft.com/en-us/research/search/?q=deepspeed), [๊ณต์ ๋ฌธ์](https://www.deepspeed.ai/getting-started/), [๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ](https://github.com/deepspeedai/DeepSpeed)๋ฅผ ์ฐธ์กฐํ์ธ์.
|
|
|
|
๋ค์ ๋ฌธ์๋ ZeRO์ ๋ํด ์์ธํ ์์๋ณผ ์ ์๋ ํ๋ฅญํ ์๋ฃ์
๋๋ค:
|
|
|
|
* [ZeRO: Memory Optimizations Toward Training Trillion Parameter Models](https://hf.co/papers/1910.02054)
|
|
* [ZeRO-Offload: Democratizing Billion-Scale Model Training](https://hf.co/papers/2101.06840)
|
|
* [ZeRO-Infinity: Breaking the GPU Memory Wall for Extreme Scale Deep Learning](https://hf.co/papers/2104.07857)
|