1. Multi gpu training
- Multi gpu training:
- 모델의 sequence1은 gpu0에, sequence2는 gpu1에 분리해서 계산 하거나 (모델 나누기)
- 데이터 절반은 gpu0에, 나머지 절반은 gpu1에 분리해서 계산 하고 결과를 평균내거나 (데이터 나누기)
- DataParallel : 한명의 gpu가 나머지 gpu에게 데이터 분배, 취합 등의 역할을 수행 (다른 gpu보다 메모리 더 사용)
- 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를 축적한 다음 한번에 모델을 업데이트 하는 방식이다.
'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 |