Ch.04
어텐션 최적화: FlashAttention과 희소 어텐션
밀집(Dense)은 전체 격자 로 표현력은 크지만 길면 매우 무겁고, Flash는 타일로 나누어 빠른 메모리에서 굴리며 HBM 왕복을 줄이고, 희소(Sparse)는 국소+글로벌 위주로 보는 쌍의 수를 줄입니다.
밀집 vs Flash vs 희소
밀집
밀집: 모든 (i,j) 쌍을 스코어 → 표현력↑, 크면 비용·메모리↑.
Flash
타일: 동일 softmax를 타일 단위로 — HBM↔SRAM 왕복↓, 실무 체감 속도↑.
희소
희소: 윈도+소수 글로벌만 허용 → 활성 위치 수↓, 장거리는 설계로 보완.
세 가지 선택 한눈에
① 병목 확인(·OOM) → ② Flash / 희소 선택 → ③ 품질·지표로 검증
① Flash: 같은 softmax를 IO-aware로 더 빠르게.
② Sparse: 연결 수 줄이기 — 필요한 장거리를 패턴에 녹이기.
③ Dense: 스케일을 항상 전제로 두기.
④ 실무: OOM → Flash·배치·dtype / 품질 → 글로벌·RAG.
Chapter 01~03에서 배운 셀프 어텐션은 문장 안 토큰 관계를 섬세히 잡아 주는 핵심 메커니즘이지만, 길이()가 길어질수록 점수 그리드( 근처) 때문에 GPU 메모리와 연산 시간이 급격히 불어나는 게 가장 큰 현실 과제입니다. 병목의 본질은 “어텐션을 버린다”가 아니라 길이 대비 비용이 너무 빨리 커진다는 점입니다.
이 챕터에서는 같은 softmax 어텐션을 메모리 계층에 맞춘 구현(타일/커널)으로 돌리는 FlashAttention과, 모든 쌍을 보지 않고 윈도·글로벌 등 패턴으로 연결을 줄이는 희소 어텐션(Sparse Attention) 을 나란히 비교합니다. 무엇을 계산할지(수학)는 유지하고 어떻게 실행할지(속도·메모리)를 개선하는 Flash와, 연결 구조 자체를 바꿔 연산량을 깎는 희소 중 무엇이 OOM·지연·품질 문제에 맞는지까지 연결해 봅니다.
핵심 수식 (scaled dot-product / softmax attention) 한 헤드의 출력은
먼저 스케일된 로짓 를 만듭니다. 는 “번째 위치가 번째 키를 얼마나 볼지”에 대한 원시 점수이고, 로 나누는 이유는 차원 가 커질수록 내적이 커져 softmax가 한쪽으로 쏠리는 것을 완화하기 위해서입니다. 각 행 에 대해 로 개의 가중치 를 얻고(), 그 가중치로 의 행 들을 가중합해 출력의 번째 행을 만듭니다.
한 줄로 풀면: ·는 각각 ·의 행 벡터, , 출력 는 입니다. FlashAttention은 이 같은 매핑을 메모리 이동을 줄여 계산하고, 희소는 softmax 전에 인 칸에 마스크(또는 키 제외)를 걸어 실질적으로 보는 열 집합만 남깁니다.
수식 쉽게 이해하기 (천천히 4단계)
Step 1) 입력 만들기
먼저 로짓(logit)부터 짚고 갈게요. 로짓은 softmax에 넣기 직전의 원시 점수입니다. 아직 확률이 아니고, "누가 더 중요해 보이는지"를 나타내는 비교 점수라고 보면 됩니다.
한 문장 길이를 이라 두면, 각 토큰은 벡터 하나씩을 가집니다. 이를 모아 만든 것이 입니다.
- (Query): "무엇을 찾고 싶은지"
- (Key): "무엇으로 비교할지"
- (Value): "실제로 가져올 정보"
이제 토큰 쌍의 로짓 행렬을 만듭니다.
여기서 는 "토큰 가 토큰 를 얼마나 참고할지"에 대한 원시 점수(로짓)입니다.
는 "키 벡터 차원 수 의 제곱근"입니다. 예를 들어 면 , 이면 입니다. 차원이 커질수록 분모도 커져 점수를 적당한 범위로 눌러 줍니다.
로 나누는 이유는 차원이 커질 때 내적값이 너무 커져 softmax가 거의 0 또는 1처럼 극단적으로 쏠리는 현상을 줄이기 위해서입니다. 쉽게 말해, 이 나눗셈은 softmax의 온도를 적당히 조절해 "한 토큰만 과하게 집착"하지 않고 여러 토큰을 안정적으로 비교하게 해 주는 안전장치입니다.
Step 2) 확률로 바꾸기 (softmax)
행 단위 softmax를 적용하면 가중치 행렬 를 얻습니다.
각 행은 확률처럼 해석되어 합이 1이 됩니다.
즉, 토큰 는 여러 토큰 를 서로 다른 비율로 참고하고, 그 비율이 바로 입니다.
왜 길이가 길면 무거울까?
와 의 크기가 모두 이기 때문입니다. 그래서 이 2배가 되면 표의 칸 수는 약 4배가 되어 연산·메모리 부담이 빠르게 커집니다.
Step 3) 값 벡터를 섞어 출력 만들기
가중치 로 를 섞으면 최종 출력이 됩니다.
위치 의 출력은 다음처럼 값 벡터들의 가중합입니다.
해석하면, "토큰 가 중요하다고 본 토큰들의 정보를 비율대로 합친 새 표현"입니다.
한 줄로 쓰면 전체 과정은 다음과 같습니다.
Step 4) Flash와 Sparse를 수식에 연결하기
핵심은 수식 자체를 바꾸는가/안 바꾸는가입니다.
- FlashAttention: 같은 식
을 유지한 채, 큰 중간 결과를 통째로 느린 메모리에 두지 않고 타일로 쪼개 계산해 HBM↔SRAM 왕복을 줄입니다.
- Sparse Attention: softmax 전에 일부 칸을 마스킹해 "보는 위치"를 제한합니다.
그러면 에서 허용 집합 바깥 가중치는 거의 0이 되어, 실질적으로 필요한 연결만 계산합니다.
정리하면: Flash = 같은 수학을 더 효율적으로 실행, Sparse = 연결 구조를 줄여 연산 자체를 절감입니다.
어텐션 최적화: FlashAttention과 희소 어텐션
1. 왜 무거워질까? (의 저주)
개념: 에서 길이 이면, 토큰 간 유사도를 담는 점수판(그리드)은 대략 입니다. 표 한 칸 한 칸이 곱·합으로 이어지므로, 만 조금 늘어도 체감 부담이 훨씬 크게 늘어납니다.
직관적 비유: 10명이 모인 파티에서 서로 빠짐없이 악수하려면 45번이면 되지만, 10,000명이 모이면 무려 5,000만 번이나 악수를 해야 합니다.
실전 문제: 책 한 권이나 긴 코드를 통째로 넣으면 OOM(Out of Memory) 이나 끊기는 응답으로 바로 드러납니다.
꼭 기억: 걱정의 중심은 “모델이 틀렸다”가 아니라 길이·배치가 커질 때 비용 곡선입니다.
2. 플래시 어텐션 (FlashAttention): 책상 위에서 끝내는 계산
개념: 거대 텐서를 느린 HBM과 빠른 SRAM(온칩) 사이에서 되도록 적게 왕복하게 만들고, 타일(작은 덩어리) 단위로 softmax 어텐션을 끝까지 밀어 넣는 커널·구현 기술입니다.
수식: 목표는 그대로 — 중간 텐서를 만드는 순서·장소만 메모리 친화적으로 바꿉니다.
직관적 비유: 도서관 창고를 한 권씩 오가며 업무하면 느립니다. 카트에 묶어 내 책상(SRAM) 위에서 처리하면 왕복 횟수가 줄어듭니다.
특징: 수학적 정의(같은 softmax 어텐션)는 유지하고, 연산 순서·메모리 접근을 바꿉니다. 그래서 동일 결과를 더 빠르게 얻는 쪽에 가깝습니다.
꼭 기억: Flash는 “근사로 바꾼다”가 기본은 아니고 “같은 걸 잘 돌린다”에 가깝습니다.
3. 희소 어텐션 (Sparse Attention): 볼 사람만 본다
개념: 매 query가 모든 key를 보지 않게 하고, 국소 윈도(Local)와 소수의 글로벌 토큰처럼 허용한 자리만 보도록 연결 수 로 만듭니다.
수식 습관: 로짓 에 대해, 허용 키 집합 밖의 에 (softmax 전)를 두면 의 질량이 안에만 남습니다. 결국 같은 식이지만 실효 지지 집합만 줄어듭니다.
직관적 비유: 만 명과 전부 악수하지 않고 내 테이블과 주최자 정도만 보는 식으로 에너지(연산)를 아낍니다.
특징: FLOPs·메모리는 크게 줄지만, 멀리 떨어진 증거가 중요한 과제에서는 패턴 실패 시 품질이 떨어질 수 있습니다.
꼭 기억: 희소는 구현만의 문제가 아니라 “무엇을 안 볼지” 설계가 핵심입니다.
4. 두 기술의 결정적 차이
Flash는 Dense와 동일한 출력을 목표로 실행만 빠르게 합니다. 희소는 연결 구조를 바꿔 계산 자체를 줄이며, 완전 동일성은 깨질 수 있습니다.
선택 가이드: OOM·지연이 크면 보통 Flash부터 켜고 측정합니다. 그래도 부담이 크면 희소 패턴·청킹·RAG 등 데이터·태스크에 맞는 조합을 검토합니다.
왜 중요한지
천문학적인 컴퓨팅 비용 절감
서비스 입장에서 GPU 시간과 피크 메모리는 곧 비용입니다. Flash·융합 커널·희소로 같은 모델을 더 긴 문맥 또는 더 큰 배치로 돌리면, 장비만 늘리지 않고도 운영 한계를 밀어 올릴 수 있습니다.
무한한 문맥(Long Context)의 문을 열다
긴 PDF·책 분량 프롬프트가 실용적으로 가능해진 배경에는 FlashAttention 류의 효율 어텐션이 큽니다. 컨텍스트 길이 경쟁은 곧 제품 경쟁력으로 이어집니다.
정확도와 속도의 아슬아슬한 줄타기
희소는 속도·메모리를 얻는 대신 안 본 연결이 생깁니다. 레이블·벤치로 장거리 의존이 얼마나 중요한지 확인하고, 필요하면 글로벌 토큰 확대·RAG로 보완합니다.
변하지 않는 본질 (Ch01~03과의 연결)
와 소프트맥스 어텐션의 논리는 그대로입니다. 이 장은 실행(Execution)과 패턴 설계로 현실적인 속도·메모리를 만드는 이야기입니다.
어떻게 쓰이는지
학습 단계 (Training): 스위치만 켜면 되는 플래시 어텐션
PyTorch / xFormers 등에서 Flash·SDP 어텐션 옵션을 켜면 피크 메모리가 줄고 Step 시간이 안정되는 경우가 많습니다. 동일 하드웨어에서 배치·시퀀스를 조금 더 크게 가져가며 실험할 여지가 생깁니다.
추론 단계 (Inference): 응답 속도의 혁신
KV 캐시로 과거 를 재사용하고, 효율 커널로 매 스텝 어텐션을 가볍게 하면 TTFT(첫 토큰)와 디코딩 체감이 좋아집니다. 사용자 경험에 직결됩니다.
패턴 설계 (데이터 맞춤형 희소 어텐션)
문서는 국소+문단 대표 조합이 흔하고, 코드는 괄호·스코프 때문에 윈도 폭을 키우거나 추가 글로벌을 두는 식으로 조정합니다. 데이터 도메인이 곧 스파스 설계입니다.
실무 디버깅 팁 (OOM 탈출기)
시퀀스 길이·배치·dtype을 먼저 확인하고, 다음으로 Flash 실제 활성 여부를 점검합니다. 그래도 부족하면 희소·분할·RAG 순으로 범위를 나눕니다. 장거리가 진짜 필요한 태스크인지 먼저 정하면 낭비가 줄어듭니다.
요약
한 줄 요약 — FlashAttention은 같은 softmax 어텐션을 더 빠르게 계산하도록 구현을 바꾼 것이고, 희소 어텐션은 모든 위치를 보지 않고 패턴으로 연결을 줄여 계산·메모리를 아낍니다.
왜 문제가 될까요? 문장 길이가 이면, 단어들끼리 맞춰 보는 점수표가 대략 처럼 커져서 GPU 메모리와 시간이 빨리 불어납니다. “어텐션이 나쁘다”가 아니라 길이가 길수록 부담이 제곱에 가깝게 커진다고 이해하면 됩니다.
FlashAttention을 쉽게 — 공식이나 목표를 바꾼다기보다, GPU의 느린 큰 메모리(HBM)와 빠른 작은 메모리(SRAM) 특성에 맞춰 데이터를 타일 단위로 옮기며 계산합니다. 그래서 수학적으로 같은 어텐션인데도 메모리 이동이 줄어들어 실사용에서 훨씬 빠르고 안정적입니다.
희소 어텐션을 쉽게 — 모든 토큰 쌍을 보지 않고, 주변 윈도, 문서 곳곳을 대표하는 소수의 토큰처럼 “이런 모양으로만 본다”를 정합니다. 연결 수가 줄어들어 연산·메모리는 줄지만, 멀리 있는 단어 관계가 꼭 필요한 작업에서는 패턴을 잘못 고르면 품질이 떨어질 수 있으니 트레이드오프를 염두에 두면 됩니다.
실무에서 — 먼저 Flash로 병목을 줄이고, 요구와 예산에 맞게 희소 패턴·RAG 등을 함께 고려하면 됩니다. 앞 챕터의 개념은 그대로이고, 이번 장은 어떻게 실행할지에 대한 이야기입니다.
핵심 수식 (복습) — 단계로 보면 로짓 , 행 softmax로 , 출력 입니다.
각 위치 의 출력 행은 이므로, “키 위치들의 값 벡터를 주의 가중치로 섞은 것”으로 기억하면 됩니다. 와 가 을 가리키므로 길이 이 비용의 중심입니다.
이 장의 핵심만:
• 부담의 원인은 길이에 따른 근처 비용.
• Flash = 구현·커널로 같은 어텐션을 효율 실행.
• 희소 = 연결 패턴으로 연산 절감, 설계·검증 필수.
문제 풀이를 위한 설명
정리 — FlashAttention은 같은 softmax 어텐션을 메모리 계층(IO)에 맞춘 커널·구현으로 더 빠르게 계산하고, 희소 어텐션은 쿼리마다 보는 키를 윈도·글로벌 토큰 등 패턴으로 제한해 연결 수·연산을 줄입니다. 길이 이 커질수록 점수 그리드가 병목이 되므로, 실무에서는 Flash vs 스파스 패턴을 OOM·지연·품질에 맞게 고릅니다.
암기 팁: “Flash = 같은 맵, 더 빠른 길”, “희소 = 적은 연결, 설계가 핵심”. OOM이면 길이·배치·dtype과 함께 Flash 켜짐 여부부터 확인하는 습관이 좋습니다.
현장 체크리스트:
• 같은 수학을 유지하며 속도만 올리려면 → Flash를 먼저.
• 연산 자체를 줄이려면 → 희소 패턴+평가.
• 멀리 있는 증거가 중요하면 → 패턴·RAG를 함께 검토.
- 유형개념 선택
- 풀이·예시 (무엇을 넣나)문장 정의에 맞는 보기 번호 → 정수 1, 2, 3
- 유형O/X
- 풀이·예시 (무엇을 넣나)참·거짓 → 1 또는 0
- 유형시나리오
- 풀이·예시 (무엇을 넣나)조건에 맞는 선택지 → 1~3
- 유형투표 합
- 풀이·예시 (무엇을 넣나)이진 벡터에서 1의 개수(합) → 정수
- 유형값 합산
- 풀이·예시 (무엇을 넣나)제시된 수들의 합 → 정수
- 유형구성·격자
- 풀이·예시 (무엇을 넣나)한 변 의 정사각 격자 칸 수 → 정수
- 유형앙상블·트레이드오프
- 풀이·예시 (무엇을 넣나)가장 알맞은 설명 번호 → 1~3
| 유형 | 풀이·예시 (무엇을 넣나) |
|---|---|
| 개념 선택 | 문장 정의에 맞는 보기 번호 → 정수 1, 2, 3 |
| O/X | 참·거짓 → 1 또는 0 |
| 시나리오 | 조건에 맞는 선택지 → 1~3 |
| 투표 합 | 이진 벡터에서 1의 개수(합) → 정수 |
| 값 합산 | 제시된 수들의 합 → 정수 |
| 구성·격자 | 한 변 의 정사각 격자 칸 수 → 정수 |
| 앙상블·트레이드오프 | 가장 알맞은 설명 번호 → 1~3 |
예시 (개념 선택)
"FlashAttention의 초점에 가장 가까운 것은?
① 근사 softmax만 허용
② IO-aware 구현으로 dense softmax 어텐션을 더 효율 계산
③ 어텐션을 완전 제거"
같은 어텐션을 더 효율적으로 구현하는 쪽 → 2
"희소 어텐션의 핵심은?
① 항상 모든 키를 봄
② 쿼리마다 보는 키 집합을 패턴으로 제한
③ FFN만 사용"
연결을 패턴으로 줄인다 → 2
예시 (O/X)
"GPU에서 타일 단위 연산은 온칩 메모리 활용에 도움이 될 수 있다. 맞으면 1, 틀리면 0."
Flash 직관과 맞음 → 1
예시 (시나리오)
"팀 규정: 수학적으로 동일한 어텐션 출력이 필요하다.
① 정확 Flash 구현
② 모든 Q-K 연결 삭제
③ 학습률만 10배"
동일 매핑을 유지하려면 정확 경로 → 1
예시 (투표 합)
"votes = [1,1,1,1,0] 일 때 1의 개수(합)는?"
→ 4
예시 (값 합산)
"values = [7,8,7] 의 합은?"
→ 22
예시 (격자·구성)
"한 변의 길이가 12인 정사각형 격자에서 칸(셀)의 개수는?"
→ 144
예시 (앙상블·역할)
"희소 도입 시 흔한 리스크에 가까운 것은?
① 항상 정확도 상승
② 드문 장거리 의존 손실 가능
③ GPU 불필요"
연결을 줄이면 멀리 있는 증거를 놓칠 수 있음 → 2