ML 연구를 위한 GPU · KYC 없는 크립토 결제
IteraGPU
학습 · 메모리와 최적화

업데이트 횟수를 잃지 않고 마이크로배치 줄이기

누적은 파라미터 업데이트 전에 여러 번의 역방향 패스 기여를 더합니다. 마이크로배치 크기가 같다면, 실효 배치는 복제본당 마이크로배치, 누적된 패스 수, 참여하는 데이터 복제본으로 계산합니다. 마이크로배치를 줄이면 보존되는 활성값을 가볍게 할 수 있지만, 가중치나 옵티마이저 상태를 없애지는 못하며 동일한 학습을 보장하지도 않습니다.

01 /

마이크로배치, 역방향 패스, 업데이트 구분하기

마이크로배치는 한 복제본에서 순방향 패스가 처리하는 예제 묶음입니다. 역방향 패스는 그 기여를 그래디언트에 계산합니다. 옵티마이저 업데이트는 사용 가능한 그래디언트로 파라미터를 수정합니다. 누적을 사용하면 이 업데이트 전에 여러 번의 순방향/역방향 패스가 선행되며, 그 묶음 동안 파라미터는 변하지 않습니다.

PyTorch에서는 그래디언트가 이를 위한 텐서에 누적됩니다. 따라서 각 마이크로배치 후에 그래디언트를 지우면 원하는 누적이 취소됩니다. 반대로 두 그룹 사이에서 0으로 초기화하는 것을 잊으면 이전 업데이트의 예제가 기여하게 됩니다.

로깅 단위를 정하세요. 마이크로배치 번호, 옵티마이저 업데이트, 본 예제 수 또는 토큰 수 중 무엇인지 정해야 합니다. 'step'이라는 말만으로는 모호합니다. 한 실험에서 축이 여덟 배 많은 예제를 나타낸다면 손실 곡선을 올바르게 비교할 수 없습니다.

기술 출처: PyTorch — 그래디언트 누적과 초기화

02 /

GPU를 두 번 세지 않고 실효 배치 계산하기

복제본당 마이크로배치의 예제 수를 m, 누적된 마이크로배치 수를 A, 데이터 병렬 복제본 수를 D라고 합시다. 이 크기들이 일정하고 예제가 올바르게 분배된다면, 하나의 전역 업데이트에 기여하는 예제 수는 m × A × D입니다.

D 인자가 반드시 머신의 모든 카드를 가리키는 것은 아닙니다. 텐서 병렬 또는 파이프라인 병렬로 같은 모델을 공유하는 GPU는 그만큼의 데이터 복제본이 되지 않습니다. 상용 로트 수량이 아니라 실제로 구성된 그룹을 적으세요.

산술 예시: 마이크로배치당 두 개의 예시, 여덟 번의 누적, 두 개의 복제본이면 전역 업데이트당 32개의 예시가 됩니다. 각 복제본은 이 그룹에서 열여섯 개의 예시를 처리합니다. 표는 개수를 비교하며, 메모리나 속도를 순위로 매기지 않습니다.

예시 단위의 실효 배치 = 복제본당 마이크로배치 m × 누적 A × 데이터 복제본 D
설명을 위한 개수이며 성능 측정이 아닙니다. 마이크로배치는 완전하고 예시는 분배됩니다.
mAD전역 업데이트당 예시 수
28232
116232
44232
28116

기술 출처: PyTorch — 혼합 정밀도의 실효 배치와 누적 · PyTorch — DistributedDataParallel 복제본의 동작

03 /

실제로 평가된 요소에 따라 손실 정규화하기

관련 요소 수가 같은 마이크로배치들에 대한 평균 손실의 경우, 각 기여를 A로 나누면 그룹의 평균이 됩니다. 이 규칙은 프레임워크가 이미 이 정규화를 수행하지 않는다고 가정합니다. 누적을 처리하는 도구를 사용한다면 수동 나눗셈을 추가하기 전에 그 도구의 계약을 다시 확인하십시오.

토큰당 평균 손실의 경우, 길이가 다르면 분모가 달라집니다. 손실의 합을 그룹에서 실제로 감독된 토큰, 즉 패딩과 무시된 위치를 제외한 토큰에 대해 나누어야 합니다. 마이크로배치 평균들의 평균은 일반적으로 같은 목표를 주지 않습니다.

이론 예시: 한 마이크로배치에는 감독된 토큰이 512개이고 평균 손실이 2이며, 다른 하나에는 1,536개이고 평균이 4입니다. 가중 평균은 (512 × 2 + 1,536 × 4) ÷ 2,048 = 3.5입니다. 비가중 평균은 3이며 작은 그룹에 과대 가중치를 줍니다. 이 값들은 계산만을 예시합니다.

기술 출처: Hugging Face Accelerate — 크기가 다양한 예시에서의 누적

04 /

완전한 누적 그룹 구성하기

먼저 그룹의 경계와 분모를 준비하십시오. 각 마이크로배치에 대해 출력, 정규화된 손실, 그리고 중간 업데이트 없는 역전파를 계산하십시오. 더 이상 필요 없는 출력은 해제하십시오. 그래프에 연결된 손실을 리스트에 보관하면 할당의 수명이 길어질 수 있습니다.

마지막 기여 후에는 전체 그래디언트에 대해 예정된 연산을 적용한 다음 업데이트를 수행하십시오. 그런 다음 다음 그룹을 위해 그래디언트를 초기화하십시오. 순회가 A보다 적은 마이크로배치로 끝난다면, 이 부분 그룹을 실제 분모로 처리할지 아니면 제외할지 명시적으로 선택하십시오. 해당 예시들을 기록해 두십시오.

GradScaler를 사용하는 혼합 정밀도의 경우, 스케일 인자는 누적 동안 일정하게 유지됩니다. 실제 역스케일링과 경우에 따른 클리핑은 기여 이후에 일어나며, 스케일러 업데이트는 스텝 시도 이후에 따릅니다. 유한하지 않은 값에 대한 검사는 파라미터 수정을 막을 수 있습니다.

스케줄러는 루프가 발표한 단위를 따라야 합니다. 옵티마이저 업데이트로 정의된 경우, 매 마이크로배치마다 호출하면 일정이 바뀝니다. 시스템이 일부를 건너뛸 수 있다면 시도와 실제로 적용된 업데이트를 별도로 기록하십시오.

기술 출처: PyTorch — autograd 그래프와 backward를 위해 보존된 텐서 · PyTorch — 누적, 언스케일, 클리핑 및 GradScaler

05 /

멀티 GPU에서 리덕션과 예시 분배 확인하기

DistributedDataParallel은 복제본 간에 그래디언트를 동기화합니다. 통상적인 동작에서 리덕션은 이들을 평균하므로, 합산 손실과 로컬에서 평균된 손실은 같은 스케일이 아닙니다. 복제본마다 토큰 수가 다른 경우, 전역 분모와 이 리덕션을 함께 고려해야 합니다.

실제로 처리된 ID를 확인하십시오. 모든 카드에 같은 예시를 의도치 않게 중복시키면 그룹의 정보가 그만큼 늘어나지 않습니다. 중간 통신을 지연시키려면 최종 동기화 이전의 마이크로배치들에서 no_sync를 사용할 수 있습니다. 그 컨텍스트는 순전파도 포함해야 합니다.

이 규칙을 모든 분산 시스템에 전용하지 마십시오. 상태 샤딩, 파이프라인, 통신 훅, 프레임워크는 실제 연산을 바꿀 수 있습니다. 도구가 지원하는 구성부터 시작한 다음, 각 복제본에서 완전한 그룹을 검증하십시오.

기술 출처: PyTorch — 그래디언트 리덕션과 DDP에서 no_sync의 범위

06 /

같은 실효 배치가 같은 경험을 보장하지 않는 이유

m × A × D의 등식은 하나의 계산 방식입니다. 큰 배치의 그래디언트를 되찾으려면 특히 올바르게 가중된 기여, 그룹 동안 동일한 파라미터 상태, 그리고 이 분해와 호환되는 연산이 필요합니다. 수치적 근접성은 적절한 허용 오차로 검증하며, 곱셈 결과만으로 추론할 수는 없습니다.

BatchNorm은 자신의 패스 입력으로부터 통계를 계산하므로, 여러 개의 작은 마이크로배치는 큰 배치와 동일한 그룹을 제공하지 않습니다. 무작위 연산, 계산 순서, 반올림도 달라질 수 있습니다. 최종 가중치가 비트 단위로 동일하다고 약속하지 마세요.

전역 배치를 변경하면 동일한 예시 수에 대해서도 업데이트 횟수가 달라질 수 있습니다. 비교 축과 품질 기준을 미리 정하세요. 이러한 새로운 가정을 문서화하지 않은 채 학습률, 스케줄러, 기간을 동시에 변경하지 마세요.

기술 출처: PyTorch — BatchNorm1d 통계 · PyTorch — 재현성 한계

07 /

메모리를 제어하고 다음 단계를 결정하기

역방향 패스와 첫 번째 업데이트를 포함하는 그룹, 그다음 그룹들을 계측하세요. 포워드 성공이 그래디언트나 옵티마이저가 생성한 상태를 검증하지는 않습니다. 카운터는 device별 범위를 유지해야 합니다. 메모리 문서는 베이스라인과 피크를 읽는 방법을 제공합니다.

그룹이 실패하면 마이크로배치를 줄이고, 이 선택이 여전히 적절할 때 목표로 한 실효 배치를 유지하도록 A를 다시 계산하세요. 이 변경은 피크의 비례적 분할이나 더 나은 소요 시간을 보장하지 않습니다. 가중치나 상태가 지배적이라면 누적만으로는 충분하지 않을 수 있습니다.

캠페인 전에 통제된 작은 데이터셋에서 한 번의 업데이트를 점검하세요: 동일한 예시, 가중 손실, 유한한 그래디언트, 그룹 경계, 스텝 수. 그런 다음 정한 프로토콜로 품질을 평가하세요. 다운로드 가능한 문서의 작은 추론용 MLP는 이 학습 레시피를 실행하지 않으며, 이 점검을 대체하지 않습니다.

최종 기록에는 m, A, D, 감독된 토큰, 정밀도, 정규화, 마지막 그룹 처리, 관측된 피크를 모으세요. 그런 다음 준비, 시험, 실제로 수용된 결과를 구분하여 구성 선택과 실험 예산으로 돌아가세요.

  • 비정상적으로 작은 손실: 누적에 의한 이중 나눗셈을 찾아보세요.
  • 분할 방식에 따라 결과가 달라짐: 무시된 토큰과 평균의 평균을 확인하세요.
  • 효과 없는 누적: zero_grad와 optimizer.step을 점검하세요.
  • 메모리 증가: 마이크로배치 간에 유지되는 참조를 찾아보세요.
  • 어긋난 일정: 역방향 패스와 업데이트를 구분하세요.

기술 출처: Hugging Face — 학습의 메모리 병목

실용적인 질문

마이크로배치 열여섯 개를 누적하면 메모리가 열여섯 배가 되나요?

반드시 그렇지는 않습니다. 기여는 순차적으로 처리됩니다. 그래디언트는 유지되지만, 불필요한 활성화는 해제될 수 있습니다. 그러나 피크는 모델, 유지된 참조, 옵티마이저 상태에 따라 달라지므로 전체 그룹을 측정하세요.

GPU 두 개면 항상 실효 배치가 두 배가 되나요?

해당 GPU가 명시된 마이크로배치로 두 개의 데이터 복제본으로 참여할 때만 그렇습니다. 하나의 동일한 모델을 공유하는 카드들이 자동으로 두 개의 복제본이 되지는 않습니다. 분산 그룹과 처리된 예시를 확인하세요.

모든 손실을 누적 횟수로 나눌 수 있나요?

이 단순한 규칙은 프레임워크가 이미 처리하지 않은 정규화 없이, 가중치가 동일한 마이크로배치에 해당합니다. 감독된 토큰 수가 가변적이거나 마지막 그룹이 불완전한 경우에는 목표의 실제 분모를 사용하세요.