Kimi 모델 분석

21,829 단어·44 분·원문(.md)

기준 시점 2026년 8월 12일

트랜스포머 블록 구성 및 MoE와 활성 총 파라미터가 뭔지 KV 캐시, GQA MLA 투기적 디코딩, 양자화 포맷, 하네스와 파서등을 사전으로 알고가면 좋다.

Kimi K3에는 새로운 이름이 여럿 붙어있다 Kimi Delta Attention, Attention Residuals, Stable LatentMoE, Quantile Balancing, Pre-Head Muon, SiTU.

Kimi 파면서 아래 질문들에게 걸릴거고 이를 답할 수 있는 것을 목적으로 두고 공부해보자

  • K2, K2 Thinking, K2.5, K2.6 Code, K3가 1년 사이에 다 나왓는데 뭐가 달라졌지
  • KDA, AttnRes, Stable LatentMoE, MuonClip 같은게 머지 어떤걸 풀기위해 나온거지
  • 선형 어텐션이라는 게 오래된 아이디어인데 왜 하필 2.8조 파라미터 모델에 들어갔지.
  • 고정 크기 상태로 바꾸면 정확히 뭐가 안좋아 지는거지.
  • 2.8조 오픈웨이트를 대체 누가 돌리는거지.

들어가기전 수학 퀵 정리 #

뒤에서 수식이 몇개 나오는데 이미 알면 건너뗘도대고 대신 논문 처음볼대 대조하려면 기호를 알아야하니 모아두겠다.

기호
q질의(Query) 벡터. "지금 뭐가 필요한지"를 나타냄
k키(Key) 벡터. "이 정보에 붙은 이름표"
v값(Value) 벡터. "실제로 저장할 내용"
S상태(State) 행렬. 과거 정보를 요약해서 들고 다니는 것. KDA의 핵심
α망각률. 0에 가까우면 빨리 잊고, 1에 가까우면 오래 기억
β갱신 강도. 새 정보를 얼마나 강하게 덮어쓸지 나타냄
n지금까지의 토큰 개수 (컨텍스트 길이)
d벡터 하나의 길이 (차원 수)
  • kᵀ (위첨자 T) — 전치(transpose)로 세로로 서 있던 벡터를 가로로 눕히는 것 v kᵀ 처럼 세로 벡터와 가로 벡터를 곱하면 결과가 행렬(표)가 되고 벡터 두 개로 표 하나를 만드는 연산이다.
  • I 항등 행렬로 곱해도 아무것도 안바뀌는 행렬이다 숫자로 치면 1에 해당하고 I - 뭔가 형태가 나오면 원래 값에서 뭔가를 빼는걸로 읽으면 된다.
  • Diag(α) α의 값들을 대각선에 늘어놓은 행렬로 이걸 곱하면 각 차원이 자기 몫의 α만큼 곱해진다 차원마다 다른 배율을 적용한다는 뜻이다.
  • — 원소별 곱셈. 같은 자리끼리만 곱함. 행렬곱과 다르다.

자주 나오는 식 네개 #

뒤에서 하나씩 자세히 다루니까 모양만 익혀두자

상태에 쓰고 읽기 #

쓰기 :  S ← S + v kᵀ
읽기 :  o = S · q

v kᵀ가 "이름표 k에 내용 v를 붙인 표"이고, 그걸 S에 더해서 쌓아둔다. 읽을 때는 질의 q를 곱해서 관련한 내용을 꺼낸다

델타 규칙 (덮어쓰기) #

S ← S − β (S·k − v) kᵀ
         └─ 지금 저장된 값과 새 값의 차이 ─┘

그냥 더하면 옛날 값과 새 값이 섞이니까, 차이만큼만 빼서 교정하는 것, S·k가 "지금 이 이름표로 읽으면 나오는 값"이고, v가 "나와야 할 값"

상태 전이 KDA 최종 형태 #

A = Diag(α) (I − β k kᵀ)
    └ 차원마다 ┘ └─ 덮어쓰기 ─┘
      다르게 잊기

매 스텝마다 상태에 곱해지는 행렬로 앞쪽이 망각, 뒤쪽이 덮어쓰기를 담당한다. 이 행렬이 어떻게 생겼느냐가 모델이 뭘 할수 잇고 못하는지를 결정한다

Muon 옵티마이저 #

M ← μM + G           지금까지의 기울기를 누적
O ← NewtonSchulz(M)  모든 방향의 크기를 고르게 맞춤
W ← W − ηO           그걸로 가중치 갱신

G가 기울기, M이 누적된 기울기, η가 학습률입니다. 가운데 줄이 Muon의 전부이고, 나머지는 일반적인 옵티마이저

Kimi #

Kimi는 중국 베이징의 Moonshoot AI가 만드는 모델 가문이다. 회사 이름이 Moonshot AI이며 제품과 모델 이름이 키미다.

다른 랩과 구분되는 지점은 오픈웨이트 크기 상한을 계속 점유한다는 점이다.

2025년 7월에 K2가 1T 파라미터로 나왔을때 그게 공개된 오픈웨이트 모델중에 최대였고 2026년 7월 K3가 2.8조로 나왔을대 다시 그게 최대다.

공식 블로그가 지난 12개월중 9개월동안 Kimi 모델이 오픈 모델 크기의 상한선이 있었다고 밝혔다.

그정도로 앞장서고 있으며 이게 그들으 전략인 것이다 이게 왜 전략인지 아는게 중요한데 크기 상한에 있으면 서빙 스택 개발자들이 자발적으로 붙고 최신 최대 모델을 돌릴 수 있는 엔진이 되고싶어서이다.

K3가 나온날 vLLM 커널과 도커 이미지와 배포 레시피가 이미 준비되어있을정도로 생태계 활성화가 되어있고 NVIDIA, AMD도 커널 작업에 참여했다.

두 번째 특징은 운영 인프라까지 공개한다는 점이 있다. 보통은 모델의 가중치만 열고 그걸 어떻게 서비스하는지는 닫는다. Moonshoot은 서빙 플랫폼 Mooncake, optimizer 스케일링 보고서, 어텐션 구조논문(Kimi Linear), 커널 구현(FlashKDA)을 전부 열었다.

이게 실제로 효과를 낸 지점은 FlashKDA 공개로 인해 외부 기여자가 H100으로 최적화한 버전을 만들어 올리고 vLLM 팀이 하루만에 검증해서 프로덕션 경로에 합치기도 했다 커널을 여는 것 자체가 성능 개선 통로가 된 샘이다.

오픈 정책과 라이선스 #

Kimi는 API 전용 모델과 오픈 모델을 따로 굴리지 않는다. 플래그십을 그대로 가중치 공개한다.

API로 쓰는 모델과 HuggingFace에서 내려받는 모델이 같다.

라이선스는 Modified MIT로 MIT 조건 하나가 붙은 형태로 월간 활성 사용자 1억명이나 월 매출 2천만 달러를 넘으면 제품 화면에 모델 이름을 표기해야한다. 그 미만이면 MIT와 다를 게 없다.

대기업이 자사 제품에 몰래 얹는 걸 막는 조항에 가깝다.

공개 방식에서 특이한 결정이 하나 있다. K3는 모델을 발표한날과 가중치를 푼 날이 열흘쯤 차이가 나는데 vLLM팀이 먼저 제안하고 Moonshot에서 먼저 받아들인 방식인데 이유가 실용적이다

발표와 가중치 공개를 같은 날로 맞추려고 하면 모델 팀은 제품과 api오 평가와 안정성 검토를 동시에 마무리하는 중이라 체크포인트가 계속 흔들린다.

오픈소스 엔진 팀 입장에서는 움직이는 표적을 상대하게 되고 마감일이 계속 밀린다. 떼어놓으면 모델 팀이 최종 체크포인트와 토크나이저, 서빙 규약을 먼저 고정할 수 있고 엔진팀은 안정된 통합 기간을 확보한다.

시기모델도입한 것
2025.2Moonlight-16B-A3BMuon 옵티마이저를 대규모에서 검증한 모델
2025.7Kimi K21.04T / 32B 활성. MuonClip으로 15.5T 토큰 학습, Loss Spike 0회
2025.10Kimi Linear-48B-A3BKDA 최초 공개. K3 Attention의 원형
2025.11K2 Thinking사고 모드. 256K. INT4 QAT. 도구 200~300회 연속 호출
2026.1K2.5네이티브 멀티모달. Agent Swarm과 PARL
2026.4K2.6환각률 개선 (AA-Omniscience 65% → 39%)
2026.6K2.7 Code코딩 특화. 사고 토큰 약 30% 절감
2026.7Kimi K32.8T. KDA + AttnRes + Stable LatentMoE. 1M 컨텍스트

1년사이에 여섯 번 나왔지만 실제로 아키텍처가 갈리는 지점은 한 번뿐으로 K2 계열은 K2, K2 Thinking K2.5, K2.6, K2.7 Code가 전부 같은 뼈대를 쓴다.

총 1.04조개 파라미터 활성 320억, 전문가 384개 중에 8개 + 공유 1개, 61층, 전 층 MLA 어텐션이다. 세대 차이는 사후학습과 데이터에서 나왔지 구조에서 나온게 아니다.

구조가 바뀐건 K2 -> K3에서 넘어가는 한 번이다.

K2 계열에서는 총 파라미터 1.04T로 전문가 384개중 8개 + 공유 1개 층수는 61, 전 층 MLA이며 컨텍스트는 128->256K, 잔차 연결은 표준 x + f(x) 정밀도는 INT4 가중치며 옵티마이저는 MuonClip

K3 계열에서는 총 파라미터 2.8T로 늘었고 전문가는 896개중에 16개 + 공유, 층수는 약 93, 어텐션은 KDA 3층과 Gated MLA 1층이다. 컨텍스트는 1M이며 잔차 연결은 Block AttnRes, 정밀도는 MXFP4 가중치 + MXFP8 활성값이며 옵티마이저는 Per-Head Muon이다.

목표 #

에이전트라는 목표 #

아키텍처를 읽으려면 목표부터 먼저 알고가야한다. Kimi의 목표는 일관되게 에이전트다.

K2의 부제 부터가 Open Agentic Intelligence 였고, 이후 모든 세대가 도구 호출, 장기 실행, 병렬 오케스트레이션 쪽으로 갔다.

이 목표를 잡으면 두 가지가 자동으로 따라온다.

컨텍스트가 길어진다. 코드베이스 스냅샷, 도구 정의, 수백회의 도구 호출 기록이 전컨텍스트에 쌓인다. 대화 몇마디가 아니라 수십만에 백만 토큰이 기본이 된다.

같은 앞부분이 반복된다: 에이전트의 다음 턴은 보통 이전 턴 프롬프트를 그대로 다시 보내면서 시작하기엥 이 성질이 나중에 서빙 비용을 결정한다.

스펙에 남은 흔적 #

Kimi는 에이전트를 노린다고 말만 한 게 아니라 스펙을 그 방향으로 깎았다. K2를 만들때 무슨 기준으로 뭘 정했는지 논문에 적어놨는데, 두 결정이 정반대 방향으로 움직인다.

  • 전문가 384개로 늘림: 참고한 모델 DeepSeek-V3는 256개였으니 약 50%를 전문가를 늘렸다 늘린 근거도 측정으로 만들었는데 활성 전문가 수를 8개로 고정해놓고 총 전문가 수만 바꿔가며 성능을 봤더니 늘릴수록 계속 좋아졌고 측정 구간 안에는 한계가 안보였다.
  • 어텐션 헤드를 64개로 줄임: 같은 DeepSeek-V3가 128개였으니 절반으로 깎은거다. 보통은 둘다 늘리는데 파라미터를 키우는 방향이니, 헤드를 깎은 이유는 논문에서 직접 밝힌바에 따라 헤드가 많으면 메모리 대역폭을 잘 쓰게 되어 짧은 문장에서는 빨라지지만 컨텍스트가 길어지면 추론할대마다 부담이 급격히 커진다고 한다. 즉 대화 몇마디 주고받는 용도면 헤드 많은게 이득인데 에이전트 시스템의 특성상 코드베이스를 통째로 물고 도구를 수백번 부르는 용도에서는 손해였기 때문

즉 짧은 컨텍스트에서의 이득을 버리고 긴 컨텍스트를 위한 구조로 바꾼것이다.

에이전트로 가겠다는 결정이 나타난 지점이다.

이 관점을 잡아두면 K3의 결정들이 훨씬 잘 읽히고 뒤에 나오는 KDA도 AttnRes도 Radix 캐싱 재설계도 전부 긴 컨텍스트를 싸게 만든다는 하나의 목표에서 나온다.


Decoding이 왜 느린가 #

오해 #

"어텐션이 O(n²)이라 길어지면 느리다"는 말을 한 번쯤 들어볼 수 있을텐데 이건 프리필(프롬프트를 한 번에 읽는)단계에 대한 이야기로 토큰 하나씩 내뱉는 디코딩 단계에서는 스텝당 O(n)이다

그리고 더 중요한게 있다 디코딩에서는 시간을 결정하는 건 계산량이 아니라 메모리에서 데이터를 읽어오는 속도다.

산술 강도 arithmetic intensity로 예시를들어 보자, 메모리 1바이트를 읽어올 대 바이트연산을 볓 번하느냐를 의미하는 값

H100을 기준으로 잡으면 BF16 조밀 연산 성능이 초당 약 495조회이고 HBM 대역폭이 초당 3.35TB이다. 나누면 바이트당 약 150회가 나온다 이 값이 손익 분기점이다.

커널의 산술 강도 > 150 -> 연산 성능에 묶임 (compute-bound)
커널의 산술 강도 < 150 -> 메모리 대역폭에 묶임 (memory-bound)

디코딩 어텐션을 계산해보자. 헤드 차원 d, 컨텍스트 n에서 K V를 각각 n x d 개를 읽어야하고 BF16이면 원소당 2바이트로 4nd 바이트다.

연산은 내적과 가중합을 합쳐서 4nd회이다.

산술강도 = 4 x n x d FLOPs / 4 x n x d bytes = 바이트당 약 1회

손익 분기점의 150분의 1로 연산 유닛이 99퍼 이상 놀고있고 GPU는 그냥 메모리에서 숫자를 퍼우는 일만 하고있다.

여기서 지연을 줄이려면 FLOPs를 줄이는게 아니라 애초에 연산 병목이 아니라서 방법은 두 가지 뿐이다.

  1. 읽는 바이트를 줄이거나
  2. 한 번 읽은 바이트로 더 많은 토큰을 만들거나

KDA가 전자이고 투기적 디코딩이 후자의 것이다.

그리고 읽는 야잉 무엇에 비례하는지가 갈린다.

전체 어텐션 : 4nd 바이트 -> 컨텍스트 길이 n에 비례해서 계속 자란다.
선형 어텐션 : 2d² 바이트   →  n과 무관하게 고정

n이 100만이면 차이는 자릿수 단위만큼 나고 여기가 K3가 손댄 지점이다 컨텍스트 늘려도 버티자를 위한


KDA - 시퀀스 축을 다시 짜기 #

KDA는 Kimi Delta Attention이다. K3 아키텍처의 핵심이며 2025년 10월 Kimi Linear라는 별도 모델로 먼저 검증한 뒤 K3에 넣었다.

1단계 - 캐시를 상태로 바꾸기 #

과거를 전부 보관하는 대신 크기가 절대 변하지 않는 행렬 하나에 요약해서 들고 다닌다.

상태 S : d × d 행렬 하나

쓰기 : 새 토큰이 오면 S를 갱신
읽기 : o = S · q  (질의 벡터를 곱함)

컨텍스트가 1천이든 100만이든 S의 크기는 같음
→ 스텝당 읽는 양이 상수

이 발상 자체는 Mamba, RWKV, GLA 같은 선형 어텐션 계열이 전부 이 뼈대를 공유한다.

KDA가 이와 다른점은 그 위에 얹은 두 가지 이다.

덮어쓰기가 되게 만들기 #

순진한 선형 어텐션은 새 정보를 더하기만 한다.

S = S + v kᵀ

문제가 바로 보이는데 같은 키에 두 번 쓰면 값이 합쳐지게 된다는 것이다.

희의실 = 3층을 적고 나중에 회의실 = 5층을 적게되면 읽을때 8층으로 나오는 문제인것이다.

즉 컨텍스트가 길어질 수록 상태가 뒤죽박죽 깨지게 되는것이다.

델타 규칙은 쓰기 전에 지우는 방식으로 동작한다.

S_t = S_{t-1} − β_t (S_{t-1} k_t − v_t) k_tᵀ
                     └── 지금 저장된 값과 새 값의 차이 ──┘

이 키를 지금 읽으면 뭐가 나오지? 를 계산하고 나와야할 값과 차이만큼 빼준다.

여기서 관점 하나를 잡아두면 좋은데 목적함수 L(S) = ½‖S k − v‖²로 두면 기울기가 (S k − v) kᵀ 가 나온다. 위 식과 똑같은데 즉 델타 규칙은 이 목적함수에 대해 학습률 β로 경사하강을 한 스텝 돌리는 것 이다.

이렇게 보면 인접 연구가 한 줄로 꿰인다.

목적 함수란 최적화 문제에서 가장 최대화하거나 최소화해야할 값을 정량적으로 정리한 수학적 함수 이익, 효율성, 성능 등은 최대화하고 비용, 손실, 오차등은 최소화하는 최적의 변수나 상태를 찾는 기준이 된다.

  • 목적함수를 바꾸면 -> 다른 메모리 갱신 규칙
  • 학습률 β를 토큰마다 다르게 하면 -> 적응적 갱신
  • 1차를 2차로 올리면 -> 모멘텀이나 Adam 스타일 상태 갱신
  • 스텝을 여러번 돌리면 -> TTT(Test Time Traning) 계열
  • 목적함수 자체를 학습시키면 -> Titans 계열

선형 어텐션의 갱신 규칙을 설계하는 일은 온라인 최적화 알고리즘을 설계하는 일과 같다.

최적화 문헌에 쌓여있는걸 여기로 옮겨오는 작업이 아직 대부분 안되어있다.

기존 모델들은 α가 스칼라 하나였다.

  • Mamba2: 헤드나 블록 단위 스칼라 하나
  • Gated DeltaNet: 헤드 단위 스칼라 하나
  • KDA: α ∈ [0,1]^d, 차원마다 독립적인 망각률

스칼로 하나로 잊으면 상태 전체가 균일한 속도로 흐려진다. 즉 오래 들고가야할 정보와 즉시 보려도 되는 정보가 같은속도로 사라진다.

고정 크기 상태에서 상태는 곧 정보 에산인데 그 예산을 알뜰하게 못쓰는 셈이 되는 것이다.

채널마다 다른 망각률을 주면 예산으 시간 척도별로 나눠 쓸 수 있다. 어떤 차원은 시간 상수가 길어서 문서 수준 정보를 담고, 어떤 차원은 짧아서 바로 앞 몇단어만 담는다.

즉 Mamba2는 헤드 블록 단위에 스칼라 값으로 과거의 기억을 잊게했고 Gated DeltaNet은 헤드에 속한 모든 특징 차원이 동일한 비율로 과거의 기억을 잊거나 유지한다. 그리고 KDA는 스칼라 대신 채널별 대각 행렬을 이용하여 특정 차원마다 독자적인 망각속도를 가지게 한다. 특정 정보는 빠르게 지우고 핵심 정보는 독립적으로 오래 유지하기 위한 전략이다.

실측 결과도 존재한다. Palindrome, MQAR, Stack같은 시퀀스 추론 과제에서 KDA가 Gated DeltaNet, Mamba2 보다 빨리 수렴하고 정확도도 높았다. MQAR(Multi-Query Associative Recall)이 특히 의미가 있는데 이게 상태 크기 대비 키 값 쌍을 몇 개나 정확히 저장할 수 있는지를 재는 벤치마크로 연산 메모리 용량을 직접 측정한다.

부수 효과도 하나 잇었다. α가 학습된 위치 감쇠 역할을 해서 RoPE 같은 위치 임베딩이 따로 필요하지 않았다. 오래된 정보가 자연스럽게 흐려진다는 사실 자체가 얼마나 옛날 것인가를 담고 있기 때문이다.

스칼라 하이퍼파라미터를 벡터로 승격시키는 것은 이 분야에서 반복해서 통하는 수법으로 추가 비용이 거의 0인데 표현력은 확실히 늘어난다.

KDA가 못하는 것 - 표현력 이론 #

선형 어텐션은 정밀한 검색에 약하다는 설명을 흔히 본다.

맞는말이긴한데 너무 몽뚱그린 서술이라 무엇을 어떻게 못하는지 알아야 어디를 보완할지 알 수 있다.

상태 전이 행렬 좌표계 #

선형 RNN 계열에서는 전부 이 형태로 쓸 수 있다.

S_t = A_t · S_{t-1} + (입력 항)

여기서 A_t 는 상태 전이 행렬이라고 부른다.

이전 상태가 다음 상태로 넘어갈 때 곱해지는 행렬이다.

이 행렬이 어떻게 생겼느냐가 모델의 표현력을 결정한다

각 모델을 이 좌표계가 놓아보면 이렇게 된다.

  • Mamba2: A_t가 대각 행렬, 각 차원을 독립적으로 감쇠시키기만 한다.
  • DeltaNet: A_t = I - β k kᵀ 대각에 rank-1 수정이 붙는다.
  • KDA: A_t = Diag(α) (I − β k kᵀ): 채널별 감쇠와 rank-1 수정을 둔다.

유일한 정밀도 선형 RNN은 전이 행렬의 고유값이 전부 양수이면 parity를 풀 수 없다. 아무리 층을 쌓아도 마찬가지다.

여기서 패리티를 풀 수 없다는 것은 3차원 일반 공식이나 회전 방식으로는 해결할 수 없다는 뜻. 전용 알고리즘이 필요하다는 뜻이다.

parity는 입력 비트열에서 1의 개수가 홀수인지 짝수인지 판정하는 문제로 아주 단순해 보이는데 이게 상태 추적 과제중에 가장 쉬운것이다 LSTM 같은 비선형 RNN은 쉽게 푼다.

상태 추적이 실제로 중요한 이유는 이런 것들이 전부 여기 속하기 때문이다

  • 코드 실행을 따라가며 변수 값 추적하기
  • 체스판 위 말 위치 추적하기
  • 깊게 중첩된 괄호 매칭하기

왜 못 푸는지 직관적이다. parity를 상태 하나로 푸는 방법은 1이 올 때마다 상태에 -1을 곱한다 이다.

부호를 뒤집어야 하는데 고유값이 0, 1 범위에 갇혀있으면 뒤집기가 불가능하다. 흐리게 만드는 것만 가능하다.

Mamba 계열이 게이트를 0, 1로 두는것 즉 얼마나 잊을것인가만 표현하는 설계가 정확히 이 한계에 해당한다.

반사가 계층을 바꿈 #

해소하는 방법은 DeltaNet 계열에서 우아하게 할 수 있는데

A_t = I − β k kᵀ

β 범위가 [0, 1] →  고유값 [0, 1]    사영에 가까움
β 범위가 [0, 2] →  고유값 [−1, 1]   β=2에서 완전한 반사

I − 2kkᵀ는 선형대수에서 Householder 반사 행렬이라고 부르는 것이다.

k에 수직인 평면을 기준으로 벡터를 뒤집는다. . β를 2까지 허용하면 델타 규칙이 반사를 수행할 수 있게 되고, 그 순간 parity가 풀린다.

이 수식에서 β가 의미하는 바에 대해서 설명해주면 델타넷의 표현력을 확장한 최신 연구인 DeltaProduct 모델등에서 다루는 기하학적 메모리 업데이트 원리로 베타가 의미하는 바는 현재 입력된 정보로 기존 메모리를 마나 지우고 덮어쓸 것인가를 결정하는 업데이트 게이트이자 학습률이다.

β를 2배 하는 한 줄 수정이 표현력이 계층을 바꾼다. 학습 비용도 추론 비용도 그대로다

더 강한 결과도 있다. 전이 행렬이 I - vvᵀ 형태 행렬들의 곱이고 고유값 -1, 1 범위 안에 있으면 그 선형 RNN은 임의의 정규 언어를 학습할 수 있다.

한계도 명확한데 Householder 반사 하나로 표현할 수 있는 두 원소를 맞바꾸는 순열까지이다.

그보다 복잡한 순열 문제를 한 층에 풀려면 rank-n 전이 행렬이 필요하고 그게 DeltaProduct 계열의 접근이다. 대가는 비대각 행렬 곱셈 비용이다.

그래서 KDA는 어디에 있는가 #

KDA의 전이 행렬을 다시 보자

A_t = Diag(α_t) (I − β_t k_t k_tᵀ)

대각 성분에 rank-1 수정이 붙은 형태 즉 DPLR(Diagonal-Plus-Low-Rank)의 특수한 경우다.

Mamba2의 순수 대각보다는 표현력이 높고, 일반 DPLR 보다는 제한적이지만 훨씬 싸다.

여기서 미해결 질문이 나오는데 가 [0,1] 범위라는 건 공개되어 있는데, β의 범위는 명시자료가 없다

β ∈ [0, 1] 이면  →  고유값이 양수  →  parity를 못 풂
β ∈ [0, 2] 이면  →  반사 가능      →  정규 언어 학습 가능

공개된 가중치와 커널 코드에서 해당 베타를 만드는 활성화 함수의 스케일을 확인하면 답이 나온다. 반나절로 돌려봐야하고 일단 더파면 끝도없으니 일단

두 번째 질문으로 Diag(α)와 (I − βkkᵀ)를 곱한 행렬의 고유값은 두 행렬 고유값의 단순 곱이 아니다.

채널별 감쇠가 표현력을 늘리는 방향인지 아니면 고유값 0, 1에 더 강하게 묶는 방향인지 실제로 계산해봐야한다. Kimi Linear 체크포인트에서 층별 고유값 분포를 뽑아보는게 첫 실험이 된다.

새로 나온 선형 어텐션 모델을 볼 때 물어야할 첫 질문은 전이 행렬이 어떤 구조이고 고유값 범위가 어디인가 이다. 나머지 설계 대부분 그 결정에서 파생된다.

하이브리드 #

잃은 것을 되사는 것.

층 단위로 해당 구조를 배급하는건데

표현력 손실을 되사는 방법은 K3는 일부 층만 전체 어텐션으로 남기는 방식으로 풀 수 있다 K3가 그선택을 한거다.

K3의 층 배치 (반복 단위)

[ KDA → MoE ] [ KDA → MoE ] [ KDA → MoE ] [ Gated MLA → MoE ]
└──── 값싼 요약 3층 ────────────────────┘ └─ 정밀 검색 1층 ─┘
                 75%                              25%

K3는 네 층마다 MLA를 쓰는데, 네 층중 셋은 KV 캐시가 아예 없고, 하나만 정확한 전역 검색을 담당한다.

KV 캐시  : 네 층 중 한 층만 유지  →  75% 감소
디코딩   : 1M 컨텍스트에서 최대 약 6배
           (토큰당 11.5ms → 1.8ms 수준으로 보고)

75%가 3:1 비율에서 정확히 떨어진다는 것을 확인하자.

발표 수치를 그대로 받아적기전에 직접 검산해보자

전체 어텐션층이 25%로 KDA층의 어텐션 비용이 0에 수렴한다고 극단적으로 가정해도 어텐션이 시간의 전부라면 암달의 법칙상 최대 속도 향상은 1 나누기 0.25 = 4배가 된다

이론 상한 4배 < 보고치 6배

6배까지는 턱없이 부족하지만 이를 더 설명가능하다

  • 전체 어텐션 층도 그냥 어텐션이 아니다: Gated MLA인데 MLA는 키와 값을 저랭크 잠재공간으로 압축해서 KV 캐시를 이미 줄여둔 구조다 그러니 캐시 감소 효과가 층 비율보다 크게 나온다.
  • 디코딩이 대역폭에 묶임: 앞서 계산한대로 읽는 바이트수가 시간을 결정하므로 캐시 75퍼 감소가 FLOPs 비율과 다르게 반영된다.
  • 비교 기준선이 다름: 전 층 전체 어텐션 모델과 비교한거라면 조건이 같지 않다
  • 커널 최적화가 별도 기여가 가능함: 융합 커널들의 효과

발표수치를 적기전에 상한 계산후에 차이를 설명하려고 시도해보면 좋은 습관이다 이론적 복잡도와 실측 성능 간극을 뜯어보는 습관은 좋은거니까


순환을 GPU에 올리기 #

순차성이라는 벽이 존재한다 수식이 이쁜것과 gpu에서 빠른건 완전히 다르기 때문이다.

상태 갱신식 t 시점 상태가 나와야 t+1을 계산할 수 있기에 수천개의 코어를 가진 gpu에 그대로 올리면 코어 대부분이 놀게된다.

선형 어텐션이 오랫동안 연구실 밖으로 못 나온 이유가 이거다.

해법은 청크 단위 병렬화다

청크 크기 C = 64 기준

1) 시퀀스를 64개씩 잘라냄
2) 청크 안 : 순차 갱신을 하나의 조밀한 표현으로 압축해 행렬곱으로 처리
3) 청크 간 : 상태만 순차로 전달

순차 스텝 수 : T개  →  T/64개
연산 구성    : 대부분 행렬곱  →  텐서 코어를 탐

문제는 2번인데 순차 갱신을 어떻게 하냐, 행렬곱으로 압축하느냐 이런거다.

압축 가능한 것들 #

  • WY 표현: 청크 안에 rank-1 갱신을 순서대로 곱하면 ∏(I − β_i k_i k_iᵀ) 형태가 나온다 이 곱을 전개하면 I − W Yᵀ 라는 조밀한 형태로 압축된다. W와 Y는 청크 안의 키 벡터들로부터 만들어지는 행렬 두개다

이건 원래 Householder 변환의 곱을 다루려고 만들어진 수치선형대수 기법으로 순차곱셈 행렬 두 개로 대체되니까 청크 전체를 한 번에 처리할 수 있다.

여기서 재밌는게 앞 절 델타 규칙의 전이 행렬이 Householder 형태라는걸 봤는데 표현력 때문에 고른 그 형태가 여기서 병렬화 가능성까지 함께 가져다 준 것이다.

Householder는 선형대수학의 개념으로 변환 또는 반사를 의미한다. 어떤 평면을 기준으로 벡터를 거울에 비추듯 완벽하게 대칭이동(반사) 시키는 변환이다. 벡터 x에 행렬 H를 곱하면 v와 수직인 평면을 기준으로 x의 반대편 대칭점으로 벡터가 홱 뒤집힌다.

  • UT 변화: WY 표현을 만들면 중간에 하삼각 행렬의 역행렬이 필요하다. 역행렬을 명시적으로 계산하면 행렬곱이 아닌 연산이 잔뜩 생기는데 UT 변환은 이 부분 행렬곱으로 다시 쓴다. Kimi Linear 보고서가 행렬곱이 아닌 FLOPs를 줄이는게 결정적이었다고 명시한다.

DPLR 특수화: 일반적인 DPLR 전이 행렬은 Diag(a) + b + cᵀ로 a b c가 전부 독립 변수다 KDA는 b = k ⊙ α 철머 저랭크 항의 변수를 키 벡터에 묶어벌니다 독립 변수가 줄어드니 청크 전개에 필요한 행렬 연산수가 크게 줄고 동시에 고전적인 델타 규칙 형태와의 일관성도 유지도니다 측정 겨로가 일반 DPLR 대비 커널이 약 2배 빠르다

⊙ 하다마르 곱(Hadamard Product)으로 같은 크기 두 행렬이 있을때 행렬 곱셈 규칙을 따르지 안혹 자리가 같은 원소끼리 그냥 일대일로 곱하는 연산, (\text{Diag}())는 벡터를 대각 행렬(Diagonal Matrix)로 변환하는 연산

수치 안정성 처리. 채널별 알파가 들어가면 청크를 전개할 때 감쇠 인자가 계속 곱해지므로 청크 시작점 기준으로 정규화하지 않으면 긴 청크에서 값이 0으로 죽는다 이처리가 구현 난이도의 축이다

현대 GPU에서 텐서코어 행렬곱과 그 외 연산은 처리량이 자릿수 단위로 차이나고 새 시퀀스 모델을 설계할때 물어야할 것은 FLOPs가 몇인가가 아니라 이 연산은 행렬곱으로 표현할 수 있는가이다 표현이 안되면 이론적 복잡도가 아무리 좋아도 느리다 Mamba1에서 Mamba2로 넘어간것도 이 교훈이다.

Moonshot은 이 커널을 FlashKDA라는 이름으로 CUTLASS 구현까지 공개했다.


AttnRes - 깊이 축을 다시 짜기 #

층이 많아지면 생기는 일 #

위의 내용까지가 가로축 얘기다, 컨텍스트를 길게 가져가는 비용을 해결했으니, 이제 모델을 키울 수 있따.

깊이를 키우면 K3는 약 93층이 된다.

트랜스포머의 각 층은 아래층이 넘겨준 값에 자기 계산 결과를 더해서 위로 올린다.

93개층이 같은 값에 순서대로 자기 결과를 더한다고 생각해보면 문제가 보인다.

1층이 더하고 2층이 더하고 ... 93층이 더하고

-> 값이 점점 커지고 온갖 정보에 뒤섞임
-> 3층이 넣은 신호가 전체에서 차지하는 비중이 점점 작아짐
-> 90층에서는 3층이 뭘 했는지 알아볼 수 없음
-> 학습할 때 초반 층으로 돌아가는 신호도 약해짐.

층이 20~30개일때는 문제가 안되지만 90층대에서는 문제가 된다.

더하는 대신에 골라오는 방식 #

K3는 이 덧셈을 어텐션으로 바꿨다. Block AttnRes 라고 부른다.,

어텐션이 원래 하는 일이 여러 개 중에 지금 필요한 걸 골라서 가중치에 매겨 섞는 것 이다.

그걸 문장 속 단어들이 아니라 앞선 층들의 출력에 대고 하는거다.

각 층이 하는일

1. "지금 나한테 머가 필요하징"를 나타내는 질의 벡터를 만든다 (학습으로 정해짐)

2. 후보를 늘어놓는다. 앞선 블록들이 남긴 출력들 최대 8개 + 현재 블록의 값 = 최대 9개

3. 질의와 각 후보에 점수를 매기고 softmax를 건다

4. 점수대로 섞은 값을 자기 입력으로 받는다.

기존 잔차는 모든 층의 기여를 똑같은 무게로 쌓는다. AttnRes는 지금 이 층에 필요한 것만 골라온다.

깊이가 깊을수록 골라오는 쪽의 이점이 커진다.

vLLM 팀은 이 구현을 FlashAttention에 비유하는데, 후보가 최대 9개 뿐이라 훨씬 작은 문제이다.

공짜는 아님 #

층마다 앞선 출력들을 계속 읽어야하고 잔차가 그냥 지나가는 값이 아니라 계속 들고다녀야하는 값이 된다.

메모리를 더 쓰고 계산도 더 쓰게된다.

그리고 커널이 없으면 느리다. 순진하게 구현하면 93개 층마다 읽기 쓰기 합치기 정규화 커널이 따로 뜬다.

층당 손해가 작아도 93번 곱하면 크다. vLLM은 이걸 하나로 묶었다.

GPU를 나누는 방식도 바꿔야했다 잔차가 무거워진 만큼 각 gpu가 그걸 중복으로 들고있는 비용이 커졌다

뒤에 나올 시퀀스 병렬이 이것때문에 도입되었다.

같은시기 DeepSeek-V4도 mHC 라는 이름으로 잔차연결을 손봤고 8년간 고정되어 있던 지점을 두 곳에 비슷한 시기에 갈아엎었다는 것 자체가 신호다 어디를 팔지 고민중이라면 이 영역이 지금 가장 저평가 되어있을 가능성이 높다.


Stable Latent MoE - 폭을 키울 때 문제 #

전문가가 896개가 되면 깊이 다음은 폭이 문제다 K3는 전문가가 896개로 늘리고 그 중 16개의 공유 전문가만 킨다. 전체의 약 1.8퍼이다.

늘린 근거는 감이 아니고 측정으로 K2를 만들때 활성 전문가수를 8개로 고정해놓고 총 전문가수를 바꿔가며 성능을 봤더니 늘릴수록 계속 좋아졌고 실험 구간 안에서는 한계가 보이지 않았다.

문제는 늘리면 세 군데가 터진다는 것이다.

  1. 전문가 가중치 읽는 시간: 앞에서 디코딩이 메모리에서 퍼오는 시간에 묶여있다 했는데 같은 얘기가 여기도 적용된다. 토큰마다 선택된 전문가의 가중치를 메모리에서 읽어와야하고 전문가가 크면 이 읽기가 시간의 대부분이다.
  2. GPU 사이의 통신: 전문가 896개가 한 gpu에 다 안들어가니까 여러 gpu에 훝어놓는데 그러면 층마다 토큰을 담당 GPU로 보내고 결과를 다시 모으는 통신이 두 번씩 발생한다. 활성 전문가가 16개면 통신량이 그만큼 늘어난다.
  3. 일감 쏠림: 896개나 되면 어떤 전문가에는 열이 몰리고 어떤 전문가는 아예 안 불린다 안불리는 전문가는 학습이 안되고 몰린 전문가가 있는 gpu가 병목이 된다.

전문가에게 요약본 보내기 #

앞의 두 문제를 한 번에 푸는게 LatentMoE로 NVIDIA가 제안한 구조다.

기존   : 토큰 값을 모델 폭 그대로 전문가에게 넘김
        → 전문가가 계산
        → 결과를 모델 폭 그대로 받음

Latent : 토큰 값을 좁은 차원으로 줄여서 넘김
        → 전문가가 좁은 공간에서 계산
        → 결과를 다시 모델 폭으로 늘림

전문가가 다루는 벡터가 좁아지니까 전문가 가중치 행렬도 작아지고 gpu 사이클이 오가는 데이터도 줄어든다. 같은 비용으로 더 많은 전문가를 켤 수 있게 된다. K3가 16개를 켜는 근거이다.

일간 쏠림 막기 #

세 번째 일감 쏠림 문제는 따로 풀어야한다.

기존 방식은 손실 함수에 별점을 붙이는 방식인데

특정 전문가만 계속 불리면 벌점을 주고 벌점 세기를 사람이 정한다

이 값이 까다로운데 세게 걸면 라우터가 아무데나 보내버려 전문화가 안되고

약하게 걸면 쏠림 방치가 된다.

모델 규모가 바뀌면 다시 찾아야한다 이 값을

Quantile Balaning은 이 값을 아예 없앴고 라우터가 매긴 점수로 순위를 줄 세워

어디에 배정할지를 거기서 직접 정한다. 사람이 정할 값이 사라진다

민감한 하이퍼파라미터는 잘 튜닝하는 것 보다 없애는게 낫다. 통제하려는 값의 통계에서 목표를 직접 뽑아낼 수 있으면 그렇게 한다. 배치 정규화부터 최근 연구까지 반복해서 나타나는 패턴이다.

곁들여 들어간것 #

SiTU는 활성값 크기를 통제하는 활성화 함수로 초대규모 학습을 안정화하려고 넣었는데 서빙쪽에 부채를 만들었따.

시그모이드랑 탄하트 성분이 포함되어있어 입력값이 아주 크거나 작을때 미분값이 0에 가까워지며 기울기 소실과 높은 연산비용이 존재한다 자연상수 지수 exp 연산이 다수 포함되어있어서다.

vLLM에서 MXFP4 최적화 경로가 SITU를 지원하지 않아 느린 폴백 구현으로 떨어졌고 이걸 뚫는 작업이 따로 필요했다. AMD 쪽도 자기 커널 스택에 SiTU를 따로 넣어야했다.

Gated MLA는 하이브리드에서 전체 어텐션을 담당하는 중이다

MLA에 게이트 하나 붙인 형태인데, 이 게이트 계산이 어텐션 본 계산과 동시에 돌아갈 수 있다는 성질이 있다.

커널 최적화에서 이 성질을 쓰는데 뒤에서 나온다.


정밀도 - 압축을 학습에 넣기 #

2.8조 파라미터를 16비트로 두면 5.6TB로 압축. 필연적으로 해야한다.

보통은 학습을 정상 정밀도로 다 해놓고 배포할때만 4비트로 줄이는데 그러면 모델이 학습중에 한 번도 못본 조건에 던져진다 정확도가 떨어지는게 당연하다

QAT는 학습중 저정밀 연산을 미리 흉내낸다 가중치는 정밀하고 들고있되 계산할때는 4비트로 줄엿다 폇을때 값을 쓴다 모델이 학습하면서 압축 오차에 미리 적응한다.

QAT는 Quantization Aware Training으로 학습 단계때부터 저정밀도 양자화 오차를 시뮬레이션해 학습시키는 모델 경량화 기법이다 학습 이후에 하는건 PTQ

K2 Thinking : 사후학습 단계에서 MoE 부분에 INT4 가중치 압축
              → 생성 속도 약 2배, 모델 크기 약 594GB

K3          : SFT 단계부터 적용
              가중치 MXFP4 + 활성값 MXFP8

활성값까지 줄이는 게 훨씬 어렵다 가중치는 학습이 끝나면 값이 고정되지만 활성값은 입력마다 달라지고 가끔 아주 큰 값이 튀어나온다 큰 값 하나때문에 나머지가 뭉개진다. microscaling 포맷이 값을 몇 개씩 묶어서 묶음마다 배율을 따로 두는 게 이 문제 대응이다.

실무적으로 눈여겨별 게 하나 있다 K2 Traning은 발표한 벤치마크를 전부 INT4 상태르 측정했다 보통은 정밀도 높은 상태로 점수를 내고 서비스는 압축해서한다 그러면 발표와 점수와 실사용 성능은 다르다 벤더 자료를 볼대 어떤 정밀도로 쟀는가를 확인해야하는데 대부분은 아예 안밝힌다.


Muon #

학습을 안 무너뜨리기

Kimi 계보에서 눈여겨볼 순서인데 K2는 모델을 만들기전에 Moonlight라는 16B 모델을 따로 만들어서 Muon이라는 새 옵티마이저가 큰 모델에서도 도는지부터 확인했다.

그 검증 없이 1조 파라미터 모델을 새 옵티마이저로 돌리는 도박은 하지 않았다.

Muon vs AdamW #

AdamW는 가중치를 숫자 하나하나의 모음으로 본다. 각 숫자마다 따로 기록을 들고 있고 각 숫자마다 학습률을 조정한다. 가중치가 원래 행렬이라는 사실 자체를 모르게 한다.

Muon은 가중치를 행렬 통째로 보게 한다.

여기서 무슨 차이가 있는지 알아보면 학습을 오래 돌리면 업데이트가 몇 개 방향으로만 심하게 쏠리는데, 특정 방향은 계속 크게 바뀌고 나머지 방향은 거의 안바뀐다. 행렬이 표현할 수 있는 공간은 넓은데 그중 일부만 쓰게 되는것이다.

Muon은 업데이트를 적용하기 전에 모든 방향의 크기를 똑같이 맞춘다.

크게 튀던 방향은 눌러주고 작던 방향은 키워주는것이다 그러면 행렬 전체가 골고루 학습한다.

이 "크기를 똑바로 맞추는" 계산을 정확히 하려면 무거운 연산이 필요한데 Newton-Schulz라는 방법으로 근사한다. 행렬 곱셈 몇번으로 끝나서 gpu에서 빠르고 정밀도를 낮춰 돌려도 된다.

적용 대상 #

  • 행렬 형태 가중치(은닉층) -> Muon
  • 일렬로 늘어난 값들 (임베딩, 바이어스) -> 기존 AdamW 유지

방향을 맞춘다는 개념 자체가 행렬에서만 성립하기 때문이다.

큰 모델을 올릴 때 필요한 두 가지

Muon은 원래 작은 모델에서 검증된 옵티마이저였는데 Moonshot이 대규모로 끌어올리면서 두 가지 문제점을 찾았다.

  1. 가중치가 무한정 커지는 것을 막아야했다. Muon 에서는 원래 이 장치가 없었는데 큰 모델을 오래 돌리면 가중치 크기가 계속 자라고 감쇠장치를 넣어야 안정적으로 수렴한다.
  2. 업데이트 크기를 파라미터 간에 맞춰야 했다. 방향을 고르게 만든느 처리를 거치면 행렬 모양에 따라 실제 업데이트 크기가 제각각이 된다. 파라미터마다 배율을 조정해서 크기를 통일 시켰다.

결과는 AdamW 대비 약 2배정도의 계산 효율 향상이였다. 같은 성능을 절반의 계산으로 낼 수 있었다.

구현에서 까다로운 지점도 하나 있는데 Muon은 가중치 행렬 전체를 봐야 방향을 고르게 만들 수 있다. 그런데 큰 모델은 파라미터를 여러 GPU처럼 쪼개놓고 순진하게 각 GPU 조각만 보게 되어 알고리즘이 깨진다. Moonshot은 이걸 해결한 분산 구현도 공개했다.

QK-Clip #

옵티마이저가 좋아도 학습은 무너질 수 있다.

대표적인 사고가 loss spike이고 큰 원인 하나가 어텐션 점수 폭주다.

어텐션은 질의와 키를 곱해서 점수를 내고, 학습이 진행되면 이 점수가 계속 커지는데

K2팀 관측으로 중간 규모 학습에서 1000을 넘겼다.

점수가 커진다
  → softmax가 한 곳에만 거의 100%를 몰아준다
  → 나머지 위치는 학습 신호를 못 받는다
  → 학습이 멈추거나 숫자가 터진다

일반적인 대응은 사후 처방으로 터지면 며칠 전 체크포인트로 되감고 학습률을 낮춰 다시 돌리는건데

수천장 GPU를 며칠 굴린게 날아가는 슈퍼 리스크가 있다.

QK-Clip은 매번 업데이트한 직후 점수가 얼마나 커질지 미리 계산을 해본다.

임계값(K2에서는 100)을 넘길 것 같으면 관련 가중치를 그 자리에서 줄여버린다. 손실 함수에서 벌점을 붙여서 간접적으로 유도하는게 아니라 가중치를 직접 건드린다.

Muon과 QK-Clip을 합친게 MuonClip이고 이 조합으로 15.5조 토큰을 학습하는 동안 loss spike가 단 한번도 없었다.

1조 파라미터 규모에서 이 결과는 K2 보고서에서 가장 재현 가치가 높다고 평가받는 부분이다.

학습 불안정은 대체로 어떤 값이 통제 없이 계속 자라는 것으로 정리된다. 막는 지점을 손실 함수에 두면 간접적이고 느리고 가중치에 직접 두면 확실해진다. 새 구조를 설계할때 "여기서 뭐가 무한정 자랄 수 있을까"를 먼저 묻고 그 자리에 상한을 걸 수 있는지 확인해보는 것이 순서다.

Per-Head Muon #

K3는 Muon을 어텐션 헤드마다 따로 적용한다.

자연스러운 확장인데 Muon은 전제가 "가중치는 행렬이니 행렬로 다뤄야한다" 이다.

멀티헤드 어텐션의 가중치는 사실 여러 개의 독립적인 행렬을 옆으로 이어붙인 형태로 이어붙인걸 통째로 처리하면서 헤드 사이 경계가 뭉개진다.

헤드별로 나눠서 처리하면 각 헤드가 독립적으로 관리된다.

옵티마이저를 어느 단위로 적용할지도 설계 변수다. 모델 하나에 옵티마이저 하나가 최적일 이유가 없고, 파라미터의 구조적 경계와 옵티마이저의 적용 경계를 맞추는 방향이다.


Serving #

Kimi 자료에서 상세하고 공개된 영역이고 실무자에게 쓸모있을 부분이다.

KDA를 쓰기로 한 결정 하나가 서빙 쪽에 구체적인 문제를 만들었고 그걸 어떻게 해결했는가를 알아보자

Mooncake #

먼저 Kimi서비스는 Mooncake라는 자체 서빙 플랫폼 위에서 돈다.

2024년 논문과 코드가 공개되었고 지금은 수천노드에서 하루 1000억 토큰 이상을 처리한다.

프리필과 디코드 분리 #

프리필은 프롬프트를 한 번에 읽는 단계라 계산이 병목이고 디코드는 토큰 하나씩 뱉는 단계라 메모리 읽기가 병목이다.

성격이 다른 작업을 같은 서버에서 섞으면 둘 다 손해라, 클러스터를 나누고 각자에게 맞는 구성을 준다.

놀고있는 자원으로 캐시창고 #

GPU 클러스터에는 CPU, DRAM, SSD가 놀고있고 이걸 다 묶어서 KV 캐시 저장소로 쓴다.

시스템 프롬프트 처럼 모두가 쓰는 부분을 여러곳에 복사해둔다.

Conductor #

Conductor라는 스케줄러가 요청을 배정한다.

캐시가 어디에 있고 각 노드가 얼마나 바쁜지를 동시에 확인하고

캐시만 보면 특정 노드에 요청이 몰리고

부하만 보면 캐시를 못쓰기에 이균형이 스케줄러의 본질이다.

사전 거절 #

어차피 제 시간에 못 끝낼 요청같은게 들어오면 아예 안받는다 예측해서 거절해버린다.

대부분의 서빙 연구는 모든 요청을 처리한다고 가정하는데 실제 서비스는 그렇지 않다는 관점에서 나온 설계다.

세부 최적화 하나가 인상적인데, 캐시를 불러오고 저장하는 작업을 층 단위로 프리필 계산과 겹쳐서 돌린다.

전송 시간을 계산 뒤에 숨기는 것이다.

접두사 캐싱이 깨지는 것 #

접두사 캐싱은 지금 서빙에서 가장 큰 비용 절감 수단인데

여러 요청이 프롬프트 앞부분을 공유하면 그 부분을 계산 재사용한다.

앞에서 에이전트 워크로드의 성질로 다음턴이 이전 턴 프롬프트를 그대로 다시 보낸다를 짚었다.

그 성질때문에 이게 비용을 지배하는데 Kimi 공식 api는 코딩 작업에서 90퍼 이상 히트율을 낸다고 밝히고 있고 가격이 캐시히트 0.30미스0.30 미스 3.00으로 약 10배 차이다.

그런데 KDA를 쓰면 이게 원리적으로 어려워진다.

전체 어텐션 : 앞부분이 토큰별 K, V 벡터로 남아 있음
             → 블록 단위로 이름표 붙여놓고 통째로 재사용하면 끝

KDA        : 앞부분이 "그 지점의 상태"로만 남아 있음
             → 정확히 그 위치의 상태를 저장해뒀어야 함
             → 앞에서부터 다시 돌리면 캐싱하는 의미가 없음
             → 그렇다고 매 토큰 저장하면 공간이 즉시 터짐

KDA 상태와 한 층의 크기가 수천 토큰 분량의 KV 캐시와 맞먹는다 상태가 작지 않은데

컨텍스트 길이와 무관하게 고정이라는 게 장점이지, 절대적으로 작다는 것은 아니다.

실무적 함의가 하나 나올 수 있는데 짧은 요청이 대부분 서비스라면 하이브리드가 오히려 손해인 구간이 있다.

자기 워크로드에서 어느 길이부터 이득인지 계산해보는 게 필요하다.

블록 크기와 캐싱 단위 분리 #

기존 vLLM에는 문제가 있었다.

vLLM은 kv캐시를 블록 단위로 관리한다

블록은 토큰 몇 개분의 캐시를 담는 고정 크기의 칸인데

문제는 이 블록 크기가 두 가지 역할을 동시에 했다는거고

  • 메모리를 실제 할당하는 단위
  • 요청끼리 앞부분이 같은지 비교하는 단위

KDA 상태(요약본)은 무거우니 블록 크기를 수천 토큰 단위로 잡아야한다.

그런데 크게 잡으면 프롬프트 99퍼를 공유하는 두 요청도 공통 부분이 블록 하나를 못채워서 캐시 미스가 난다.

저장은 효율적인데 재사용이 안되는 것이다.

해법은 이 둘을 떼어놓는 것으로 블록은 크게 두되 블록 안쪽의 세밀한 위치에서도 요약본을 등록할 수 있게 했다.

나중 요청이 그 위치에 맞으면 요약본을 자기 자리로 복사한 뒤 이어나간다. 복사해서 쓰니 원본은 남고 다른 요청도 계속 쓸 수 있다.

Moonshot은 이 문제를 자기 서비스에서만 풀지 않고 vLLM 코어에서 구현을 기여했다.

그래서 이 인프라는 이제 비슷한 구조의 모든 모델이 쓸 수 있다.

요약본 저장 위치 #

캐싱이 가능해져도 어느 지점에 저장할지 여전히 정책 문제다

두 가지로 구현이 되어있는데

  1. 일정 간격 저장하는 방식. 예를들어 32K 토큰마다 저장이 된다.

VLLM_PREFIX_CACHE_RETENTION_INTERVAL로 조절한다.

더 좋은 지점은 프롬프트가 긑나는 자리다. 에이전트의 다음 턴이 이전 턴 프롬프트를 그대로 다시 보내니 여기 요약본은 재사용될 확률이 아주 높다. vLLM이 이 자리를 자동으로 찾아 항상 저장한다.

  1. 보일 때 저장한다. Marconi라는 방식이고 규칙이 한줄이다.
요청 1 : 자기 프롬프트 끝에만 저장. 공유 지점에는 안 남김
요청 2 : KV 캐시는 맞았는데 KDA 요약본이 없어서 미스
        → 이 미스가 "이 앞부분은 실제로 공유되고 있다"는 증거
        → 이제 그 자리에 저장
요청 3 : 재사용

첫 번째로 본건 그런 앞부분이 존재한다는 정보일 뿐이고 두번째로 봣을때 비로소 공유되고 있다는 증거로 판단해 그때 저장공간을 쓴다

한 번 쓰이고 마는 앞부분이 캐시를 밀어내지 않으면서 반복되는 건 자동으로 승격한다 어느 부분이 자주 쓰일지 사람이 미리 예측할 필요가 없어진다.

커널 최적화 #

K3는 무거운 부분 자체를 바꿔놨는데

어텐션 커널만 손봐서는 부족하다.

실제로 최적화한 지점들을 보면 병목이 어디로 옮겨갔는지 알 수 있다.

  • KDA층을 하나로 묶기: KDA층 하나에 여러 계산이 들어가는데 따로따로 실행하면 매번 GPU에 작업을 물리는 비용이 생긴다 3:1 배치라 KDA 층이 아주 많으니 층당 작은 손해가 그대로 지연이 된다. 전부 한 커널로 묶었다.
  • 어텐션 메타데이터 빌더 커널을 띄우기전에 GPU에 색인 정보를 넘겨줘야한다 배치에 묶인 요청들이 각 시퀀스의 어디부터 어디까지인지 캐시 블록이 어느 자리에 있는지 KDA 요약본을 어느 슬롯에서 읽고 쓸지 같은것들이고 이걸 어텐션 메타데이터라고 한다. 초기 K3 구현은 Gated DeltaNet용 범용 빌더를 그대로 가져다 썼는데 K3가 쓰지도 않는 항목까지 만들고 있었고 그것도 작은 PyTorch 연산을 줄줄이 이어붙여 조립하고 있었다 K3 전용 빌더를 만들고 그 연산들은 Triton 커널 하나로 합치니 배치 1기준70μs가 34μs가 됐다(96% 감소) 어텐션 게산이 아니라 그 앞의 메타데이터 조립이 병목이었던것으로 배치가 작을수록 이런 고정 오버헤드의 비중이 커진다.
  • 작은 행렬곱 전용 코드: 배치가 작을때 행렬곱 전용 유닛은 쓰기 전 준비단계까 있다 행렬이 크면 준비 비용(어텐션 메타데이터 빌드)을 뽑고 남지만 작으면 준비하다가 시간이 다간다. 커널 기준 8~100%개선이다.

행렬곱으로 만들어야 빠르다 라는 얘기가 있었는데 여기서는 전용 유닛을 피해버린다 큰 덩어리 블록을 처리할때 아주 작은걸 처리할때 진행방식이 다르게 처리하면 더 효율적이라는 것이다

시퀀스 병렬도 여기에 들어가는데 AttnRes 때문에 잔차가 무거워져 모든 gpu가 전체를 중복으로 들고있는게 비싸졌다. 각 gpu가 자기 몫만 들고 처리하도록 바꿨다.

여기서 교훈이 하나 나오는데 이론상 통신량은 줄어드는데 NVIDIA 통신 라이브러리가 이 크기 메시지에 최적화되어있지 않아 실측 이득이 안나왔다. 그래서 통신 커널을 직접 짰고 기존 대비 1.7~4.5배 빨라졌다.

이론적으로 계산한 통신량이 실측을 예측 못하는 경우가 흔해 통신 라이브러리는 특정 크기 구간에 맞춰져있고 그 구간을 벗어나면이론상 더 싼 방식이 느리다. 재봐야한다.

Dspark 투기적 디코딩 #

커널과 통신을 다 손봐도 근본 제약이 남는데, 토큰 하나를 만들때 2.8조 중 활성 가중치를 전부 읽어야 된다는 것이다. 디코딩 계산은 이 메모리 읽기에 제약이 묶여있다.

투기적 디코딩은 그 읽기 한 번으로 여러 토큰을 처리하게 만드는 기법이다.

가볍고 빠른 드래프트 모델이 다음 토큰 여러개를 미리 제안하고 본 모델이 확정하게 만든다.

빠른 드래프트 모델이 다음 토큰 여러개를 미리 제안하고 본 모델이 한 번의 순전파로 전부 검증한다.

맞은데까지 확정하고 틀린지점부터 다시 진행하는 방식으로 결과는 본 모델이 혼자 생성한 것과 같다. (무손실)

이게 이득이 나는이유가 가중치를 한 번 읽는 비용이 토큰을1개 만들때나 7개 검증할때나 같기 때문이다 놀고 있던 연산 자원으로 여러 토큰을 확정하는거다.

DSpark는 K3가 별도로 붙인 드래프트 모델이다.

MTP를 안쓰고 왜 별도 모델로? #

드래프트를 만드는 표준 방식은 MTP(Multi Token Prediction, 다중 토큰 예측) 이다.

학습할때 다음 토큰 하나가 아니라 여러 개를 동시에 예측하게 시키고, 그때 붙인 예측 헤드를 추론 시점에 드래프터로 재활용한다.

Qwen3.5 계열이 이 방식이고 별도 모델을 만들 필요가 없다는게 장점이다.

문제는 MTP 헤드가 자기회귀 드래프터라는 것이다 토큰 하나를 뽑아야 그걸 보고 다음걸 뽑는다.

자기회귀 드래프터로 7개를 만들려면
  → 7번 돌아야 함
  → 드래프트 개수를 늘릴수록 드래프팅 비용도 같이 늘어남
  → 개수를 늘려서 얻는 이득이 금방 상쇄됨

K3는 별도의 드래프트 모델 DSpark를 붙였고 여기에 세 가지가 들어간다.

  • 블록 디퓨전 백본: 여러 토큰을 순서대로가 아니라 한 번의 병렬패스로 한꺼번에 생성한다. 확산 모델이 이미지를 한 번에 만들어 내는것과 같은 발상을 토큰 블록에 적용한 것이다. 덕분에 블록이 깊어져도 드래프팅 비용이 거의 평평하게 유지된다 자기 회귀 방식의 한계를 정면으로 푼 부분이다.
  • 저랭크 마르코프 헤드: 한꺼번에 뽑으면 블록 안의 토큰들이 서로를 모르는 상태로 나온다 각자 그럴듯한데 이어붙이면 문법이 어긋나는 후보가 생기고 이 헤드가 블록 내부의 앞뒤 의존성을 공급해서 후보 품질을 올린다.
  • 신뢰도 헤드: 각 드래프트가 검증을 통과할 확률을 미리 예측한다 가망 없는 후보를 스케줄링 단계에서 걸러내면 검증에 쓰는 계산을 아낄 수 있다. (vLLM에선 아직 작업중임 현시점기준)

드래프트를 MLA 네이티브로 만들었는데 본체가 하이브리드의 전체 어텐션 층에서 Gated MLA를 쓰는데 같은 어텐션 구조로 맞추어 KV 캐시 레이아웃으로 일치시켰따.

앞에서 만든 접두사 캐싱과 프리필/디코드 분리 환경에서 드래프트와 본체가 같은 캐시 관리 체계를 위해 돌아가게 하려는 것이다.

드래프트 모델을 아무렇게나 만들면 서빙 스택 통합에서 문제가 생긴다는 인식이다.

GB300 NVL72, 배치 1 기준

TP8   : 111 tok/s  →  331 tok/s
TP16  : 118 tok/s  →  370 tok/s   (약 3.14배)

투기적 디코딩의 이득은 **수용률(acceptance rate)**로 결정된다.

드래프트가 제안한 것 중 본 모델 검증을 통과하는 비율이고 보통 "한 스텝에 평균 몇 토큰을 확정했나"로 본다.

이 값이 1에 가까우면 드래프트가 계속 틀렸다는 뜻이라 이득이 없고, 오히려 드래프팅 비용만 더 든다.

K3에서 측정된 값은

코딩처럼 다음에 뭐가 올지 뻔한 작업  : 스텝당 약 4.73 토큰 수용
창작처럼 예측하기 어려운 작업        : 스텝당 약 2.61 토큰 수용

다음에 뭐가 올지 예측 가능한 작업일수록 드래프트가 잘맞고 코드는 문법과 관용구가 정해져있어 예측이 쉽고 창작은 그렇지 않다 자기 워크로드가 어느쪽인지에 따라 투기적 디코딩의 값어치가 크게 갈린다.

여기 미해결 지점이 하나 있는데 투기적 디코딩은 드래프트가 틀리면 되돌려야한다. KV 캐시는 뒤를 잘라내면 그만인데 KDA 요약본은 제자리에서 덮어쓰니까 잘라낼 수가 없다.

vLLM이 투기적 디코딩때는 다른 커널 경로를 쓴다고 명시하는데 이 제약과 관련이 있어보인다.


배포 #

실행 명령 #

vllm serve moonshotai/Kimi-K3 \
  --tensor-parallel-size 8 \
  --trust-remote-code \
  --load-format fastsafetensors \
  --enable-prefix-caching \
  --enable-auto-tool-choice \
  --tool-call-parser kimi_k3 \
  --reasoning-parser kimi_k3
  • --tool-call-parser kimi_k3: 모델이 내는 도구 호출 형식을 OpenAI 형식으로 변환한다. 없으면 모델은 도구 호출을 정상 생성하는데 하네스가 인식을 못한다. 증상이 에이전트가 도구를 안쓴다로 나타나서 모델 성능 문제로 오인하기 쉽다.
  • --reasoning-parser kimi_k3: 사고 토큰을 최종 응답에서 분리한다. 없으면 사고 과정이 답변에 섞여 나온다.
  • --enable-prefix-caching: k3는 이게 기본값으로 꺼져있다. 하이브리드 캐시 설계가 계속 바뀌는 중이라 명시적으로 켜야하고 앞에서 본 10배 가격차이를 생각하면 안켜고 돌리는건 비싼 실수다/
  • --load-format fastsafetensors: 2.8조 가중치를 올리는 시간이 무시할 수 없다.

투기적 디코딩 활성화 #

--speculative-config '{"model":"Inferact/Kimi-K3-DSpark","method":"dspark",
  "num_speculative_tokens":7,"attention_backend":"FLASHINFER_MLA",
  "draft_sample_method":"probabilistic","rejection_sample_method":"block"}'

통신 백엔드는 GPU 연결 방식에 맞춰 고르자

GPU 간 통신
  NVLink로 묶여 있으면   → flashinfer_nvlink_one_sided
  네트워크로 묶여 있으면 → deepep_v2

MoE
  TP > 1     → flashinfer_trtllm
  전문가 병렬 → deep_gemm_mega_moe

하네스는 모델을 감싸 도구를 주고 파일을 읽게하고 명령을 실행시키는 껍데기로 Kimi Code, Claude Code, Cline 같은것들이 해당한다 같은 모델이라도 하네스에 따라 성능이 달라지고 시스템 프롬프트, 도구 정의 형식, 컨텍스트 관리 방식이 다르기 때문이다.

체크 리스트, 주의점 #

도구 호출을 자기 트래픽으로 검증해야한다. vLLM 팀이 직접 경고한 항목으로 K3가 파서가 예상 못 한 형식으로 도구 호출을 뱉어 결과가 빈 채로 돌아오는 경우가 관측됐다. 같은 환경에서는 간단한 테스트는 잘 되지만 프롬프트와 실행에 따라 달라져 재현이 어렵고 더 위험하다 빈 결과를 감지해 재시도하거나 다른 경로로 넘기는 장치를 둬야한다.

사고 이력을 전부 되돌려야한다. K3는 자기가 앞에서 생각한 내용을 계속 들고가는 방식으로 학습되었다. 하네스가 과거 사고 내용을 다 안넘기거나 다른 모델로 진행하던 대화를 중간에 K3로 갈아타면 품질이 크게 불안정해진다. 공식 문서가 세션 중간 전환을 하지 말라고 권고한다.

과잉 자율성을 프롬프트로 막아야한다. K3는 오래걸리는 과제 위주로 학습되어 사소한 문제나 모호한 지시를 만나면 사용자에게 안 묻고 알아서 결정해버린다 경계를 지켜야 하는 애플리케이션이나 시스템 프롬프트나 AGENT.md에 제약을 명시해야한다.

평가할 때 잘림을 먼저 의심하라 K3는 답하기전에 아주 많이 생각하기에 벤치마크 점수가 낮게 나오면 틀린게 아니라 생성이 중간부터 끊긴 경우가 많다 사고예산을 올리며 max_tokens를 넉넉하게 잡고 끊겼는지 확인부터가 먼저다

비전 인코더는 그냥 복제를 한다. K3 비전 인코더의 헤드 크기가 12라 GPU 8장으로 균등하게 나눠진다 인코더가 1B 미만이고 본체가 약 2T 이므로 억지로 나눠 통신 비용을 만드느니 각 gpu에 복사해두는 편이 낫다는 판단이다.

챗 템플릿이 프로그램인 이유 #

작지만 가져다 쓸만한 결정이 하나 있다.

대부분의 모델은 요청을 일단 텍스트로 만든 다음 토큰으로 쪼갠다.

K3는 토큰시퀀스를 프로그램으로 직접 조립한다.

이유는 제어 토큰인데, 시스템 메시지, 사용자 메시지, 도구 정의 ,도구 결과를 구분하려면 특수한 표시가 필요한데, 텍스트를 거쳐 가면 사용자가 보낸 내용에 그 표시와 똑같은 문자열이 있을때 경계가 무너진다.

프롬프트 인젝션 관점에서도 이 설계가 더 안전한데 사용자 텍스트와 제어 표시가 같은 공간에서 만나지 않기 때문이다.


Agent Swarm and PARL #

에이전트가 도구를 순서대로 부르면 단계 수만큼 시간이 쌓인다.

앞에서 한 커널 최적화와 투기적 디코딩은 토큰 생성 속도만 올릴 뿐이고 도구 호출 왕복 자체는 못줄인다.

모델을 키워도 마찬가지다

병렬로 부르면 되는데, 하위 에이전트 역할과 순서를 사람이 미리 짜두는 방식은 확장성이 없다.

작동 원리 #

**PARL(Parallel-Agent Reinforcement Learning)**은 모델에게 하위 에이전트를 만들고 일을 나눠주는 기능을 주고, 그 사용법을 강화학습으로 가르친다.

작업 도착
  ↓
오케스트레이터 (학습되는 쪽)
  ├─→ 하위 에이전트 1 (동시에) → 도구 A, B
  ├─→ 하위 에이전트 2 (동시에) → 도구 C, D
  ├─→ 하위 에이전트 3 (동시에) → 도구 E, F
  └─→ 결과 취합

설계에서 중요한 선택 두 가지가 있다. 둘 다 무엇을 학습시키지 않을 것인가에 대한 결정이다

하위 에이전트는 학습을 시키지 않고 고정해놓고 오케스트레이션만 학습시킨다.

이 분리가 두 문제를 동시에 피할 수 있다.

  1. 공로 배분, 결과가 좋았을때 오케스트레이터가 일을 잘 나눈 덕인지 하위 에이전트가 잘 실행한 덕인지 구분할 수 없는데 이를 구분하게 해준다.
  2. 다른 하나는 학습 불안정성으로 열쪽이 동시에 바뀌면 서로에게 환경이 계속 변하는 셈이라 학습이 수렴하지 않는다.

병렬이 항상 좋다고 가정하지 않는다. 뒷 단계가 앞단계 결과를 받아야만 진행되는 작업도 존재한다

파일을 찾아야 그 파일을 고칠 수 있고 테스트를 돌려야 뭘 고칠지 정해지기에, 이런걸 억지로 나눠보내면 하위 에이전트들이 서로 모순되는 작업을 하거나 헛일을 한다.

그래서 PARL은 무조건 나누는 규칙을 박지않고 언제 무엇을 어떻게 나눌지 결과 피드백으로 배우게한다.

문제는 이 판단을 배우는 게 어렵다는 것이다. 순차로 처리하면 느리긴 해도 확실히 답이 나오는데

병렬로 나눴을 대 이득은 한참 뒤에 최종 결과로만 드러나고 그것도 가끔씩만 온다.

그러다 보니 학습이 안전한 쪽으로 쏠린다. 이게 장점도 되지만 너무 안전하게만 판단하는것도 또 문제다

그 결과가 serial collapse 이다. 병렬로 부를 수 있는 상황에서도 오케스트레이터가 판단 자체를 포기하고 그냥 하나씩 순서대로 부르는 현상이다.

정상: 이 작업은 순차여야 하니까 순차로 간다 -> 판단한 결과
실패: 판단을 안하고 항상 순차로 간다 -> serial collapse

병렬 기능을 줬는데 안쓰는게 문제이지 순차로 가는 것 자체가 문제인게 아니다

PARL이 푸는건 이 판단 능력을 어떻게 학습시키냐 이다.

K2.5 : 하위 에이전트 최대 100개, 조율 단계 최대 1500회, 시간 최대 4.5배 단축
K2.6 : 하위 에이전트 300개, 4000단계, 12시간 이상 연속 자율 실행 (보고 기준)

곁가지 발견 #

K2.5 보ㅓ고서에서 흥미로운 보고가 있었는데, 이미지 데이터로 강화학습을 돌렸더니 텍스트 성능도 같이 올랐다는 ㄱ점이다.

MMLU-Pro / GPQA-Diamnod가 개선되었다.

멀티모달을 넣으면 텍스트가 희생된다는 통념과 반대 성향으로 텍스트 시각을 끌어올리고 다시 텍스트를 다듬는 상호 강화라고 설명된다.

다른 가문과의 차이 #

긴 컨텍스트를 푸는 갈래

갈래대표 전략대표 모델얻는 것 / 잃는 것
그대로 정확히Full AttentionGPT, Claude 계열정확도 최상 / 컨텍스트 길이에 따른 메모리·연산 부담
압축한다KV 압축 + 선택적 AttentionDeepSeek-V2~V4메모리 절감 / 압축에 따른 정보 손실 가능
바꿔버린다State Space / Linear AttentionMamba2, RWKV, GLA긴 시퀀스에서 효율적 / 정밀한 검색 능력 저하 가능
섞는다Hybrid AttentionKimi K3, Qwen3.5효율성과 정확도 절충 / 설계·서빙 복잡도 증가

선형 어텐션이 연구 호기심에서 프론티어 프로덕션으로 졸업한 평가를 받는 이유다.

Kimi vs DeepSeek 같은 문제와 다른 답 #

둘 다 1M 컨텍스트를 싸게 만들려고 하는데 전제가 반대다

비교 항목Kimi K3DeepSeek-V4
어텐션KDA(선형) 다수 + Gated MLA 소수압축·희소 어텐션 교대
철학어텐션을 대부분 버린다어텐션은 지키되 압축한다
깊이 축AttnResmHC
옵티마이저Per-Head MuonMuon
규모2.8T / 896개 중 16개 활성1.6T / 49B 활성
1M 효율디코딩 약 6배, KV 75% 감소계산량 27%, KV 10%
  1. 1M 컨텍스트는 어텐션 구조를 바꿔야만 경제적이다.
  2. 층을 아주 깊게 쌓으려면 잔차연결을 손봐야한다.
  3. Muon과 4비트 QAT가 대규모 학습의 기본값이 되고있다.

반대로 갈린 지점도 있는데 시퀀스 축에서 한쪽은 바꾸는것, 한쪽은 압축하는것을 골랐다.

  • Kimi는 초점을 크기 상한과 에이전트로 라인업은 플래그십 하나, 로컬실행은 사실상 불가하다 특징은 서빙인프라도 공개
  • DeepSeek는 효율과 추론에 초점을 맞추고 플래그십 중심 라인업에 로컬실행은 어렵고 특징은 어텐션 압축 연구위주다
  • Qwen은 라인업폭에 초점을 맞췄고 0.8~2.4T 전구간 라인업이며 로컬실행에 강하며 파생 모델 생태계가 특징이다.

용어 정리 #

용어 정리 #

용어정의와 메커니즘
활성 파라미터 / 총 파라미터토큰 하나 처리에 참여하는 양 vs 메모리에 올려야 하는 양. 전자가 속도를, 후자가 하드웨어 요구를 결정
MLA키·값을 좁은 공간으로 압축해 KV 캐시를 줄이는 어텐션. K2 전 세대의 주력
KDAKimi Delta Attention. 고정 크기 요약본 + 델타 규칙(덮어쓰기) + 채널별 망각. KV 캐시가 사라지지만 정밀 검색이 약해 하이브리드로 씀
델타 규칙새 정보를 더하는 대신 현재 저장된 값과의 차이만큼 교정. 같은 항목에 다시 쓸 때 값이 뭉개지는 걸 막음
채널별 망각잊는 속도를 차원마다 다르게 설정. 오래 들고 갈 정보와 금방 버릴 정보를 구분
하이브리드 어텐션선형 어텐션 층과 전체 어텐션 층을 섞는 구조. Kimi와 Qwen 모두 3:1
Gated MLA하이브리드에서 전체 어텐션을 담당하는 층. MLA에 게이트 추가
AttnRes층의 결과를 그냥 더하는 대신 앞선 층들 중 필요한 것을 골라 섞는 방식. 초심층에서 신호가 묻히는 걸 막음
LatentMoE전문가 계산을 좁은 공간에서 수행해 가중치 읽기와 GPU 간 통신을 줄임
Quantile Balancing라우터 점수를 순위로 줄 세워 전문가 배정을 정함. 민감한 하이퍼파라미터를 제거
MuonClipMuon 옵티마이저 + QK-Clip. 어텐션 점수 폭주를 사전 차단해 초대형 학습의 loss spike를 막음
QK-Clip업데이트 직후 점수가 커질지 미리 보고 임계값을 넘길 것 같으면 가중치를 직접 축소
Per-Head MuonMuon을 어텐션 헤드별로 따로 적용
SiTU값의 크기를 통제하는 활성화 함수
QAT학습 중에 저정밀 연산을 흉내 내서 모델이 미리 압축 오차에 적응하게 함. 사후 압축보다 손실이 적음
MXFP4 / MXFP8값을 묶음으로 나눠 묶음마다 배율을 두는 저정밀 포맷. 최신 GPU가 하드웨어로 지원
어텐션 메타데이터어텐션 커널을 띄우기 전에 GPU에 넘기는 색인 정보. 각 요청의 시퀀스 범위, 캐시 블록 위치, 요약본 슬롯 등. 배치가 작으면 이 조립 비용이 커널 실행 시간보다 클 수 있음
접두사 캐싱여러 요청이 공유하는 프롬프트 앞부분의 계산을 재사용. 에이전트 워크로드에서 비용을 좌우
P/D 분리프리필(계산 병목)과 디코드(대역폭 병목)를 다른 서버에서 처리
MooncakeKimi의 서빙 플랫폼. P/D 분리 + 놀고 있는 자원으로 만든 캐시 창고 + 전역 스케줄러
Marconi 방식접두사가 두 번째로 관측될 때 캐싱. 한 번 쓰이고 마는 것이 캐시를 밀어내지 않게 함
투기적 디코딩가벼운 드래프트 모델이 여러 토큰을 제안하고 본 모델이 한 번의 순전파로 검증. 결과는 무손실. 가중치를 한 번 읽는 비용이 토큰 1개를 만들 때나 7개를 검증할 때나 같다는 점을 이용
MTP (다중 토큰 예측)학습 시 다음 토큰 여러 개를 동시 예측하게 하고 그 헤드를 추론 때 드래프터로 재활용. 별도 모델이 필요 없지만 자기회귀라 개수를 늘리면 드래프팅 비용도 같이 늘어남
블록 디퓨전토큰을 순서대로가 아니라 블록 단위로 한꺼번에 생성하는 방식. 드래프트 개수를 늘려도 비용이 평평
수용률드래프트 제안 중 본 모델 검증을 통과한 비율. 스텝당 평균 확정 토큰 수로 표현. 예측 가능한 작업일수록 높음
DSparkK3용 드래프트 모델. 블록 디퓨전 + 저랭크 마르코프 헤드 + 신뢰도 헤드. 단일 스트림 디코딩을 약 3배로
PARL오케스트레이터가 하위 에이전트에 일을 나눠주도록 강화학습으로 가르치는 방식. 하위 에이전트는 고정
serial collapse병렬로 나눌 수 있는 상황인지 판단하는 것 자체를 포기하고 항상 순차로 처리해버리는 학습 실패. 순차 처리가 옳은 작업에서 순차로 가는 건 정상이고, 판단을 안 하는 게 문제
하네스모델에 도구·파일 접근·명령 실행을 제공하는 껍데기. 같은 모델도 하네스에 따라 성능이 달라짐
스캐폴딩에이전트 작업을 감싸는 프롬프트·도구·루프 구조. 벤치마크 점수를 크게 좌우
AI/ow/kimi_deepdive.md