English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

게스트
1 / ?
수업 목록으로

그래디언트 스파이크의 출처

평온한 미니-배치 & 충격적인 미니-배치

대부분의 미니-배치들은 합리적인 크기의 그래디언트를 생성합니다. 데이터에 대략적으로 적합한 모델의 교차 엔트로피 손실은 좁은 범위에 머무르며; 역전파는 그 신호를 비슷한 크기의 그래디언트로 되돌립니다.


일부 미니-배치들은 그렇지 않습니다. 그래디언트 스파이크의 세 가지 출처:


1. 이상치 예시. 극도로 드문 토큰 조합을 가진 단일 시퀀스가 평균에서 멀리 떨어진 손실과 평균에서 멀리 떨어진 그래디언트를 생성합니다.

2. 수치적 경계 사례. 거의 0에 가까운 softmax 분모, NaN을 생성하는 layernorm, FP16 오버플로. 각각이 일반적인 것보다 몇 배나 큰 그래디언트를 생성할 수 있습니다.

3. 분포 변화. 단일 훈련 중 데이터 소스를 전환하면 모델이 새로운 분포로 충격을 받습니다. ANDREA의 bandit은 매 7~42 스텝마다 소스 가중치를 재조정합니다. 각 전환은 작은 분포 변화입니다.


ANDREA-120M v1: Spike Cascade

v1에는 그래디언트 클리핑이 없었습니다. bandit으로부터 매 7~42 스텝마다 소스 전환(repo-docs(리스트 구조), 그 다음 gutenberg(긴 산문), 그 다음 hermes3-general(Q&A))이 모델에 짧은 repo-docs 버스트를 주입했습니다. 각 전환은 그래디언트 스파이크를 생성했습니다: 각 스파이크는 120M 규모에서 가중치를 퇴화된 어트랙터로 밀어넣었습니다.


핵심 경험적 사실. ANDREA-12M은 클리핑 없이 동일한 bandit을 견뎌냈습니다. 작은 가중치 행렬은 그래디언트 충격에 대해 견고성을 유지합니다; 하나의 나쁜 배치는 12M 파라미터를 도망치는 어트랙터로 밀어넣을 수 없지만, 120M은 가능합니다. 모델이 확장될수록 클리핑이 더 중요해집니다.

전역 L2 노름 클리핑

두 가지 선택: Per-Tensor 또는 Global

그래디언트 크기를 제한하는 두 가지 방법:


Per-tensor 클리핑. 각 그래디언트 텐서를 독립적으로 클리핑합니다. 임베딩 그래디언트는 자신의 노름으로 클리핑되고, 어텐션 그래디언트는 자신의 노름으로 클리핑됩니다. 간단하지만 상대적 스케일을 왜곡합니다: 한 텐서의 작은 스파이크(이제 0 그래디언트)가 다른 텐서의 거대한 그래디언트(변경되지 않음)와 짝을 이룹니다.


Global L2 norm 클리핑. 모든 그래디언트를 하나의 큰 벡터로 취급합니다. 모든 파라미터에 걸쳐 총 L2 노름을 계산합니다. 노름이 max_norm을 초과하면 모든 그래디언트를 동일한 요인으로 스케일링합니다. 텐서 간 상대적 크기를 보존합니다.


ANDREA는 global을 사용합니다. Pascanu 등 (2013)은 실증적으로 global clipping이 transformer 훈련에서 per-tensor보다 우수함을 보여주었습니다.


수학

전역 L2 노름을 계산합니다:


norm = sqrt(sum over all params of g_i^2)


norm <= max_norm인 경우, 그래디언트는 변경되지 않고 그대로 통과합니다. norm > max_norm인 경우, 모든 그래디언트를 max_norm / norm으로 스케일링합니다:


g_i_clipped = g_i * (max_norm / norm)


스케일링 후, 새로운 norm은 정확히 max_norm과 같습니다. ANDREA는 max_norm = 1.0을 사용합니다.

스케일 팩터 계산

한 훈련 단계 동안 모든 그래디언트의 글로벌 L2 norm이 `3.5`로 계산되었다고 가정합니다. ANDREA의 `max_norm = 1.0`입니다. (a) 적용되는 스케일 팩터, (b) 스케일링 후 새로운 글로벌 L2 norm 값, (c) 클리핑되지 않은 norm이 `3.5` 대신 `0.4`였다면 어떻게 되는지 계산하세요. 산술 과정을 보여주세요.

그래디언트 노름 계산이 세 개의 커널을 필요로 하는 이유

순진한 알고리즘은 GPU에서 실행될 수 없습니다

전역 L2 노름 계산을 위한 의사코드:


total = 0
각 param p에 대해:
p.grad의 각 요소 g에 대해:
total += g * g
norm = sqrt(total)

GPU에서 이 단순한 루프는 두 가지 이유로 실패합니다:


1. 순차적 누적. 단일 total 누적기가 모든 스레드가 다른 모든 스레드를 기다리게 하여 GPU 병렬성을 무효화합니다.

2. 이종 텐서. ANDREA-120M은 매우 다른 모양의 텐서를 가지고 있습니다: 임베딩 (8449 x 768), 어텐션 QKV (768 x 768), layernorm (768). 하나의 커널로는 모든 모양을 효율적으로 반복할 수 없습니다.


ANDREA의 세 커널 파이프라인

작업을 microgpt_cuda.cu의 세 개의 CUDA 커널로 분할합니다:


커널 1: k_grad_norm_partial. 각 매개변수 텐서에 대해 제곱의 부분 합을 계산합니다. 각 스레드 블록이 텐서의 청크를 축소합니다; 결과는 작은 스크래치 버퍼에 기록됩니다. 병렬성: 청크당 하나의 블록, 모든 텐서에 걸쳐 수백 개의 블록.


커널 2: k_grad_norm_final. 스크래치 버퍼를 단일 스칼라로 줄입니다. 그 제곱근을 취합니다. 작은 커널 하나, 마이크로초 단위로 실행됩니다.


커널 3: k_grad_scale. norm > max_norm인 경우, scale = max_norm / norm을 계산하고 모든 그래디언트 요소에 scale을 곱합니다. 모든 그래디언트 텐서에 한 번의 패스, 완벽하게 병렬화 가능.


순서가 중요합니다: Pre-Adam

클리핑 파이프라인은 AdamW가 m, v 또는 어떤 매개변수도 업데이트하기 이전에 실행됩니다. 왜 그런가요?


클리핑된 그래디언트가 AdamW의 지수 이동 평균으로 들어갑니다. 스파이크가 m & v로 흘러들어가도록 허용하면, 그 실행 평균을 손상시켜 스파이크 후 많은 단계 동안 회복을 늦춥니다. Adam 이전 클리핑은 스파이크의 영향을 단일 나쁜 단계로 제한합니다.


Gradient Clipping with 3 CUDA Kernels

왜 세 개의 커널인가, 하나가 아닌가?

누군가 `k_grad_norm_partial` & `k_grad_norm_final`을 하나의 패스에서 전체 글로벌 노름을 계산하는 단일 커널로 병합하는 것을 제안했다고 가정하세요. 이 병합이 GPU에서 실패하거나 성능이 저하되는 구체적인 한 가지 이유를 설명하세요. GPU 스레드 블록이 메모리를 공유하고 동기화하는 방식을 참조하세요.

No-Clipping이 v1을 죽인 방법

7에서 42 스텝마다 발생하는 Bandit 소스 전환

ANDREA의 bandit은 단계별로 작동합니다. 각 단계는 7, 14, 21, 28 또는 42 스텝(무작위로 선택) 동안 지속됩니다. 각 단계 경계에서 소스 가중치가 이동합니다: 예를 들어 repo-docs가 0.1에서 0.6으로 급등하고, gutenberg이 0.4에서 0.1로 하락하며, hermes3-general이 0.5에서 0.7로 상승할 수 있습니다.


각 전환은 모델에 분포 충격을 줍니다. 손실이 잠시 급등합니다. 그래디언트도 함께 급등합니다: gutenberg 스타일의 산문에 대한 손실을 최소화하던 모델이 이제 repo-docs 스타일의 목록 구조를 보게 되고, 그래디언트는 일반적인 크기의 10배 또는 100배에 달하는 수정 신호를 전달합니다.


v1 실패 모드

클리핑 없이, 그 10-100배 그래디언트 스파이크들이 AdamW의 m & v 평균으로 흘러들어갔습니다. AdamW의 스무딩으로 인해 스파이크 효과는 실제 나쁜 배치 이후에도 많은 스텝 동안 지속되었습니다. v1의 바닐라 Adam(가중치 감소 없음)과 결합되어, 스파이크 주도 가중치 업데이트가 단계적으로 누적되어 가중치가 퇴화된 어트랙터로 표류했습니다: 한 토큰의 로짓이 소프트맥스를 지배하고, 샘플링된 출력이 그 토큰이었으며, 훈련 컨텍스트에 그 토큰이 포함되어 그래디언트가 그 토큰을 강화했습니다. 반복 고착.


v2 안정성

v2는 max_norm = 1.0으로 클리핑을 추가했으며, AdamW & LR 워밍업과 함께했습니다. m & v에 대한 스파이크 효과가 제한됩니다; 가중치는 피크 시 매 매개변수당 스텝당 lr max_norm = 0.0003 1.0 = 0.0003보다 빠르게 표류할 수 없습니다. 단계 전환은 여전히 스파이크를 생성하지만, 그 스파이크들은 옵티마이저에 도달하기 전에 캡됩니다.


결과: v2(데이터 필터 v2.5 & v3 폴리시 후)는 사실적 회상, 다단락 일관성, 및 생물학 & 신호 처리 샘플에서 9.5/10 외부 평가를 달성했습니다.


용량-취약성 결합

같은 bandit. 같은 데이터. 클리핑을 제외한 동일한 하이퍼파라미터. 왜 12M은 클리핑 없이 생존했는데 120M은 붕괴했을까?


두 가지 복합 요인:


1. 더 큰 가중치 행렬은 더 많은 어트랙터를 저장합니다. 768x768 어텐션 프로젝션은 590K 매개변수를 가지며; 매개변수당 작은 드리프트조차 어텐션 행동에 의미 있는 변화를 일으킵니다. 384x384 어텐션 프로젝션은 147K 매개변수를 가지며 더 제한된 부분공간에 머무릅니다.

2. 더 많은 레이어는 더 많은 곱셈 상호작용을 의미합니다. v3는 12개의 트랜스포머 레이어를 가집니다 (12M의 6개에 비해). 스파이크는 12개의 복합 비선형성을 통과하며 전파됩니다; 각 레이어는 이전 레이어의 드리프트를 증폭할 수 있습니다.


취약성은 용량과 함께 복합됩니다. 클리핑은 특정 규모 임계값 이상에서 필수가 됩니다; ANDREA는 그 임계값을 12M ~ 120M 매개변수 사이 어딘가에 둡니다.

v1 캐스케이드 진단

v1 훈련의 50,000단계에서 단일 미니-배치가 전역 L2 노름이 50.0인 기울기를 생성한다고 가정(일반적인 배치는 ~0.5를 생성). 이후 배치들이 일반적인 기울기 크기로 돌아간 경우, 다음 10단계 동안 AdamW의 첫 번째 모멘트 `m`에 어떤 일이 발생하는지 추적하세요. `m = beta1 * m + (1 - beta1) * g`가 beta1=0.9로 스파이크를 어떻게 전파하는지 고려하세요.

클리핑이 적용되는 다른 곳은?

ANDREA의 bandit-driven 커리큘럼을 넘어, 전역 L2 기울기 클리핑이 유사하게 중요한 **다른** 훈련 시나리오 하나를 이름 짓고, 그것을 그렇게 만드는 **하나의 메커니즘**을 설명하세요.

관련 활동

클리핑과 연결된 세 가지 형제 활동:


- Activity 10: AdamW. 클리핑은 AdamW의 m & v를 스파이크 오염으로부터 보호합니다. 클리핑 없이, 하나의 나쁜 배치가 50+ 스텝 동안 옵티마이저 상태를 손상시킵니다.

- Activity 11: LR warmup. Warmup은 lr을 완화합니다; 클리핑은 g를 완화합니다. 함께: 스텝 1에서 최악의 매개변수 업데이트는 lr_after_warmup max_norm = 1.5e-7 1.0 = 1.5e-7로, 어느 가드도 없이 0.0003 * 50 = 0.015 대비 100,000배 감소한 최악의 초기 업데이트 크기입니다.

- 활동 14: 다중 팔 강도. 강도 단계 길이(7에서 42단계)는 특별히 한 소스가 지배하는 것을 방지하기 위해 짧게 설정되었습니다. 클리핑이 빈번한 전환을 안전하게 만드는 것입니다.


클리핑은 트랜스포머 훈련에서 가장 저렴한 안정성 이득입니다: 3개의 작은 CUDA 커널, 단계당 마이크로초, 120M+ 모델이 수렴할지 붕괴할지를 결정짓는 영향.