1- Getting Started with Distributed Data Parallel
2- =================================================
3- **Author **: `Shen Li <https://mrshenli.github.io/ >`_
1+ 분산 데이터 병렬 처리 시작하기
2+ ===================================
3+ **저자 **: `Shen Li <https://mrshenli.github.io/ >`_
44
5- **Edited by **: `Joe Zhu <https://github.com/gunandrose4u >`_
5+ **감수 **: `Joe Zhu <https://github.com/gunandrose4u >`_
66
7- Prerequisites:
7+ ** 번역 **: ` 조병근 < https://github.com/Jo-byung-geun >`_
88
9- - `PyTorch Distributed Overview <../beginner/dist_overview.html >`__
10- - `DistributedDataParallel API documents <https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html >`__
11- - `DistributedDataParallel notes <https://pytorch.org/docs/master/notes/ddp.html >`__
9+ 선수과목(Prerequisites):
1210
11+ - `PyTorch 분산 처리 개요 <../beginner/dist_overview.html >`__
12+ - `분산 데이터 병렬 처리 API 문서 <https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html >`__
13+ - `분산 데이터 병렬 처리 문서 <https://pytorch.org/docs/master/notes/ddp.html >`__
1314
14- `DistributedDataParallel <https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel >`__
15- (DDP) implements data parallelism at the module level which can run across
16- multiple machines. Applications using DDP should spawn multiple processes and
17- create a single DDP instance per process. DDP uses collective communications in the
18- `torch.distributed <https://tutorials.pytorch.kr/intermediate/dist_tuto.html >`__
19- package to synchronize gradients and buffers. More specifically, DDP registers
20- an autograd hook for each parameter given by ``model.parameters() `` and the
21- hook will fire when the corresponding gradient is computed in the backward
22- pass. Then DDP uses that signal to trigger gradient synchronization across
23- processes. Please refer to
24- `DDP design note <https://pytorch.org/docs/master/notes/ddp.html >`__ for more details.
2515
16+ `분산 데이터 병렬 처리 <https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel >`__\( DDP)는
17+ 여러 기기에서 실행할 수 있는 데이터 병렬 처리를 모듈 수준에서 구현합니다.
18+ DDP를 사용하는 어플리케이션은 여러 작업(process)을 생성하고 작업 당 단일 DDP 인스턴스를 생성해야 합니다.
19+ DDP는 `torch.distributed <https://tutorials.pytorch.kr/intermediate/dist_tuto.html >`__
20+ 패키지의 집합 통신(collective communication)을 사용하여 변화도(gradient)와 버퍼를 동기화합니다.
21+ 좀 더 구체적으로, DDP는 ``model.parameters() ``\에 의해 주어진 각 파라미터에 대해 Autograd hook을 등록하고,
22+ hook은 역방향 전달에서 해당 변화도가 계산될 때 작동합니다.
23+ 다음으로 DDP는 이 신호를 사용하여 작업 간에 변화도 동기화를 발생시킵니다. 자세한 내용은
24+ `DDP design note <https://pytorch.org/docs/master/notes/ddp.html >`__\를 참조하십시오.
2625
27- The recommended way to use DDP is to spawn one process for each model replica,
28- where a model replica can span multiple devices. DDP processes can be
29- placed on the same machine or across machines, but GPU devices cannot be
30- shared across processes. This tutorial starts from a basic DDP use case and
31- then demonstrates more advanced use cases including checkpointing models and
32- combining DDP with model parallel.
26+
27+ DDP의 권장 사용법은, 여러 장치에 있을 수 있는 각 모델 복제본당 하나의 작업을 생성하는 것입니다.
28+ DDP 작업은 동일한 기기 또는 여러 기기에 배치할 수 있지만 GPU 장치는 작업 간에 공유할 수 없습니다.
29+ 이 튜토리얼에서는 기본 DDP 사용 사례에서 시작하여,
30+ checkpointing 모델 및 DDP와 모델 병렬 처리의 결합을 포함한 추가적인 사용 사례를 보여줍니다.
3331
3432
3533.. note ::
36- The code in this tutorial runs on an 8-GPU server, but it can be easily
37- generalized to other environments.
38-
39-
40- Comparison between ``DataParallel `` and ``DistributedDataParallel ``
41- -------------------------------------------------------------------
42-
43- Before we dive in, let's clarify why, despite the added complexity, you would
44- consider using ``DistributedDataParallel `` over ``DataParallel ``:
45-
46- - First, ``DataParallel `` is single-process, multi-thread, and only works on a
47- single machine, while ``DistributedDataParallel `` is multi-process and works
48- for both single- and multi- machine training. ``DataParallel `` is usually
49- slower than ``DistributedDataParallel `` even on a single machine due to GIL
50- contention across threads, per-iteration replicated model, and additional
51- overhead introduced by scattering inputs and gathering outputs.
52- - Recall from the
53- `prior tutorial <https://tutorials.pytorch.kr/intermediate/model_parallel_tutorial.html >`__
54- that if your model is too large to fit on a single GPU, you must use **model parallel **
55- to split it across multiple GPUs. ``DistributedDataParallel `` works with
56- **model parallel **; ``DataParallel `` does not at this time. When DDP is combined
57- with model parallel, each DDP process would use model parallel, and all processes
58- collectively would use data parallel.
59- - If your model needs to span multiple machines or if your use case does not fit
60- into data parallelism paradigm, please see `the RPC API <https://pytorch.org/docs/stable/rpc.html >`__
61- for more generic distributed training support.
62-
63- Basic Use Case
64- --------------
65-
66- To create DDP modules, first set up process groups properly. More details can
67- be found in
68- `Writing Distributed Applications with PyTorch <https://tutorials.pytorch.kr/intermediate/dist_tuto.html >`__.
34+ 이 튜토리얼의 코드는 8-GPU 서버에서 실행되지만 다른 환경에서도 쉽게 적용할 수 있습니다.
35+
36+ ``DataParallel ``\과 ``DistributedDataParallel `` 간의 비교
37+ ----------------------------------------------------------
38+
39+ 내용에 들어가기에 앞서 복잡성이 증가했음에도 불구하고
40+ ``DataParallel ``\에 ``DistributedDataParallel `` 사용을 고려하는 이유를 생각해봅시다.
41+
42+ - 첫째, ``DataParallel ``\은 단일 작업, 멀티쓰레드이며 단일 기기에서만 작동하는 반면,
43+ ``DistributedDataParallel ``\은 다중 작업이며 단일 및 다중 기기 학습을 전부 지원합니다.
44+ ``DataParallel ``\은 쓰레드간 GIL 경합, 복제 모델의 반복 당 생성, 산란 입력 및 수집 출력으로 인한
45+ 추가적인 오버헤드로 인해 일반적으로 단일 시스템에서조차 ``DistributedDataParallel ``\보 다 느립니다.
46+ - 모델이 너무 커서 단일 GPU에 맞지 않을 경우 **model parallel **\을 사용하여 여러 GPU로 분할해야 한다는
47+ `prior tutorial <https://tutorials.pytorch.kr/intermediate/model_parallel_tutorial.html >`__\을 떠올려 보세요.
48+ ``DistributedDataParallel ``\은 **model parallel **\에 서 실행되지만 ``DataParallel ``\은 이때 실행되지 않습니다.
49+ DDP를 모델 병렬 처리와 결합하면 각 DDP 작업은 모델 병렬 처리를 사용하며
50+ 모든 작업은 데이터 병렬 처리를 사용합니다.
51+ - 모델이 여러 대의 기기에 존재해야 하거나 사용 사례가 데이터 병렬화 패러다임에 맞지 않는 경우,
52+ 일반적인 분산 학습 지원을 보려면 `the RPC API <https://pytorch.org/docs/stable/rpc.html >`__\를 참조하십시오.
53+
54+
55+
56+ 기본적인 사용법
57+ ---------------
58+
59+ DDP 모듈을 생성하기 전에 우선 작업 그룹을 올바르게 설정해야 합니다. 자세한 내용은
60+ `PYTORCH로 분산 어플리케이션 개발하기 <https://tutorials.pytorch.kr/intermediate/dist_tuto.html >`__\에 서 확인할 수 있습니다.
6961
7062.. code :: python
7163
@@ -80,32 +72,32 @@ be found in
8072
8173 from torch.nn.parallel import DistributedDataParallel as DDP
8274
83- # On Windows platform, the torch.distributed package only
84- # supports Gloo backend, FileStore and TcpStore.
85- # For FileStore, set init_method parameter in init_process_group
86- # to a local file. Example as follow:
75+ # 윈도우 플랫폼에서 torch.distributed 패키지는
76+ # Gloo backend, FileStore 및 TcpStore 만을 지원합니다.
77+ # FileStore의 경우, init_process_group 에서
78+ # init_method 매개변수를 로컬 파일로 설정합니다.
79+ # 다음 예시:
8780 # init_method="file:///f:/libtmp/some_file"
8881 # dist.init_process_group(
8982 # "gloo",
9083 # rank=rank,
9184 # init_method=init_method,
9285 # world_size=world_size)
93- # For TcpStore, same way as on Linux .
86+ # TcpStore의 경우 리눅스와 동일한 방식입니다 .
9487
9588 def setup (rank , world_size ):
9689 os.environ[' MASTER_ADDR' ] = ' localhost'
9790 os.environ[' MASTER_PORT' ] = ' 12355'
9891
99- # initialize the process group
92+ # 작업 그룹 초기화
10093 dist.init_process_group(" gloo" , rank = rank, world_size = world_size)
10194
10295 def cleanup ():
10396 dist.destroy_process_group()
10497
105- Now, let's create a toy module, wrap it with DDP, and feed it with some dummy
106- input data. Please note, as DDP broadcasts model states from rank 0 process to
107- all other processes in the DDP constructor, you don't need to worry about
108- different DDP processes start from different model parameter initial values.
98+ 이제 DDP로 감싸여진 Toy 모듈을 생성하고 더미 입력 데이터를 입력해 보겠습니다.
99+ 우선 DDP는 0순위 작업에서부터 DDP 생성자의 다른 모든 작업들에게 모델의 상태를 전달하므로,
100+ 다른 모델의 매개 변수 초기값들에서 시작하는 다른 DDP 작업들에 대하여 걱정할 필요가 없습니다.
109101
110102.. code :: python
111103
@@ -124,7 +116,7 @@ different DDP processes start from different model parameter initial values.
124116 print (f " Running basic DDP example on rank { rank} . " )
125117 setup(rank, world_size)
126118
127- # create model and move it to GPU with id rank
119+ # 모델을 생성하고 순위 아이디가 있는 GPU로 전달
128120 model = ToyModel().to(rank)
129121 ddp_model = DDP(model, device_ids = [rank])
130122
@@ -146,47 +138,40 @@ different DDP processes start from different model parameter initial values.
146138 nprocs = world_size,
147139 join = True )
148140
149- As you can see, DDP wraps lower-level distributed communication details and
150- provides a clean API as if it is a local model. Gradient synchronization
151- communications take place during the backward pass and overlap with the
152- backward computation. When the ``backward() `` returns, ``param.grad `` already
153- contains the synchronized gradient tensor. For basic use cases, DDP only
154- requires a few more LoCs to set up the process group. When applying DDP to more
155- advanced use cases, some caveats require caution.
156-
157- Skewed Processing Speeds
158- ------------------------
159-
160- In DDP, the constructor, the forward pass, and the backward pass are
161- distributed synchronization points. Different processes are expected to launch
162- the same number of synchronizations and reach these synchronization points in
163- the same order and enter each synchronization point at roughly the same time.
164- Otherwise, fast processes might arrive early and timeout on waiting for
165- stragglers. Hence, users are responsible for balancing workloads distributions
166- across processes. Sometimes, skewed processing speeds are inevitable due to,
167- e.g., network delays, resource contentions, unpredictable workload spikes. To
168- avoid timeouts in these situations, make sure that you pass a sufficiently
169- large ``timeout `` value when calling
170- `init_process_group <https://pytorch.org/docs/stable/distributed.html#torch.distributed.init_process_group >`__.
171-
172- Save and Load Checkpoints
173- -------------------------
174-
175- It's common to use ``torch.save `` and ``torch.load `` to checkpoint modules
176- during training and recover from checkpoints. See
177- `SAVING AND LOADING MODELS <https://tutorials.pytorch.kr/beginner/saving_loading_models.html >`__
178- for more details. When using DDP, one optimization is to save the model in
179- only one process and then load it to all processes, reducing write overhead.
180- This is correct because all processes start from the same parameters and
181- gradients are synchronized in backward passes, and hence optimizers should keep
182- setting parameters to the same values. If you use this optimization, make sure all
183- processes do not start loading before the saving is finished. Besides, when
184- loading the module, you need to provide an appropriate ``map_location ``
185- argument to prevent a process to step into others' devices. If ``map_location ``
186- is missing, ``torch.load `` will first load the module to CPU and then copy each
187- parameter to where it was saved, which would result in all processes on the
188- same machine using the same set of devices. For more advanced failure recovery
189- and elasticity support, please refer to `TorchElastic <https://pytorch.org/elastic >`__.
141+ 보여지는 바와 같이 DDP는 하위 수준의 분산 커뮤니케이션 세부 사항을 포함하고
142+ 로컬 모델처럼 깔끔한 API를 제공합니다. 변화도 동기화 통신(gradient synchronization communications)은
143+ 역전파 전달(backward pass)간 수행되며 역전파 계산(backward computation)과 겹치게 됩니다.
144+ ``backword() ``\가 반환되면 ``param.grad ``\에 는 동기화된 변화도 텐서(synchronized gradient tensor)가 포함되어 있습니다.
145+ 기본적으로 DDP는 작업 그룹을 설정하는데 몇 개의 LoCs만이 필요하지만 보다 다양하게 사용하는 경우 주의가 필요합니다.
146+
147+ 비대칭 작업 속도
148+ --------------------
149+
150+ DDP에서는 생성자, 순전파(forward pass) 및 역전파 전달 호출 지점이 분산 동기화 지점(distribute synchronization point)입니다.
151+ 서로 다른 작업이 동일한 수의 동기화를 시작하고 동일한 순서로 이러한 동기화 지점에 도달하여
152+ 각 동기화 지점을 거의 동시에 진입을 요구합니다.
153+ 그렇지 않으면 빠른 작업이 일찍 도착하고 다른 작업의 대기 시간이 초과될 수 있습니다.
154+ 따라서 사용자는 작업 간의 작업량을 균형 있게 분배할 필요가 있습니다.
155+ 때때로 비대칭 작업(skewed processing) 속도는 다음과 같은 이유로 인하여 불가피하게 발생합니다.
156+ 예를 들어, 네트워크 지연, 리소스 경쟁(resource contentions), 예측하지 못한 작업량 급증 등입니다.
157+ 이러한 상황에서 시간 초과를 방지하려면, `init_process_group <https://pytorch.org/docs/stable/distributed.html#torch.distributed.init_process_group >`__\를
158+ 호출할 때 충분한 ``timeout ``\값 을 전달해야 합니다.
159+
160+ 체크포인트를 저장하고 읽어오기
161+ ------------------------------
162+
163+ 학습 중에 ``torch.save ``\와 ``torch.load `` 로 모듈의 체크포인트를 만들고 그 체크포인트로부터 복구하는 것이 일반적입니다.
164+ 더 자세한 내용은 `SAVING AND LOADING MODELS <https://tutorials.pytorch.kr/beginner/saving_loading_models.html >`__\를 참고하세요.
165+ DDP를 사용할 때, 최적의 방법은 모델을 한 작업에만 저장하고
166+ 그 모델을 모든 작업에 쓰기 과부하(write overhead)를 줄이며 읽어오는 것입니다.
167+ 이는 모든 작업이 같은 매개변수로부터 시작되고 변화도는
168+ 역전파 전달로 동기화되므로 옵티마이저(optimizer)는
169+ 매개변수를 동일한 값으로 계속 설정해야 하기 때문에 정확합니다. 이러한 최적화를 사용하는 경우,
170+ 저장이 완료되기 전에 읽어오는 작업을 시작하지 않도록 해야 합니다. 게다가, 모듈을 읽어올 때,
171+ 작업이 다른 기기에 접근하지 않도록 적절한 ``map_location `` 인자를 제공해야합니다.
172+ ``map_location ``\값 이 없을 경우, ``torch.load ``\는 먼저 모듈을 CPU에 읽어온 다음 각 매개변수가
173+ 저장된 위치로 복사하여 동일한 장치를 사용하는 동일한 기기에서 모든 작업을 발생시킵니다.
174+ 더 추가적인 실패 복구와 엘라스틱(elasticity support)은 `TorchElastic <https://pytorch.org/elastic >`__\을 참고하세요.
190175
191176.. code :: python
192177
@@ -202,13 +187,12 @@ and elasticity support, please refer to `TorchElastic <https://pytorch.org/elast
202187
203188 CHECKPOINT_PATH = tempfile.gettempdir() + " /model.checkpoint"
204189 if rank == 0 :
205- # All processes should see same parameters as they all start from same
206- # random parameters and gradients are synchronized in backward passes .
207- # Therefore, saving it in one process is sufficient .
190+ # 모든 작업은 같은 매개변수로부터 시작된다고 생각해야 합니다.
191+ # 무작위의 매개변수와 변화도는 역전파 전달로 동기화됩니다 .
192+ # 그럼으로, 하나의 작업은 모델을 저장하기에 충분합니다 .
208193 torch.save(ddp_model.state_dict(), CHECKPOINT_PATH )
209194
210- # Use a barrier() to make sure that process 1 loads the model after process
211- # 0 saves it.
195+ # 작업 0이 저장한 후 작업 1이 모델을 읽어오도록 barrier()를 사용합니다.
212196 dist.barrier()
213197 # configure map_location properly
214198 map_location = {' cuda:%d ' % 0 : ' cuda:%d ' % rank}
@@ -222,20 +206,19 @@ and elasticity support, please refer to `TorchElastic <https://pytorch.org/elast
222206 loss_fn(outputs, labels).backward()
223207 optimizer.step()
224208
225- # Not necessary to use a dist.barrier() to guard the file deletion below
226- # as the AllReduce ops in the backward pass of DDP already served as
227- # a synchronization.
209+ # 파일삭제를 보호하기 위해 아래에 dist.barrier()를 사용할 필요는 없습니다.
210+ # DDP의 역전파 전달 과정에 있는 AllReduce 옵스(ops)가 동기화 기능을 수행했기 때문에
228211
229212 if rank == 0 :
230213 os.remove(CHECKPOINT_PATH )
231214
232215 cleanup()
233216
234- Combine DDP with Model Parallelism
235- ----------------------------------
217+ 모델 병렬 처리를 활용한 DDP
218+ ---------------------------
236219
237- DDP also works with multi- GPU models. DDP wrapping multi-GPU models is especially
238- helpful when training large models with a huge amount of data .
220+ DDP는 다중 – GPU 모델에서도 작동합니다.
221+ 다중 – GPU 모델을 활용한 DDP는 대용량의 데이터를 가진 대용량 모델을 학습시킬 때 특히 유용합니다 .
239222
240223.. code :: python
241224
@@ -254,17 +237,16 @@ helpful when training large models with a huge amount of data.
254237 x = x.to(self .dev1)
255238 return self .net2(x)
256239
257- When passing a multi-GPU model to DDP, ``device_ids `` and ``output_device ``
258- must NOT be set. Input and output data will be placed in proper devices by
259- either the application or the model ``forward() `` method.
240+ 다중 GPU 모델을 DDP로 전달할 때, ``device_ids ``\와 ``output_device ``\를 설정하지 않아야 합니다.
241+ 입력 및 출력 데이터는 어플리케이션 또는 모델 ``forward() ``\에 의해 적절한 장치에 배치됩니다.
260242
261243.. code :: python
262244
263245 def demo_model_parallel (rank , world_size ):
264246 print (f " Running DDP with model parallel example on rank { rank} . " )
265247 setup(rank, world_size)
266248
267- # setup mp_model and devices for this process
249+ # 작업을 위한 mp_model 및 장치 설정
268250 dev0 = rank * 2
269251 dev1 = rank * 2 + 1
270252 mp_model = ToyMpModel(dev0, dev1)
@@ -274,7 +256,7 @@ either the application or the model ``forward()`` method.
274256 optimizer = optim.SGD(ddp_mp_model.parameters(), lr = 0.001 )
275257
276258 optimizer.zero_grad()
277- # outputs will be on dev1
259+ # 출력값은 dev1에 저장
278260 outputs = ddp_mp_model(torch.randn(20 , 10 ))
279261 labels = torch.randn(20 , 5 ).to(dev1)
280262 loss_fn(outputs, labels).backward()
0 commit comments