본문 바로가기

boostcamp AI tech/boostcamp AI

Multi gpu training, Hyper parameter Search, etc

728x90

1. Multi gpu training

- Multi gpu training: 

    - 모델의 sequence1은 gpu0에, sequence2는 gpu1에 분리해서 계산 하거나 (모델 나누기)

    - 데이터 절반은 gpu0에, 나머지 절반은 gpu1에 분리해서 계산 하고 결과를 평균내거나 (데이터 나누기)

- DataParallel : 한명의 gpu가 나머지 gpu에게 데이터 분배, 취합 등의 역할을 수행 (다른 gpu보다 메모리 더 사용)

https://medium.com/huggingface/training-larger-batches-practical-tips-on-1-gpu-multi-gpu-distributed-setups-ec88c3e51255

- DistributedDataParallel : 이 방식으로 데이터를 나누고자 dataloader를 만들 때는 distributedSampler 정의, pin_memory=True등의 설정이 필요함. 예를들어 n개의 cpu가 n개의 gpu에게 각각 데이터를 주고 받고 한다. (모아주는 한명이 없음)

 

2. Hyper parameter tuning

- 성능을 제일 끌어 올리기 좋은 방법은 데이터와 모델에 있다.

- 그럼에도 불구하고 마른 수건에 물을 짜볼 수 있다.

- learning rate, optimizer, batch size 등등을 튜닝

- ray tune 라이브러리 등을 활용 : https://docs.ray.io/en/latest/tune/index.html

 

Ray Tune: Hyperparameter Tuning — Ray 2.8.0

To run this example, install the following: pip install "ray[tune]". In this quick-start example you minimize a simple function of the form f(x) = a**2 + b, our objective function. The closer a is to zero and the smaller b is, the smaller the total value o

docs.ray.io

from ray.tune import CLIReporter
from ray.tune.search.hyperopt import HyperOptSearch

import ray

config_space = {
    "NUM_EPOCH" : tune.choice([4,5,6,7,8,9]),
    "LearningRate" : tune.uniform(0.0001, 0.001),
    "BatchSize" : tune.choice([32,64,128]),
}

optim = HyperOptSearch( # HyperOptSearch 통해 Search를 진행합니다. 더 다양한 Optimizer들은 https://docs.ray.io/en/master/tune/api_docs/suggestion.html#bayesopt 문서를 참고해주세요
    metric='accuracy', # hyper parameter tuning 시 최적화할 metric을 결정합니다. 본 실험은 test accuracy를 target으로 합니다
    mode="max", # target objective를 maximize 하는 것을 목표로 설정합니다
)

NUM_TRIAL = 3 

reporter = CLIReporter( 
    parameter_columns=["NUM_EPOCH", "LearningRate", "BatchSize"],
    metric_columns=["accuracy", "loss"])

ray.shutdown() # ray 초기화 후 실행
ray.init()
analysis = tune.run(
    training,
    config=config_space,
    search_alg=optim,
    #verbose=1,
    progress_reporter=reporter,
    num_samples=NUM_TRIAL,
    resources_per_trial={'gpu': 1}
)

- 이게 main 부분이다.

- 학습 과정을 training 함수로 묶어서 ray가 호출할 수 있도록 한다.

best_trial = analysis.get_best_trial('accuracy', 'max')
print(f"best performance config : {best_trial.config}")
print(f"best test accuracy : {best_trial.last_result['accuracy']}")

- ray가 발견한 가장 좋은 config를 볼 수 있다.

 

3. Etc

- gpu 상태를 보여주는 모듈 

!pip install GPUtil

import GPUtil
GPUtil.showUtilization()

gpu_usage()

torch.cuda.empty_cache()

 

total_loss = 0
for i in range(1000):
    optimizer.zero_grad()
    output = model(input)
    loss = criterion(output)
    loss.backward()
    optimizer.step()
    total_loss += loss

- 메모리 잠식의 문제

- training loop의 모습이다. loss를 계속해서 total_loss에 더하고 있다. tensor를 이렇게 계속 축적하는 것은 gpu 메모리에 큰 영향을 준다. loss tensor의 require_grad=True이기 때문에 버퍼까지 잡느라 이 loss tensor는 더 큰 공간을 점유한다.

- 따라서 loss.item() 으로 스칼라 값만 가져온다던지

- loss를 더하고 나서 del loss로 가비지 컬렉터에게 지워달라 요청하거나

- loss를 누적해서 더하지 말고 [] 리스트에 넣고 for loop 이후 제거하는 방법이 있다.

 

for i, data in enumerate(dataloader):
    ...
    # forward
    ...
    loss.backward()
    
    if (i+1) % accumulation_step == 0:
        optimizer.step()
        optimizer.zero_grad()

- gradient accumulation

- gpu 메모리 제약때문에 큰 배치 크기를 사용할 수 없을 때 사용할 수 있는 방법이다.

- 여러 작은 배치에 대한 gradient를 축적한 다음 한번에 모델을 업데이트 하는 방식이다.

 

728x90
반응형

'boostcamp AI tech > boostcamp AI' 카테고리의 다른 글

Regularization  (1) 2023.11.21
Optimization  (2) 2023.11.21
Monitoring tools  (0) 2023.11.15
Model save, load & Transfer Learning  (0) 2023.11.15
PyTorch Project  (0) 2023.11.13