똑바른 날개

[용어] Gradient Accumulation이란? 본문

공부/인공지능

[용어] Gradient Accumulation이란?

Upright_wing 2026. 2. 12. 17:32
반응형

1. 왜 사용하는가? (핵심: VRAM 절약)

대규모 모델을 학습하거나 이미지 해상도가 클 때, GPU 메모리(VRAM) 한계로 인해 배치 사이즈(Batch Size)를 크게 잡을 수 없는 경우가 많다.

  • 문제: 배치 사이즈를 1이나 2로 줄이면 학습이 불안정해지고 수렴이 느려진다.
  • 해결: 물리적인 배치 사이즈는 작게 유지하되, 여러 번 계산한 기울기를 합쳐서 마치 큰 배치 사이즈로 학습한 것과 같은 효과를 낼 수 있다.

2. 작동 공식

Gradient Accumulation를 반복횟수를 N이라고 가정했을 때, 실제 학습에 적용되는 가상 배치 사이즈(Virtual Batch Size)는 다음과 같다.

  • Physical Batch Size: 실제 GPU 메모리에 한 번에 올라가는 데이터 수 (예: 4)
  • gradient_accumulate 반복 횟수:  누적 횟수 (예: 8)
  • Virtual Batch Size: 4 * 8 = 32 (모델은 마치 배치 사이즈 32로 학습하는 효과를 얻음)

3. 코드 구현 예시 (PyTorch)

# 설정값
gradient_accumulate_every = 4  # 4번 모아서 업데이트하겠다
batch_size = 16                # 실제 GPU에 올라가는 배치 크기

for i, (inputs, labels) in enumerate(dataloader):
    # 1. Forward Pass
    outputs = model(inputs)
    loss = criterion(outputs, labels)

    # 2. Loss Normalization (중요!)
    # 여러 번 더해지므로, 평균을 맞추기 위해 미리 나눕니다.
    loss = loss / gradient_accumulate_every 

    # 3. Backward Pass (기울기 계산 및 누적)
    # PyTorch는 기본적으로 backward() 호출 시 기울기를 덮어쓰지 않고 더합니다(accumulate).
    loss.backward()

    # 4. Step (누적된 횟수가 찼을 때만 업데이트)
    if (i + 1) % gradient_accumulate_every == 0:
        optimizer.step()       # 가중치 업데이트
        optimizer.zero_grad()  # 기울기 초기화

4. 주의할 점

  1. Loss 나누기: loss.backward()를 호출할 때마다 기울기가 계속 더해지므로, 합쳐진 기울기의 크기가 커진다. 수학적으로 "평균" 기울기를 구하려면 lossgradient_accumulate_every로 나누어 주어야 한다.
  2. BatchNorm: 배치 정규화(Batch Normalization) 층은 물리적인 배치 사이즈(Physical Batch Size)에 의존합니다. 따라서 Gradient Accumulation을 써도 BatchNorm 통계량은 작은 배치 기준으로 계산되므로, 배치 사이즈가 너무 작으면(예: 1~2) 성능 저하가 올 수 있다.

요약

  • 의미: 가중치 업데이트 한 번을 수행하기 위해 거치는 Forward/Backward 패스의 횟수.
  • 목적: 적은 GPU 메모리로 큰 배치 사이즈의 학습 효과를 내기 위함.
반응형