URL: https://www.youtube.com/watch?v=c1hGBoWw20A 날짜: 2026-09-20 채널: aiDotEngineer 발표자: Filip Makraduli 공저자: Nils Graef
📌 핵심 질문 / 이 영상이 다루는 핵심 논점
==트랜스포머의 RMSNorm은 산술 연산량보다 작업 시작·메모리 이동·동기화에 드는 시간이 더 크므로, 정규화의 gain을 가중치에 미리 접고 스칼라 나눗셈을 뒤로 미루면 프로젝션과 정규화를 겹쳐 실행할 수 있다.==
- RMSNorm은 한 번의 decode 단계에서 모델에 따라 약 33번 실행될 수 있지만 실제 산술량은 작다.
- GPU는 행렬 곱셈 같은 수학 연산에는 빠르고, 커널 launch·메모리 이동·대기에는 상대적으로 느리다.
- gain weight folding, deferred division, 중복 pre-normalization 제거를 조합하면 RMSNorm과 프로젝션 묶음에서 33~35% 속도 향상을 얻을 수 있다.
- CUDA의 두 스트림을 명시적으로 join하지 않으면 테스트를 통과하고도 긴 생성에서 오래된 버퍼를 읽는 race condition이 생겨 모델이 한 토큰씩 뒤처진 출력을 낸다.
RMSNorm 최적화는 작은 수식 변경으로 끝나는 문제가 아니다. 어떤 연산을 오프라인으로 옮길지, 어떤 연산을 tensor core와 CUDA core에서 동시에 수행할지, 두 실행 스트림이 언제 결과를 안전하게 공유할지를 함께 설계해야 한다. 수식이 맞더라도 동기화가 틀리면 모델 품질이 무너질 수 있으므로, 대수적 동치와 GPU 실행 의미론을 동시에 검증해야 한다.
1. RMSNorm이 산술량보다 느린 이유
RMSNorm의 계산 자체는 작지만, 반복적인 커널 실행과 데이터 흐름 때문에 전체 추론 지연 시간에서 무시할 수 없는 비중을 차지한다.
1.1. 연구의 출발점과 FlashAttention과의 유사성
-
두 줄의 대수로 시작한 제안
- 트랜스포머의 RMSNorm을 더 저렴하고 빠르게 만들면서 아키텍처 안에서 더 효율적으로 동작시키는 것이 출발점이다.
- 제안의 핵심은 복잡한 새 모델 구조가 아니라 RMSNorm과 뒤따르는 프로젝션의 계산 순서를 바꾸는 짧은 대수적 변환이다.
- LayerNorm이 한때 표준 정규화였지만 RMSNorm으로 대체된 것처럼, 정규화의 수학적 형태가 바뀌면 트랜스포머의 실행 비용 구조도 바뀔 수 있다.
-
오픈소스 협업에서 논문으로 이어진 과정
- Filip Makraduli는 오픈소스 생태계의 사람들을 만나 이 아이디어를 발전시켰고 Nils Graef와 논문을 공동 작성했다.
- 논문은 arXiv에 공개되어 있으며, 구현을 시험할 수 있는 저장소와 Hugging Face 모델도 함께 제공된다.
- 구현은 특정 Llama 계열에만 갇히지 않고, 정규화와 프로젝션이 같은 실행 패턴을 갖는 다른 아키텍처에도 적용할 수 있도록 구성됐다.
-
FlashAttention에서 얻은 설계 직관
- FlashAttention은 연산 자체만 빠르게 하는 것이 아니라 메모리 사이의 불필요한 통신을 줄여 전체 과정을 빠르게 만든다.
- RMSNorm 최적화도 같은 방향을 따른다. GPU가 이미 잘하는 행렬 연산보다 GPU가 기다리거나 데이터를 옮기는 상황을 줄이는 것이 핵심이다.
- 정규화에 필요한 일부 계산을 오프라인으로 미리 처리하고, 런타임에는 메모리 왕복과 순차적 대기를 최소화한다.
1.2. RMSNorm의 산술량과 wall time의 불일치
-
작은 산술 비중
- RMSNorm은 제곱·평균·제곱근·스케일링을 수행하지만, 트랜스포머의 큰 행렬 곱셈과 비교하면 산술량이 거의 없다.
- 따라서 FLOPs만 보면 최적화 우선순위가 낮아 보인다.
-
반복 실행이 만드는 실제 비용
- 한 번의 decode 단계에서 RMSNorm이 모델에 따라 약 33번 launch될 수 있다.
- 정확한 횟수는 모델과 구현에 따라 달라지지만, 작은 연산을 여러 번 시작하는 비용이 누적되면 wall-clock time은 커진다.
- 각 실행이 짧을수록 launch와 synchronization의 고정 비용이 실제 계산 시간에서 차지하는 비율이 커진다.
-
GPU가 느린 부분은 수학 바깥에 있다
- GPU는 행렬 곱셈처럼 병렬화가 잘 되는 수학 연산에는 빠르다.
- 반면 작업을 시작하고, 여러 메모리 계층 사이에서 데이터를 옮기고, 앞선 결과를 기다리는 과정에는 상대적으로 비효율적이다.
- 따라서 목표는 RMSNorm의 수식을 더 적게 계산하는 것만이 아니라 launch, memory movement, waiting이라는 세 가지 주변 비용을 줄이는 것이다.
2. FlashNorm의 세 가지 대수적 변환
세 가지 변환은 각각 메모리 이동, 순차적 대기, 중복 정규화라는 병목을 겨냥한다. 앞의 두 변환이 논문의 주된 제안이고, 세 번째는 새로운 아키텍처에서 나타나는 중복을 제거하는 확장이다.
2.1. Gain을 프로젝션 가중치에 접는 weight folding
-
RMSNorm과 프로젝션의 기본 형태
- RMSNorm을 다음처럼 쓸 수 있다. $$\operatorname{RMSNorm}(x)=\gamma\odot\frac{x}{r(x)},\qquad r(x)=\sqrt{\frac{1}{d}\sum_i x_i^2+\epsilon}$$
- 정규화 뒤 프로젝션 가중치 (W)를 곱하면 다음과 같은 형태가 된다. $$\left(\gamma\odot\frac{x}{r(x)}\right)W=\frac{xW^*}{r(x)}$$
- 여기서 (W^)는 gain (\gamma)를 가중치에 흡수한 행렬이다. 행벡터/열벡터 관례에 따라 (W^=\operatorname{diag}(\gamma)W) 또는 이에 대응하는 오른쪽 곱으로 표현되지만, 의미는 동일하다.
-
오프라인 계산으로 바뀌는 부분
- (W^*)는 모델 로딩 또는 체크포인트 변환 시점에 한 번 계산할 수 있다.
- 런타임마다 입력에 gain을 원소별로 곱하고 그 결과를 별도 버퍼에 저장하는 단계를 줄인다.
- FlashAttention이 일부 보조 계산을 옆에서 미리 처리해 메모리 통신을 줄이는 것처럼, weight folding은 정규화의 일부를 오프라인으로 이동한다.
-
왜 메모리 이동이 줄어드는가
- 원래 경로는 입력을 읽고 gain을 적용한 뒤 결과를 다시 사용하고, 이어서 프로젝션을 수행해야 한다.
- 접힌 가중치를 사용하면 프로젝션이 gain의 효과까지 포함하므로 원소별 gain 적용과 그에 따른 메모리 왕복을 줄일 수 있다.
- 산술량이 크게 줄지 않아도 별도 커널과 중간 버퍼가 사라지기 때문에 실제 지연 시간이 개선된다.
2.2. Scalar division을 뒤로 미루는 deferred normalization
-
순차 실행에서 생기는 대기
- 일반적인 구현은 RMS를 계산하고, 그 결과로 나눈 뒤, 프로젝션을 진행하는 식으로 보인다.
- 한 연산이 끝날 때까지 다음 연산이 기다리면, 행렬 유닛 또는 벡터 유닛 중 하나가 유휴 상태가 된다.
- 특히 입력의 RMS를 구하는 reduction과 큰 matrix multiplication은 서로 다른 하드웨어 자원을 사용할 수 있으므로 순차화가 낭비가 된다.
-
나눗셈의 위치를 이동하는 변환
- weight folding을 적용하면 프로젝션 결과를 먼저 만들고 마지막에 RMS 스칼라로 나눌 수 있다.
- 즉, 다음처럼 공통 스칼라 나눗셈을 프로젝션 뒤로 옮긴다. $$\left(\gamma\odot\frac{x}{r(x)}\right)W=\frac{xW^*}{r(x)}$$
- 최종 post-scale 전까지는 (xW^*) 계산과 (r(x)) 계산을 독립적으로 실행할 수 있다.
-
병렬 실행의 목표
- matrix unit은 (xW^*)를 계산하고, vector unit은 RMS reduction과 스케일 값을 계산한다.
- 두 작업을 동시에 시작하면 RMS가 끝날 때까지 matrix multiplication이 놀지 않고, matrix multiplication이 끝날 때까지 vector unit도 놀지 않는다.
- 두 결과가 모두 준비된 다음 post-scale을 적용하면 원래 수학적 결과와 같은 값을 얻으면서 idle waiting을 줄일 수 있다.
2.3. scale invariance를 이용한 중복 pre-normalization 제거
-
정규화의 스케일 불변성
- RMSNorm은 입력의 크기 정보를 RMS로 나누어 제거하므로, 양의 스칼라 배율이 앞에 붙어도 정규화된 방향은 변하지 않는다.
- 따라서 특정 아키텍처에서 같은 정규화가 연달아 나타나면 둘 중 하나가 계산상 기여하지 않을 수 있다.
-
새 아키텍처에 대한 적용
- Gemma 4처럼 RMS 정규화가 두 번 나타나는 구조에서는 pre-normalization 하나를 제거하는 변환이 가능하다.
- 이 변환은 임의로 정규화를 삭제하는 것이 아니라, 해당 블록의 scale-invariant한 계산 구조를 대수적으로 확인한 뒤 적용한다.
- 논문은 weight folding, deferred normalization, 중복 pre-normalization 제거의 동치성을 대수적으로 증명한다.
-
세 변환의 역할 분담
- weight folding은 원소별 gain 적용과 메모리 이동을 줄인다.
- deferred division은 행렬 유닛과 벡터 유닛이 병렬로 일하게 해 대기를 줄인다.
- 중복 pre-normalization 제거는 새로운 블록에서 불필요한 정규화 launch 자체를 없앤다.
3. 수식에서 CUDA 커널로 내려갈 때 생긴 버그
대수적으로는 간단한 변환도 GPU 스트림으로 병렬화하는 순간 실행 순서와 메모리 가시성을 직접 책임져야 한다. 이 지점에서 테스트를 통과한 구현이 긴 생성에서만 실패하는 버그가 드러났다.
3.1. 기대한 병렬 실행 구조
-
순차 경로의 idle time
- 순차 구현에서는 vector unit이 RMS와 scaling을 계산하는 동안 matrix unit이 기다리거나, 반대로 matrix multiplication이 끝날 때까지 vector unit이 기다린다.
- 정규화와 프로젝션의 산술량 자체보다 이 유휴 시간이 더 큰 병목이 될 수 있다.
-
FlashNorm의 병렬 경로
- FlashNorm이라는 구현 아이디어는 matrix unit에서 matmul을 실행하는 동시에 vector unit에서 RMS를 계산한다.
- 두 스트림이 작업을 끝내면 마지막에 post-scale이 matmul 결과를 RMS 스칼라로 나눈다.
- 이렇게 하면 행렬 곱셈이 RMS 계산을 기다리느라 멈추지 않고, RMS 계산도 행렬 곱셈을 기다리느라 멈추지 않는다.
-
Python만으로는 부족한 이유
- Python 레벨에서는 CUDA 스트림의 세밀한 실행 순서와 이벤트를 원하는 방식으로 표현하기 어렵다.
- 실제 병렬화와 join을 제어하려면 CUDA 커널과 스트림 동기화 코드를 직접 작성해야 한다.
- 이 구현은 논문의 두 번째 제안인 deferred division을 실제 GPU에서 검증하기 위한 실험이었다.
3.2. 모델이 과거의 출력을 반복한 증상
-
처음 관찰한 출력
- 테스트 프롬프트는 “The Transformer architecture revolutionized NLP because”처럼 정상적인 이어쓰기 결과를 기대하는 문장이었다.
- 구현된 모델은 출력에 이미 나온 단어를 반복했고, 특히
because가 다시 나타나는 식의 반복과 one-step lag를 보였다. - 출력이 현재 입력에 대한 결과가 아니라 과거 단계의 결과를 한 칸 늦게 내놓는 것처럼 보였다.
-
초기 검증이 버그를 놓친 이유
- 단위 테스트는 통과했다.
- perplexity 같은 품질 지표도 정상 구현과 비슷하게 보였다.
- 짧은 생성에서는 잘못된 실행 순서가 우연히 가려질 수 있고, 비슷한 분포를 내는지 보는 검사는 stale buffer의 시간적 의존성을 잘 드러내지 못한다.
-
긴 생성에서 나타난 차이
- 생성 단계를 길게 이어가자 반복과 한 단계 지연이 누적되었다.
- 따라서 커널 최적화는 단위 테스트와 짧은 perplexity 비교만으로 충분하지 않으며, 긴 autoregressive generation에서 토큰 순서와 상태 의존성을 확인해야 한다.
3.3. Tensor core·CUDA core와 스트림의 race condition
-
서로 다른 하드웨어 자원
- Tensor core는 행렬 곱셈의 일부를 처리한다.
- CUDA core 쪽은 원소별 연산, reduction, 제곱근 같은 RMS 계산을 처리한다.
- 두 자원을 병렬로 사용하는 것이 FlashNorm의 성능상 핵심이지만, 병렬성은 자동으로 안전한 데이터 의존성을 보장하지 않는다.
-
암묵적 join의 문제
- 구현에서는 두 CUDA 스트림을 마지막에 합치는 join이 암묵적으로 처리되고 있었다.
- 한 스트림의 행렬 곱셈이 아직 끝나지 않았는데 다른 단계가 post-scale에 들어갈 수 있었다.
- post-scale이 읽은 값은 현재 matmul 결과가 아니라 이전 단계에 남아 있던 오래된 버퍼 값일 수 있었다.
-
실제 race condition
- 완료되지 않은 matrix multiplication의 결과를 읽는 순간, 실행 순서에 따라 과거 값과 현재 값이 섞인다.
- 이는 수식 오류가 아니라 producer가 데이터를 쓰기 전에 consumer가 읽는 CUDA 스트림 race condition이다.
- 그 결과 모델이 한 단계 전의 상태로 계산한 logits를 사용하게 되고, 자연스러운 문장 대신 반복·역방향처럼 보이는 출력을 생성한다.
4. 명시적 이벤트와 대기 순서로 버그 수정
해결책은 병렬성을 포기하는 것이 아니라 두 작업이 끝났다는 사실을 명시적으로 기록하고, 최종 결합 단계가 두 완료 신호를 모두 기다리게 하는 것이었다.
4.1. 수정 전후의 실행 순서
-
수정 전
- matrix multiplication 스트림과 RMS 스트림을 실행한다.
- 두 스트림이 언제 끝났는지 명시적으로 기록하지 않는다.
- post-scale이 암묵적 join에 의존해 오래된 버퍼 값을 읽을 가능성이 생긴다.
-
수정 후
- matrix multiplication 스트림의 끝을 명시적으로 표시한다.
- RMS 계산 스트림의 끝도 별도로 표시한다.
- post-scale 단계가 첫 번째 스트림을 기다린다.
- 이어서 두 번째 스트림도 기다린 뒤, 두 결과를 모두 사용할 수 있을 때만 최종 스케일링을 수행한다.
-
정확성과 병렬성의 균형
- matmul과 RMS 계산은 여전히 앞부분에서 병렬로 실행된다.
- 동기화는 두 결과가 실제로 필요해지는 마지막 결합 지점에만 둔다.
- 이 방식은 병렬 실행의 성능 이점을 유지하면서 stale read를 막는다.
4.2. 버그 수정의 의미
-
모델 출력의 회복
- 명시적 join과 두 스트림 대기를 추가하자 반복되는 과거 버퍼 읽기가 사라졌다.
- FlashNorm 구현이 대수적으로 의도한 결과를 내기 시작했다.
- 모델이 “뒤로 말하는” 것처럼 보이던 현상이 사라지고 정상적으로 앞으로 생성했다.
-
검증 방법에 대한 교훈
- 유닛 테스트는 연산의 개별 값이 우연히 맞는지 확인하는 데 유용하지만, 비동기 실행 순서의 race condition을 충분히 검증하지 못할 수 있다.
- perplexity가 비슷하다는 결과도 장기 생성에서 발생하는 시간적 오류를 보장하지 않는다.
- GPU 커널을 바꿀 때는 짧은 정확성 테스트, 긴 autoregressive 생성, 스트림 동기화 검사를 함께 수행해야 한다.
5. 실험 결과와 기존 도구와의 호환성
수식 변환을 실제 모델과 도구에 적용했을 때, 가장 단순한 weight folding만으로도 개선이 나타났고 더 공격적인 커널 구현으로 확장할 수 있었다.
5.1. Llama 계열과 단계별 실험
-
실험 대상
- 주요 결과는 Llama 모델을 중심으로 측정됐다.
- 제안은 Llama에 한정되지 않으며, 정규화와 프로젝션 구조가 맞는 다른 아키텍처에도 적용할 수 있다.
-
서로 다른 최적화 수준
- 세 번째 normalization 관련 변환만 적용했을 때의 효과를 따로 비교한다.
- weight folding만 적용했을 때의 효과를 따로 비교한다.
- 모든 단계를 하나의 fused kernel에 넣었을 때의 효과도 비교한다.
- 이런 여러 수준의 실험으로 각 제안이 실제 개선에 얼마나 기여하는지 확인한다.
-
관찰된 개선
- 가장 단순한 weight folding만으로도 개선이 나타난다.
- 논문 설명문 기준으로 RMSNorm과 프로젝션 작업 묶음에서 약 33~35% 속도 향상을 얻는다.
- 더 깊은 kernel fusion과 스트림 병렬화는 추가 개선 가능성을 제공하지만, 구현 복잡성과 동기화 검증 비용도 함께 커진다.
5.2. 일상적인 모델 도구와의 호환성
-
torch.compile
- folded checkpoint는 새로운 가중치 체크포인트처럼 취급할 수 있어 torch.compile과 함께 사용할 수 있다.
- 사용자가 전체 모델 실행 그래프를 처음부터 다시 발명하지 않아도 최적화된 체크포인트를 기존 흐름에 넣을 수 있다.
-
FlashAttention과의 관계
- FlashAttention도 다른 레이어에서 메모리와 실행 순서를 최적화하는 유사한 발상을 사용한다.
- RMSNorm 최적화는 FlashAttention을 대체하는 것이 아니라, 트랜스포머의 다른 병목에 같은 종류의 시스템 설계 원리를 적용한다.
-
양자화 모델
- weight folding 방식은 양자화 모델에도 적용할 수 있다.
- 따라서 최적화된 정규화 레이어를 얻기 위해 모델 전체를 새로 작성할 필요가 없다.
- 다만 실제 배포에서는 folding 전후의 수치 정밀도와 양자화 포맷 호환성을 별도로 검증해야 한다.
5.3. 코드와 체크포인트를 얻는 경로
-
TransformerTricks 저장소
TransformerTricks저장소는 논문에 나온 여러 대수적 트릭과 구현을 제공한다.- weight folding은
flashify형태의 코드를 사용해 모델에 적용할 수 있다. - 이 경로는 모델 전체의 CUDA 커널을 직접 작성하지 않고 첫 번째 제안을 시험하는 진입점이다.
-
커널 작업이 필요한 부분
- deferred division을 실제 두 스트림 병렬화로 구현하려면 CUDA kernel work가 필요하다.
- 단순히 저장소의 체크포인트 변환만 실행하는 것과, matrix unit·vector unit을 동시에 구동하는 것은 난이도가 다르다.
- 후자의 경우 이벤트, stream wait, buffer lifetime과 장기 생성 정확성을 함께 관리해야 한다.
-
Hugging Face 모델
- 일부 변환이 적용된 모델은 Hugging Face model repo에서 확인하고 테스트할 수 있다.
- 연구자는 자신의 fine-tuned checkpoint나 새 정규화 변형을 같은 방식으로 실험할 수 있다.
6. 오픈 모델 연구를 프로덕션으로 가져가는 배포 경로
커널 수준의 연구를 실제 서비스 규모에서 검증하려면 모델을 수정할 수 있는 오픈 inference 환경과, 여러 작은 모델을 효율적으로 배치할 수 있는 클러스터 운영 계층이 필요하다.
6.1. Superlinked inference engine의 역할
-
수정된 Hugging Face 모델 배포
- Hugging Face에 올린 folded checkpoint 또는 custom model을 클러스터에 배포할 수 있다.
- 모델 inference 엔진이 오픈되어 있으면 연구자가 자신의 커널과 체크포인트를 실제 환경에서 시험할 수 있다.
- 모델을 서비스로 올릴 때 필요한 glue code를 매번 직접 작성하지 않아도 된다.
-
해커톤에서의 사용 사례
- 해커톤 참가자가 직접 fine-tune한 모델이나 custom checkpoint를 가져와 배포하고 결과를 확인할 수 있다.
- FlashNorm 같은 대수적 최적화를 적용한 모델도 같은 방식으로 cluster에서 실행할 수 있다.
- 과학적 아이디어를 로컬 정확성 실험에서 끝내지 않고 실제 요청 부하에 가까운 조건에서 확인할 수 있다.
-
연구와 운영의 간극 축소
- 연구자는 모델 내부를 수정할 수 있고, 배포 계층은 클러스터 운영과 inference를 담당한다.
- 따라서 커널 조작이나 새로운 normalization을 시험하면서도 배포 인프라 전체를 처음부터 구축하지 않아도 된다.
6.2. 임대한 endpoint보다 open inference가 필요한 이유
-
rented endpoint의 한계
- 외부 endpoint를 임대하면 이미 정해진 inference 구현을 호출할 수는 있지만, 내부 kernel과 stream scheduling을 수정하기 어렵다.
- FlashNorm처럼 matmul·RMS·post-scale 순서를 바꾸는 연구는 endpoint 내부를 소유하지 않으면 시험하기 어렵다.
-
포터블하고 유연한 연구 환경
- 전체 클러스터와 모델 inference 계층이 오픈되어 있으면 원하는 kernel manipulation을 직접 넣을 수 있다.
- 동시에 production-ready한 배포 환경이면 단일 GPU 실험을 넘어 규모 있는 테스트를 수행할 수 있다.
- 오픈 가중치·오픈 모델·오픈소스 연구를 계속 소유하고 통제할 수 있다는 점도 중요하다.
-
에이전트형 더 큰 사용 사례
- flashified 모델을 다른 모델들과 조합해 agentic task를 수행하는 end-to-end 시스템을 구성할 수 있다.
- 최적화된 소형 모델을 라우터, 임베딩, reranking 또는 에이전트 구성 요소와 연결할 수 있다.
6.3. 작은 모델을 위한 클러스터 운영 기능
-
스마트 큐잉
- FlashNorm 실험은 작은 Llama 모델과 Hugging Face의 작은 agent 모델을 함께 다뤘다.
- 이런 모델은 같은 GPU에서 번갈아 실행할 수 있으므로, 요청을 지능적으로 큐잉하면 유휴 GPU 시간을 줄일 수 있다.
- 모델을 동시에 모두 띄워 GPU를 과다 구매하기보다 필요할 때 모델을 전환하는 방식이 비용 효율적이다.
-
API 기반 제어
- 모델 설정뿐 아니라 클러스터 설정도 API로 제어할 수 있다.
- 오픈소스 연구마다 인프라 담당자가 수동으로 설정을 바꾸지 않아도 된다.
- 실험 조건을 코드와 API 호출로 재현할 수 있어 연구 반복성이 높아진다.
-
모델 카탈로그
- 배포 대상은 발표에서 언급한 모델에만 한정되지 않는다.
- 카탈로그에는 다양한 모델이 있고, reranking·embedding 모델처럼 검색·에이전트 시스템을 구성하는 모델도 포함된다.
- 최적화된 생성 모델을 주변 모델과 조합해 더 큰 제품 흐름으로 확장할 수 있다.
주요 발언 모음
“The proposition is very clear. It's basically two lines of algebra.”
“GPUs are not slow or bad at math, but they're bad at everything else around the actual math.”
“One of the streams hadn't finished the work, so I got race conditions that kind of read the past from the unfinished matrix multiplication.”
“That fixed the bug and made the paper work and the model speak forwards instead of backwards.”
“Even the simple one with weight folding shows some improvement.”
핵심 데이터 & 수치
- 약 33회: 모델에 따라 한 번의 decode 단계에서 RMSNorm이 launch될 수 있는 횟수다.
- 33~35%: 설명문에 제시된 RMSNorm+프로젝션 작업 묶음의 속도 향상 폭이다.
- 2줄의 대수: gain을 가중치에 접고 scalar division을 뒤로 미루는 핵심 제안의 직관적 크기다.
- 3가지 병목: 작업 시작(launch), 메모리 이동(memory movement), 대기(waiting)를 줄이는 것이 최적화의 목표다.
- 2개 실행 자원: matrix multiplication을 맡는 tensor/matrix unit과 RMS reduction·원소별 연산을 맡는 vector/CUDA core 경로를 겹쳐 실행한다.
- 2개 스트림: matmul 스트림과 RMS 스트림 모두의 종료를 명시적으로 확인한 뒤 post-scale을 실행해야 한다.
- 2개 검증 수준: 단위 테스트와 perplexity가 통과해도 긴 autoregressive generation에서는 race condition이 드러날 수 있다.
결론 및 시사점
- RMSNorm의 최적화 목표는 산술량을 줄이는 데만 있지 않고, 작은 커널을 반복 launch하고 데이터를 옮기고 결과를 기다리는 비용을 줄이는 데 있다.
- RMSNorm gain을 프로젝션 가중치에 오프라인으로 접으면 런타임의 원소별 연산과 중간 메모리 이동을 줄일 수 있다.
- RMS 스칼라 나눗셈을 matmul 뒤로 미루면 matmul과 RMS reduction을 서로 다른 GPU 실행 자원에서 병렬화할 수 있다.
- scale invariance를 만족하는 새 아키텍처에서는 중복 pre-normalization을 제거해 launch 하나와 관련 메모리 작업을 없앨 수 있다.
- 대수적 동치만으로 구현이 완성되지 않으며, CUDA 스트림의 producer-consumer 순서를 명시적으로 보장해야 한다.
- 암묵적 join은 오래된 버퍼를 읽는 race condition을 만들 수 있고, 이 오류는 짧은 테스트보다 긴 생성에서 반복·one-step lag로 나타난다.
- matmul 종료 이벤트와 RMS 종료 이벤트를 각각 기록하고 post-scale이 두 스트림을 모두 기다리게 하면 병렬성은 유지하면서 stale read를 막을 수 있다.
- weight folding은
TransformerTricks와flashify경로로 비교적 쉽게 적용할 수 있지만, deferred division은 CUDA kernel 수준의 작업이 필요하다. - 가장 단순한 weight folding만으로도 개선이 나타나며, 논문 설명문은 RMSNorm과 프로젝션 묶음에서 33~35% 향상을 제시한다.
- folded checkpoint는 torch.compile과 양자화 모델 같은 기존 도구와 함께 사용할 수 있어 도입 장벽이 낮다.
- Llama 계열 실험은 기본 적용, 세 번째 변환, full fused kernel을 나누어 각 최적화의 기여를 비교한다.
- 긴 생성 테스트는 GPU 커널 변경에서 필수이며, 단위 테스트와 perplexity 결과만으로 비동기 버그가 없다고 결론 내리면 안 된다.
- 커널을 직접 수정하려면 inference 내부를 통제할 수 있어야 하므로, 이미 고정된 rented endpoint보다 open inference engine이 연구에 적합하다.
- Hugging Face checkpoint와 오픈 클러스터를 결합하면 연구용 모델을 실제 요청 부하가 있는 환경에 배포해 검증할 수 있다.
- 작은 모델 여러 개를 한 GPU에서 전환하는 스마트 큐잉은 FlashNorm 같은 소형 모델 실험의 GPU 비용을 낮출 수 있다.
- 모델과 클러스터 설정을 API로 제어하면 인프라 담당자의 수동 지원 없이 오픈소스 연구를 반복할 수 있다.
- flashified 모델을 reranker·embedding 모델과 조합하면 단일 최적화가 agentic end-to-end 사용 사례로 확장된다.
- 수식 변환, CUDA 이벤트, 체크포인트, 배포 클러스터를 하나의 흐름으로 다뤄야 실제 성능과 정확성을 함께 얻을 수 있다.
- 논문과 구현은 vLLM 및 Hugging Face 주변의 PR로도 이어질 수 있어 연구 결과를 기존 오픈소스 스택에 환류시킬 수 있다.
- 작은 정규화 레이어라도 반복 횟수와 실행 주변 비용이 크면 시스템 전체의 병목이 될 수 있으므로, 프로파일러에서 FLOPs와 wall time을 함께 확인해야 한다.
참고 링크
- 원문 발표: https://www.youtube.com/watch?v=c1hGBoWw20A
- 발표자 LinkedIn: https://www.linkedin.com/in/filipmakraduli/
- 발표자 Substack: https://filipmakraduli.substack.com/
- 발표자 X: https://x.com/f_makraduli
