Kanana-2 SLM 개발기 뜯어보기
Kanana-2 SLM 개발기를 읽고 정리. 온디바이스 모델을 만드는 과정에서 30B에 통하던 레시피가 반복적으로 망가지는 지점들에 주목했다. tool call 평가에 대한 이야기는 별도 포스트로 분리.
Motivation
7월 28일 카카오가 Kanana-2 경량 언어모델을 공개하고 같은 날 개발기가 소개됐다. 공개 대상은 3B와 1.3B의 base 및 instruct 모델이고, 개발 과정에서 만든 0.9B는 글 안에서만 다뤄지는 것으로 보인다.
언론 기사들은 대체로 “작은데 성능이 좋다”에 머물지만, 개발기 본문에서 반복적으로 눈에 걸린 건 성능 수치 보다는 30B에서 잘 통하던 방법이 1.3B에서는 거의 매번 무너졌고, 그때마다 다른 처방이 필요했다는 서술이 네 번 정도 등장한다. 축소(scaling down)라기보다 재설계에 가깝다는 인상.
경량화가 같은 걸 작게 만드는 일이 아니라는 건 직관적으로는 알고 있지만, 그게 파이프라인의 어느 단계에서 어떤 형태로 되어야 하는지를 이렇게 구체적으로 적어둔 글은 드물어서 정리해두려고 한다.
Kanana-2 SLM의 학습 경로
1. Kanana-2-3B: from-scratch pre-training + distillation
3B는 TPU v5e 클러스터에서 MaxText 기반 자체 프레임워크로 from scratch 사전학습했다. 2-staged pre-training으로 1단계 7.5T, 2단계 2T 토큰을 학습했고 전 구간에 Muon optimizer를 적용했다.
하이퍼파라미터 탐색은 본 학습 스케일에서 learning rate를 직접 탐색하는 게 불가능하니 stage 1의 데이터 분포를 유지한 100B 토큰 규모의 proxy scale에서 후보군을 먼저 찾고, Token Horizon 스케일링 법칙으로 본 스케일에 옮겼다.
\[\mathrm{LR}^*(D_{\text{target}}) \approx \mathrm{LR}^*(D_{\text{proxy}}) \cdot (D_{\text{target}}/D_{\text{proxy}})^{-\beta}\]$D_{\text{proxy}} = 100\text{B}$, $D_{\text{target}} = 7.5\text{T}$, $\beta = 0.32$를 사용했다고 한다.
이후 GPU 클러스터로 옮겨 Megatron-LM 기반으로 distillation을 수행했고, YaRN으로 32K까지 확장한 long context 학습과 LR decay 구간의 mid-training 데이터 투입을 거쳐 Kanana-2-3B-Base가 나왔다.
teacher는 전 구간에서 Kanana-2-30B-A3B-Instruct-2601이다.
base, instruct, thinking을 각각 teacher로 놓고 비교한 결과 instruct가 가장 좋았다고 하는데, 사후학습된 모델을 teacher로 쓸 때 수학과 코드에서 이득이 크다는 최근 distilled pretraining 계열의 보고와 일치한다.
2. Kanana-2-1.3B/0.9B: cascade pruning & distillation
1.3B와 0.9B는 3B에서 깎아 만들었다. 3B → 2B → 1.3B → 0.9B로 단계적으로 pruning과 distillation을 반복하는 cascade 방식이다. 총 distillation 토큰 수를 동일하게 맞춘 조건에서 3B → 0.9B로 직접 압축하는 single-stage와 3B → 2B → 0.9B의 two-stage를 비교했고, two-stage가 학습 초기부터 끝까지 일관되게 앞섰다고 한다. 최종 파이프라인은 이 결과를 네 단계 cascade로 확장한다.
압축 방법 자체도 이전 세대와는 달라졌다. Kanana Nano는 Minitron 기반 structured pruning을 썼는데, 이번에는 Ministral 3에서 제안한 PCA 기반 hidden dimension pruning을 적용했다고 한다. 기존 index 기반 방식은 각 hidden dimension을 독립적으로 평가해서 representation이 여러 dimension에 걸쳐 형성하는 정보를 못 본다는 한계가 있었고, PCA로 global rotation matrix를 구해 회전 후 축소하는 방식으로 이를 보완했다.
소형화가 강제한 재설계
앞선 규모 축소 다음이 개인적으로는 흥미로운 지점이었는데, 공개된 개발기에서 “작은 모델이라 다르게 해야 했다”는 서술이 등장하는 지점을 모아보면 4 가지다.
첫째, catastrophic forgetting. SFT 단계에서 tool call 데이터를 넣자 이전 지식이 일부 사라지는 현상이 “매 순간” 관찰됐다는 표현이 나온다. 처방은 데이터를 한 번에 다 넣지 않고 tool call 비중을 낮게 시작해 점차 올리는 staged SFT였다고. 당연히 스케일이 큰 모델의 post-training 레시피에는 없던 단계다.
둘째, 가중치 병합의 간섭. 3B는 도메인별로 따로 RL을 돌려 expert를 만들고 병합하는 parallel-RL로 잘 학습됐다. 같은 방법을 1.3B와 0.9B에 적용하자 학습이 불안정해지고 성능 향상이 유의미하게 나타나지 않았다고 한다. 파라미터가 적을수록 병합 시 도메인 간 간섭과 가중치 충돌이 심해지기 때문이라는 설명이다. 결국 병합을 포기하고 여러 도메인을 동시에 학습하는 multi-domain RL(RLVR + generative reward model)로 방향을 틀었다.
두 가지 모두 모델이 작으면 여러 능력을 동시에 담기 어렵다는 현상을 다른 각도에서 확인한 것으로 보인다.
셋째, 데이터 노이즈에 대한 민감도. 한국어 long context 데이터 일부에 노이즈가 있었고, 그 영향이 작은 모델에서 더 크게 나타났다. 해당 데이터 비중을 줄이고 math, code, 영어를 늘려 재구성하자 RULER-32K에서 성능이 올랐다. 같은 데이터셋이 모델 크기에 따라 다른 품질로 작동하기에, 데이터 큐레이션이 모델별로 따로 가야 한다는 함의를 갖는다. (작을수록 더 꼼꼼히 봐야한다는 수고.. 역설적으로 잘만 큐레이션하면 data-driven으로 좋은 성능을 유의하게 가져갈 수 있다는 소리.)
넷째, 얼마나 깎느냐보다 어디를 깎느냐. 동일한 2B 규모에서도 hidden dimension, MLP intermediate dimension, attention head 중 무엇을 줄이느냐에 따라 회복 속도가 달랐다고 한다. attention head를 줄인 구조에서 저하가 가장 컸고, attention capacity가 제한될수록 주요 hidden representation을 보존하는 게 더 중요해졌다는 해석이 붙는다. layer를 줄이는 depth pruning은 block influence나 norm ratio 중 무엇으로 layer importance를 계산해도 동일 파라미터 규모의 width pruning을 이기지 못했다. 최종 파이프라인은 layer 32를 고정하고 폭만 줄이는 쪽으로 갔다고.
온디바이스 제약: Sliding Window Attention
성능과 별개로, 배포 환경이 아키텍처를 바꾼 대목도 짚어둘 만하다.
GPU 서빙은 메모리 대역폭이 넉넉하고 배치를 크게 묶을 수 있어 KV cache 비용을 흡수한다. 온디바이스는 그렇지 않아서 decode 속도가 사실상 매 토큰의 메모리 읽기량으로 결정되고, 문맥이 길어질수록 KV cache가 그대로 병목이 된다.
그래서 1.3B와 0.9B에는 SWA를 넣되, 모든 레이어를 SWA로 하면 window 밖을 참조할 수 없으니 full attention 레이어를 주기적으로 끼워 3:1로 교차 배치했다. 전체 레이어의 3/4에서 KV cache가 상수로 유지된다.
| Architecture | 2K | 8K | 32K |
|---|---|---|---|
| Full-only | 256MiB | 1024MiB | 4096MiB |
| SWA:Full = 1:1 | 192MiB (-25.0%) | 576MiB (-43.8%) | 2112MiB (-48.8%) |
| SWA:Full = 3:1 (채택) | 160MiB (-37.5%) | 352MiB (-65.6%) | 1120MiB (-72.7%) |
보도자료에 실린 “메모리 최대 72.7% 절감”이 여기서 나온 숫자로 이해했다. 문맥이 길수록 절감 폭이 커진다는 게 코어 메세지고, 그래서 온디바이스 long context 서빙에서 유의하다. window size는 1024를 채택했고, long context 확장 시 YaRN은 full attention 레이어에만 적용하고 SWA 레이어는 기존 RoPE를 유지한다.
Wrap-up
개발기에서 기술적으로 가장 인상적이었던 건 사실 위에 보다는, on-policy distillation의 KL 방향을 고르는 문단이었다.
forward KL과 reverse KL 중 뭐가 나은지는 흔한 질문이지만, 개발기의 질문은 이 단계 다음에 RL이 오고, RL의 성능 상한은 초기 policy가 탐색 중 정답을 얼마나 자주 발견하느냐에 달려 있다고 한다. reverse KL은 mode-seeking이라 분포를 미리 skew하게 만들어 엔트로피를 줄이는데, 그러면 RL이 쓸 탐색 여지를 선제적으로 깎는 것과 같다. 분포를 뾰족하게 하는 건 어차피 RL이 실제 reward로 더 정확하게 할 일이므로 forward KL로 teacher 분포의 커버리지를 넓게 유지하고 “탐색 여지가 남아 있는 시작점”을 만드는 데 집중했다는 것이다.
같은 논리로 rejection sampling도 하지 않았다. 실패한 trajectory야말로 exposure bias 교정 효과가 가장 큰 데이터인데, 성공 궤적만 남기면 학습 분포가 이미 잘 푸는 문제 쪽으로 bias된다는 이유다. 실제 최근 연구들의 경향에서 발견되는 것과 일치한다고 본다.
단계별 최적이 아니라 파이프라인 전체의 최적을 기준으로 판단하고 그 근거가 소개됐다는 점에서, 굉장히 실용적이고 개별 기법 나열보다 이런 문단에 흥미를 갖게 될 수밖에 없다고도 생각한다. 이런 규모의 사후학습,,을 현재 연구에서 흔하게 할 일은 아니지만 파이프라인을 설계하는 입장에서 참고할 부분이 많다.
Open Question
가중치 병합 간섭과 catastrophic forgetting가 정말 (구별되는) 다른 현상인가..? 둘 다 “작은 모델에 여러 능력을 동시에 담기 어렵다”의 발현으로 보이므로, 전자는 학습 시점에서 후자는 병합 시점에서 나타난다. 같은 원인이라면 solution도 하나로 통합될 여지가 있을 것으로 보인다.
출처: 더 작고 강해진 Kanana SLM 개발, 카카오 기술블로그, 2026.07.28