Hyperparameter Tuning
- 크게 3가지, model, data, Hyperparameter Tuning
- 모델 스스로 학습하지 않는 값에 대해 사람이 지정
- learning rate, 모델의 크기, optimizer, etc..
- cf) NAS, AutoML
- 하이퍼 파라메터에 의해 값이 크게 좌우 될 때도 있음
- 2015, 2016, 구글의 recipe 대로 안하면 성능이 떨어졌던 때
- 근래는 데이터가 너무 많기 때문에 일반 기업에서도 하기 어려운 감이 있음.
- 대회에서 마지막 0.01을 쥐어짜야 할 때, 도전해볼만 하다. 이미 어느정도 성능 나올 때!
- Distillation (디스틸레이션), 모델을 압축하거나 가볍게 만드는 기법
- 큰 모델(선생 모델)의 지식을 더 작고 간단한 모델(학생 모델)에 전달하는 방법
- 선생 모델의 성능을 유지하면서도 더 작은 연산량으로 빠르게 추론 가능.
- 디스틸레이션 하는 과정에서 하이퍼 파라미터 튜닝하기도 한다.
- grid v.s. random
- grid Layout Search : 일정한 범위를 정하여 학습 수행
- Random Layout Search : 랜덤하게 정하여 학습 수행
- 전통적인 기법 (Old School)
- Random Search 를 통해 서치를 진행한 후, 성능이 잘 나오는 구간에 대하여 Grid Search
- 베이지안 기반 기법
- BOHB (2018)
- Ray
- 분산 명령
- multi-node multi processing 지원 모듈
- ML/DL의 병렬 처리를 위해 개발된 모듈
- 기본적으로 현재의 분산병렬 ML/DL 모듈의 표준
- Hyperparameter Search 를 위한 다양한 모듈 제공
- train_cifar → 반드시 하나의 함수로 만들어져야 Ray 적용 가능.
data_dir = os.path.abspath("./data") load_data(data_dir) # config에 search space 지정; grid search 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), #log scale로 uniform하게 가져옴. "batch_size" : tune.choice([2,4,8,16]), } # 의미 없다고 생각되는 metric들을 잘라내는 역할 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( # train_cifar : 학습 할때의 함수 partial(train_cifar, data_dir=data_dir), # 데이터 쪼개기 resources_per_trial = {"cpu":2, "gpu":gpus_per_trial}, # 한번 trial의 자원 config=config, num_samples=num_samples, scheduler=scheduler, progress_reporter=reporter)
Pytorch Troubleshooting
- OOM (Out Of Memory)
- 어려워
- 왜 발생했는지 모르겠음.
- 어디서 발생했는지 모르겠음.
- Error backtracking 이 이상한데로 감
- 메모리의 이전상황의 파악이 어려움. (iteration 과정 중이면..)
- 1차원적인 해결법
- Batch Size 줄이기
- GPU clean
- Run
- 어려워
- GPUUtil 사용하기
- nvidia-smi 처럼 GPU 상태를 보여주는 모듈
- nvidia-smi 는 스냅샷 일뿐, iteration 마다의 GPU 상태를 보여주지 않음.
- Colab은 환경에서 GPU 상태 보여주기 편함
- iter 마다 메모리가 늘어나는지 확인
!pip install GPUtil import GPUtil GPUtil.showUtilization()
- nvidia-smi 처럼 GPU 상태를 보여주는 모듈
- torch.cuda.empty_cache()
- 사용되지 않은 GPU상 cahce 정리
- 가용 메모리 확보
- del 과는 구분이 필요
- del 이후
- 가비지 콜렉터가 돌아가면서 남는 메모리를 가져옴
- 이 과정을 강제한다는 느낌.
- reset 대신 쓰기 좋은 함수
- loop이 시작되기 전에 한번 써주면 이전의 학습에 의한 영향을 덜 받겠다.
- trainning loop에 tensor로 축적 되는 변수는 확인할 것.
- tensor로 처리된 변수는 gpu 상에 메모리 사용.
- required_gradient=True 라면, gradient를 위한 메모리 버퍼까지 사용하게 된다.
- 해당 변수가 loop 안에 있을 때, GPU에 computational graph 를 생성한다. (메모리 잠식)
total_loss = 0 for i in range(10000): optimizer.zero_grad() output = model(input) loss = criterion(output) loss.backward() optimizer.step() total_loss += loss # loss1 + loss2 + loss3 + loss4 = total # loss 값은 사실 한번만 필요한데 연산을 위해 # 메모리에 계속 적재된다.
- 1-d tensor의 경우 python 기본 객체로 변환하여 처리할 것. (일회용, 적재 x 위해)
- .item 또는 float 등으로 기본 객체로 변경
- # 적재되는 경우 total_loss = 0 for x in range(10): # assume loss is computed iter_loss = torch.randn(3,4).mean() iter_loss.requires_grad = True iter_loss += iter_loss ------------------------------------------------------------------------ # 적재 x total_loss = 0 for x in range(10): # assume loss is computed iter_loss = torch.randn(3,4).mean() iter_loss.requires_grad = True iter_loss += iter_loss.item iter_loss += float(iter_loss)
- del 명령어 적절히 사용하기
- 필요가 없어진 변수는 적절한 삭제가 필요함.
- python 메모리 배치 특성상 loop 이 끝나도 메모리 차지함.
for x in range(10): i = x print(i) # loop이 끝나도 9가 출력됨. del i
- 학습 시 OOM 발생했다면, batch 사이즈를 1로 해서 실험해보기
- batch size가 어디까지 가능한지 확인하기 위해 아래와 같은 코드를 구성한다.
# 배치 사이즈를 줄여서 시도 oom = False try : run_model(batch_size) except RuntimeError : # out of memory oom = True # 줄였는데도 안되면 1로만 시 if oom : for _ in range(batch_size): run_model(1)
- torch.no_grad()
- Inference 시점에서 torch.no_grad() 구문 사용.
- backward pass 로 인해 쌓이는 메모리에서 자유로움
with torch.no_grad(): for data, target in test_loader: output = network(data) test_loss += F.nll_loss(output, target, size_average=False).item() pred = output.data.max(1, keepdim=True)[1] correct += pred.eq(target.data.view_as(pred)).sum()
- CUDNN_STATUS_NOT_INIT
- 디바이스를 제대로 설치 안했을 때 생기는 에러
- device-side-assert
- OOM의 일종
- 그 밖의 에러
- 그밖의 GPU 에러
- colab에서 너무 큰 사이즈는 실행하지 말 것
- Linear, CNN, LSTM
- CNN의 대부분의 에러는 크기가 안맞아서 생기는 경우.
- (torchsummary 등으로 사이즈를 맞출 것.)
- tensor의 float precision을 16bit로 줄일 수도 있음.
- 최후의 수단 정도.
'TIL' 카테고리의 다른 글
[Transformer & Generative Models] 부트캠 day-17 (1) | 2023.11.23 |
---|---|
[딥러닝 기초 다지기] 부트캠 day-15 (2) | 2023.11.21 |
[Pytorch] 네부캠 day-11 (0) | 2023.11.17 |
[Pytorch] 네부캠 day-10 (1) | 2023.11.16 |
[Pytorch] 부트캠 day-9 (1) | 2023.11.15 |