제퍼넷 로고

다중 GPU 및 Dask로 신경망 훈련 속도 향상

시간

다중 GPU 및 Dask로 신경망 훈련 속도 향상

신경망을 훈련할 때 흔히 발생하는 순간은 모델이 CPU에서 충분히 빠르게 훈련되지 않는다는 것을 깨닫고 GPU 사용으로 전환해야 하는 경우입니다. Dask를 사용하면 여러 컴퓨터에 걸친 다중 GPU 모델 교육이 매우 쉬운 것으로 나타났습니다. 이 블로그 게시물은 Dask와 함께 여러 GPU를 사용하는 첫 번째 실험과 그 결과에 관한 것입니다.


By 재클린 놀리스, Saturn Cloud 데이터 과학 책임자


이 블로그 게시물의 기반이 된 이야기입니다.

 

신경망을 훈련할 때 흔히 발생하는 순간은 모델이 CPU에서 충분히 빠르게 훈련되지 않는다는 것을 깨닫고 GPU 사용으로 전환해야 하는 경우입니다. 덜 일반적이지만 여전히 중요한 순간은 대형 GPU라도 모델을 교육하기에는 너무 느리고 추가 옵션이 필요하다는 사실을 깨닫는 순간입니다.

한 가지 옵션은 여러 시스템에 걸쳐 여러 GPU를 함께 연결하여 하나의 단위로 작동하고 모델을 더 빠르게 교육할 수 있도록 하는 것입니다. 대부분의 시간 동안 저는 GPU를 연결하는 것이 엄청나게 어렵고 어쩌면 대규모 모델 훈련을 보여주려는 엔지니어링 팀에게만 가능할 수도 있다는 생각으로 신경망을 사용해 왔습니다. 고맙게도 Dask를 사용하면 여러 컴퓨터에 걸친 다중 GPU 모델 교육이 매우 쉬운 것으로 나타났습니다. 이 블로그 게시물은 Dask와 함께 여러 GPU를 사용하는 첫 번째 실험과 그 결과에 관한 것입니다.

GPU와 함께 Dask를 사용하여 모델을 더 빠르게 훈련하는 방법을 확인하려면 먼저 훈련을 시도할 모델이 필요했습니다. 나는 시애틀 애완동물 면허 데이터로 훈련된 신경망인 내 오랜 친구에게 의지하여 실제처럼 들리는 애완동물 이름을 생성하기로 결정했습니다. 나는 이전에 이 신경망을 다음과 같이 사용했습니다. R의 예, Python과 Dask로 전환하는 것이 재미있을 것 같았습니다. 저는 프레임워크로 PyTorch를 사용하기로 결정했지만, 단어의 패턴을 캡처하기 위해 여전히 다중 계층 LSTM을 사용했습니다.

생성된 이름을 가진 애완동물
사랑스러운 애완동물을 위해 생성된 사랑스러운 이름입니다.

 

이 블로그 게시물 전체는 다음에서 무료로 게재될 수 있습니다. Saturn 클라우드 호스팅 무료 등급 무료 Jupyter 서버와 Dask 클러스터를 사용합니다.

모델 아키텍처

 
 
사실적인 텍스트를 생성하도록 신경망을 훈련하려면 데이터 형식이 적절해야 했습니다. 특히, (문장의 단어가 아닌) 이름의 각 문자를 예측하고 싶기 때문에 기본 데이터는 텍스트의 문자 시작 시퀀스이고 대상 데이터는 텍스트 시퀀스의 다음 문자였습니다. 예를 들어, 애완동물 이름 "SPOT"에 대한 모델을 훈련하려면 첫 글자가 "S"이고, "S" 다음은 "P"이고, "SP" 다음은 "O"가 되도록 훈련해야 합니다. 에. 필러로 공백을 사용했으며 특수 중지 문자는 이름이 완료되었음을 나타냅니다. 이것은 아래와 같이 행렬로 만들어졌습니다(데이터가 너무 길면 이전 문자를 잘라냈습니다).

X_1 X_2 X_3 X_4 X_5 Y
(공백) (공백) (공백) (공백) (공백) S
(공백) (공백) (공백) (공백) S P
(공백) (공백) (공백) S P O
(공백) (공백) S P O T
(공백) S P O T (중지)

그런 다음 각 문자는 1-핫 인코딩되었습니다(따라서 A=1, B=2 등과 같은 사전 값이 주어지고 하나가 0인 1의 벡터로 변환됨). 이를 통해 모델에 대한 입력으로 3차원 이진 행렬을 얻었고 대상으로 2차원 이진 행렬을 얻었습니다.

네트워크는 XNUMX개의 LSTM 레이어와 사전의 각 문자에 대한 노드가 있는 밀집 레이어로 구성되었습니다. XNUMX개의 LSTM 레이어는 텍스트 내의 패턴을 찾고 밀도는 결과를 각 문자 수준 예측에 매핑합니다. 단일 GPU의 경우 단일 함수를 사용하여 모델을 학습합니다.

def train(): device = torch.device(0) # Set GPU as the device dataset = OurDataset(pet_names, device=device) loader = DataLoader(dataset, batch_size=batch_size, shuffle=True, num_workers=0) model = Model() model = model.to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) for epoch in range(num_epochs): dataset.permute() for i, (batch_x, batch_y) in enumerate(loader): optimizer.zero_grad() batch_y_pred = model(batch_x) loss = criterion(batch_y_pred.transpose(1, 2), batch_y) loss.backward() optimizer.step() time = datetime.datetime.now().isoformat() print(f"{time} - epoch {epoch} - loss {loss.item()}") return model

(최종 모델의 전체 코드는 여기에서 찾을 수 있습니다. Saturn Cloud GitHub 리포지토리.)

여러 GPU를 사용한 훈련

 
 
다중 GPU로 훈련하는 기본 아이디어는 PyTorch의 DDP(Distributed Data Parallel) 기능을 사용하는 것입니다. DDP를 사용하면 동시에 훈련되는 여러 모델이 각 배치 후에 서로 매개변수를 전달하고 동시에 기울기를 계산할 수 있습니다. 따라서 DDP로 모델을 훈련하는 장치가 3개 있는 경우 이는 3배 큰 배치 크기로 단일 모델을 훈련하는 것과 같습니다. 장치는 모두 동시에 훈련되므로 이 시나리오에서는 모델이 배치 크기가 XNUMX배 더 큰 단일 장치의 모델보다 XNUMX배 더 빠르게 훈련될 수 있다는 것이 이론적으로 가능합니다. 실제로는 모델 간 통신 시 대기 시간 때문에 그렇지 않습니다. 그러나 여전히 결과는 꽤 좋을 수 있습니다.

내 훈련 코드를 다중 GPU 설정으로 전환하려면 몇 가지 조정이 필요했습니다. 먼저, 앞으로 훈련할 때 모델 주위에 PyTorch DDP 래퍼를 추가해야 했습니다. 그리고 다시 전체 코드는 다음에서 사용할 수 있습니다. GitHub의):

model = Model()
model = model.to(device) # Was in single-GPU scenario
model = DDP(model) # Added for multi-GPU scenario

다음으로, 단일 기계만 작업(예: Epoch 마지막에 출력 작성)을 수행하기를 원하는 훈련 기능의 모든 위치에서 "한 명의 작업자만 이 작업을 수행하도록 합니다"라는 논리문을 포함해야 했습니다. 직원번호를 사용했어요 0 이 명령을 실행하는 사람으로.

worker_rank = int(torch.distributed.get_rank())
if worker_rank == 0: # ...

그런 다음 dask.delayed를 사용하여 여러 버전의 훈련 기능을 동시에 실행했습니다. 추가한 후 @dask.delayed 훈련 함수 위에 데코레이터를 사용했습니다. dask_pytorch_ddp 함수를 실행하기 위한 간단한 래퍼로:

from dask_pytorch_ddp import dispatch
futures = dispatch.run(client, train)

마지막으로 Dask 클러스터 내에서 결과가 저장되는 위치를 조정하는 대신 모델 결과를 기록하기 위해 다음을 사용했습니다. 무게와 Biases 결과와 모델을 저장하는 장소로 사용됩니다.

결과 비교

 
 
분석을 위해 여러 매개변수를 조정하고 단일 GPU 버전과 다중 GPU 버전이 어떻게 다른지 살펴보기로 결정했습니다. 비교를 단순화하기 위해 단일 GPU의 경우 여전히 DDP 기반 코드를 사용했지만 하나의 시스템에서만 사용했습니다(완전히 제거하는 대신).

  • 네트워크 GPU – 1, 4, 16
  • GPU당 훈련 배치 크기 – 1024, 4096, 16384
  • 모델 학습률 – 0.001, 0.004, 0.016

그런 다음 Saturn Cloud Dask 클러스터를 사용하여 각 조합을 반복했습니다. 다양한 실험 결과를 비교할 때는 주의해야 합니다. 동등한 비교를 위해 네트워크 GPU 수가 4배 증가한 경우 GPU당 훈련 크기를 값의 1/4로 줄여야 합니다. 나는 내 비교가 동등하지 않다는 것을 깨닫기 전에 무엇이 잘못되었는지 알아내려고 몇 시간을 보냈을 것입니다. 그 결과는 다음과 같습니다.

GPU 실험 실행

보시다시피, 더 많은 GPU를 사용하면 모델을 훈련하는 데 걸리는 시간을 크게 줄이는 동시에 동일한 품질의 모델 정확도를 제공할 수 있습니다.

다음은 다른 방식으로 시각화된 동일한 데이터의 그래프입니다. 훈련 실행 기간에 대한 곡선을 표시하는 대신 모델이 합리적인 수준의 정확도에 도달하기까지 걸리는 시간을 나타냅니다. GPU 수를 4배 늘리면 속도가 거의 4배 향상되는 것을 볼 수 있습니다.

최소 시간을 달성하기 위한 GPU 실험
 

이 매우 놀라운 결과에 대한 몇 가지 참고 사항입니다. 첫째, 이러한 기술은 모델에 더 큰 배치 크기가 필요할 때 가장 잘 작동합니다. 다중 GPU는 결과 속도를 높일 뿐만 아니라 메모리 부족 오류도 방지할 수 있습니다. 따라서 문제가 충분히 단순하다면 속도는 여전히 증가하지만 여러 GPU를 사용하여 많은 가치를 얻지 못할 수 있습니다. 하지만 GPU가 통신하는 데 걸리는 시간이 길면 이 값도 줄어들 수 있습니다. 또한 GPU 모델 교육을 모두 조정하는 여러 시스템을 보유하는 것 외에도 V100 그래픽 카드와 같은 리소스를 사용하여 동일한 시스템에서 여러 GPU를 사용하여 교육하는 옵션도 있습니다. 이는 DDP만 사용하여 수행할 수 있습니다. Dask가 로컬로 통신하도록 하는 것은 여전히 ​​작동할 수 있지만 아마도 중복될 것입니다.

Dask와 함께 여러 GPU를 사용하여 동일한 모델을 조정된 방식으로 교육하는 것 외에도 Dask를 사용하여 다양한 매개변수 세트로 모델을 동시에 교육할 수 있습니다. 이를 통해 매개변수 공간을 훨씬 더 빠르게 탐색할 수 있습니다. 빠른 하이퍼 매개변수 조정을 위해 Dask-ML과 같은 도구를 사용하면 더 빠르게 탐색할 수 있습니다.

마지막으로, 이 모든 노력의 결실을 확인하기 위해 모델이 생성한 애완동물 이름 세트가 아래에 나와 있습니다(직접 생성할 수도 있음). 여기에서 지금 확인해 보세요.).

['Karfa', 'Samalpidells', 'Avexen', 'Ejynsp', 'Charlie', 'Kooie', 'Winnundie', 'Wunla', 'Scarlie A', 'Fli', 'Argio', 'Kucka', 'Karlor', 'Litr', 'Bheneng', 'Gelo', 'Cangalantynes', 'Mop', 'Nimi', 'Hary', 'Cassm Tur', 'Ullyne', 'Hollylof', 'Sopa', 'Ghugy', 'Bigde', 'Nucha', 'Mudser', 'Wridney', 'Mar Bas', 'Rugy Bi', 'Roba', 'Ruedel', 'Henrie', 'Sharlia Hu', 'Yellaj', 'Balil']

 
바이오 : 재클린 놀리스 그는 비즈니스 문제를 해결하기 위해 데이터 과학을 사용하는 데 XNUMX년 이상의 경험을 갖고 있으며 Microsoft, Adobe, Airbnb 및 T-Mobile에서 데이터 과학, 기계 학습 및 AI 프로젝트를 주도했으며 처음부터 데이터 과학 팀을 구성하는 데 도움을 주었습니다.

실물. 허가를 받아 다시 게시했습니다.

관련 :


PlatoAi. Web3 재창조. 데이터 인텔리전스 증폭.
액세스하려면 여기를 클릭하십시오.

출처: https://www.kdnuggets.com/2021/09/speeding-neural-network-training-multiple-gpus-dask.html

spot_img

최신 인텔리전스

spot_img

우리와 함께 채팅

안녕하세요! 어떻게 도와 드릴까요?