| <!--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`]์ `torch_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 | |
| }, | |
| "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 ๊ตฌ์ฑ[[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"> | |
| PyTorch AMP์ ๊ฐ์ fp16 ํผํฉ ์ ๋ฐ๋๋ฅผ ๊ตฌ์ฑํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ์ค์ด๋ค๊ณ ํ๋ จ ์๋๊ฐ ๋นจ๋ผ์ง๋๋ค.[`Trainer`]๋ `args.fp16_backend` ๊ฐ์ ๋ฐ๋ผ fp16์ ์๋์ผ๋ก ํ์ฑํ ๋๋ ๋นํ์ฑํํ๋ฉฐ, ๋๋จธ์ง ๊ตฌ์ฑ์ ์ฌ์ฉ์๊ฐ ์ค์ ํ ์ ์์ต๋๋ค. ๋ช ๋ น์ค์์ ๋ค์ ์ธ์๋ฅผ ์ ๋ฌํ๋ฉด fp16์ด ํ์ฑํ๋ฉ๋๋ค: `fp16`, `--fp16_backend amp` ๋๋ `--fp16_full_eval`. | |
| ```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) ์ฐธ์กฐ๋ฅผ ์ฐธ์กฐํ์ธ์. | |
| Apex์ ๊ฐ์ fp16 ํผํฉ ์ ๋ฐ๋๋ฅผ ๊ตฌ์ฑํ๋ ค๋ฉด ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด `"auto"` ๋๋ ์ง์ ๊ฐ์ ์ค์ ํฉ๋๋ค.[`Trainer`]๋ `args.fp16_backend` ๋ฐ `args.fp16_opt_level`์ ๊ฐ์ ๋ฐ๋ผ `amp`๋ฅผ ์๋์ผ๋ก ๊ตฌ์ฑํฉ๋๋ค. ๋ค์ ์ธ์๋ฅผ ์ ๋ฌํ๋ฉด ๋ช ๋ น์ค์์ ํ์ฑํํ ์๋ ์์ต๋๋ค: `fp16`, `--fp16_backend apex` ๋๋ `--fp16_opt_level 01`. | |
| ```yaml | |
| { | |
| "amp": { | |
| "enabled": "auto", | |
| "opt_level": "auto" | |
| } | |
| } | |
| ``` | |
| </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 --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 | |
| ``` | |
| </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 --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 | |
| ``` | |
| 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) | |