pytorch gpu parallel 설정
언제나 그렇듯 gpu 설정은 빡치는 작업이다
nvidia-docker로 띄우고 끝나는게 아니라 cudnn 도 설정해줘야하고 등등등......
아무튼 환경 설정은 어찌어찌 해서 gpu를 사용하는데
torch.nn.DataParallel을 사용해서 학습을 시키는데
메모리만 잡아먹고 오른쪽 사용량은 100%와 0%를 1:1 비율로 오락가락하는 모습을 보여준다 (딥빡)
그래서 아래 링크를 보고 gpu 병렬 처리를 다시 설정하려는데
🔥PyTorch Multi-GPU 학습 제대로 하기
PyTorch를 사용해서 Multi-GPU 학습을 하는 과정을 정리했습니다. 이 포스트는 다음과 같이 진행합니다.
medium.com
왜 jupyter나 내부 코드에서 돌리는 예제가 아닙니까 선생님.....
그래서 apex 분산 병렬 처리를 사용하려고 했다
이건 여러 대의 컴퓨터에서 하나의 모델을 학습하는데 쓰는 거라 분산 처리 환경을 설정해줘야 하는 단점? 이라고 해야하나
그래서 아래 링크들을 보고 코드를 따라해봤다
https://9bow.github.io/PyTorch-tutorials-kr-0.3.1/intermediate/dist_tuto.html
Pytorch로 분산 어플리케이션 개발하기 — PyTorch Tutorials 0.3.1 documentation
이 짧은 튜토리얼에서 Pytorch의 분산 패키지를 둘러봅니다. 분산 설정 방법을 살펴보고, 다른 통신 전략을 사용하고, 몇몇 내부 패키지를 확인해 봅니다. Setup Pytorch에 포함된 분산 패키지 (i.e., torch.distributed)는 연구자와 개발자가 여러개의 프로세서와 머신 클러스터에서 계산을 쉽게 병렬화하게 해준다.
9bow.github.io
이거 맨 위하고 맨 아래 코드 보고 코드 복붙해봤는데 안됌....
tcp가 아니라 nccl 로 설정해야하나 해서 해보니 안됌.... (쓰레기 같은)
그래서 아래 링크에서 그 아래 코드를 따옴
https://forums.fast.ai/t/distributeddataparallel-init-hanging/41218
DistributedDataParallel init hanging
Hi, I am trying to do single node multi-gpu (4 gpus) training with DistributedDataParallel using to_distributed(): # environment vars os.environ['CUDA_VISIBLE_DEVICES'] ='0,1,2,3' os.environ['MASTER_ADDR'] = '127.0.0.1' os.environ['MASTER_PORT'] = '5444' o
forums.fast.ai
os.environ['MASTER_ADDR'] = '127.0.0.1'
os.environ['MASTER_PORT'] = '29500'
os.environ['WORLD_SIZE'] = '4'
os.environ['RANK'] = '0'
torch.distributed.init_process_group(backend='nccl')
이랬는데 init_process_group에서 한세월 걸리면서 넘어가지를 않더라....
그래서 이번에는 python의 multiprocessing을 이용해서 해보려고 해찌
https://pytorch.org/docs/stable/notes/multiprocessing.html
Multiprocessing best practices — PyTorch master documentation
Multiprocessing best practices torch.multiprocessing is a drop in replacement for Python’s python:multiprocessing module. It supports the exact same operations, but extends it, so that all tensors sent through a python:multiprocessing.Queue, will have thei
pytorch.org
이거 써봤는데 'spawn' 어쩌구 에러가 떠서
from multiprocessing import set_start_method
set_start_method('spawn')
이거도 썼는데 에러뜸....
좀 찾아보니까
set_start_method('spawn', force=True)
이거 쓰니까 일단 넘어는 가지고 돌아는 가졌는데
돌아'만' 가지고 프로세스가 에러도 안뱉고 죽어버린다
그러면서 core.~~ 파일을 생성하고 튀어버리는데 부셔버리고 싶었다
그래서 다시 맨 처음으로 돌아가서
🔥PyTorch Multi-GPU 학습 제대로 하기
PyTorch를 사용해서 Multi-GPU 학습을 하는 과정을 정리했습니다. 이 포스트는 다음과 같이 진행합니다.
medium.com
여기서 loss function 만 parallel 하는 코드가 있길래 고대로 따라해서
loss_fn = torch_util.DataParallelCriterion(bootstrapped_cross_entropy2d)
는 씨알도 안먹히고
대신에 loss function을 pytorch 안에 있는 loss와 같이 만들었다
class bootstrapped_cross_entropy2d(torch.nn.modules.loss._Loss):
def __init__(self, size_average=True, reduce=False, reduction='mean'):
super(bootstrapped_cross_entropy2d, self).__init__(size_average, reduce, reduction)
self.size_average = size_average
self.reduce = False
def forward(self, input, target, min_K=4096, loss_th=0.3, weight=None):
n, c, h, w = input.size()
nt, ht, wt = target.size()
batch_size = input.size()[0]
if h != ht and w != wt: # upsample labels
input = F.interpolate(input, size=(ht, wt), mode="bilinear", align_corners=True)
thresh = loss_th
def _bootstrap_xentropy_single(input, target, K, thresh, weight=None, size_average=True):
n, c, h, w = input.size()
input = input.transpose(1, 2).transpose(2, 3).contiguous().view(-1, c)
target = target.view(-1)
loss = F.cross_entropy(
input, target, weight=weight, reduce=self.reduce, size_average=self.size_average, ignore_index=250
)
sorted_loss, _ = torch.sort(loss, descending=True)
if sorted_loss[K] > thresh:
loss = sorted_loss[sorted_loss > thresh]
else:
loss = sorted_loss[:K]
reduced_topk_loss = torch.mean(loss)
return reduced_topk_loss
loss = 0.0
# Bootstrap from each image not entire batch
for i in range(batch_size):
loss += _bootstrap_xentropy_single(
input=torch.unsqueeze(input[i], 0),
target=torch.unsqueeze(target[i], 0),
K=min_K,
thresh=thresh,
weight=weight,
size_average=self.size_average,
)
return loss / float(batch_size)
이렇게 하고 loss function을 생성할 때는 아래와 같이 선언
loss_fn = bootstrapped_cross_entropy2d().to(device)
이렇게 하고 추가적으로 data loader도 건드려줬다
num_worker = 4, pin_memory=True로 설정해줬더니 30분에서 15분으로 줄어들었다
(근데 loss function에서 .to(device)는 해당 train time을 줄이는데 기여한 것은 아닌걸로 보임)
loss function은 모델하고 데이터가 gpu에 올라가면 loss function도 자동적으로 gpu에서 해주나 싶은데....
그건 나중에 테스트해보고 bacth size하고 num_workers 테스트해서 한계까지 설정했는데도 15분 나온다