Issue 01중국 AI
AC POST
중국 AI 목록
掘金2026년 10월 31일 16:59중국어 → 한국어

선형 어텐션을 인터랙티브로 보여주는 경량 대형모델 복각

경량 대형모델 복각 시리즈로 선형 어텐션의 6가지 스텝 비교와 KDA 상태 변화를 인터랙티브하게 보여준다.

중국어 원문을 AI로 번역했습니다. 고유명사와 수치는 원문 표기를 우선하며, 중요한 판단에는 아래 출처 원문을 함께 확인하세요.

0x01 개요

- 1.1 모듈 포지셔닝

- 1.2 핵심 수학

0x02 각 Tab 상세 설명

- Tab 1: 6가지 Step 비교

- Tab 2: KDA 상태 진화

- Tab 3: v1 vs v2 게이팅

- Tab 4: 점화식 vs 블록화

- Tab 5: 실패 Case

- Tab 6: 파라미터 민감도

- Tab 7: 위치 감쇠 vs RoPE

- Tab 8: 반대 관점

- Tab 9: 차원 흐름

- Tab 10: DeltaNet 수정

- Tab 11: 선형 어텐션 혼합

- Tab 12: GLA vs DeltaNet

- Tab 13: KDA alpha 제약

- Tab 14: KDA v1 호환성

- Tab 15: 도구 함수

- Tab 16: Layer 형상

- Tab 17: Layer 동등성

- Tab 18: Gate 학습 가능성

0x03 정리

- 3.1 Tab 논리 관계도

- 3.2 독자가 가져가야 할 핵심 인식

0xFF 참조

experiments/models/llm/linear_attn/gradio_linear_attn_demo.py는 선형 어텐션 패밀리의 인터랙티브 데모 진입점이며 Gradio 6 기반으로 구축되었다. 이는 6가지 step 변형(Vanilla / DeltaNet / GLA / GatedDeltaNet / KDA v1 / KDA v2), KDA 상태 진화, 게이팅 곡선 비교, 점화-블록 동등성, 실패 사례, 파라미터 민감도, 위치 감쇠, 반대 관점, 그리고 10가지 테스트 시각화(형상/수정/혼합/GLA-vs-DeltaNet/제약/호환성/도구/Layer 형상/Layer 동등/Gate 학습 가능성)를 하나의 18 tab Web UI로 통합하며, 모든 그래프는 CPU에서 실시간 계산되어 산출된다.

총괄 수식

입력: q_t , k_t ∈ R^(B,H,Dk) # 현재 token의 query/key v_t ∈ R^(B,H,Dv) # 현재 token의 value S_{t -1 } ∈ R^(B,H,Dk,Dv) # 이전 단계의 상태 행렬(고정 크기) g_t ∈ R^(B,H,Dk) # gate logit (K 차원별) beta_t ∈ R^(B,H) # 쓰기 강도 logit A_log ∈ R^(H,) # 헤드별 게이팅 스케일 파라미터 범용 점화 뼈대 (Eq. 1 ): S_t = Diag ( alpha_t ) ⊙ S_{t -1 } + beta_t · k_t ⊗ ( v_t - k_t ^T S_{t -1 }) ___________/ ____/ ____/ _______________/ 감쇠/망각 쓰기 강도 새 key 예측 오차(Delta Rule) o_t = q_t ^T S_t # (Eq. 2 ) 검색 출력 변형 차이: Vanilla Linear (Eq. 3 ): S_t = S_{t -1 } + phi ( k_t ) ⊗ v_t # 순수 가산 누적, phi = elu+ 1 DeltaNet (Eq. 4 ): alpha_t = alpha (스칼라), beta_t = beta # Delta Rule 덮어쓰기 도입 GLA (Eq. 5 ): S_t = Diag ( sigmoid ( g_t )) S_{t -1 } + k_t ⊗ v_t # 가산 + 게이팅 감쇠 Gated DeltaNet (Eq. 6 ): S_t = Diag ( sigmoid ( g_t )) S_{t -1 } + sigmoid ( beta_t )· k_t ⊗( v_t - k_t ^T S_{t -1 }) KDA v1 (Eq. 7 ): g_t = - softplus (g_logit + exp (A_log)) → alpha = exp (g) ∈ ( 0 , 1 ) KDA v2 (Eq. 8 ): g_t = g_min_log · sigmoid ( exp (A_log) ⊙ z) → alpha ∈ ( exp (g_min_log), 1 )

하위 메커니즘 분해

Delta Rule (핵심 수정 메커니즘)

수식: S_t = alpha ⊙ S_{t-1} + beta · k_t ⊗ (v_t - k_t^T S_{t-1})

직관적 설명: 쓰기 전에 먼저 k_t로 이전 상태에서 "예측값"을 검색하고, 새 값에서 예측값을 뺀 예측 오차를 구해 오차 부분만 쓴다. 이렇게 하면 동일한 key에 두 번째로 쓸 때 기존 값을 누적하는 것이 아니라 덮어쓴다.

핵심 성질:

- alpha=1, beta=1이고 key가 동일할 때, S_t는 해당 key 부분공간에서 최신 쓰기 값과 정확히 같아진다(Tab 10의 0.2에 대응).

- alpha<1, beta<1일 때 "누설식" 덮어쓰기가 형성되며, 이전 정보는 alpha^k에 따라 지수적으로 감쇠한다.

게이팅 감쇠(gating)

수식: alpha_t = exp(g_t) , 여기서 v1은 g_t = -softplus(z) , v2는 g_t = g_min_log · sigmoid(exp(A_log) ⊙ z) 를 사용한다.

직관적 설명: "얼마나 망각할지"를 학습 가능한 logit으로 삼아, 각 K 차원이 자신의 시간 척도를 독립적으로 선택하게 한다.

- v1의 하한은 0에 근접할 수 있어(완전 망각) 가능하지만, z→+∞일 때 그래디언트가 지수적으로 감쇠하여 그래디언트 소실 위험이 있다.

- v2의 하한 exp(g_min) > 0 은 하드한 최저 보장으로, 결코 0까지 망각하지 않으며, 그래디언트 형태가 sigmoid와 유사하고 z=0 근처에서 그래디언트가 최대이다.

상태 검색

- 수식: o_t = q_t^T S_t

- 직관적 설명: 상태 S를 하나의 키-값 연상 기억 행렬로 보고, query는 검색 벡터이며, 출력은 해당 query가 기억 위에 투영된 것이다.

- 핵심 성질: 메모리 점유가 O(Dk·Dv)로 시퀀스 길이와 무관하며, 이는 KV cache O(T·D) 대비 핵심적인 장점이다. 대가는 용량 병목이다(Tab 5).

핵심 통찰

핵심 통찰: 선형 어텐션의 본질은 "과거를 고정 크기의 상태 행렬 S에 압축하는 것"이다. Vanilla Linear는 순수 가산적 누적(혼입 발생)이고, DeltaNet은 Delta Rule을 통해 "동일 key 덮어쓰기"(오류 정정)를 구현하며, GLA/GDN은 여기에 게이팅 감쇠(시간 스케일)를 더하고, KDA v2는 나아가 g_min으로 망각에 하한을 단단히 보장한다(수치 안정성). 이 전체 계열은 "어떻게 쓰고, 어떻게 잊고, 어떻게 조회하는가"라는 세 축을 중심으로 전개된다.

목적

완전히 동일한 입력 시퀀스(주기화된 key, 변화하는 value) 하에서 6가지 step 함수(Vanilla / DeltaNet / GLA / GatedDeltaNet / KDA v1 / KDA v2)를 나란히 실행하여, 각 토큰 스텝의 출력 벡터를 히트맵으로 쌓는다. 검증하려는 명제는, 주기적으로 반복되는 key 시나리오에서 순수 가산 방식(Vanilla)의 출력은 시간에 따라 표류/발산하는 반면, Delta Rule을 갖춘 방식(DeltaNet/GDN/KDA)은 출력 진폭을 억제할 수 있고, sigmoid 게이팅을 갖춘 방식(GLA)은 진폭이 중간 정도라는 것이다.

배경 개념

주기화된 key 패턴: 코드에서 시퀀스를 period = seq_len // 8로 여러 그룹으로 분할하며, 동일 그룹 내의 모든 토큰은 같은 k_base를 공유하지만 v_base는 그룹 내에서 위치에 따라 사인 곡선 형태로 변한다. 이렇게 설계한 이유는 "같은 key, 다른 value"의 쓰기 충돌을 확대하기 위해서다. Delta Rule 계열 방식은 덮어쓰고, 순수 가산 방식은 누적한다.

설계 사상

왜 이렇게 실험을 설계했는가: 2×3 히트맵(행=출력 차원, 열=토큰 스텝)을 선택한 이유는 시간 차원(수평 줄무늬가 주기성을 반영)과 진폭 차원(colorbar 범위)이라는 두 가지 핵심 정보를 동시에 드러낼 수 있기 때문이다. 비교 대상을 2가지가 아닌 6가지로 선택한 이유는, 독자가 "순수 가산에서 KDA v2로의 진화 경로"를 볼 수 있게 하기 위해서다. 각 단계의 진화는 이전 세대의 어떤 문제를 해결했는가. 파라미터 범위(seq 10-100, dim 8-64)는 CPU에서 실시간으로 관찰 가능한 진화 효과를 내기 위한 것이다.

검증하려는 것:

- Vanilla Linear의 출력 진폭은 range=[-706.26, 706.26]으로, 다른 5가지(나머지는 모두 ±1에서 ±58 사이)보다 훨씬 크다 — 순수 가산 누적이 발산함을 검증한다.

- DeltaNet의 출력 범위 [-0.83, 0.83]이 가장 좁다 — Delta Rule 덮어쓰기가 실제로 진폭을 억제함을 검증한다.

- KDA v2 [-0.54, 0.54]가 KDA v1 [-0.25, 0.25]보다 다소 넓다 — v2의 하한 g_min이 망각을 더 완만하게 하여 더 많은 역사를 보존함을 검증한다.

독자가 배우길 바라는 것:

- "순수 가산 vs Delta Rule"의 출력 진폭 차이는 세부 사항이 아니라 양적(자릿수) 차이다.

- 동일한 입력이 서로 다른 state update rule 하에서 완전히 다른 동역학을 낳는다.

그림에서 보길 바라는 것: tab-1.webp 실제 그림에서 볼 수 있듯이, 6개 서브플롯 모두 수직 방향의 붉은 줄무늬를 보인다(주기 내에서 key가 반복되고 query도 주기적으로 변하므로, 출력은 주기 내에서 대략 반복되는 패턴을 보인다). 성공 신호: Vanilla 서브플롯의 colorbar 값은 -700~700(최대)이고, 나머지 5개는 모두 ±58 이내이다. 6개 그림 전체의 색조가 붉은 편이다(query와 key가 동일 방향이기 때문). 실패 신호: DeltaNet / GDN / KDA의 출력 colorbar도 ±700에 도달하면 Delta Rule이 작동하지 않은 것이다. KDA v2의 색이 v1과 완전히 같다면 g_min 제약이 작동하지 않은 것이다.

UI 컴포넌트와 파라미터 영향

파라미터 | 범위 | 기본값 | 조정 효과: 무작위 시드 0-999, 42 → 변경 시 초기화 기저는 바뀌지만 전체 패턴은 변하지 않음; 시퀀스 길이 10-100, 40 → 증가 시 줄무늬 주기 수가 늘어나 Vanilla 누적이 더 뚜렷해짐; 특징 차원 8-64, 16 → 증가 시 히트맵 행 수가 늘어나 패턴이 더 정교해짐; gate logit(통일 상수) -5.0, -2.0, -1.0 → 증가 시 sigmoid/softplus가 1에 가까워져 망각이 약해지고 누적 효과가 강해짐; A_log(KDA 게이팅 스케일) 0.0-5.0, 2.0 → 증가 시 KDA v2의 sigmoid가 가팔라져 alpha가 상하한에 더 가까워짐

출력 그래프 해석

tab-1

레이아웃: 2×3 육연도(6개 패널) 그림으로, 각 칸에 히트맵 + colorbar가 있고 서브플롯 제목에 range=[min, max]가 표기된다(이것이 핵심 수치 신호이다).

- 좌상단 (a) Vanilla Linear: 히트맵, X축=token step(0-40), Y축=dim(0-16), colormap=RdBu_r. 무엇을 봐야 하는가: colorbar 수치 범위. 이상적인 경우: |range|가 다른 5개보다 현저히 크다(실제 그림에서는 ±706). 출력이 토큰 수에 따라 선형으로 누적되기 때문이다. 이상 징후: 만약 range 역시 ±1 규모라면 phi(k)가 작동하지 않았거나 코드가 DeltaNet을 잘못 사용한 것이다.

- 중상단 (b) DeltaNet: 마찬가지로 히트맵, colorbar는 ±0.83. 무엇을 봐야 하는가: 붉은 줄무늬가 매우 선명하고 규칙적이다. Delta Rule이 매 주기마다 상태를 덮어쓰기 때문이다. 이상적인 경우: 범위가 ±1 근처. 이상 징후: 만약 Vanilla와 일치한다면(±700) alpha=0.5와 beta=0.5의 감쇠가 작동하지 않은 것이다.

- 우상단 (c) GLA: colorbar ±57.96. 무엇을 봐야 하는가: 범위가 Vanilla보다 작지만 DeltaNet보다는 크다 — GLA는 "게이팅 감쇠 + 가산 쓰기"로, 여전히 누적이 있으나 sigmoid 감쇠에 의해 억제된다. 이상적인 경우: 범위가 Vanilla와 DeltaNet 사이.

- 좌하 (d) Gated DeltaNet: colorbar ±0.27, 6개 중 가장 좁다. 무엇을 봐야 하는가: 이중 제약(gate 감쇠 + Delta 덮어쓰기).

- 중하 (e) KDA v1: colorbar ±0.25, GDN과 비슷하다.

- 우하 (f) KDA v2: colorbar ±0.54, v1보다 약간 크다. 무엇을 봐야 하는가: v2의 g_min 하한 때문에 망각이 더 느려져 더 많은 역사를 보존하므로 → 출력 진폭이 약간 더 크다.

조절 제안

- Vanilla의 발산을 보고 싶다면 → 시퀀스 길이를 100으로 조절하라. colorbar 범위가 더욱 확대된다.

- KDA v1 vs v2의 차이를 보고 싶다면 → gate logit을 -3으로 조절하라. sigmoid가 0에 가까워지고, v2는 g_min이 받쳐주지만 v1은 계속 0으로 향해 둘의 출력 범위 차이가 커진다.

- "주기성이 입력에서 비롯된다"를 검증하고 싶다면 → 랜덤 시드를 다른 값으로 조절하라. 줄무늬 위치는 변하지만 주기 간격은 변하지 않는다.

왜 중요한가

이것은 전체 데모의 총 관문이다. 그림 하나로 독자에게 "선형 어텐션 계열은 같은 것이 아니다"라는 것을 알려주며, 6가지 변체가 동일한 입력에서 출력 진폭이 3자릿수(3 orders of magnitude) 차이가 난다. 독자가 탭을 하나만 볼 수 있다면 이것을 봐야 한다. 이것이 Delta Rule이 왜 필요한지(그렇지 않으면 발산), 게이팅이 왜 필요한지(그렇지 않으면 망각 불가), KDA v2에 왜 g_min 하한을 더해야 하는지(그렇지 않으면 극단적 logit에서 수치가 불안정)를 직접 결정하기 때문이다.

KDA 상태 행렬 S ∈ R^(Dk × Dv)가 시퀀스 처리 과정에서의 스냅샷을 토큰 단위로 추적하며, 5개 시점({0, T/4, T/2, 3T/4, T-1})에서 S를 포착해 시각화한다. 검증하는 명제: KDA의 상태는 정적이 아니라 입력에 따라 지속적으로 재구성되며, 서로 다른 버전(v1 vs v2)은 동일한 gate에서 망각 속도에 가시적인 차이가 있다.

왜 이렇게 실험을 설계했는가: 꺾은선이 아닌 imshow를 선택한 이유는 S가 2차원 행렬(K 차원 × V 차원)이기 때문이며, 히트맵은 "어떤 (k,v) 쌍의 채널이 강화/억제되는지"를 직접 보여줄 수 있다. 5개의 등간격 스냅샷은 "진화 과정" 시각화의 최소 집합이다. 더 많으면 UI에 다 들어가지 않고, 더 적으면 추세를 볼 수 없다. v1/v2 전환을 제공하는 것은 독자가 게이팅 함수가 상태의 장기적 행동에 미치는 영향을 직접 비교하게 하기 위해서다.

- v1은 gate=-0.5, A_log=5에서 S가 t=80일 때 여전히 뚜렷한 구조를 가진다(완전히 0으로 돌아가지 않음).

- v2는 같은 조건에서 S의 색이 전체적으로 더 포화된다(더 많은 역사를 보존). g_min 하한 때문에 alpha > exp(g_min)이기 때문이다.

- 상태에서 NaN이나 순수 검정색은 나타나지 않는다(수치적으로 안정함을 의미).

- "상태"는 동적인 기억이지 정적인 가중치가 아니다. 각 행(K 차원)은 독립적인 기억 채널과 같다.

- v1과 v2의 차이는 장기적 행동에 나타나며, 단기적으로는 보이지 않는다.

그림에서 보고자 하는 것: tab-1-2.webp(v1)와 tab-2-2.webp(v2)의 실제 그림에서 볼 수 있듯이, 두 그림 모두 5개 스냅샷의 8×12 히트맵을 보여준다. v1 그림: t=1일 때 색이 비교적 옅고(적은 쓰기), t=21부터 뚜렷한 빨강/파랑 교차 사각형이 나타나며, t=80에도 여전히 선명한 구조가 있다. v2 그림: t=1의 색이 v1보다 더 옅다(v2의 sigmoid gate는 z=-0.5일 때 alpha가 높아 더 많이 보존하지만, 초기 S=0이므로 첫 프레임은 거의 내용이 없음), t=21부터 색의 깊이가 v1을 넘어서고, t=80에서도 여전히 매우 포화되어 있다. 성공 신호: v2의 뒤쪽 몇 프레임의 색 깊이 ≥ v1, 5개 스냅샷 모두 내용이 있음(전부 흰색이 아님). 실패 신호: 어느 한 프레임이라도 전부 흰색이나 전부 검정색이 되면 망각이 너무 빠르거나 수치가 오버플로했음을 의미한다.

매개변수 범위 기본값 조절 효과 랜덤 시드 0-999 42 변경 → 기저 패턴 변화 시퀀스 길이 10-200 80 증가 → 진화 경로가 더 길어지고 망각 효과가 더 뚜렷해짐 K 차원 4-32 8 증가 → 상태 행렬 행 수 증가 V 차원 4-32 12 증가 → 상태 행렬 열 수 증가 gate logit -5.0 - 2.0 -0.5 증가 → alpha→1, 상태 누적; 감소 → alpha→g_min, 상태가 빠르게 망각됨 A_log 0.0 - 5.0 1.0 증가 → sigmoid가 가팔라져 alpha가 상하한에 더 가까워짐 KDA 버전 v1 / v2 v2 전환 → alpha 함수족 변화

V1

tab-1-2

V2

tab-2-2

레이아웃: 1×5 오연도(각 시간점마다 8×12 히트맵 한 장).

- 각 하위 그림: colormap=RdBu_r, X축=V dim(0-12), Y축=K dim(0-8), colorbar는 vmin/vmax 공유.

- v1 다섯 프레임(tab-1-2.webp): t=1은 흰색에 가깝고, t=21에 "좌상 빨강, 우하 파랑"의 체커 구조가 나타나며, t=41/61/80 구조가 계속 진화하고, 빨강 블록과 파랑 블록의 위치가 입력 정현파의 변화에 따라 이동한다. 이상적 상황: 각 프레임의 색 깊이가 점차 증가하고 마지막에 포화된다. 이상 징후: 만약 t=80이 전부 흰색이라면 alpha가 모두 0이어서 state가 완전히 망각되었음을 의미한다.

- v2 다섯 프레임(계속): t=21부터 빨강 블록(양수)과 파랑 블록(음수)이 v1의 같은 프레임보다 모두 더 깊고, t=80에 이르면 그림 전체가 고채도의 빨강·파랑 체커를 보여주며, v2의 g_min 하한이 옛 정보를 더 많이 보존하게 함을 의미한다. 이상 징후: 만약 v1과 v2의 다섯 프레임이 완전히 동일하다면(픽셀 단위로 같음) version 매개변수가 kimi_linear_step에 전달되지 않았음을 의미한다.

- "v1의 빠른 망각 vs v2의 하한 보장"을 보고 싶다면 → gate logit을 2.0으로 조절하라(sigmoid가 1에 가까워지고, v1의 alpha→exp(-softplus(2+exp(A_log)))는 매우 작아지며, v2는 g_min이 받쳐줌).

- "상태가 공백에서 포화까지 가는 전체 과정"을 보고 싶다면 → 시퀀스 길이를 200으로 조절하고, gate를 -0.1(약한 망각)로 설정하라.

- "큰 상태 행렬의 세밀한 구조"를 보고 싶다면 → K 차원과 V 차원을 모두 32로 조절하라.

Tab 1은 "출력"을 보고, Tab 2는 "상태 자체"를 본다. 선형 어텐션의 모든 동작은 상태 행렬 S의 진화에서 비롯된다——이 tab은 **독자가 "기억이 어떻게 쓰이고 잊히는지"를 직접 관찰할 수 있는 유일한** 창이다. 프로덕션에서 v2의 g_min을 너무 작게 설정하면(예: 1e-6), 긴 시퀀스의 꼬리 부분 상태가 영행렬에 가까워져 모델이 "기억상실"을 겪는다. 이 tab은 5프레임 내에 이러한 실패 모드를 직관적으로 드러낼 수 있다.

A_log가 진화에 미치는 영향

gate=−0.5 고정.

A_log v1 진화 v2 진화 물리적 해석 0 alpha = exp(−softplus(−0.5)) ≈ 0.62, S가 천천히 감쇠 alpha = exp(−5·sigmoid(−0.5)) ≈ 0.30, S가 중간 정도 감쇠 v1 감쇠가 v2보다 느림(v2는 sigmoid로 g를 더 음수 쪽으로 밀어냄) 1 alpha ≈ exp(−e·softplus(−0.5)) ≈ 0.28, S 감쇠가 다소 빠름 alpha = exp(−5·sigmoid(−e·0.5)) ≈ 0.13, S 감쇠가 더 빠름 위와 동일, v2 감쇠가 더 맹렬함 3 alpha ≈ exp(−20·0.474) ≈ 7e-5, S가 매 스텝 거의 소거됨 alpha = exp(−5·sigmoid(−10)) ≈ 0.9998, 거의 감쇠하지 않음 v2 반포화: sigmoid 출력 ≈0, g가 0으로 되밀리고, alpha가 1로 되밀림 5 alpha ≈ 3e-31, S가 완전히 망각됨(전부 흰색) alpha = exp(−5·sigmoid(−74)) ≈ 1.0000, 전혀 감쇠하지 않음 v2 심각한 반포화, S는 지속적으로 누적되지만 sin/cos 신호가 정부(正負) 상쇄되어 시각적으로도 옅은 색

핵심 개념: v2의 반포화(inverse saturation)

v2 게이트 g = g_min · sigmoid(expA · z)의 sigmoid 출력이 0일 때 오히려 alpha=1이 된다——이것은 v2의 설계 부작용이다:

sigmoid 출력 g alpha = exp(g) 의미 ≈ 0(z가 극히 음수) ≈ 0 ≈ 1 불망각(새 값이 계속 누적됨) ≈ 0.5(z≈0) g_min/2 exp(−2.5) ≈ 0.082 중간 정도 망각 ≈ 1(z가 극히 양수) g_min exp(−5) ≈ 0.0067 강한 하한(최대 망각)

주의, 이것은 직관과 반대다: z가 음수일수록 alpha가 크고(더 잊지 않음), z가 양수일수록 alpha가 작다(더 잊음). 이것은 K3가 "망각 게이트"를 역방향으로 설계한 결과다——z는 "망각 logit"이 아니라 "기억 logit"이다.

KDA v1(softplus gate)과 v2(sigmoid gate)의 감쇠 인자 α(z) 곡선과 기울기 dα/dz 곡선을 그려, 두 게이트 함수의 수학적 형태를 직접 비교한다. 명제 검증: v1의 α는 0에 근접할 수 있고(완전 망각), v2의 α는 g_min의 강제 하한에 떠받쳐지며, v2는 z=0 근처에서 기울기가 더 집중되고, v1은 z→+∞일 때 기울기가 지수적으로 감쇠한다.

게이트 함수의 Log 영역 설계: KDA의 α는 반드시 (0,1)에 속해야 감쇠를 수행하면서도 수치 안정성을 보장할 수 있다. v1은 g = -softplus(z)로 z를 (-∞, 0)에 매핑한 뒤 α = exp(g) ∈ (0, 1)를 취하고, v2는 g = g_min_log · sigmoid(z)로 z를 (g_min_log, 0)에 매핑하여 α ∈ (exp(g_min_log), 1)이 된다. 하한 g_min은 v2가 도입한 핵심 하이퍼파라미터로——z가 아무리 커도 상태가 최소 g_min 비율은 유지되도록 보장한다.

실험을 이렇게 설계한 이유: 1×2 이중 그래프(왼쪽=α 곡선, 오른쪽=기울기 곡선)를 고른 것은 "함수 형태"와 "기울기 형태"가 게이트를 설계할 때 반드시 동시에 고려해야 하는 두 가지이기 때문이다——왼쪽 그래프는 "망각이 얼마나 낮아질 수 있는가"를, 오른쪽 그래프는 "역전파가 학습될 수 있는가"를 답한다. z 범위 (-6, 6)은 sigmoid/softplus의 유효 구간을 포괄한다(그 밖에서는 둘 다 포화된다). plot_forget_limit.py의 실제 함수를 재사용하여 그래프가 논문/코드와 일치하도록 보장한다.

- v1 곡선(파랑)은 z=6일 때 α가 0에 근접한다(가로축에 근접).

- v2 곡선(주황)은 z=6일 때 α가 g_min=0.01의 점선 지점에 멈추고, 더 이상 내려가지 않는다.

- v2 기울기 곡선(주황)은 z≈-2에서 최댓값을 가지며, v1 기울기(파랑)는 z≈0에서 최댓값을 가지고, v2의 피크가 더 "가늘고 높다".

- "v2는 v1의 작은 수정이 아니라" 함수족 자체가 다르다——v1은 softplus족(하한 없음), v2는 sigmoid족(하한 있음)이다.

- 하한 g_min은 수치 안정성과 망각 능력의 절충이다: 너무 작으면 → 최저 보장의 의미를 잃고, 너무 크면 → 망각할 수 없다.

그래프에서 보고자 하는 것: tab-3.webp 실제 그림에서 볼 수 있듯이, 왼쪽 그래프: 파란 선(v1)은 z=-6일 때 1.0에서 단조 감소하여 z=6일 때 ≈0.0이 되고, 주황 선(v2)도 마찬가지로 감소하지만 z≈2 이후 평탄해지기 시작하여 최종적으로 g_min=0.01의 점선에 멈춘다(파란 v1과 뚜렷이 분리됨). 오른쪽 그래프: 두 기울기 곡선 모두 "종 모양"을 띠며, 파란 선(v1)은 z≈0에서 최솟값 ≈ -0.25를, 주황 선(v2)은 z≈-1.5에서 최솟값 ≈ -0.29를 가지며, v2 기울기 피크가 더 깊고 더 왼쪽에 있다. 성공 신호: v1은 오른쪽 끝에서 계속 하강하여 g_min 점선을 통과하고, v2는 오른쪽 끝에서 g_min 점선과 겹친다. 실패 신호: 만약 두 α 곡선이 오른쪽 끝에서 모두 0으로 수렴하면 v2의 g_min이 작동하지 않은 것이고, 만약 기울기 곡선에 평탄 구간이 나타나면 sigmoid/softplus가 포화된 것이다.

파라미터 범위 기본값 조정 효과 z 범위 2-10 6 증가 → 더 깊은 포화 영역을 보게 되고, v1과 v2가 오른쪽 끝에서 더 뚜렷이 분리됨 g_min (v2 하한) 0.001-0.1 0.01 증가 → v2 곡선이 내려가는 "바닥"이 높아져 망각 능력이 약해짐

tab-3

레이아웃: 1×2 이중 그래프.

- 왼쪽 그림 (감쇠 인자 α(z)): 꺾은선 그래프, X축=z(gate logit), Y축=α, Y 범위 [0, 1]. 파란색 실선=v1, 주황색 실선=v2, 회색 점선=g_min=0.01 수평 기준선. 무엇을 봐야 하는가: v1이 g_min 점선을 통과하는지(통과해야 함), v2가 g_min 점선에서 멈추는지(멈춰야 함). 이상적인 경우: 두 선이 z<0일 때 거의 겹치고, z>0일 때 갈라지며, v1은 계속 하강하고 v2는 평탄해진다. 이상 징후: 만약 v2도 g_min 점선을 통과하면 g_min_log * sigmoid(z) 공식 구현이 잘못된 것이고, 두 선이 완전히 겹치면 version을 구분하지 못한 것이다.

- 오른쪽 그림 (기울기 dα/dz): 꺾은선 그래프, X축=z, Y축=dα/dz(항상 음수, α가 z 증가에 따라 감소하기 때문). 무엇을 봐야 하는가: 두 종형 곡선의 최저점 위치(기울기 크기가 최대인 곳)와 폭. v2의 최저점이 더 왼쪽에 있고 더 깊다면, z<0 영역에서 학습 신호가 더 강하다는 뜻이다. 이상적인 경우: 두 곡선 모두 매끄러운 종형이며 톱니가 없다. 이상 징후: 기울기 곡선이 z>2에서 0이 아닌 상수를 보이면 exp/softplus 수치 오버플로를 의미한다.

- "v2가 v1으로 퇴화하는 모습"을 보고 싶다 → g_min을 0.001로 조정(0에 가깝게), 그러면 v2 곡선이 거의 v1과 겹친다.

- "v2가 완전히 망각 능력을 상실한 모습"을 보고 싶다 → g_min을 0.1로 조정, 그러면 v2 곡선이 z>2 이후 0.1의 높은 값에서 멈춘다.

- 포화 영역을 보고 싶다 → z 범위를 10으로 조정하고, 두 α 곡선이 z=10에서 분리되는 것을 관찰한다.

게이트 함수는 KDA의 "심장"이며, α 곡선은 망각 속도를, 기울기 곡선은 학습 가능성을 결정한다. 이 tab은 그림 한 장으로 "v1 vs v2"의 차이를 추상적인 공식에서 시각적 형상으로 바꿔 보여준다. 실제 운용에서 학습 시 gate logit이 z=5 밖으로 벗어나면 v1의 기울기는 지수적으로 감쇠하여 gate가 학습되지 않게 되고, v2의 sigmoid 기울기도 감쇠하지만 하한 g_min이 최소한 전방 계산에서 NaN이 나오지 않도록 보장한다—이 차이는 긴 시퀀스 학습 안정성에 직접적인 영향을 준다.

KDA의 두 가지 계산 모드—토큰별 순차 재귀(kda_step 루프)와 청크 단위 병렬(kda_chunkwise)—가 수치적으로 등가인지 검증한다. 검증 명제: 동일한 입력에 대해 두 모드의 출력 최대 오차는 < 1e-3이어야 한다.

청크 단위 병렬(chunkwise): 선형 어텐션의 재귀 형태 S_t = α_t S_{t-1} + β_t k_t (v_t - k_t^T S_{t-1}) 는 시퀀스 의존적이다(병렬화 불가). 그러나 수학적으로는 행렬 결합법칙을 통해 각 chunk 내부의 업데이트를 한 번의 행렬 곱셈으로 합치고, chunk 사이에서는 상태를 직렬로 전달할 수 있다—이렇게 하면 chunk 내부는 병렬화할 수 있고, chunk 사이는 재귀를 유지한다. 이것이 선형 어텐션을 GPU에 배포하는 핵심 기술이다.

실험을 이렇게 설계한 이유: 히트맵+꺾은선 조합을 고른 것은 히트맵이 "오차가 (token, dim) 2차원 평면에 분포하는 패턴"을 드러낼 수 있기 때문이며(오차가 특정 chunk 경계에 집중된다면 분块 로직에 버그가 있다는 뜻), 꺾은선 그래프는 "오차가 시간에 따라 누적되는지"를 보여줄 수 있기 때문이다. 파라미터 범위 seq 32-256, chunk 8-64는 CPU가 감당할 수 있으면서 chunk 경계를 유발할 수 있는 합리적인 구간이다.

- max_diff < 1e-3 (코드 내 판정 임계값).

- 오차 히트맵에 뚜렷한 chunk 경계 줄무늬가 없어야 함(있다면 chunk 경계 처리가 잘못된 것).

- 오차가 token에 따라 누적되지 않음(꺾은선 그래프는 평탄해야 하며, 단조 상승해서는 안 됨).

- "청크 단위 병렬"은 근사 알고리즘이 아니라, 수학적으로 엄밀히 재귀와 등가이다(부동소수점 정밀도 내에서).

- 부동소수점 누적 오차는 주로 행렬 곱셈 순서 차이에서 오며, 오차가 시퀀스 길이에 따라 증가하는 것은 정상이지만, 1e-3 수준 이하로 유지되어야 한다.

그림에서 보고자 하는 것: ⚠️ 중요: 실제 그림 tab-4.webp는 max_diff = 8.12e-01을 보여주며, 1e-3 임계값을 크게 초과하여 코드 로직은 "편차가 큼"을 출력한다. 왼쪽 히트맵은 token≈48-88 구간에서 다량의 밝은 노란색 줄무늬(오차가 0.8에 근접)가 나타나며, 이는 현재 CPU 참조 구현에서 kda_chunkwise와 kda_step이 dim=16, chunk=16, seq=128 설정에서 수치 편차가 현저함을 의미한다. 이는 문서 오류가 아니라 구현 수준에서 수정이 필요한 버그다. 성공 신호(이상적인 경우): max_diff < 1e-3, 히트맵 전체가 검은색(오차가 0에 근접), 오른쪽 꺾은선이 1e-5 근처에서 소폭 변동. 실패 신호(실제 상황): 히트맵에 큰 밝은 영역이 나타나고, 오른쪽 꺾은선이 특정 token에서 1e-1 수준으로 치솟는다.

bug 표기: 현재 kda_chunkwise와 kda_step은 이 파라미터에서 수치 편차가 0.812로 임계값을 크게 초과하며, 구현 검증이 필요하다(아마도 SGLang fused_recurrent.py 또는 chunked 참조 구현과 대조 필요). 문서는 bug 현황을 기록하기 위해 이 절을 유지하며, 수정 후 그림을 업데이트한다.

파라미터 범위 기본값 조정 효과 무작위 시드 0-999 42 변경 → 입력 분포 변화, 그러나 등가성은 유지되어야 함 시퀀스 길이 32-256 128增大 → chunk 수 증가, 부동소수점 오차 누적 가능 특징 차원 8-64 16增大 → 행렬 곱셈 차원 증가, 오차 크기 상승 가능 chunk_size 8-64 16增大 → chunk 내 병렬 부분 비중 증가, chunk 수 감소

tab-4

- 왼쪽 그림 (요소별 오차 분포 head=0): 히트맵, X축=token(0-128), Y축=dim(0-16), colormap=hot(검정→빨강→노랑→흰색). 무엇을 봐야 하는가: chunk 경계의 수직 줄무늬가 있는지(chunk_size=16 → 경계는 16, 32, 48...에 있어야 함). 이상적인 경우: 전체 그림이 거의 검은색(오차<1e-3)이며, 개별 위치에만 미세한 밝은 점이 있다. 실제 그림: token=48-88 구간에 다량의 밝은 노랑/빨강 줄무늬가 있고, dim 차원의 16개 행 모두 영향을 받는다—이것이 현재 구현의 bug 신호다.

- 오른쪽 그림(토큰당 평균 오차): 꺾은선 그래프, X축=token, Y축=mean abs diff(log 스케일). 빨간 점선=max_diff 수평 참조선. **이상적 상황**: 꺾은선이 1e-5에서 1e-4 사이에서 작게 변동하며 추세성 증가가 없음. **실제 그림**: 꺾은선이 token=48~88 구간에서 10^0(즉 1.0)에 가깝게 치솟아 1e-3 임계값을 크게 초과함.

- 현재 bug를 회피하려면 → chunk_size를 seq_len과 동일하게 설정(예: seq=128, chunk=128, 이때 chunk가 하나뿐이라 분할이 일회성 행렬 곱으로 퇴화).

- chunk 경계의 영향을 보고 싶다면 → chunk_size를 8(최소)로 설정하고 오차 줄무늬가 더 촘촘해지는지 관찰.

- seq에 따라 누적되는지 검증하려면 → seq_len을 256으로 설정하고 오른쪽 그림의 꺾은선이 계속 증가하는지 관찰.

분할 병렬화는 KDA가 GPU에 올라갈 수 있는지의 관건이다. 만약 점화식과 분할 결과가 등가가 아니라면, 모든 "선형 어텐션 O(1) 상태"의 이론적 이점은 엔지니어링 이익으로 전환될 수 없다. 이 tab은 **구현 정확성의 주된 기준점**이다 — 이것만 통과하면 안심하고 chunkwise로 학습하고 step으로 추론할 수 있으며, 실패한다면(현재 실제 그림에서 보이듯이) 전체 KDA 파이프라인을 다시 점검해야 한다. 이것이 바로 문서가 현재 bug를 사실대로 표기해야 하는 이유이기도 하다.

KDA 상태 용량 병목 시연: 동일한 key에 서로 다른 value가 반복적으로 기록될 때, 이전 value는 새로운 value로 덮어쓰여져 장기간 보존될 수 없다. 이는 고정 크기 상태 행렬의 **이론적 한계**이지 구현 bug가 아니다.

**용량 병목**: 상태 S ∈ R^(Dk × Dv)는 고정 크기이며, Dk 차원의 "키 공간"에 해당한다. 서로 다른 (k, v) 쌍이 기록될 때, k들 사이에 선형 상관(또는 그냥 동일한 k)이 존재하면, 나중에 기록된 value가 먼저 기록된 value를 **덮어쓴다**(Delta Rule을 통해). 이는 KV cache와 대조된다 — KV cache는 각 token마다 독립적인 K/V 슬롯이 있어 **덮어쓰지 않는다**.

**왜 이렇게 실험을 설계했는가**: "동일한 key에 8개의 서로 다른 value를 반복 기록"을 스트레스 테스트로 쓰는 것이 용량 병목을 드러내는 가장 직접적인 방법이다. 꺾은선 그래프(히트맵이 아닌)를 쓴 이유는 독자가 **수치 추세**를 봐야 하기 때문이다 — 검색값(빨강)이 실제 기록값(파랑)을 따라가는지 여부. plot_failure.capacity_bottleneck을 재사용하여 정적 demo와 일관성을 보장한다.

- 검색값(빨간선)이 실제 기록값(파란 점선)의 진폭 변화를 완전히 추종하지 못한다.

- 검색값의 진폭이 실제 기록값보다 작다(이전 값이 덮어쓰여진 후, S의 해당 행이 새 값의 감쇠된 버전이기 때문).

- 두 선의 **부호 변화 추세는 일치**(동일 부호)하여, Delta Rule이 여전히 작동하고 있음을 보여주며 단지 감쇠가 있을 뿐이다.

- 고정 크기 상태 = 유한 용량. 여러 key가 부분 공간을 공유할 때, 이전 정보는 필연적으로 새로운 정보로 덮어쓰여진다.

- KDA는 "공짜 점심"이 아니다 — 용량을 O(1) 메모리로 맞바꾼 것이다.

**그림에서 무엇을 봐야 하는가**: tab-5.webp 실제 그림에서 볼 수 있듯이, **파란 점선**(실제 기록값 v)은 8번의 기록 단계에서 사인파식으로 오르내리며 범위는 약 ±0.85이다. **빨간 실선**(검색값 S[0,0])도 유사한 추세를 보이지만 **진폭이 뚜렷하게 작고**(범위 약 ±0.45), 전체적으로 파란선보다 "지연"된다(파란선의 극값 지점에서 빨간선은 절반까지만 간다). **성공 신호**: 두 선의 추세가 일치하고 진폭에 차이가 있다. **실패 신호**: 빨간선이 파란선에 완전히 밀착하면 상태가 덮어쓰여지지 않는 것(Delta Rule 실패); 빨간선이 완전히 평평하면 상태가 기록되지 않는 것(기록 로직 실패).

매개변수 없이, 버튼을 클릭하면 바로 실행된다.

tab-5

**레이아웃**: 단일 그림, 꺾은선 그래프.

- **단일 그림**: X축=기록 단계 수(0-7, 동일 key 반복 기록), Y축=값. 파란 점선+사각형 마커=실제 기록값 v, 빨간 실선+원형 마커=상태 S에서 검색해 낸 값. **무엇을 봐야 하는가**: 두 선의 **진폭 차이**(용량 병목의 직접 증거)와 **추세 일치성**(덮어쓰기가 점진적이며 갑작스럽지 않음을 보여줌). **이상적 상황**: 빨간선 진폭 < 파란선 진폭이되 위상은 일치. **이상 지시**: 만약 빨간선이 완전히 평평하면(파란선을 따라 변하지 않으면), 쿼리 q가 상태 S와 무관함을 의미하며 구현에 bug가 있음; 만약 빨간선 진폭이 파란선보다 크면, 상태가 덮어쓰기가 아니라 누적되고 있음을 의미하며 Delta Rule 설계와 모순됨.

조절 가능한 매개변수가 없다.

이는 **반대 측 관점의 이론적 기초** — 선형 어텐션의 고정 크기 상태는 필연적으로 용량 상한을 가진다. 이 tab은 추상적 병목을 구체적 곡선으로 만든다: 독자는 "동일한 key에 8번째 기록할 때, 앞선 7번의 기록 정보가 이미 50%만 남도록 덮어쓰여졌다"는 것을 직접 목격한다. 생산 환경에서 이는 KDA가 긴 컨텍스트 작업에서 MLA(전정밀도 어텐션)와 혼합이 필요한 이유를 설명한다(K3 아키텍처의 3:1 비율). KDA가 단거리를 담당하고 MLA가 장거리 정밀 검색을 보완한다. 이 용량 병목을 무시하고 무작정 순수 KDA로 모든 어텐션 층을 대체하면, 모델은 장거리 정밀 참조가 필요한 작업(예: 코드, 계약서)에서 붕괴할 것이다.

Delta Rule에서 alpha(감쇠/보존 비율)와 beta(기록 강도) 두 하이퍼파라미터가 **검색 오차**에 미치는 영향을 스캔한다. 검증 명제: alpha가 클수록 이전 정보가 더 많이 보존되지만 혼입(aliasing)이 더 심해지고, beta가 클수록 수정이 더 공격적이지만 불안정해질 수 있다; 둘은 목표 전환 빈도 아래에서 균형을 찾아야 한다.

**목표 전환 작업**: target_steps마다 한 번씩 실제 값 v를 전환(+1과 -1 사이 교대)하며, DeltaNet의 검색값과 실제 값의 오차를 관찰한다. 이 작업은 "스트리밍 데이터에서의 개념 드리프트" 장면을 모사하며, 온라인 학습/적응 능력을 테스트하는 표준 패러다임이다.

**왜 이렇게 실험을 설계했는가**: 연속 오차 곡선(이산 스캔 히트맵이 아닌)을 택한 이유는 독자가 **시간에 따른 오차 역학**을 봐야 하기 때문이다 — 매 목표 전환 시尖峰(spike)이 나타나는지, 尖峰 후 얼마나 빨리 기준선으로 돌아오는지. alpha ∈ [0,1], beta ∈ [0,2]는 "완전 망각"부터 "완전 보존"까지, "기록 없음"부터 "과잉 기록"까지의 전체 범위를 포괄한다. target_steps ∈ [5, 50]은 드리프트 빈도를 제어한다.

- 매 목표 전환 시(target_steps마다) 오차에 **尖峰**이 나타난다.

- 尖峰 후 오차가 **지수적으로 감쇠**하여 기준선으로 돌아간다(감쇠 속도는 alpha가 결정).

- beta가 클수록 尖峰이 낮아지고(수정이 빠름); alpha가 클수록 기준선은 더 안정적이지만 전환 시 혼입이 더 뚜렷해진다.

- alpha와 beta는 결합되어 있다: 큰 alpha + 큰 beta는 목표 전환 시 최대 오차를 발생시킨다(구값 잔류가 많고, 신값이 다시 공격적으로 기록되기 때문이다).

- 전역 최적 파라미터란 없다. 오직 "목표 전환 빈도에 적합한" 파라미터만 있을 뿐이다.

도표에서 보고자 하는 것: tab-6.webp 실제 이미지에서 볼 수 있듯이, 녹색 꺾은선은 규칙적인 "톱니" 패턴을 보인다. 매 10스텝(target_steps=10)마다 위쪽으로 +1.0×10⁻²까지 치솟는 첨단이 나타나고, 첨단 직후 즉시 음수(약 -1.7×10⁻²)로 떨어졌다가, 다음 전환 전까지 서서히 기준선(약 -0.3×10⁻²)으로 회복된다. 주의: Y축 라벨 1e-8+5e-2는 matplotlib의 과학적 표기법으로, 값이 1e-8 + 5e-2 × 표시값임을 뜻하므로 실제 오차 크기는 0.05 정도다. 성공 신호: 오차가 규칙적 톱니 형태를 보이고, 주기가 target_steps와 같으며, 첨단 후 단조 감쇠한다. 실패 신호: 만약 오차가 지속적으로 상승하면(회복 없이) alpha+beta 조합이 불안정함을 뜻하고, 만약 오차가 완전히 평탄하면(첨단 없음) 기록 로직이失效했음을 뜻한다.

파라미터 범위 기본값 조절 효과 alpha (감쇠/보존 비율) 0.0-1.0 0.8 증가 → 구정보 보존이 많아져 기준선은 안정적이지만 전환 시 혼입이 심해진다; 감소 → 구정보를 빠르게 망각하여 기준선 노이즈는 크지만 전환이 신속해진다 beta (기록 강도) 0.0-2.0 0.8 증가 → 수정이 공격적이어서 전환 첨단은 작지만 불안정해질 수 있다; 감소 → 수정이 느려져 전환 첨단이 커진다 목표 전환 간격 (스텝) 5-50 10 증가 → 전환이 드물어 첨단이 적다; 감소 → 전환이 밀집되어 첨단이 연속으로 이어진다

tab-6

- 단일 도표 (시간에 따른 검색 오차): X축=Token 스텝 수(0-100), Y축=검색 오차(과학적 표기법, 실제 크기 약 0.05). 녹색 실선. 주목할 점: (1) 첨단의 주기성(target_steps와 같아야 함); (2) 첨단의 높이(beta가 커질수록 낮아져야 함); (3) 첨단 후 감쇠 속도(alpha가 작아질수록 빨라져야 함). 이상적 상황: 톱니가 규칙적이고, 첨단이 선명하며, 감쇠가 매끄러움. 이상 징후: 만약 톱니가 지속 상승으로 변하면(회복 없이) alpha·beta 누적으로 상태가 폭발함을 뜻하고, 만약 오차가 완전히 0이면 검색 q와 상태 S가 완전히 일치함(비현실적)을 뜻한다.

- "전환 시 혼입"을 보고 싶다 → alpha를 0.95, beta를 0.5로 조절하면 첨단이 현저히 높아진다.

- "빠른 적응"을 보고 싶다 → alpha를 0.5, beta를 1.5로 조절하면 첨단은 낮지만 기준선 노이즈가 크다.

- "밀집 전환"을 보고 싶다 → target_steps를 5로 조절하여 첨단이 여전히 구분되는지 관찰한다.

alpha와 beta는 Delta Rule의 유일한 두 초파라미터이며, 모델의 기억-적응 능력을 직접 결정한다. 이 tab은 "하이퍼파라미터 튜닝 직관"을 시각적 곡선으로 바꿔 놓았다. 독자는 직접 슬라이더를 드래그하며 "alpha가 너무 크면 → 전환이失灵, beta가 너무 크면 → 기준선이 불안정"을 볼 수 있다. 생산 환경에서 이는 다운스트림 작업(장문서 vs 스트리밍 대화)에 따라 적절한 KDA 하이퍼파라미터를 선택하는 방법을 안내한다——장문서는 큰 alpha(장거리 기억 보존)를 선호하고, 스트리밍 대화는 작은 alpha + 큰 beta(새 주제에 빠르게 적응)를 선호한다.

KDA가 RoPE를 필요로 하지 않는 근본 이유를 보여준다: 위치 정보가 이미 감쇠 인자 α의 다중 시간 척도에 인코딩되어 있기 때문이다. 검증 명제: 서로 다른 K 차원 채널은 각자의 감쇠율 γ를 독립적으로 학습할 수 있어, 동시에 "장기 기억"(작은 γ, 느린 감쇠)과 "국소 기억"(큰 γ, 빠른 감쇠)을 보존할 수 있는데, 이는 RoPE/ALiBi 등 상대 위치 인코딩이 할 수 없는 일이다.

지수 감쇠를 위치 인코딩으로서: KDA에서 token j가 token t에 대한 기여 가중치는 prod_{i=j+1}^{t} alpha_i 에 비례하며, alpha가 상수일 때 이것은 alpha^(t-j) = exp(-gamma * (t-j))——하나의 자연스러운 지수 감쇠 위치 편향이 된다. 서로 다른 채널은 서로 다른 γ를 가질 수 있으며(A_log를 통해 학습), 다중 시간 척도 기억을 구현한다.

왜 이런 실험을 설계했는가: 1×2 이중 연동 도표(왼쪽=서로 다른 γ의 감쇠 곡선, 오른쪽=다중 채널 감쇠 패턴)를 선택한 이유는, 왼쪽 도표가 "단일 γ는 어떤 모습인가"에 답하고, 오른쪽 도표가 "왜 다중 채널이 필요한가"에 답하기 때문이다. γ ∈ [0.05, 1.0]은 "거의 감쇠하지 않음"부터 "빠른 망각"까지의 범위를 포괄한다. n_tokens ∈ [32, 256]은 독자가 서로 다른 시퀀스 길이에서 감쇠 곡선의 형태를 관찰할 수 있게 한다.

- 왼쪽 도표에서 γ=0.1의 곡선은 감쇠가 가장 느리고(긴 꼬리), γ=0.6의 곡선은 감쇠가 가장 빠르다(빠르게 0으로 수렴).

- 오른쪽 도표에서 느린 감쇠 채널(파랑)은 t-j=128에서도 여전히 약 0.2의 보존 강도를 가지며, 빠른 감쇠 채널(주황)은 t-j=20에서 이미 0에 가깝다.

- 모든 곡선은 단조 지수 감쇠이며, 진동이 없다.

- KDA의 "위치 인코딩"은 채널 특이적이다: 서로 다른 채널은 서로 다른 거리의 정보를 기억한다.

- 명시적 RoPE/ALiBi가 필요 없다. 감쇠 인자 자체가 위치 함수이기 때문이다.

도표에서 보고자 하는 것: tab-7.webp 실제 이미지에서 볼 수 있듯이, 왼쪽 도표: 4개의 지수 감쇠 곡선(파랑, 진파랑, 진빨강, 주황)이 있으며, γ=0.1의 파란 곡선은 긴 꼬리가 t-j=128까지 늘어져 여전히 약 0.05이고, γ=0.6의 주황 곡선은 t-j=20에서 이미 0에 가깝다. 오른쪽 도표: 6개의 곡선이 두 그룹으로 나뉜다——3개의 느린 감쇠(파랑, γ=0.06-0.15)는 t-j=128에서 여전히 상당한 값을 가지며, 3개의 빠른 감쇠(주황, γ=0.30-0.46)는 t-j=20에서 이미 0에 가깝다. 성공 신호: 왼쪽 도표의 4개 곡선이 선명하게 분리되고(γ가 작을수록 위쪽), 오른쪽 도표의 두 그룹 곡선이 뚜렷이 군집화된다(파랑 그룹 위, 주황 그룹 아래). 실패 신호: 만약 모든 곡선이 겹치면 γ가 작용하지 않음을 뜻하고, 만약 곡선에 진동이나 음수가 나타나면 exp 구현이 잘못되었음을 뜻한다.

파라미터 범위 기본값 조절 효과 Token 수 32-256 128 증가 → 감쇠 곡선의 긴 꼬리가 연장되어 느린 감쇠 채널의 우위가 더 뚜렷해진다 gamma (감쇠율) 0.05-1.0 0.2 증가 → 모든 곡선이 더 빨리 감쇠한다; 감소 → 감쇠가 느려져 장거리 기억 보존이 많아진다

tab-7

- 왼쪽 그림 (서로 다른 gamma에서의 지수 감쇠): 꺾은선 그래프, X축 = 상대 거리 (t-j), Y축 = 유지 강도 [0,1]. 4개 곡선(파랑=γ/2, 진파랑=γ, 진빨강=2γ, 주황=3γ), 원형 마커. 무엇을 봐야 하는가: 곡선의 감쇠 속도 순서(γ가 작을수록 감쇠가 느림)와 긴 꼬리(γ=0.1인 곡선은 X=128에서도 값이 있음). 이상적인 경우: 4개 곡선이 명확히 분리되고, 절대 교차하지 않으며, 단조 감소한다. 이상 징후: 곡선이 교차하거나 상승하면 exp 계산이 잘못된 것이다.

- 오른쪽 그림 (서로 다른 채널의 감쇠 패턴): 꺾은선 그래프, X축 = 상대 거리, Y축 = 유지 강도. 6개 곡선(파랑 3개 느린 감쇠 + 주황 3개 빠른 감쇠). 무엇을 봐야 하는가: 두 그룹 곡선의 분리 — 느린 감쇠 그룹(파랑)은 X=128에서도 여전히 >0이고, 빠른 감쇠 그룹(주황)은 X=20에서 이미 ≈0이다. 이는 '다중 시간 스케일 기억'의 실현 가능성을 보여준다. 이상적인 경우: 두 그룹 곡선이 뚜렷이 군집을 이루고, 파랑 그룹이 전체적으로 주황 그룹보다 높다. 이상 징후: 두 그룹 곡선이 뒤섞여 있으면 다중 채널의 γ가 차별화되지 않은 것이다.

- '극단적 장거리 기억'을 보고 싶다면 → gamma를 0.05로, Token 수를 256으로 조정하면, 느린 감쇠 곡선이 X=256에서도 여전히 >0.3이다.

- '순수 국소 기억'을 보고 싶다면 → gamma를 1.0으로 조정하면, 모든 곡선이 X=10 이내에서 0으로 수렴한다.

- RoPE 효과를 비교하고 싶다면 → 현재 그림을 표준 Transformer의 RoPE 어텐션 가중치 그림과 나란히 두면, KDA의 '다중 채널 서로 다른 γ' 우위가 한눈에 드러난다.

이 tab은 '왜 KDA에 RoPE가 필요 없는가'를 답한다 — 감쇠 인자 자체가 위치 인코딩이고, 게다가 채널 특이적이어서 RoPE의 전역 통일 주파수보다 더 유연하기 때문이다. 생산 환경에서 이는 KDA가 RoPE의 cos/sin 캐시 계산을 생략할 수 있음을 의미하며, 동시에 A_log를 통해 각 채널에 필요한 시간 스케일을 자동으로 학습한다 — 단거리 채널은 구문에 집중하고, 장거리 채널은 의미에 집중하며, 주파수 기저를 수동으로 설계할 필요가 없다.

채널(channel)의 의미

KDA 코드에서 '채널'은 key 차원의 각 성분(즉 gate_logit의 마지막 차원 Dk)을 가리킨다:

variants.py:161 — GatedDeltaNet alpha = torch.sigmoid(gate_logit) # shape: (B, H, Dk) — per‑channel decay # gate_logit의 각 Dk 성분이 자신의 감쇠율을 독립적으로 제어 # variants.py:260 — KDA alpha = torch.exp(g) # shape: (B, H, Dk) — per‑channel decay # g의 각 Dk 성분이 독립적이므로, 각 채널이 서로 다른 감쇠 인자를 가진다

각 채널은 자신의 γ(감쇠율)를 독립적으로 학습하며, 이는 다음을 의미한다:

- Dk=8인 모델은 8개의 독립 채널을 가지며, 각 채널은 서로 다른 감쇠율을 학습할 수 있다

- 일부 채널은 γ=0.05(느린 감쇠, 장기 기억)를 학습하고, 일부는 γ=0.5(빠른 감쇠, 국소 기억)를 학습한다

- 이는 모델이 다중 시간 스케일의 혼합 어텐션을 자동으로 학습한 것과 등가이다: 빠른 채널은 국소 의존성(슬라이딩 윈도우와 유사)을, 느린 채널은 장거리 의존성(전역 어텐션과 유사)을 담당한다

RoPE와 비교: RoPE의 회전 각도 θ는 전역 공유되며(모든 채널이 같은 주파수를 사용), 서로 다른 채널이 서로 다른 거리의 정보에 주목하게 할 수 없다. KDA의 per‑channel 학습 가능 감쇠는 이 문제를 자연스럽게 해결한다.

표준 어텐션과 비교: 표준 softmax 어텐션에는 '감쇠' 개념이 없어 모든 과거 token이 (인과 mask를 제외하면) 동등한 가중치로 참여하며, '가까우면 중요하고 멀면 덜 중요하다'를 구분할 수 없다. KDA는 지수 감쇠를 통해 이러한 거리 감쇠를 자동으로 구현한다.

KDA의 두 가지 주요 반대 관점을 객관적으로 제시한다: (a) Delta Rule은 시퀀스 의존 순환을 도입하여 prefix sum 병렬화가 불가능하고, 단계별 추론이 표준 어텐션보다 느리다; (b) KDA는 고정 상태 용량이 제한되어, 같은 key의 오래된 value가 덮어씌워진다(Tab 5와 호응). 검증 명제: 블록 병렬화는 시퀀스 의존 비용을 완화할 수 있지만 제거할 수는 없으며; KDA의 메모리 우위는 용량을 맞바꾼 것이다.

왜 이렇게 실험을 설계했는가: 1×2 2연 그림(왼쪽=추론 시간 비교, 오른쪽=메모리 점유 비교)을 선택한 것은 반대 관점이 '시간'과 '공간' 두 차원을 다루기 때문이며, 분리해서 제시하여 혼동을 피한다. 왼쪽 그림에 꺾은선 그래프(T에 따른 시간 증가 추세)를, 오른쪽 그림에 막대 그래프(T에 따른 메모리 증가 비교)를 쓴 것은, 시간은 두 곡선의 분리도를 비교하는 것이고 메모리는 두 범주 막대의 높이 차이를 비교하는 것이기 때문이다.

- 왼쪽 그림: 단계별 추론 시간(빨간 선)이 블록 병렬화(초록 선)보다 현저히 높고, 격차는 T가 커질수록 확대된다.

- 오른쪽 그림: KV Cache 메모리(파란 막대)는 T에 따라 선형으로 증가하고, KDA 상태 메모리(초록 막대)는 거의 변하지 않는다(고정 크기이므로).

- 두 그림이 함께 말하는 것: KDA는 용량으로 메모리를 맞바꾸고, 시퀀스 의존으로 O(1) 상태를 맞바꿨다.

- KDA는 만능 해결책이 아니다 — 메모리에서는 거대한 우위가 있지만, 시퀀스 의존과 용량에서는 실제 비용이 있다.

- 블록 병렬화는 필수 최적화이며, 단계별 추론의 O(T²)를 O(T)에 가깝게 낮춘다.

그림에서 무엇을 보고 싶은가: tab-8.webp 실제 그림에서 볼 수 있듯이, 왼쪽 그림: 빨간 '단계별 추론' 곡선은 T=64일 때 1.0에서 T=1024일 때 17.5로 상승하고(대략 2차 증가), 초록 '블록 병렬화' 곡선은 0.8에서 6.2로 상승하며(대략 선형 증가), 두 곡선의 격차는 T=1024에서 3배에 달한다. 오른쪽 그림: 파란 'KV Cache' 막대는 T=64일 때 약 100에서 T=1024일 때 2050으로 선형 증가하고, 초록 'KDA 상태' 막대는 5에서 60으로 완만하게 증가한다(증가가 느림). 성공 신호: 왼쪽 그림의 두 곡선이 명확히 분리되고(빨강 위, 초록 아래); 오른쪽 그림에서 파란 막대가 초록 막대보다 훨씬 높고, 파란 막대는 T에 따라 선형 증가하며 초록 막대는 거의 변하지 않는다. 실패 신호: 왼쪽 그림의 두 선이 겹치면 블록 병렬화가 효과가 없는 것이고; 오른쪽 그림의 초록 막대도 선형으로 2000까지 증가하면 KDA 상태가 고정 크기가 아닌 것이다.

tab-8

- 왼쪽 그림 (반대측 a: Delta Rule이 병렬화될 수 없는 대가) : 꺾은선 그래프, X축=시퀀스 길이 T(64-1024), Y축=추론 시간(상대 단위). 빨간 원점 선=단계별 추론, 초록 사각형 선=분할 병렬. 무엇을 봐야 하는가 : 두 선의 증가율 차이 — 빨간 선은 근사적으로 2차 증가(각 토큰이 전체 상태를 순회해야 하기 때문), 초록 선은 근사적으로 선형 증가(분할 내 병렬이기 때문). 이상적인 경우 : T=1024일 때 빨간 선이 초록 선의 2-4배. 이상 징후 : 두 선이 겹치면 분할 병렬이 작동하지 않았거나 시퀀스 길이가 너무 짧은 것이다.

- 오른쪽 그림 (반대측 b: KDA 상태 압축 vs KV Cache 메모리) : 그룹 막대그래프, X축=시퀀스 길이 T, Y축=메모리 점유(상대 단위). 파란 막대=KV Cache(표준 어텐션), 초록 막대=KDA 상태. 무엇을 봐야 하는가 : 파란 막대와 초록 막대의 높이 차 가 T가 커짐에 따라 변하는 양상 — T=64일 때 격차가 작고(100 vs 5), T=1024일 때 격차가 막대하다(2050 vs 60). 이상적인 경우 : 파란 막대는 T에 따라 선형으로 증가하고, 초록 막대는 거의 변하지 않는다. 이상 징후 : 초록 막대도 T에 따라 선형으로 증가해 파란 막대에 맞먹는다면, KDA 상태에 고정 크기가 없다는 뜻이다(구현 오류).

이 tab은 반대측 관점의 정직한 제시 다 — 그것은 KDA가 대가가 없다는 것이 아님을 독자에게 알려준다. 왼쪽 그림은 KDA에 왜 chunkwise 구현(Tab 4)이 필요한지 설명하고, 오른쪽 그림은 KDA가 대형 모델에서 왜 반드시 MLA와 혼합되어야 하는지(Tab 5) 설명한다. 생산 환경에서 이는 아키텍트에게 모든 어텐션 레이어를 무작정 KDA로 대체하지 말고, 과제 요구(메모리 민감 vs 용량 민감)에 따라 적절한 혼합 비율을 선택하도록 지침을 준다 — K3의 3:1 KDA:MLA가 바로 이러한 트레이드오프에 근거한 것이다.

표 형식으로 6가지 step 함수(LinearAttn / DeltaNet / GLA / GatedDeltaNet / KDA v1 / KDA v2)의 입력·출력 차원 규약 을 보여주며, 모든 함수가 통일된 I/O 인터페이스를 공유함을 검증한다: S(B,H,Dk,Dv), q/k(B,H,Dk), v(B,H,Dv).

왜 이렇게 실험을 설계했는가 : 표(히트맵이나 꺾은선이 아닌)를 선택한 이유는 차원 정보가 이산적 구조화 데이터 이기 때문이며, 표가 가장 명확한 제시 방식이다. 매개변수 B/H/Dk/Dv를 조절 가능하게 한 것은 독자가 "차원 규약이 서로 다른 구성에서도 성립함"을 검증할 수 있게 하기 위해서다.

- 모든 6가지 방법의 out은 (B, H, Dv) 또는 (B, H, Dk) 이다(구현에 따라 구체적으로 달라지지만, 일관되어야 한다).

- 모든 방법의 S_new는 (B, H, Dk, Dv) 이다.

- DeltaNet / GatedDeltaNet / KDA v1 / KDA v2는 추가로 ret와 err를 반환하며(형태는 out과 같음), LinearAttn / GLA는 반환하지 않는다.

- 선형 어텐션 계열은 통일된 I/O 규약 을 가지므로 상호 교체와 비교가 용이하다.

- Delta Rule 계열 방법은 추가로 검색값 ret와 오차 err를 반환하며, 모니터링과 디버깅에 사용된다.

그림에서 보고 싶은 것 : tab-9.webp 실제 그림에서 볼 수 있듯이, 표는 6행 5열 이다: 방법 열(LinearAttn/DeltaNet/GLA/GatedDeltaNet/KDA v1/KDA v2), out 열은 모두 [2, 4, 16], S_new 열은 모두 [2, 4, 16, 16], ret와 err 열은 LinearAttn과 GLA 행에서 - , 나머지 4행에서는 [2, 4, 16]이다. 성공 신호 : 같은 열의 형태가 완전히 일치하며, ret/err는 Delta Rule 계열 방법 행에서만 값이 있다. 실패 신호 : 만약 어떤 행의 형태가 다른 행과 다르다면, 그 step 함수의 I/O 규약이 일치하지 않아 상호 교체가 불가능하다는 뜻이다.

매개변수 범위 기본값 조절 효과 무작위 시드 0-999 0 변경 → 입력 수치 변화, 그러나 형태는 불변 B 1-8 2 증가 → 모든 형태의 첫 번째 차원 변화 H 1-8 4 증가 → 모든 형태의 두 번째 차원 변화 Dk 4-32 16 증가 → out/S_new/ret/err의 K 차원 변화 Dv 4-32 16 증가 → S_new의 마지막 차원 변화

tab-9

레이아웃 : 단일 그림, 5열 표.

- 표 : 열=방법/out/S_new/ret/err. 행=6가지 step 함수. 무엇을 봐야 하는가 : (1) out 열이 모두 [B, H, Dv] 인지(실제로는 [2, 4, 16] 이며, 여기서 Dv=Dk=16이라 K/V 차이를 구분할 수 없음); (2) S_new 열이 모두 [B, H, Dk, Dv] 인지; (3) ret/err 열이 LinearAttn/GLA에서는 - , 다른 4가지에서는 구체적 형태인지. 이상적인 경우 : 각 열의 형태가 6행 전체에서 완전히 일치한다(ret/err의 - 제외). 이상 징후 : 어떤 행의 형태가 다른 행과 다르다면, 그 함수 구현이 다른 함수와 일치하지 않아 상호 교체가 불가능하다는 뜻이다.

- K와 V 차원이 다를 때의 형태를 보고 싶다면 → Dk=8, Dv=32 로 조절하고, S_new가 [B, H, 8, 32]로 바뀌는지 관찰한다.

- 다중 헤드 형태를 보고 싶다면 → H=8 로 조절하고, 모든 형태의 두 번째 차원이 8로 바뀌는지 관찰한다.

통일된 I/O 규약은 아키텍처 조합 가능성 의 기초다 — 6가지 step 함수의 입력·출력 형태가 완전히 일치해야만 동일한 프레임워크 안에서 자유롭게 전환할 수 있다(예: Tab 1의 비교 실험). 생산 환경에서 이는 "KDA v1을 v2로 교체"하는 데 매개변수 하나만 바꾸면 되고 어떤 다운스트림 코드도 바꿀 필요가 없음을 보장한다. 만약 차원 규약이 통일되지 않는다면, 선형 어텐션 계열 전체가 플러그인 가능한 모듈로 존재할 수 없게 된다.

Delta Rule의 핵심 수정 동작 을 시연한다 : alpha=1, beta=1일 때, 새 토큰이 이전 값을 정확히 덮어쓸 수 있으며, 최종 상태는 최신 기록값과 같다.命题 검증: v=0.8을 기록한 후 다시 v=0.2를 기록하면(동일 key), 조회 결과는 0.2여야 한다(0.8도 아니고, 평균값도 아니다).

Delta Rule의 "예측-수정" 메커니즘: 쓰기 전에 먼저 검색 ret = k^T S (예측값)을 수행하고, 오차 err = v - ret 를 계산한 뒤, S_new = S + beta · k ⊗ err 를 쓴다. beta=1일 때 새 값은 해당 key 부분공간에서의 옛 값의 투영을 완전히 대체한다; alpha=1일 때 옛 상태의 다른 성분은 완전히 보존된다.

왜 실험을 이렇게 설계했는가: 3개 프레임 스냅샷(t=0 초기, t=1에 0.8 기록, t=2에 0.2로 수정)을 고른 이유는 이것이 "덮어쓰기"를 보여주는 최소한의 시계열이기 때문이다—더 줄이면 "수정"을 볼 수 없고, 더 늘리면 중복이다. 2×1 상태 행렬(Dk=2, Dv=1)을 쓴 이유는 충분히 작아서 각 성분의 변화를 직관적으로 볼 수 있기 때문이다. q=(1,0)은 상태의 첫 번째 행만 검색하기 위해서다(key=(1,0)의 기록에 대응).

- t=1일 때 S[0,0]=0.8 (기록 성공)。

- t=2일 때 S[0,0]=0.2 (1.0=0.8+0.2도 아니고, 0.5=평균도 아님), 덮어쓰기이며 누적이 아님을 증명한다。

- 쿼리 결과 q^T S = 0.2 로, 최신 기록값과 완전히 일치한다。

- Delta Rule의 "수정"은 정밀한 덮어쓰기이며, 감쇠 평균이 아니다。

- 이것이 순수 가법적 선형 어텐션(Tab 11)과의 본질적 차이다。

그림에서 무엇을 보아야 하는가: tab-10.webp 실제 그림에서 볼 수 있듯이, 3개 프레임 히트맵: t=0은 전체 흰색(S=0), t=1은 위쪽 절반이 짙은 빨강(S[0,0]=0.8, 제목 "기록 v=0.8"), t=2는 위쪽 절반이 연한 빨강(S[0,0]=0.2, 제목 "0.2로 수정")이다. 제목은 "쿼리 결과=0.2000 (기대=0.2)"을 명확히 보여준다. 성공 신호: t=2의 색 농도가 t=1보다 명확히 옅다(왜냐하면 0.2 < 0.8), 제목 수치 0.2000이 예상과 일치한다. 실패 신호: 만약 t=2의 색 농도가 t=1과 같다면(여전히 0.8), 덮어쓰기가 일어나지 않은 것이다; 만약 색이 더 짙다면(예: 1.0), 누적이며 덮어쓰기가 아니다.

tab-10

레이아웃: 1×3 삼연도, 각 그림은 2×1 히트맵이다.

- 왼쪽 그림 (t=0 초기): 전체 흰색(S=0), colorbar 범위 [-1, 1]. 이상적 상황: 전체 흰색。

- 가운데 그림 (t=1에 v=0.8 기록): 위쪽 절반(S[0,0])이 짙은 빨강, 아래쪽 절반(S[1,0])이 흰색. 봐야 할 것: 색 농도는 0.8에 대응(colorbar 상한 1.0에 근접). 이상적 상황: S[0,0]=0.8(짙은 빨강), S[1,0]=0(흰색). 이상 징후: 만약 S[1,0]에도 색이 있다면, key=(1,0)이 두 번째 행으로 누출된 것이다。

- 오른쪽 그림 (t=2에 v=0.2로 수정): 위쪽 절반이 연한 빨강, 아래쪽 절반이 흰색. 봐야 할 것: 색 농도가 가운데 그림보다 명확히 옅고(왜냐하면 0.2 < 0.8), 여전히 빨강(양수)이다. 이상적 상황: S[0,0]=0.2(연한 빨강), 제목은 "쿼리 결과=0.2000"을 표시. 이상 징후: 만약 색 농도가 가운데 그림과 같다면(0.8), 덮어쓰기가 일어나지 않은 것이다; 만약 색이 더 짙다면(1.0), 누적이다; 만약 파란색(음수)으로 변한다면, 부호 오류다。

이 tab은 Delta Rule을 이해하기 위한 "Hello World"다—가장 단순한 2×1 행렬로 "덮어쓰기"라는 핵심 메커니즘을 보여준다. 만약 독자가 단 하나의 tab만 보고 DeltaNet을 이해해야 한다면, 이것을 봐야 한다. 생산 환경에서 이것은 왜 DeltaNet이 스트리밍 업데이트 시나리오(새 데이터가 옛 데이터를 덮어씀)에 적합하고, 순수 가법적 선형 어텐션이 누적 통계 시나리오(예: 단어 빈도 통계)에 적합한지를 설명해준다. 만약 덮어쓰기 메커니즘이 실패하면, DeltaNet은 Vanilla Linear(Tab 1의 발산 문제)로 퇴화한다.

순수 가법적 선형 어텐션의 혼합 동작을 보여준다: 여러 값이 상태 행렬에 누적되며, 덮어쓰이지 않는다. 명제 검증: v=0.8과 v=0.2(동일 key)를 기록한 후, 쿼리 결과는 phi(q)^T @ S = 5.0(누적 결과)이어야 하며, 0.2(최신값)가 아니어야 한다.

순수 가법적 누적: S_t = S_{t-1} + phi(k_t) ⊗ v_t, 여기서 phi = elu + 1은 출력이 항상 양수임을 보장한다. Delta Rule과 달리 여기에는 오차 수정이 없고, 매 기록은 단순 누적이다. 이로 인해 동일 key의 여러 value가 상태의 같은 행에 "혼합"된다.

왜 실험을 이렇게 설계했는가: Tab 10과 완전히 대칭이다—같은 3개 프레임 스냅샷, 같은 2×1 행렬, 같은 기록값(0.8 → 0.2), 유일한 차이는 linear_attn_step을 쓰고 delta_net_step을 쓰지 않는다는 점이다. 이런 대칭 설계는 독자가 "덮어쓰기 vs 혼합" 두 메커니즘의 결과 차이를 직접 비교하게 해준다. phi(q)=(2,1)을 고른 이유는 쿼리 결과=2×S[0,0] + 1×S[1,0]가 되게 하여 "상태 행렬의 선형 결합"을 보여주기 위해서다.

- t=1일 때 S[0,0]=phi(k)·v = 2×0.8=1.6 (phi(k)=(2,1)의 첫 번째 차원이 2임에 주목)。

- t=2일 때 S[0,0]=1.6 + 2×0.2=2.0 (누적이며, 덮어쓰기가 아님)。

- 쿼리 결과 phi(q)^T @ S = (2,1)@(2.0, 1.0) = 4.0+1.0=5.0, 제목과 일치한다。

- 순수 가법적 선형 어텐션은 누적기이며, 저장기가 아니다—옛 값은 덮어쓰이지 않는다。

- 이것이 발산의 근본 원인이다(Tab 1에서 Vanilla Linear 출력 ±706)。

그림에서 무엇을 보아야 하는가: tab-11.webp 실제 그림에서 볼 수 있듯이, 3개 프레임 히트맵: t=0은 전체 흰색, t=1은 위쪽 절반이 빨강(농도 약 1.6, colorbar 범위 [-3,3]이므로), t=2는 위쪽 절반이 더 짙은 빨강(농도 약 2.0, t=1보다 명확히 짙음). 제목은 "phi(q)^T@S = 5.0000 (기대=5.0)"을 표시. 성공 신호: t=2의 색이 t=1보다 짙다(왜냐하면 0.4가 누적됨), 제목 수치 5.0000이 예상과 일치한다. 실패 신호: 만약 t=2의 색이 t=1과 같다면, 누적이 일어나지 않은 것이다; 만약 색이 옅어진다면(예: 0.2), 잘못 Delta Rule을 사용한 것이다.

tab-11

레이아웃: 1×3 삼연도(三聯圖)이며, 각 그림은 2×1 히트맵이고 colorbar 범위는 [-3, 3]이다(주의: Tab 10의 [-1, 1]보다 크다. 누적 결과를 담아야 하기 때문이다).

- 왼쪽 그림 (t=0 초기): 전부 흰색. 이상적 상황: 전부 흰색.

- 가운데 그림 (t=1, v=0.8 기록): 위쪽 절반은 빨간색, 아래쪽 절반은 연한 빨간색. 무엇을 봐야 하나: S[0,0]≈1.6(phi(k)[0]×v=2×0.8), S[1,0]≈0.8(phi(k)[1]×v=1×0.8). 이상적 상황: 위쪽 색 농도가 colorbar 범위의 약 50%(1.6/3), 아래쪽은 약 27%(0.8/3).

- 오른쪽 그림 (t=2, v=0.2 혼합 → 누적): 위쪽 절반은 더 진한 빨간색, 아래쪽 절반도 더 진해진다. 무엇을 봐야 하나: S[0,0]=2.0(1.6+2×0.2), S[1,0]=1.0(0.8+1×0.2). 제목에는 5.0000(=2×2.0+1×1.0)이 표시된다. 이상적 상황: t=2의 색이 t=1보다 진하고, 제목 수치가 예상과 일치한다. 이상 징후: 만약 t=2의 색이 t=1과 같다면 누적이 일어나지 않은 것이며(Delta Rule 오용), 색이 t=1보다 연하다면 덮어쓰기가 발생한 것이다(역시 Delta Rule 오용).

이 tab은 Tab 10과 완벽한 대조를 이룬다: 동일한 입력에 대해 DeltaNet은 0.2를 출력하고(덮어쓰기), Vanilla Linear는 5.0을 출력한다(누적). 이것이 순수 가산적 선형 어텐션이 왜 발산하는지를 이해하는 열쇠다——상태의 무한 성장(Tab 1의 ±706이 바로 그 증거다). 생산 환경에서 이는 현대의 선형 어텐션(DeltaNet/KDA)이 모두 Delta Rule이나 게이트 감쇠를 도입한 이유를 설명하며, 순수 가산 방식은 이미 도태되었다. 독자가 이 두 메커니즘을 혼동한다면 이후의 모든 발전 과정을 이해할 수 없다.

동일한 시퀀스(3개 토큰, key/value/gate 모두 다름)에서 GLA(게이트 감쇠 + 가산 기록)와 DeltaNet(Delta Rule 덮어쓰기)의 상태 진화를 비교한다. 명제 검증: GLA는 모든 역사의 혼합을 보존하고(출력 1.3061), DeltaNet은 최신 값으로 수정한다(출력 0.2).

GLA(Gated Linear Attention): S_t = Diag(sigmoid(g_t)) ⊙ S_{t-1} + k_t ⊗ v_t. DeltaNet과의 차이: GLA에는 오차 수정이 없고, 게이트 감쇠 + 가산 기록만 있다. 이로 인해 GLA는 "감쇠하는 누산기", DeltaNet은 "덮어쓰기 장치"가 된다.

왜 이렇게 실험을 설계했나: 2×4 레이아웃(윗줄=GLA 4프레임, 아랫줄=DeltaNet 4프레임)을 선택한 이유는 동일한 시점에서 두 방법의 상태를 병렬로 비교해야 하기 때문이다. 3개 토큰 설계(t=1: k=(1,0), v=0.5, g=0.9; t=2: k=(0,1), v=0.7, g=0.3; t=3: k=(1,0), v=0.2, g=0.9)는 "높은 보존, 낮은 보존, 첫 번째 행으로 복귀"의 세 가지 상황을 포괄하여 두 방법의 차이를 충분히 드러낼 수 있다.

- GLA는 t=3에서 S[0,0] = 0.9×0.5 + 0.2 = 0.65(첫 번째 기록이 gate=0.9에 의해 감쇠된 뒤 보존되고, 세 번째 기록이 더해진다).

- DeltaNet은 t=3에서 S[0,0] = 0.2(세 번째 기록이 첫 번째를 덮어쓴다).

- 최종 조회 출력: GLA=1.3061(혼합), DeltaNet=0.2(수정).

- GLA는 "감쇠가 있는 누산기", DeltaNet은 "덮어쓰기 장치"——동일한 시퀀스가 완전히 다른 상태를 만든다.

- gate의 역할: 0.9 높은 보존 → 이전 값 영향이 큼, 0.3 낮은 보존 → 이전 값 영향이 작음.

그림에서 무엇을 보기를 기대하나: tab-12.webp 실제 그림에서 볼 수 있듯이, 8프레임 히트맵(2×4): 윗줄 GLA: t=1 위쪽 진한 빨강 아래쪽 연한 빨강(S[0,0]=0.5, S[1,0]=0); t=2 위쪽 색이 연해짐(gate=0.3에 의해 감쇠) 아래쪽 진한 빨강(S[1,0]=0.7); t=3 위쪽 색이 진해짐(세 번째 기록) 아래쪽 여전히 진한 빨강. 아랫줄 DeltaNet: t=1 위쪽 진한 빨강; t=2 위쪽 색이 연해짐 아래쪽 진한 빨강; t=3 위쪽 연한 빨강(0.2, 덮어쓰기됨) 아래쪽 여전히 진한 빨강. 제목에는 "GLA (혼합, out=1.3061) vs DeltaNet (수정, out=0.2000)"이 표시된다. 성공 신호: GLA t=3 위쪽 색이 DeltaNet t=3 위쪽보다 진함(GLA가 더 많은 역사를 보존하기 때문); 제목 수치가 예상과 일치. 실패 신호: 만약 GLA와 DeltaNet이 t=3에서 색이 완전히 같다면, 덮어쓰기 메커니즘이 작동하지 않은 것이다.

레이아웃: 2×4 팔연도(八聯圖), 윗줄 GLA 4프레임, 아랫줄 DeltaNet 4프레임, colorbar 범위 [-1.5, 1.5].

- 윗줄 (GLA 진화): t=0 전부 흰색; t=1 (gate=0.9) 위쪽 진한 빨강(0.5); t=2 (gate=0.3) 위쪽 색이 뚜렷이 연해짐(0.3에 의한 감쇠) 아래쪽 진한 빨강(0.7); t=3 (gate=0.9) 위쪽 색이 진해짐(세 번째 기록 누적) 아래쪽 여전히 진한 빨강. 무엇을 봐야 하나: GLA의 색은 지속적으로 누적되며, 다만 gate에 의해 감쇠될 뿐이다.

- 아랫줄 (DeltaNet 진화): t=0 전부 흰색; t=1 위쪽 진한 빨강(0.5); t=2 위쪽이 거의 사라짐(두 번째 기록 k=(0,1)이 첫 번째 행에 영향을 주지 않기 때문) 아래쪽 진한 빨강(0.7); t=3 위쪽 연한 빨강(0.2, 0.5를 덮어씀) 아래쪽 여전히 진한 빨강. 무엇을 봐야 하나: DeltaNet은 t=3에서 위쪽 색이 GLA t=3보다 뚜렷이 연한데, 이는 누적이 아니라 덮어쓰기이기 때문이다.

- 제목: GLA out=1.3061, DeltaNet out=0.2000을 표시. 이상적 상황: GLA 출력 > DeltaNet 출력(GLA가 모든 역사의 가중합을 보존하기 때문). 이상 징후: 만약 두 출력이 같다면 두 방법에 차이가 없다는 뜻이다(구현 오류).

이 탭은 GLA와 DeltaNet의 본질적 차이를 이해하는 핵심이다 — 둘 다 "게이티드 선형 어텐션"이지만, GLA는 감쇠+누적이고 DeltaNet은 덮어쓰기다. 생산 환경에서 이는 언제 GLA를 쓰고 언제 DeltaNet을 쓰는지를 결정한다: GLA는 "장기 통계"가 필요한 시나리오(예: 언어 모델의 단어 빈도 통계)에 적합하고, DeltaNet은 "정밀 갱신"이 필요한 시나리오(예: 코드 완성에서의 변수 추적)에 적합하다. 둘을 혼동하면, 덮어쓰기가 필요한 작업에서 GLA를 쓰거나(구값의 간섭 초래), 누적이 필요한 작업에서 DeltaNet을 쓰게 된다(정보 손실 초래).

KDA v2의 alpha 유계성 검증: alpha = exp(g_min · sigmoid(exp(A_log) · z))는 항상 (exp(g_min), 1) 구간 내에 위치하며, z가 극단값(±50)을 취해도 경계를 벗어나지 않는다. 명제 검증: z→+∞일 때 alpha→exp(g_min)≈0.0067(포화 망각), z→-∞일 때 alpha→1.0(포화 보존), alpha는 결코 0이 되거나 1을 초과하지 않는다.

왜 이렇게 실험을 설계했는가: 1×2 이중 패널 그래프(좌=z에 따른 alpha 스캔 곡선, 우=극단 z에서의 막대그래프)를 선택한 이유는 좌측 그래프가 함수 형태(연속성)를 보여주고, 우측 그래프가 극단값(경계 거동)을 보여주기 때문이다. z 범위 [-50, 50]은 sigmoid의 심층 포화 영역으로, "하한 보장"의 역할을 충분히 보여줄 수 있다. A_log=5(큰 값)는 sigmoid를 급격하게 만들어 계단 함수에 더 가깝게 한다.

- 좌측 그래프 곡선은 z=0 부근에서 급격히 하강하며(A_log=5가 z를 증폭하기 때문), 1.0에서 0.0067로 뛴다.

- 좌측 그래프 곡선은 결코 exp(g_min)=0.0067의 점선 아래로 내려가지 않으며, 결코 1.0의 점선 위로 올라가지도 않는다.

- 우측 그래프의 두 막대: z=50일 때 alpha=0.0067(하한), z=-50일 때 alpha=1.0(상한).

- KDA v2의 alpha는 강제 유계되어 있어, "완전 망각"(alpha=0)이나 "과도 보존"(alpha>1)이 나타나지 않는다.

- 이는 수치 안정성의 이론적 보장이며, 경험적 관찰이 아니다.

그래프에서 보고자 하는 것: tab-13.webp 실제 이미지에서 볼 수 있듯이, 좌측 그래프: 파란 곡선은 z<0일 때 1.0(상단)에 가깝고, z=0 부근에서 수직으로 하강하며(거의 계단 형태), z>0일 때 0.0067(하단)에 붙어 있다. 빨간 점선(하한 0.0067)과 초록 점선(상한 1.0)이 명확히 보인다. 우측 그래프: 두 막대로, 왼쪽(포화 망각, z=50) 높이=0.0067(하단에 가까움), 오른쪽(포화 보존, z=-50) 높이=1.0000(상단). 성공 신호: 좌측 그래프 곡선이 두 점선 사이에 엄격히 위치하며, 교차가 없다; 우측 그래프 두 막대 높이가 각각 정확히 0.0067과 1.0과 같다. 실패 신호: 곡선이 하한 점선을 통과하면(alpha<0.0067), g_min이 작동하지 않았음을 의미한다; 곡선이 상한 점선을 초과하면(alpha>1.0), exp 계산이 잘못되었음을 의미한다.

tab-13

- 좌측 그래프 (alpha가 (exp(g_min), 1) 내로 제약됨): 꺾은선 그래프, X축=z(logit 입력, 범위 -50에서 50), Y축=alpha=exp(g). 파란 실선=A_log=5의 스캔 곡선, 빨간 점선=하한 exp(g_min)=0.0067, 초록 점선=상한 1.0. 확인할 점: 곡선이 두 점선 사이에 엄격히 위치하는지(위치해야 함), 그리고 곡선이 z=0 부근에서 얼마나 급격한지(A_log=5는 곡선을 거의 수직으로 만들어야 함). 이상적 상황: 곡선이 z<0일 때 1.0에 가깝고, z=0 부근에서 급격히 하강하며, z>0일 때 0.0067에 가깝고, 결코 경계를 벗어나지 않는다. 이상 징후: 곡선이 완만하게 전이하면(급격하지 않으면), A_log가 너무 작음을 의미한다; 곡선이 점선을 통과하면, 경계 제약이 실패했음을 의미한다.

- 우측 그래프 (극단 z에서의 alpha 값): 막대그래프, X축=두 가지 극단 상황(포화 망각 z=50, 포화 보존 z=-50), Y축=alpha 값. 빨간 막대=z=50, 초록 막대=z=-50. 확인할 점: 두 막대 높이가 정확히 0.0067과 1.0과 같은지(막대 위에 수치 표기 있음). 이상적 상황: 빨간 막대=0.0067, 초록 막대=1.0000, 표기 수치가 예상과 일치. 이상 징후: 빨간 막대>0.0067이면 sigmoid가 포화되지 않았음을 의미한다; 초록 막대<1.0이면 exp(g_min·sigmoid(-∞))≠1임을 의미한다(공식 오류).

이 탭은 KDA v2 수치 안정성의 수학적 증명이다 — 입력이 아무리 극단적이어도 alpha가 (0.0067, 1) 내에 있음을 보장하며, NaN이나 Inf가 나타나지 않는다. 생산 환경에서 이는 KDA v2를 임의 길이의 시퀀스에 안전하게 사용할 수 있으며, gate logit 폭발을 걱정할 필요가 없다는 것을 의미한다. 만약 alpha가 유계가 아니라면(v1처럼), z가 클 때 alpha가 0에 가까워져 상태가 완전히 망각되거나(Tab 2의 전면 흰 프레임), z가 작을 때 alpha가 1에 가까워져 상태가 폭발한다(Tab 1의 발산). v2의 하한 g_min은 공학적으로 없어서는 안 될 보장 메커니즘이다.

kimi_linear_step의 하위 호환성 검증: version 파라미터를 명시하지 않으면, 기본 동작이 명시적 version="v1"과 완전히 동일하다(byte-identical). 명제 검증: out/S_new/ret/err 네 개 반환값이 두 호출 방식에서 원소별로 동일하며, max|diff|=0이다.

왜 이렇게 실험을 설계했는가: 2×2 텍스트 패널(히트맵이나 꺾은선이 아니라)을 선택한 이유는 검증 결과가 이진값(동일/불동일)이기 때문이며, 큰 글씨 텍스트+색상(초록=통과, 빨강=실패)이 가장 직접적이다. 4개 서브플롯이 각각 4개 반환값에 대응하여, out만 검사하는 것이 아니라 모든 출력이 일치함을 보장한다.

- out 완전 일치(max|diff|=0).

- S_new 완전 일치.

- ret 완전 일치.

- err 완전 일치.

- 새 버전의 version 파라미터는 기존 코드를 깨뜨리지 않는다 — version을 지정하지 않으면 동작이 v1과 완전히 동일하다.

- 이는 API 설계의 모범 사례이다: 신규 기능은 새 파라미터로 도입하고, 기본 동작은 변경하지 않는다.

图에서 무엇을 보길 기대하는가: 코드 로직에 기반한 추론: 성공 신호: 4개 서브플롯 모두 녹색 텍스트 "max|diff| = 0.00e+00"와 "✓ 완전 일치"를 표시한다. 실패 신호: 어느 서브플롯이든 빨간 텍스트 또는 "✗ 차이 존재"를 표시하면, 기본 version이 v1과 일치하지 않으며 하위 호환성이 깨졌음을 의미한다.

tab-14

레이아웃: 2×2 사분면 그래프, 각 패널은 텍스트 패널이다(축 없음).

- 좌상단 (out): 큰 글씨로 "max|diff| = 0.00e+00"(녹색) 표시, 아래에 "✓ 완전 일치". 이상적 상황: 녹색, diff=0. 이상 징후: 빨간색이 표시되거나 diff>0이면 out이 일치하지 않음을 의미한다.

- 우상단 (S_new): 위와 동일. 이상적 상황: 녹색, diff=0.

- 좌하단 (ret): 위와 동일. 이상적 상황: 녹색, diff=0.

- 우하단 (err): 위와 동일. 이상적 상황: 녹색, diff=0.

하위 호환성은 소프트웨어 공학의 초석이다——KDA가 v1에서 v2로 진화할 때, 반드시 구 코드(version을 명시하지 않은)의 동작이 변하지 않도록 보장해야 한다. 이 tab은 4개 반환값의 완전 동일성으로 이를 증명한다. 프로덕션에서 기본 동작이 바뀌면(예를 들어 기본값이 v2가 되면), v1 게이팅 특성에 의존하는 모든 모델이失效하며 디버깅도 어려워진다. 이 tab은 API 안정성의 수호자로, 새 버전이 매끄럽게 업그레이드될 수 있음을 보장한다.

두 도구 함수의 동작을 시각화한다: l2_normalize(단위 구면으로 정규화, ||y||=1)와 elu_plus_one(ELU(x)+1, 출력이 항상 양수임을 보장, 선형 어텐션의 phi 함수에 사용). 명제 검증: l2_normalize 후 벡터의 노름=1, elu_plus_one의 출력 최솟값>0.

왜 이렇게 실험을 설계했는가: 1×2 히스토그램(꺾은선이 아닌)을 선택한 이유는 독자가 함수 곡선이 아니라 출력 분포(예상 범위에 집중되는지 여부)를 보아야 하기 때문이다. 100개의 무작위 샘플이면 통계적 특성을 보여주기에 충분하다.

- 왼쪽 그림: l2_normalize 후 모든 성분의 노름=1(제목에 ||y||=1.000000 표시).

- 오른쪽 그림: elu_plus_one 후 최솟값>0(제목에 min=0.1101>0 표시), 모든 값이 양수.

- l2_normalize는 선형 어텐션의 전처리 단계로, 수치 안정성을 보장한다(Tab 1에서 q/k 입력 전에 이미 정규화됨).

- elu_plus_one은 phi 함수의 선택으로, 매끄럽고 항상 양수이며 구현이 쉽기 때문이다.

图에서 무엇을 보길 기대하는가: tab-15.webp 실제 그림에서 볼 수 있듯이, 왼쪽 그림: 파란 히스토그램, X축=값(범위 -0.25에서 0.25), Y축=빈도, 제목 "l2_normalize: ||y|| = 1.000000 ≈ 1.0", 오른쪽 상단에 "모든 성분 노름=1" 주석. 오른쪽 그림: 녹색 히스토그램, X축=값(범위 0에서 3.2), Y축=빈도, 제목 "elu_plus_one: min=0.1101 > 0", 오른쪽 상단에 "모든 성분>0" 주석. 성공 신호: 왼쪽 그림 제목 수치=1.000000, 오른쪽 그림 제목 min>0이며 히스토그램 X축이 0에서 시작(음수 없음). 실패 신호: 왼쪽 그림 제목≠1.0이면 정규화 실패를 의미하고, 오른쪽 그림 히스토그램이 음수 영역까지 뻗으면 elu_plus_one에 버그가 있음을 의미한다.

tab-15

레이아웃: 1×2 이중 그래프, 각 패널은 히스토그램이다.

- 왼쪽 그림 (l2_normalize): 파란 히스토그램, X축=정규화 후의 성분값, Y축=빈도. 빨간 점선=x=0 기준선. 무엇을 보아야 하는가: 제목의 ||y|| 값이=1.0인지(소수점 6자리까지). 이상적 상황: 제목에 1.000000 표시, 히스토그램이 [-0.25, 0.25] 구간에 분포(100차원 벡터의 단위 구면 투영이기 때문). 이상 징후: ||y||≠1.0이면 정규화 공식 오류를 의미한다.

- 오른쪽 그림 (elu_plus_one): 녹색 히스토그램, X축=출력값, Y축=빈도. 빨간 점선=x=0 기준선. 무엇을 보아야 하는가: 히스토그램이 완전히 X>0 영역에 있는지(음수 없음), 그리고 제목의 min 값이>0인지. 이상적 상황: 히스토그램이 X=0.1 근처에서 시작(최솟값 0.1101)하여 오른쪽으로 3.2까지 뻗고, 제목 min>0. 이상 징후: 히스토그램이 X<0까지 뻗으면 ELU+1 구현 오류를 의미한다(마땅히 max(0,x)+min(0,exp(x)-1)+1, 항상 양수여야 함).

이 두 도구 함수는 선형 어텐션의 기반 시설이다——l2_normalize는 수치 안정성을 보장하고(q/k가 너무 커져 상태가 폭발하는 것을 방지), elu_plus_one은 비선형 phi 함수를 제공한다(표현 능력 향상). 프로덕션에서 l2_normalize가 실패하면 상태 행렬이 빠르게 발산한다(Tab 1의 ±706이 바로 정규화하지 않은 결과다). elu_plus_one이 음수를 출력하면 Delta Rule의 부호가 혼란스러워진다. 이 tab은 수치 안정성의 초석이다.

GatedLinearAttentionLayer와 GatedDeltaNetLayer 두 래퍼 레이어의 입력·출력 형상을 검증한다: 입력 (B,T,D) → 출력 (B,T,D), Transformer 아키텍처에 곧바로 쌓을 수 있다.

왜 이렇게 실험을 설계했는가: 표(히트맵이 아닌)를 선택한 이유는 형상 정보가 이산적인 구조화 데이터이기 때문이다. 파라미터 수를 나열한 것은 두 layer의 복잡도 차이를 독자가 이해하도록 하기 위해서다(GDN은 gate_up/gate_down + beta_proj가 추가로 있어 파라미터 수가 더 많다).

- GLA Layer 입력 (2,5,16) → 출력 (2,5,16).

- GDN Layer 입력 (2,5,16) → 출력 (2,5,16).

- GDN 파라미터 수 > GLA 파라미터 수(gate와 beta 투영이 더 있기 때문).

- 선형 어텐션 레이어는 플러그 앤 플레이 방식이다——입출력이 동형이므로 표준 어텐션 레이어를 곧바로 대체할 수 있다.

- GDN은 GLA보다 파라미터 수가 많지만, Delta Rule 덮어쓰기 능력을 제공한다.

그림에서 보고자 하는 것 : 코드 로직에 근거한 추론: 성공 신호 : 표에 GLA와 GDN의 입력/출력 형상이 모두 (2,5,16)으로 표시되고, GDN의 파라미터 수가 GLA보다 명확히 크다. 실패 신호 : 만약 출력 형상≠입력 형상이라면, layer 래핑에 버그가 있어 적층할 수 없음을 의미한다.

tab-16

레이아웃 : 단일 그림, 4열 표 (Layer / 입력 x / 출력 / 파라미터 수).

- 표 : 두 행 (GLA와 GDN). 이상적인 경우 : 두 행의 입력/출력이 모두 (2,5,16), GDN 파라미터 수 > GLA. 이상 표시 : 만약 출력 형상≠(2,5,16)이라면, q/k/v 투영 또는 o_proj 차원이 잘못되었음을 의미한다.

입출력 동형은 층 적층 가능성의 전제 조건이다 —— 이렇게 해야만 선형 어텐션 층이 표준 어텐션 층처럼 여러 겹으로 적층되어 심층 네트워크를 형성할 수 있다. 생산 환경에서 이는 KDA/GLA/GDN이 다른 코드를 수정하지 않고도 Transformer의 어텐션 층을 무결점하게 교체할 수 있음을 보장한다. 만약 출력 형상≠입력 형상이라면 추가 투영 층이 필요해 복잡도와 파라미터 수가 증가한다.

layer.forward가 수동 토큰별 재귀와 수치적으로 완전히 동등함을 검증한다 (max|diff| < 1e-6). 검증 명제: GLA Layer와 GDN Layer의 래핑( q/k/v 투영, step 루프, o_proj 포함)이 수작성 루프와 부동소수점 정밀도 내에서 일치한다.

실험을 이렇게 설계한 이유 : 1×2 텍스트 패널(히트맵이 아님)을 선택한 것은 검증 결과가 단일값(max|diff|)이기 때문이며, 큰 글씨 텍스트+색상이 가장 직접적이다. GLA와 GDN을 분리하여 검증해 두 layer가 모두 정확함을 보장한다.

- GLA Layer: max|diff| < 1e-6.

- GDN Layer: max|diff| < 1e-6.

- layer 래핑은 추가 오차를 도입하지 않았다 —— 내부적으로는 토큰별로 step 함수를 호출할 뿐이다.

- 이것은 단위 테스트의 시각화이다 —— 테스트 단언(assertion)을 그래픽으로 바꾼 것이다.

그림에서 보고자 하는 것 : 성공 신호 : 두 패널 모두 초록색 텍스트 "max|diff| = X.XXe-XX"(X<1e-6)와 "✓ 수동 재귀와 완전히 일치"를 표시한다. 실패 신호 : 만약 빨간색으로 표시되거나 diff>1e-5라면, layer 래핑이 수동 루프와 일치하지 않음을 의미하며 버그가 있을 수 있다.

tab-17

레이아웃 : 1×2 이중 그림, 각 그림은 텍스트 패널(좌표축 없음).

- 왼쪽 그림 (GLA Layer) : 큰 글씨로 max|diff| 값(초록색, <1e-6)을 표시하고, 아래에 "✓ 수동 재귀와 완전히 일치". 이상적인 경우 : 초록색, diff<1e-6. 이상 표시 : 만약 빨간색이거나 diff>1e-5라면, GLA layer 래핑에 버그가 있음을 의미한다.

- 오른쪽 그림 (GatedDeltaNet Layer) : 위와 동일. 이상적인 경우 : 초록색, diff<1e-6.

이 tab은 래핑 정확성의 증명이다 —— layer.forward는 "블랙박스"처럼 보이지만 실제로는 토큰별로 step 함수를 호출할 뿐이다. 만약 둘이 동등하지 않다면 래핑 층이 버그(예: 투영 차원 오류, 상태 초기화 오류)를 도입했음을 의미한다. 생산 환경에서 이는 고수준 API의 신뢰성을 보장한다 —— 사용자는 수작성 루프 없이 layer를 안심하고 사용할 수 있으며, 결과는 수작성과 완전히 일치한다. 이것은 또한 Tab 4(재귀 vs 분할)의 보충이다: Tab 4는 알고리즘 동등성을 검증하고, Tab 17은 래핑 동등성을 검증한다.

W_gate가 학습 가능하고 data-dependent한 투영임을 검증한다 : 서로 다른 입력이 서로 다른 gate 값을 생성하고, W_gate의 기울기가 0이 아님(역전파에 참여 가능)을 검증한다. 검증 명제: gate는 고정 상수가 아니라 입력에 따라 변하는 학습 가능한 파라미터다.

실험을 이렇게 설계한 이유 : 1×3 삼중 히트맵(왼쪽=gate(x1), 가운데=gate(x2), 오른쪽=W_gate 기울기)을 선택한 것은 두 가지를 동시에 증명해야 하기 때문이다: (1) gate가 입력에 따라 변함(왼쪽 vs 가운데의 차이), (2) W_gate에 기울기가 있음(오른쪽 그림이 0이 아님). 무작위로 초기화된 layer + 역전파(loss=layer(x2).sum())를 사용하는 것이 가장 최소한의 재현 가능한 검증 방식이다.

- gate(x1)와 gate(x2)의 평균이 다르며(0.0072 vs -0.0646), gate가 data-dependent임을 증명한다.

- W_gate 기울기의 절댓값 합 > 0 (74.5770)으로 학습 가능함을 증명한다.

- 왼쪽 그림과 가운데 그림의 히트맵 패턴이 다르다(입력이 다르기 때문).

- gate는 입력의 함수( W_gate 투영을 통해)이며, 고정된 하이퍼파라미터가 아니다.

- W_gate는 역전파에 참여하며, 학습을 통해 최적의 망각 전략을 자동으로 학습할 수 있다.

그림에서 보고자 하는 것 : tab-20.webp (실제 파일명은 tab-20으로, Tab 18에 해당)에서 볼 수 있듯이, 왼쪽 그림 (gate(x1)) : 초록 계열 히트맵, X축=특징 차원(0-32), Y축=샘플/token(0-3), 제목 "mean=0.0072", colorbar 범위 [-1.5, 1.0], 대부분 영역이 초록색(0에 가까움)이고 소량의 노란색(양수값)과 보라색(음수값) 줄무늬가 있다. 가운데 그림 (gate(x2)) : 마찬가지로 초록 계열 히트맵, 제목 "mean=-0.0646", 패턴이 왼쪽 그림과 명확히 다르며(줄무늬 위치가 다름), 전체적으로 초록빛이지만 색조가 약간 더 짙다(평균이 더 음수이기 때문). 오른쪽 그림 (W_gate 기울기) : 적청 계열 히트맵(RdBu_r), X축=입력 차원(0-16), Y축=출력 차원(0-32), 제목 "sum=74.5770", 뚜렷한 빨간색(양의 기울기)과 파란색(음의 기울기) 블록이 있어, 전부 흰색이 아니다(기울기가 0이 아님을 의미). 성공 신호 : 왼쪽 그림과 가운데 그림의 패턴이 명확히 다름(data-dependent임을 증명), 오른쪽 그림에 다량의 0이 아닌 기울기(학습 가능함을 증명). 실패 신호 : 만약 왼쪽 그림과 가운데 그림이 완전히 동일하다면 gate가 입력에 의존하지 않음을 의미하며, 만약 오른쪽 그림이 전부 흰색(기울기=0)이라면 W_gate가 학습 불가능함을 의미한다.

tab-18

레이아웃 : 1×3 삼중 히트맵.

- 왼쪽 그림 (gate(x1) 첫 샘플, mean=0.0072): 히트맵, colormap=viridis, X축=특징 차원, Y축=token 스텝 수(T=3). 여기서 봐야 할 것: 색 분포의 패턴(어떤 차원이 노란색 고값이고, 어떤 차원이 보라색 저값인지). 이상적인 경우: 뚜렷한 노랑-보라 교차 줄무늬가 보이며, 이는 gate가 서로 다른 차원에서 서로 다른 값을 가진다는 것을 의미한다.

- 가운데 그림 (gate(x2) 첫 샘플, mean=-0.0646): 왼쪽 그림과 같은 레이아웃. 여기서 봐야 할 것: 왼쪽 그림과의 패턴 차이——줄무늬 위치가 다른지 여부. 이상적인 경우: 패턴이 뚜렷하게 다르고(입력 x2≠x1이므로) mean 값도 다르다(-0.0646 ≠ 0.0072). 이상 징후: 두 그림이 완전히 동일하면 gate가 입력에 의존하지 않는다는 뜻이다(bug).

- 오른쪽 그림 (W_gate 기울기, sum=74.5770): 히트맵, colormap=RdBu_r, X축=입력 차원, Y축=출력 차원. 여기서 봐야 할 것: 다량의 비영(非零) 빨간색과 파란색 사각형(양의 기울기와 음의 기울기)이 있는지 여부. 이상적인 경우: 기울기 그림이 뚜렷한 빨강-파랑 분포를 보이고, sum 값이 0보다 현저히 크다(74.5770). 이상 징후: 기울기 그림이 전부 흰색(또는 전부 검은색)이면 기울기=0이며 W_gate를 학습할 수 없다는 뜻이다.

이 tab은 gate가 모델의 학습 가능한 구성 요소이며, 수작업으로 설계한 하이퍼파라미터가 아님을 증명한다. 실제 운영에서 이는 KDA/GLA/GDN이 학습을 통해 각 채널의 망각 전략을 자동으로 학습할 수 있음을 의미한다——어떤 채널은 "빠른 망각"(gate가 0에 가까움)을 학습하고, 어떤 채널은 "장기 보존"(gate가 1에 가까움)을 학습하며, 수동 파라미터 조정이 필요 없다. 만약 gate가 학습 불가능하다면(고정 상수), 모델의 표현 능력은 크게 저하되어 서로 다른 작업의 요구에 적응할 수 없게 된다. 이것이 바로 KDA가 전통적인 선형 어텐션에 비해 가지는 핵심 강점이다——게이팅 메커니즘의 도입으로 모델은 "어떻게 기억할지 학습하는" 능력을 갖게 된다.

┌─────────────────────────────────────────────────────────────┐ │ 기본 메커니즘 (Tab 1 -2): 6가지 step 비교 + KDA 상태 진화 │ │ ├─ Tab 1: 출력 차원 → 6가지 변형의 진폭 차이 표시 (±706 vs ±0.25)│ │ └─ Tab 2: 상태 차원 → S 행렬의 동적 재구성 표시(v1 vs v2) │ ├─────────────────────────────────────────────────────────────┤ │ 핵심 원리 (Tab 3, 10, 11, 12): 게이팅/덮어쓰기/혼합/GLA 비교 │ │ ├─ Tab 3: v1 vs v2 게이팅 곡선(수학 함수) │ │ ├─ Tab 10: DeltaNet 덮어쓰기 (Hello World, out=0.2) │ │ ├─ Tab 11: Vanilla 혼합 (대조, out=5.0) │ │ └─ Tab 12: GLA vs DeltaNet (혼합 vs 덮어쓰기, 1.30 vs 0.20) │ ├─────────────────────────────────────────────────────────────┤ │ 엔지니어링 구현 (Tab 4, 9, 16, 17): 동등성/차원/Layer 캡슐화 │ │ ├─ Tab 4: 재귀 vs 분할 (⚠️ 현재 bug 존재, max_diff=0.81) │ │ ├─ Tab 9: 차원 흐름 (통일된 I/O 규약) │ │ ├─ Tab 16: Layer 형상 (입출력 동형) │ │ └─ Tab 17: Layer 동등성 (캡슐화 == 수동 루프) │ ├─────────────────────────────────────────────────────────────┤ │ 능력 경계 (Tab 5, 6, 7, 8): 용량/파라미터/위치/반대 관점 │ │ ├─ Tab 5: 실패 Case (용량 병목, 옛값이 덮어써짐) │ │ ├─ Tab 6: 파라미터 민감도 (alpha/beta 스캔) │ │ ├─ Tab 7: 위치 감쇠 (왜 RoPE가 필요 없는가) │ │ └─ Tab 8: 반대 관점 (시퀀스 의존성 + 용량 한계) │ ├─────────────────────────────────────────────────────────────┤ │ 수치 보장 (Tab 13, 14, 15, 18): 제약/호환/도구/학습 가능 │ │ ├─ Tab 13: KDA v2 alpha 유계 (0.0067, 1.0) │ │ ├─ Tab 14: KDA v1 하위 호환 (byte-identical) │ │ ├─ Tab 15: 도구 함수 (l2_norm, elu_plus_one) │ │ └─ Tab 18: Gate 학습 가능 (data-dependent + 역전파 가능) │ └─────────────────────────────────────────────────────────────┘

- 선형 어텐션의 본질은 "상태 압축"이다: 가변 길이의 역사를 고정 크기 S ∈ R^(Dk×Dv)에 압축하여, O(1) 메모리로 O(T) 메모리를 대체하지만(Tab 8 오른쪽 그림), 그 대가는 용량 병목이다(Tab 5).

- Delta Rule은 "덮어쓰기 도구", 순수 가산은 "누산기"다: 동일한 입력에서 DeltaNet은 0.2(덮어쓰기), Vanilla Linear는 5.0(누산), GLA는 1.3(감쇠+누산)을 출력한다——세 가지 메커니즘은 완전히 다른 역학을 만든다(Tab 10/11/12).

- KDA v2의 g_min 하한은 수치 안정성의 핵심이다: v1의 alpha는 0에 근접할 수 있었지만(완전 망각), v2는 (0.0067, 1) 내로 강제 제약되어(Tab 13), 극단적 입력에서 NaN이나 상태 폭발이 발생하지 않도록 보장한다(Tab 2 비교).

- KDA는 RoPE가 필요 없다. 감쇠 인자가 곧 위치 인코딩이기 때문이다. 서로 다른 채널이 감쇠율 γ를 독립적으로 학습할 수 있어(Tab 7 오른쪽 그림) '다중 시간 척도 기억'을 구현한다. 느리게 감쇠하는 채널은 장거리를 기억하고, 빠르게 감쇠하는 채널은 국소를 기억하므로, RoPE의 전역 통일 주파수보다 더 유연하다.

- 통일된 I/O 규약 + Layer 캡슐화 동등성은 엔지니어링 조합 가능성의 기초다. 6가지 step 함수가 S(B,H,Dk,Dv), q/k(B,H,Dk), v(B,H,Dv) 인터페이스를 공유하고(Tab 9), layer.forward가 수동 루프와 수치적으로 동등함(Tab 17)을 보장하여, 선형 어텐션 패밀리를 플러그인 가능한 모듈로서 자유롭게 대체할 수 있다.

TransFormer-표지

본문은 markdown.com.cn으로 조판됨

로시의 사고

436

글