인공지능/Toy Projects

Multi-GPU Deep Learning_1 (using DDP)

은긔짜응 2022. 5. 12. 14:59

목차

    Introduction

    Data Parallel과 분산 딥러닝에 익숙해지기 위해서 간단한 auto-encoder를 만들었다.

    Data Parallel에는 크게 DP와 DDP가 있는데, 그 둘의 차이점은 이미 간단하게 서술한바가 있다.

     

    Data Parallel(DP), Distributed Data Parallel(DDP)의 차이

    목차 Keywords Data Parallel(DP), Distributed Data Parallel (DDP), Multi-GPU training, All reduce Data Parallel(DP), Distributed Data Parallel(DDP)의 차이 Compared to DataParallel, DistributedDataPar..

    engui-note.tistory.com

    본 실험에서는 DDP를 이용해 분산 딥러닝을 실험한다.

     

    Method & Material

    주요 실험환경은 다음과 같다.

    • Intel(R) Xeon(R) Gold 5120 CPU @ 2.20GHz
    • Tesla V100-SXM2 32GB * 3
    • 256GB RAM

     

    실험에 사용한 서버가 특정 서버를 거쳐야만 접속이 가능한 구조를 가지고 있기 때문에, ssh를 두 번 이용해야만 접근이 가능하다. 이 귀찮음을 해결하기위해 중간 서버를 proxy서버처럼 취급하여 실험서버에 바로 접근할 수 있는 방법을 찾아 적용했다. 해당 내용은 이전에 간단하게 서술했으므로 아래 내용을 참고하면 된다.

     

    특정 서버를 경유해야하는 SSH, SCP 설정(ProxyJump)

    목차 특정 서버를 경유해야하는 SSH, SCP 설정 local PC에서 직접적으로 접속할 수 없는 서버에 접속해야하는 경우가 생길때가 있다. 예를 들어 서버에 설치된 VM이나, docker에 접근하게되는 경우

    engui-note.tistory.com

     

    실험에 사용한 데이터는 이전에 image segmentation 할 때 미리 만들어 둔 이세돌 영상을 이용했고, 모델은 우선 간단하게 Auto-Encoder를 사용했다.

    self.encoder = nn.Sequential(
                nn.Conv2d(3,8,kernel_size=5, padding=2), 
                nn.ReLU(), 
                nn.MaxPool2d(4,4),
                nn.Conv2d(8,16,kernel_size=5, padding=2),
                nn.ReLU(),
                nn.MaxPool2d(5,5),
                )
    self.decoder = nn.Sequential(
                nn.ConvTranspose2d(16,8,kernel_size=5,stride = 5),
                nn.ReLU(),
                nn.ConvTranspose2d(8,3,kernel_size=5,stride = 4, padding=1, output_padding=1),
                nn.ReLU()
                )

    Pytorch lightning을 이용해 구현하였으며,  Data Parallel이 잘 적용되는지 확인하기 위해 GPU갯수, batch size등을 바꿔가며 실험을 진행했다.

    학습이 잘 진행되는지 분석하기위해 logger는 wandb를 사용했으며, 다양한 machine에서 사용할 수 있게 하기위해 ONNX 형식으로도 모델을 출력했다.

     

    Result

    실제 모델을 만드는 것이 중요한 실험이 아니라 DDP를 이용한 분산 딥러닝을 테스트하는 것이 주 목적이므로, 학습데이터셋과 검증데이터셋을 그냥 같은 데이터셋으로 퉁쳐서 데이터로더를 구성했다.

    실험에 사용한 데이터셋의 크기는 학습데이터셋과 검증데이터셋이 각각 6472개 이다.

    다양한 batch size와 gpu갯수에서 실행해봤다.

    Num_GPUS Batch_size iters per epoch total training time
    3 128 34 33 secs
    1 128 102 55 secs
    3 64 68 31 secs

    1epoch에서 학습데이터셋 한번, 검증데이터셋 한번을 돌리기 때문에 iters per epoch은 학습데이터 iter + 검증데이터 iter값이 나오게된다.

    즉 17iter = (6472/3/128=16.85)가 2번 적용되서 첫번째 실험의 iters per epoch가 34로 나오게된다.

    gpu갯수와 batch size에따라 iters per epoch값이 바뀌는 걸 보면 gpu에 데이터가 잘 분산되어 학습되는 것을 확인할 수 있다.

    그리고 batch size와 training time간의 관계는 유의미해보이지 않는데, GPU개수와 training time간의 관계는 유의미해보인다.

    GPU를 많이 쓸 수록 학습이 더 빠르게 되는 경향을 확인할 수 있다.

     

    GPU 3개, Batch_size 128환경에서 테스트한 내용이다.

    GPU 1개, Batch_size 128환경에서 테스트한 내용이다.

    GPU 3개, Batch_size 64환경에서 테스트한 내용이다.

     

    Conclusion & Discussion

    기존에 가지고 있던 이미지 데이터에 단순한 auto-encoder를 적용해 분산 딥러닝을 실험해봤다.

    본 글에 작성한 실험 내용 외에도 약 20번의 실험을 더 진행했는데, 확실히 GPU를 많이 쓸 수록 학습이 더 빠르게 되는 경향을 확인할 수 있었다.

    코드 구현자체가 어렵지는 않았지만, data loader를 만들때 삽질을 좀 해서 생각보다 시간이 오래걸렸다.

    결국 dataloader를 따로 만들지 못해서 auto-encoder 모델에 dataloader까지 포함시켜서 학습하긴 했는데, 다음 실험에서는 dataloader를 따로 모듈화시키고 auto-encoder가 아닌 mask r-cnn을 학습시켜볼 예정이다.

     

    실험한 코드는 깃헙에 정리했다.

     

    GitHub - wlsdml1114/ddp_test: distributed data parallel test

    distributed data parallel test. Contribute to wlsdml1114/ddp_test development by creating an account on GitHub.

    github.com