HyperParameter Tuning - Ray
Date:
Multi GPU
- 예전에는 어떻게 하면 GPU를 적게 쓸까?
- 지금은 GPU를 많이 사용하여 성능좋은 모델을 만들자!
- 오늘날의 딥러닝은 엄청난 데이터와의 싸움(GPT-3 $10^11$ 데이터를 사용)
- 연구는 장비빨…
기본 개념 정리
- single GPU : GPU 1개
- Multi GPU : GPU 2개 이상
- Node는 1대의 컴퓨터를 의미함
- Single Node Single GPU - 1대의 컴퓨터에 GPU 1개
- Single Node Multi GPU(4~8개?) - 1대의 컴퓨터에 2개 이상의 GPU
- Multi Node Multi GPU(server) - 여러대의 컴퓨터에 여러개의 GPU
Multi GPU 사용 방법
1. Model Parallel
- 모델을 GPU에 따로 나눠서 돌리는 것
- 예전부터 많이 사용했던 방식 (Alexnet에 사용)
- 사실 모델의 병목현상과 파이프라인의 어려움으로, 모델 병렬화는 고난이도 과제
- 프로세스
- Model1,2를 각각 GPU1,2에 넣어줌
- network 학습 -> 중간에 데이터를 다른 GPU로 넘겨주며 병목현상 발생
- 마지막 결과를 GPU하나로 모아서 Loss or 결과 출력
- 동일한 데이터를 모델을 둘로 나눠 Multi GPU를 사용함
📰code
class ModelParallelResNet50(ResNet):
def __init__(self, *args, **kwargs):
super(ModelParallelResNet50, self).__init__(
Bottleneck, [3, 4, 6, 3], num_classes=num_classes, *args, **kwargs)
self.seq1 = nn.Sequential(self.conv1, self.bn1, self.relu, self.maxpool, self.layer1, self.layer2).to('cuda:0')# GPU1
self.seq2 = nn.Sequential(self.layer3, self.layer4, self.avgpool).to('cuda:1') #GPU2
self.fc.to('cuda:1') #GPU2
def forward(self, x):
x = self.seq2(self.seq1(x).to('cuda:1')) #GPU로 합쳐서 마지막 작업 진행
return self.fc(x.view(x.size(0), -1))
2. Data Parallel
-
데이터를 Batch로 나눠서 L# Hyperparameter Tuning
- 모델 학습을 할 때 사람이 정해줘야하는 몇까지 parameter들을 Hyperparameter라고 부름
- 학습률(Learning_Rate), Activation Function 등
-
성능을 높이기 위해서 크게 3가지 방법을 사용함(제일 효과가 큰 건 Data)
- 모델을 바꿔본다 -> 거의 고정되어 있음(CV : Resnet, CNN 계열, ViT /NLP : transformer)
- 데이터 추가 or 이상 데이터 -> 제일 중요함, 제일 많이 바꿈
- Hyperparameter Tuning -> 마른 수건도 짜보는 느낌
-> 모델 스스로 학습하지 않는 값은 사람이 지정(learning rate(NAS), 모델의 크기, Optimizer 등등)
- 예전에는 Hyperparameter에 따라서 결과가 크게 좌우됨(요즘은 차이가 크지 않음, why? 데이터를 훨씬 많이 사용하기 때문)
- 마지막 성능을 0.01, 0.001 쥐어짜야할때 시도..
Hyperparameter를 찾는 방법
Grid Search
- 몇개의 Hyperparameter를 특정 범위에서 변동 시키며 확인하는 방법
- 일정한 간격(log scale)으로 Grid를 만들어 최적의 hyperparameter를 찾음
random Search
- Hyperparameter를 랜덤으로 선택하여 최적의 hyperparameter를 찾음
BOHB(2018)
- 베이지안 기반 기법으로 요즘 유행함
- 참고자료
Ray
- Multi-node Multi processing 지원 모듈
- ML/DL의 병렬 처리를 위한 개발된 모듈
- 요즘의 Python 병렬처리는 Ray가 거의 표준
- Hyperparameter Search를 위한 다양한 모듈 제공
- SPARK를 만든 연구실, 요즘은 Ray에 집중하고 있다고 함
💡 SPARK(데이터를 병렬처리하는 모듈, 하둡의 기능을 뛰어넘음)
-
ray를 활용하기 위해서는 기본적으로 4가지를 만들어줘야함
- 탐색할 Hyperparameter별 범위 설정(search space 지정) - dictionary형태로
- 어떻게 학습할지 학습 알고리즘 설정
- 결과를 출력 양식 설정
- 위 3가지를 모아서 result로 하나로 묶어주는 작업
📰code
data_dir = os.path.abspath("./data")
load_data(data_dir)
config = {
"l1": tune.sample_from(lambda _: 2 ** np.random.randint(2, 9)),
"l2": tune.sample_from(lambda _: 2 ** np.random.randint(2, 9)),
"lr": tune.loguniform(1e-4, 1e-1),
"batch_size": tune.choice([2, 4, 8, 16])
}
scheduler = ASHAScheduler(metric="loss", mode="min", max_t=max_num_epochs, grace_period=1,reduction_factor=2)
reporter = CLIReporter(metric_columns=["loss", "accuracy", "training_iteration"])
result = tune.run(
partial(train_cifar, data_dir=data_dir),
resources_per_trial={"cpu": 2, "gpu": gpus_per_trial},
config=config, num_samples=num_samples,
scheduler=scheduler,
progress_reporter=reporter
)
📌reference
- boostcourse AI tech
- Random Search for Hyper-Parameter Optimization
💡 수정 필요한 내용은 댓글이나 메일로 알려주시면 감사하겠습니다!💡
댓글