Split View: Hybrid SWA로 긴 컨텍스트 추론 최적화하기 — Xiaomi MiMo v2.5가 실제로 한 것
Hybrid SWA로 긴 컨텍스트 추론 최적화하기 — Xiaomi MiMo v2.5가 실제로 한 것
- 들어가며 — 같은 전장, 다른 무기
- Hybrid SWA란 무엇인가 — 지역 창과 전역 시선
- MiMo v2.5가 실제로 한 것 — 아키텍처
- 잠재력을 프로덕션으로 — KV 캐시 리팩터링과 스케줄링
- 마치며 — 정직하게 읽기
- 참고 자료
들어가며 — 같은 전장, 다른 무기
지난 양자화 글의 마지막 결론은 "다음 병목은 KV 캐시"였습니다. 긴 컨텍스트에서는 캐시가 가중치보다 커지고, 그래서 캐시를 더 적은 비트로 저장하는 KV 양자화가 다음 전장이라고 적었습니다. 이 글은 같은 전장을 다른 축에서 공격하는 이야기입니다. 양자화가 "KV 항목 하나를 몇 비트로 저장할까"라면, 오늘의 주제인 하이브리드 SWA는 "KV 항목을 애초에 몇 개나 들고 있을까"입니다.
계기는 Xiaomi가 공개한 MiMo v2.5 추론 최적화 글입니다. 글의 첫 문장이 문제의식을 정확히 요약합니다 — "강력하면서도 긴 컨텍스트 추론에 효율적인 모델"을 원하지만 "이 두 목표는 본질적으로 긴장 관계"에 있다는 것. 이 긴장을 아키텍처로 푸는 도구가 하이브리드 SWA입니다.
Hybrid SWA란 무엇인가 — 지역 창과 전역 시선
표준 어텐션에서는 모든 토큰이 앞의 모든 토큰을 봅니다 — 시퀀스 길이 N에 대해 연산은 N의 제곱, KV 캐시는 N에 비례해 커집니다. 슬라이딩 윈도우 어텐션(SWA) 은 각 토큰이 최근 W개 토큰만 보게 제한합니다. 그러면 층 하나의 연산은 N×W로 선형화되고, KV 캐시는 시퀀스 전체가 아니라 창 크기 W로 상한이 잡힙니다 — 시퀀스가 길수록 이득이 커집니다.
좋아지는 것은 두 가지이고, 나눠 보는 게 좋습니다. KV 항목이 줄면 메모리가 줄어 같은 GPU에 더 많은 동시 요청과 더 긴 컨텍스트를 태울 수 있고(용량 이득), decode는 메모리 대역폭에 묶여 있으므로 스텝마다 더 작은 캐시를 읽는 것은 곧 속도이기도 합니다(지연 이득). MiMo 글이 KV 압축을 "용량 차원(capacity-level)의 이득"이라 부르는 이유가 이것입니다 — 긴 컨텍스트에서 더 큰 상은 워크로드를 애초에 올릴 수 있느냐입니다.
문제는 SWA만으로는 창 밖 정보를 잃는다는 점입니다. 문서 앞머리의 이름을 뒤에서 정확히 되짚는 종류의 과제(이른바 needle-in-a-haystack)는 지역 창만으로 무너집니다. 그래서 최신 모델들은 SWA를 단독으로 쓰지 않고, 대부분의 층은 지역 창(SWA), 소수의 핵심 층은 전역 시선(풀 어텐션) 으로 섞습니다. 이것이 하이브리드 SWA이며, Mistral의 SWA에서 시작해 Gemma 3(로컬/글로벌 층 비율을 높이고 창을 짧게 유지)·GPT-OSS 등으로 이미 자리 잡은 설계입니다. 요지는 "지역성으로 비용을 깎되, 전역 층 몇 개로 장거리 의존성을 붙잡는다"입니다.
이게 왜 지금 중요하냐면, 컨텍스트가 수십만~100만 토큰으로 밀리면서 풀 어텐션 KV 캐시가 서빙 비용의 지배적 항목이자 병목이 됐기 때문입니다. 양자화가 이 문제에 대한 '숫자' 축의 답이라면, 하이브리드 SWA는 '아키텍처' 축의 답입니다.
MiMo v2.5가 실제로 한 것 — 아키텍처
글에 따르면 MiMo-V2.5-Pro는 70개 층 중 10개만 풀 어텐션, 나머지 60개가 SWA입니다(약 1/7만 전역). 슬라이딩 윈도우 크기는 128 토큰 — Gemma 3의 짧은 창 기조보다도 더 공격적입니다.
전체 70개 층
├─ SWA 60개 (각 토큰은 최근 128 토큰만 → KV는 창 크기로 상한)
└─ 풀 어텐션 10개 (전역 시선·장거리 회상 → KV는 시퀀스 길이로 증가)
이론상 상한: 연산 ≈ 1/7, KV 캐시 ≈ 1/7 (약 7.0배)
이 구성에서 글은 총 연산량이 풀 어텐션의 "약 1/7", KV 캐시 메모리도 "1/7에 가깝게" 떨어져 각각 약 7.0배 절감된다고 말합니다. 다만 이 7배는 아키텍처가 주는 상한(이론값)이지, 실측된 종단 속도 향상이 아니라는 점을 먼저 못박아 둡니다.
산수에 정직한 단서 하나. 10개 풀 어텐션 층은 여전히 O(N) 캐시를 들고 있으므로, 전체 KV는 대략 (60·W + 10·N) / (70·N)입니다. 시퀀스가 짧을 때는 1/7 근처도 아니고, N이 커져야 지역 항이 씻겨 나가며 비율이 10/70에 다가갑니다. 글이 "1/7에 가깝게"라고 말하고 이득이 시퀀스 길이와 함께 커진다고 강조하는 이유가 이것입니다 — 7배는 상수가 아니라 점근선입니다.
나머지 구성은 요즘 서빙 모델의 표준 조합입니다 — 희소 MoE(층당 평균 전문가 부하 약 0.85), 디코드를 가속하는 3층 MTP(Multi-Token Prediction). MTP는 아래에서 다시 나오니 한마디만 하면, 모델이 한 스텝에 여러 미래 토큰을 예측·검증해 수용률이 높으면 한 번의 순전파로 한 토큰보다 많이 나아가는 기법입니다(모델에 내장된 스펙 디코딩류 트릭). 전체 파라미터 수는 공개하지 않았습니다.
잠재력을 프로덕션으로 — KV 캐시 리팩터링과 스케줄링
여기가 이 글에서 제일 값진 부분입니다. 흥미로운 건 아키텍처 자체가 아니라(이제 흔합니다) 이 7배 "잠재력"을 실제로 회수하는 데 든 엔지니어링입니다.
- 이중 풀 KV 캐시 — 전통적 단일 풀은 모든 층에 O(N) 메모리를 잡아 SWA의 창 희소성을 살리지 못합니다. 그래서 풀 어텐션용 풀과 SWA용 풀을 분리하고, SWA 풀은 창 크기만큼만 잡아 저장을 O(W)로 강제합니다.
- SWA 인식 프리픽스 캐시 — 프리픽스 캐시는 "같은 토큰 시퀀스면 같은 KV"를 전제로 재사용하는데, SWA에서는 같은 시퀀스라도 KV의 꼬리 일부만 남았거나 아예 축출됐을 수 있습니다. 그래서 "꼬리 W개 토큰이 SWA 풀에 유효한 슬롯을 갖는지"까지 따지는 윈도우 안전 길이(window-safe length) 로 매칭 길이를 잘라냅니다. 대충 넘어가면 무효 슬롯을 읽어 조용히 틀립니다.
- 청크 프리필 — 긴 프리필을 16K 토큰 고정 청크로 쪼갭니다. 글은 프리픽스가 길수록 처리량이 급락한다고 정직하게 밝힙니다 — 프리픽스가 거의 없을 때 1배에서 1M 토큰 프리픽스에서 약 0.12배로.
- PD 분리 + EP 축소 — 프리필과 디코드를 분리 배치하고, SWA로 KV 캐시가 줄어든 덕에 전문가 병렬(EP) 크기를 절반으로 줄였습니다. 글은 이것만으로 종단 성능이 약 40% 개선됐다고 보고합니다(자체 측정치).
- MTP 프리필 지원 — 프리필에서 MTP를 안 켜면 초기 128 디코드 토큰의 예측 수용률이 바닥이었는데, 이를 고쳐 초기 0–128 토큰 2.3배, 128–256 토큰 1.5배 가속을 얻었다고 합니다(자체 측정치).
- 길이 버킷팅 + NUMA 튜닝 — 요청을 길이대로 버킷(0–64K / 64K–256K / 256K–1M)에 나눠 담고 NUMA 배치를 조정해, 배치를 균질하게 유지하고 메모리 접근을 로컬로 붙듭니다.
프로덕션 지표로는 서버측 KV 캐시 적중률이 평균 93%, 헤비 유저는 95% 이상이라고 밝힙니다. 모두 벤더 자체 보고 수치이며 재현 가능한 공개 벤치마크는 아닙니다. KV 캐시 효율 순위에서 자사 모델이 DeepSeek-V4 계열에 이어 2위라는 주장도 자체 랭킹입니다.
마치며 — 정직하게 읽기
먼저 진짜 좋은 점. 이 글의 값어치는 "우리가 빠르게 만들었다"는 자랑이 아니라, SWA를 프로덕션에 얹을 때 조용히 깨지는 지점을 드러낸 것입니다. 특히 프리픽스 캐시가 SWA에서 무효화되는 문제(윈도우 안전 길이)는 대부분의 홍보 글이 건너뛰는, 실무자에게 실제로 쓸모 있는 함정입니다. 아키텍처 이득(7배)이 시스템 엔지니어링 없이는 회수되지 않는다는 서사도 정직합니다.
긴 컨텍스트 서빙을 만든다면 가져갈 교훈은 모델이 아니라 체크리스트입니다 — KV 풀을 분리하고, 프리픽스 캐시 매칭을 윈도우 인식으로 만들고, 긴 프리필을 청크로 쪼개고, 프리필 직후 초기 토큰의 MTP 수용률을 다시 재라. 어느 것도 MiMo 전용이 아니며, 전부 순진한 SWA 배포가 조용히 이득을 잃는 지점입니다.
빠진 것도 분명합니다. 첫째, 품질 얘기가 통째로 없습니다. SWA는 정의상 창 밖 정보를 잃고 그래서 하이브리드가 존재하는 것인데 — 10개 전역 층이 그 손실을 얼마나 메우는지, needle-in-a-haystack이나 장거리 회상에서 128 창이 버티는지에 대한 수치가 하나도 없습니다. 128은 상당히 공격적인 창이라 더 궁금한 지점입니다. 둘째, 헤드라인 숫자는 대부분 벤더 자체 프로덕션 지표(93%, 40%, 2.3배)이지 독립 재현이 되는 벤치마크가 아닙니다. 7배도 실측이 아니라 상한입니다.
공정하게 짚자면, 이건 프로덕션 시스템 리포트입니다. 그러니 캐시 적중률이나 종단 개선 같은 자체 프로덕션 지표는 이 주장에 맞는 종류의 숫자이기도 합니다 — 학술 벤치마크가 아니라는 게 흠은 아닙니다. 진짜 공백은 시스템 숫자가 아니라 품질에 대한 침묵입니다.
그래서 지난 양자화 글과 결론이 같습니다. 양자화는 KV 항목의 비트 수를 줄이고, SWA는 KV 항목의 개수를 줄입니다 — 직교하는 두 축이라 겹쳐 쓸 수도 있습니다(창으로 좁힌 캐시를 다시 FP8로 저장). 그리고 두 축 모두, 종이 위의 절감은 자기 과제의 평가 셋에서 재보기 전까지는 잠재력일 뿐입니다. MiMo 글의 후반부 전체가 바로 그 "7배를 실제로 얼마나 가져오나"의 기록이라는 점이, 이 글이 주는 가장 솔직한 교훈입니다.
참고 자료
Optimizing Long-Context Inference with Hybrid SWA — What Xiaomi's MiMo v2.5 Actually Does
- Introduction — Same Battlefield, Different Weapon
- What Hybrid SWA Is — a Local Window and a Global View
- What MiMo v2.5 Actually Did — the Architecture
- Turning Potential into Production — KV-Cache Refactoring and Scheduling
- Closing — Reading It Honestly
- References
Introduction — Same Battlefield, Different Weapon
The last quantization post closed on one line: "the next bottleneck is the KV cache." In long context the cache grows larger than the weights, so storing it in fewer bits — KV-cache quantization — is the next front. This post attacks the same front from a different axis. Quantization asks "how many bits per KV entry?"; today's topic, hybrid SWA, asks "how many KV entries do we keep at all?"
The trigger is Xiaomi's published MiMo v2.5 inference writeup. Its opening line frames the problem precisely — they wanted a model "both powerful and efficient for long-context reasoning," but "these two objectives are inherently in tension." Hybrid SWA is the architectural tool for resolving that tension.
What Hybrid SWA Is — a Local Window and a Global View
In standard attention every token sees every prior token — for sequence length N, compute grows as N squared and the KV cache grows linearly with N. Sliding-window attention (SWA) restricts each token to the last W tokens. Now a layer's compute is linear at N×W, and the KV cache is capped by the window W rather than the whole sequence — the longer the sequence, the bigger the win.
Two things improve at once, and it helps to keep them apart. Fewer KV entries means less memory — you fit more concurrent requests and longer contexts on the same GPU (a capacity win). And because decode is memory-bandwidth-bound, reading a smaller cache each step is also more speed (a latency win). The MiMo writeup calls the KV compression a capacity-level benefit for exactly this reason — at long context the bigger prize is fitting the workload at all.
The catch is that SWA alone loses everything outside the window. Tasks that require pulling a name from the top of a document hundreds of tokens later (the classic needle-in-a-haystack) collapse under a purely local window. So modern models never use SWA alone; they interleave most layers as local windows (SWA) with a few key layers keeping a global view (full attention). That is hybrid SWA — a design that started with Mistral's SWA and is now settled practice in Gemma 3 (raising the local-to-global ratio and keeping the span short), GPT-OSS, and others. The thesis: shave cost with locality, but hold long-range dependencies with a handful of global layers.
Why this matters now: as context windows push into the hundreds of thousands and toward a million tokens, the full-attention KV cache becomes the dominant serving cost and the binding constraint. If quantization is the answer on the numeric axis, hybrid SWA is the answer on the architectural one.
What MiMo v2.5 Actually Did — the Architecture
Per the writeup, MiMo-V2.5-Pro runs 10 of its 70 layers as full attention and the other 60 as SWA (only ~1/7 global). The sliding window is 128 tokens — more aggressive than even Gemma 3's short-window stance.
70 layers total
├─ 60 × SWA (each token sees only the last 128 tokens → KV capped at window)
└─ 10 × Full (global view, long-range recall → KV grows with sequence)
theoretical ceiling: compute ≈ 1/7, KV cache ≈ 1/7 (~7.0×)
On this layout the writeup states total compute is "roughly 1/7" of full attention and KV-cache memory "drops close to 1/7," each a ~7.0× reduction. But note up front: that 7x is the ceiling the architecture grants (a theoretical figure), not a measured end-to-end speedup.
One honest nuance in the arithmetic: the 10 full-attention layers still keep an O(N) cache, so total KV is roughly (60·W + 10·N) / (70·N). For short sequences that is nowhere near 1/7; only as N grows does the local term wash out and the ratio approach 10/70. That is why the writeup says "close to 1/7" and stresses the advantage grows with length — the 7x is an asymptote, not a constant.
The rest is the standard serving-model kit — sparse MoE (average per-layer expert load ~0.85) and a 3-layer MTP (Multi-Token Prediction) to accelerate decode. A word on MTP since it recurs below: the model predicts several future tokens per step and verifies them, so decode advances more than one token per forward pass when acceptance is high — a speculative-decoding-style trick baked into the model. Total parameter count is not disclosed.
Turning Potential into Production — KV-Cache Refactoring and Scheduling
This is the most valuable part of the piece. What is interesting is not the architecture itself (now common) but the engineering it took to actually collect that 7x potential.
- Dual-pool KV cache — a traditional single pool allocates O(N) memory for every layer, so SWA's window sparsity is never realized. They split a Full pool from an SWA pool and size the SWA pool only for the window, forcing its storage to O(W).
- SWA-aware prefix cache — prefix caching reuses KV on the premise "same token sequence, same KV," but under SWA the same sequence may have only the tail of its KV left, or none at all. So matching is clipped by a window-safe length: the tail W tokens must still hold valid slots in the SWA pool. Skip this and you read invalid slots and are silently wrong.
- Chunked prefill — long prefills are split into fixed 16K-token compute chunks. The writeup is honest that throughput falls hard as the prefix grows — from 1x near zero prefix to about 0.12x at a 1M-token prefix.
- Disaggregated PD + smaller EP — prefill and decode are placed separately, and because SWA shrank the KV cache they halved the expert-parallel (EP) size. That change alone, they report, improved end-to-end performance by ~40% (their own measurement).
- MTP during prefill — with MTP off during prefill, the first 128 decode tokens had near-zero prediction acceptance; fixing that yielded 2.3× speedup over tokens 0–128 and 1.5× over 128–256 (their own measurement).
- Length bucketing + NUMA tuning — requests are bucketed by length (0–64K / 64K–256K / 256K–1M) and NUMA placement is tuned, keeping batches homogeneous and memory access local.
For production metrics they report server-side KV-cache hit rates averaging 93%, and 95%+ for heavy users. All of these are vendor self-reported figures, not reproducible public benchmarks. Their claim that MiMo ranks second in KV-cache efficiency behind the DeepSeek-V4 family is likewise their own ranking.
Closing — Reading It Honestly
First, the genuinely good part. The value here is not "we made it fast" but that it surfaces where SWA quietly breaks in production. The prefix-cache invalidation problem under SWA (the window-safe length) is exactly the kind of trap most marketing posts skip and practitioners actually hit. The narrative that the architectural win (7x) is not collected without systems engineering is honest too.
If you build long-context serving, the transferable lesson is the checklist, not the model — separate your KV pools, make prefix-cache matching window-aware, chunk long prefills, and re-measure MTP acceptance on the first tokens after prefill. None of these is MiMo-specific; all of them are where a naive SWA deployment silently loses the win.
What is missing is just as clear. First, there is no discussion of quality at all. SWA loses out-of-window information by definition — that is why hybrids exist — yet there is not one number on how well the 10 global layers recover it, or whether a 128 window holds up on needle-in-a-haystack or long-range recall. 128 is an aggressive window, which makes the silence louder. Second, the headline numbers are mostly vendor production internals (93%, 40%, 2.3×), not independently reproducible benchmarks. Even the 7x is a ceiling, not a measurement.
To be fair, this is a production-systems report, so self-reported production metrics like cache-hit rate and end-to-end gains are the right kind of number for that claim — not being academic benchmarks is not the flaw. The real gap is not the systems numbers but the silence on quality.
So the conclusion matches the last quantization post. Quantization shrinks the bits per KV entry; SWA shrinks the number of KV entries — orthogonal axes you can stack (store the windowed cache in FP8 on top). And on both axes, the savings on paper are only potential until you re-measure on your own eval set. That the entire back half of the MiMo piece is a record of "how much of the 7x can we actually collect" is the most honest lesson it offers.
References
- Xiaomi, "MiMo v2.5 Inference Optimization — Pushing Hybrid SWA Efficiency to the Limit" (source)
- Beltagy et al. (2020), "Longformer: The Long-Document Transformer" — the origin of SWA
- Gemma 3 Technical Report (2025) — local/global attention ratio and a short window
- Previous post — The State of LLM Quantization