AI 모델을 직접 서버에 올려 쓰는 곳이라면, GPU 메모리를 가장 많이 잡아먹는 범인을 흔히 오해한다. 보통 모델 자체를 떠올리지만, 실제로는 "지금 대화 중인 사람들을 기억해 두는 메모장"이 더 무거울 때가 있다. 사용자가 늘수록 이 메모장 더미가 불어나, 어느 순간 모델 본체를 넘어선다.
STEPQuant는 그 메모장을 6비트로 압축한다. 선형 어텐션 계열 모델을 직접 서버에 올리고 동시 사용자가 많은 환경에서, 정확도는 사실상 FP32(32비트, 거의 무손실) 그대로 지키면서도 메모리를 눈에 띄게 줄였다. 논문이 제시한 가장 큰 절감폭은 68.7%인데, 이는 Qwen을 가중치 4비트(W4)·배치 512로 돌린 특정 조건의 값이고, 가중치·예약 상태 풀·KV 캐시를 더한 메모리를 기준으로 한 것이지 서버 전체 메모리가 아니다(부록 산정 기준이며 일부 구성요소와 할당 오버헤드는 제외). 쓸 수 있는 조건이 정해져 있다는 뜻이기도 한데, 그 이야기는 뒤로 미루자.
비결은 압축을 더 세게 한 데 있지 않다. 오차를 가려서 다뤘다. 기존 양자화가 주로 오차의 '공간' 문제, 즉 "상태의 어느 자리가 중요한가"에 집중했다면, STEPQuant는 거기에 '시간' 축, 즉 "이 오차가 얼마나 오래 남는가"라는 차원을 더했다. 이것이 이 기법의 핵심 기여다. 이 글은 그 시간 축을 따라간다.
지금 널리 쓰는 소프트맥스 어텐션은 주고받은 단어 조각(토큰)이 늘수록 과거 기록을 담는 'KV 캐시'가 함께 커진다. 반면 선형 어텐션(linear attention)은 과거를 전부 순환 상태(recurrent state) — 크기가 고정된 요약 메모장 하나 — 에 눌러 담아 이 문제를 비켜 간다. 문맥이 아무리 길어져도 메모장 크기는 그대로다. 이 메모장을 매 스텝 조금씩 지우고 새로 덮어쓰는 갱신 방식을 게이트 델타 규칙(gated Delta-rule)이라 하며, Qwen3.8-27B(이하 Qwen, 구조 이름 GDN)와 Kimi-Linear-48B-A3B-Instruct(이하 Kimi, 구조 이름 KDA)처럼 이 방식과 일반 어텐션을 섞은 하이브리드 모델이 최근 자주 나온다.
그런데 "고정 크기"라는 장점이 서버 운영 단계에서는 다른 병목으로 돌아온다. 동시에 들어오는 요청마다 자기만의 메모장을 따로 들고 있어야 하기 때문이다. 여기에 서빙 시스템이 미리 잡아 두는 여분 자리까지 더해지면, 문맥이 짧아도 동시 요청이 늘수록 메모장을 모아 두는 '상태 풀'의 메모리가 함께 불어난다. 실제로 공식 SGLang 배포 기준을 보면, Qwen의 FP32 상태 풀은 동시 요청 70개 지점에서 모델 본체(BF16 가중치)의 메모리를 넘어선다.
메모장을 가볍게 만드는 길이 양자화(quantization)다. 숫자를 더 적은 비트로 거칠게 반올림해 표현하는 압축법이다. 32비트로 적던 값을 6비트로 줄이면 자리는 확 줄지만 미세한 오차가 생긴다. 보통은 이 오차가 조금 쌓여도 모델이 버틴다. 그런데 상태를 그냥 균일하게 양자화하면 정확도가 무너진다. Qwen의 긴 생성 과제 평균이 FP32 80.60%에서 6비트 균일 양자화 45.04%로 반 토막 났다.
왜 유독 상태가 까다로운지는 가중치와 비교하면 또렷해진다. 모델 가중치는 한 번 찍어 두고 끝나는 사진과 같다. 올릴 때 한 번 양자화하면 추론 내내 그 값 그대로라, 오차가 한 장에 고정될 뿐 번지지 않는다. 반면 순환 상태는 매번 덧칠해 완성해 가는 초상화에 가깝다. 그런데 물감을 아끼려고 매번 희미한 색으로만 덧칠한다고 해 보자. 한 번의 희미한 붓질은 괜찮다. 하지만 그 위에 또 희미한 붓질을 쌓으면 결국 초상화 전체의 색이 바래 버린다. 답을 한 글자씩 만들어 내는 디코딩 스텝마다 상태를 갱신하고, 그 값을 다시 양자화해 저장하므로, 이번 스텝의 반올림 오차가 다음 스텝의 입력으로 되먹임되며 쌓인다. 양자화 오차가 누적된다는 건 바로 이 과정이다.
출발점은 하나의 관찰이다. 상태에 낀 오차라고 다 같은 무게가 아니다. 그 영향력은 서로 다른 두 축으로 갈린다. 얼마나 오래 남는가(시간), 그리고 얼마나 중요한 자리에 있는가(공간).
오래 살아남는 오차가 더 큰 문제를 일으킨다. 그러니 이런 '좀비 오차'가 생길 만한 곳을 집중 방어한다. 이 아이디어가 수명 인지 비트 배분(Lifetime-aware Bit Allocation)이다.
상태의 어떤 칸은 금방 덮어써져 사라지고, 어떤 칸은 오래 보존된다. 오래 사는 칸에 낀 오차는 수많은 디코딩 스텝에 걸쳐 끈질기게 영향을 남긴다. 수식도 같은 말을 한다. 상태를 갱신할 때, 새로 들어온 정보와 방향이 비슷한 오차는 금방 깎여 나가지만, 방향이 어긋난 엉뚱한 오차는 '잊는 비율'(게이트)에만 기대어 천천히 희미해진다(Proposition 1). 기억을 오래 붙드는 칸일수록 엉뚱한 오차가 좀비처럼 살아남는다. 측정도 이 그림을 그대로 그린다. 기억 칸을 일부러 거칠게 압축해 보면, 오래 붙드는 칸일수록 누적 오차가 더 컸다(Fig. 1(b)).
그래서 정해진 평균 비트 예산 안에서, 오차가 크고 오래 사는 단위에 비트를 더 몰아준다. 각 단위의 복원 왜곡과 그 칸이 기억을 평균 얼마나 오래 붙드는지를 함께 반영한 점수로 비트 폭을 고른다. 단위는 구조마다 달라, Qwen에서는 기억 칸(헤드) 하나 전체, Kimi에서는 키 행(key row) 하나가 된다. 끝내 압축이 안 되는 소수의 고위험 단위는 FP16 그대로 남겨 핀포인트(pivot)로 지킨다.
같은 크기의 오차라도 상태의 어느 자리에 있느냐에 따라 출력에 주는 충격이 다르다. 그래서 각 행이 최종 출력 오차에 얼마나 기여하는지를 행 영향 점수(row-impact score)로 매긴다. 검증은 단순하다. 키 행을 영향 순으로 나눠 한 묶음씩만 4비트로 떨어뜨려 보니, 영향이 큰 묶음일수록 퍼플렉시티(모델이 다음 글자를 얼마나 헷갈리는지, 낮을수록 좋음)가 더 나빠졌다.
관찰이 하나 더 붙는다. 상태 행렬에서 유독 튀는 큰 값이 행과 열(스프레드시트의 가로줄·세로줄) 양쪽에 동시에 나타난다. 한 축만 스케일을 맞춰서는 둘 다 담을 수 없다. 기존 LLM 양자화가 대개 큰 값이 한 축에만 몰린다고 보고 그 한 축만 겨냥하던 것과 갈라지는 지점이다. 이 패턴은 디코딩 2048스텝 내내 유지됐다. 그래서 행과 열에 각각 별도 스케일을 주는 키 행 인지 이중축 피팅(Key-Row-Aware Dual-Axis Fitting)으로 이어진다.
6비트 STEPQuant는 두 모델 모두 사실상 무손실인 FP32와의 차이가 소수점 둘째 자리에 그쳤다. 같은 6비트라도 균일하게 압축하면 정확도가 반 토막 나 사실상 다른 모델이 된다. 단순히 압축하느냐, 어디에 비트를 쓸지 가려 압축하느냐가 결과를 갈랐다.
| 설정(긴 생성 평균) | STEPQuant | 균일 양자화 | FP32 |
|---|---|---|---|
| 6비트 · Qwen | 80.59% | INT6 45.04% | 80.60% |
| 6비트 · Kimi | 61.47% | INT6 45.70% | 61.52% |
| 4비트 · Qwen | 80.51% | INT8 71.86% | 80.60% |
| 4비트 · Kimi | 58.52% | INT8 56.02% | 61.52% |
더 공격적인 4비트 예산에서도 STEPQuant는 두 배 비트를 쓴 균일 INT8을 앞선다. 다만 Kimi 4비트는 FP32와 약 3포인트 격차가 남는다 — 모든 조합에서 완승은 아니라는 뜻이다. 짧은 생성 과제에서는 4비트 STEPQuant가 FP32에 Qwen 0.15·Kimi 0.25포인트밖에 뒤지지 않았고, 가중치까지 4비트 AWQ로 누른 실전형 설정에서도 6비트 STEPQuant는 Qwen 0.05·Kimi 0.33포인트 차이에 그쳤다. 가중치를 압축할수록 상태가 메모리에서 차지하는 비중이 커지니, 상태 압축의 값어치는 이 조합에서 오히려 더 분명해진다.
효율도 여러 각도에서 확인된다. 6비트 STEPQuant는 순환 상태를 Qwen 5.03배·Kimi 5.08배로 압축하는데, 이 압축비(특히 Kimi 5.08배)는 실측 할당량이 아니라 저장 형식에 기반한 이론 계산값이다(부록 D). 같은 메모리 산정 기준(가중치·예약 상태 풀·KV 캐시 합산, 일부 구성요소와 할당 오버헤드는 제외)에서 Kimi의 메모리는 53.7% 줄었고, 상태 업데이트는 최대 2.91배 빨라졌다.
이 결과는 어떻게 가능했을까. 두 축이 서로를 보완하며 시너지를 낸 덕분이다. 구성 요소를 하나씩 떼어 본 실험(Qwen)에서, 시간·공간을 합친 STEPQuant는 4비트 84.72%·6비트 84.51%로 공간만(73.95%·80.19%)이나 시간만(12.87%·75.63%) 쓴 경우를 모두 넘어 FP32(84.61%)에 수렴했다. 어느 한 축만으로는 부족하고, 특히 시간 축만 홀로 쓰면 오히려 무너진다. 핀포인트 효과도 크다. Qwen 헤드의 1.39%만 FP16으로 지켰는데 4비트 3과제 평균이 6.70포인트, 6비트 AIME가 14.16포인트 올랐다. 전체의 1%대를 지켜 내는 투자가 정확도를 크게 끌어올린 셈이다.
온틀은 소기업과 1인 창업가의 반복 업무를 덜어 주는 AI 프로젝트 매니저(PM)를 파견하는 서비스다. 고객 수십 곳이 각자의 AI PM을 하루 종일 열어 두고 저마다의 기록과 대화 맥락을 들고 돌아간다. 비용을 아끼려 모델을 자체 호스팅하면, GPU를 잡아먹는 주범은 가중치가 아니라 동시 세션마다 따로 유지되는 상태 풀이 되기 쉽다. 신규 고객을 받을 때마다 "GPU를 한 장 더 사야 하나"를 고민하는 상황을 떠올려 보자.
만약 당신이 온틀의 CTO라면, STEPQuant 도입을 결정하기 전 세 가지 질문을 먼저 던져야 한다. 첫째, 우리 서비스는 정말 상태 풀 때문에 허덕이고 있는가. 서빙이 가중치에서 막히는지 상태 풀에서 막히는지부터 분리해 재야 한다. 동시 요청이 적어 저부하라면 우선순위가 낮다. 둘째, 우리가 쓰는 모델이 이 기술을 받는 구조인가. 게이트 델타 규칙 계열(GDN·KDA)이어야 하고, 검증도 Qwen·Kimi 두 모델에 한정돼 있다. 셋째, 모델을 바꿀 때마다 다시 보정해야 하는 부담을, 우리 트래픽 규모가 상쇄할 만큼 커졌는가.
세 질문에 모두 "그렇다"가 나올 때, STEPQuant는 "한 GPU에 고객 몇 명을 태울 수 있는가"의 천장을 올려 준다. 신규 고객을 받을 때마다 GPU를 늘리던 선택의 일부가 압축 설정으로 흡수될 여지가 생긴다. 다만 이는 설정 한 줄로 끝나는 일이 아니다. 뒤에 설명하는 보정과 커널 작업이 함께 따라온다.
실험의 핵심 질문은 하나다. 가중치는 고정한 채 상태 양자화만 바꾸면 품질이 얼마나 상하는가. 모든 설계가 이 질문을 깨끗이 분리해 재도록 짜였다. 평가는 Qwen과 Kimi를 NVIDIA A800 4장 위 SGLang에서 돌렸고, 기준선은 FP32 상태, 비교 대상은 균일 양자화 INT4/6/8이다. 과제를 긴 생성 7종과 짧은 생성 6종으로 나눈 것은 각각 긴 출력에서의 오차 누적과 짧은 출력에서의 손상을 따로 시험하기 위해서다. 짧은 생성 과제도 실제 생성된 답으로 채점했는데, STEPQuant가 겨냥하는 상황이 모델이 한 글자씩 스스로 뽑아내는 실제 서빙이기 때문이다. 가중치를 BF16과 4비트 AWQ 두 설정으로 돌린 것은 상태 압축이 가중치 압축과 함께 쓰일 때도 성립하는지 확인하려는 것이고, 보정에는 WikiText-2를 썼다(32개 구간, 각 2048토큰).
오프라인에서 모델을 돌리기 전에 한 번 정해 두는 것은 이중축 스케일이 아니라 비트 배분·FP16 핀포인트·행 영향 점수다. 이중축 스케일 자체는 매 디코딩 스텝마다 갱신된 상태에 맞춰 다시 계산한다. 행 스케일은 그 행의 현재 크기와 영향 점수를 함께 저울질하고, 열 스케일은 영향이 큰 행에서 생기는 복원 오차에 더 무거운 벌점을 주는 쪽으로 맞춘다. 큰 값 행에는 넓은 범위를, 중요한 행에는 더 고운 해상도를 주는 셈이다. 다만 이 스케일 피팅과 압축 저장은 별도 CUDA 스트림에서 돌려 디코딩 경로를 막지 않고, 디코딩 중에 상태를 풀고·갱신하고·내보내는 과정은 SGLang 커널 하나로 융합해 돌린다. 성능 이득의 상당 부분이 이 융합 커널에서 나오므로, 다른 서빙 스택을 쓴다면 커널 포팅 비용을 먼저 셈에 넣어야 한다.
자리를 어떻게 잡았는지도 짚어 둘 만하다. 기존 주류 양자화(SmoothQuant·OmniQuant 등)는 큰 값이 한 축에 몰린다고 보고 그 한 축만 겨냥했다. Mamba용 Q-Mamba(DSQ)가 가장 가깝지만, 행 영향 점수를 스케일 선택에 끌어들인 것이 결과를 갈랐다. 공간 피팅만 떼어 봐도 4비트 73.95%로, DSQ를 그대로 가져온 7.64%를 크게 앞선다. 혼합 정밀도 비트 배분 자체는 새롭지 않지만, 거기에 '메모리 수명'이라는 시간 축을 더한 것이 STEPQuant의 몫이다. 동시기 연구 DAMP가 어렵다고 규정한 8비트 미만 구간에서도 FP32에 근접했다.
남은 격차도 분명하다. Kimi 4비트의 열세가 있고, 구조와 비트 예산 조합에 따라 손실이 남는다. 평가가 게이트 델타 규칙 계열 하이브리드 두 모델에 한정돼, 다른 선형 어텐션 변종이나 순수 SSM에서도 같은 구조가 성립할지는 이 논문만으로 단정하기 어렵다. 보정에 WikiText-2를 썼으니 코드·수학처럼 분포가 다른 도메인에서 핀포인트 선정이 얼마나 일반화되는지도 더 지켜볼 대목이다. 압축한 값을 메모리에 촘촘히 붙여 담는 설계는 구현을 복잡하게 하고, 모델을 바꿀 때마다 재보정 부담이 남는다.
한 가지 덤도 있다. 상태를 균일 양자화로 떨어뜨리면 정확도만 무너지는 게 아니라 출력이 상한까지 늘어지는 과잉 생성이 나타난다. Kimi는 4비트 균일 양자화에서 AIME 평균 6만3400토큰, HMMT 6만4220토큰까지 뽑아 6만5536토큰 상한에 거의 닿으면서도 정확도는 0에 가까웠다. 답을 못 찾고 장황하게 맴도는 붕괴인데, STEPQuant는 이 함정을 비켜 간다.
이론상 조금 깎입니다. 다만 Qwen 기준 FP16으로 남기는 비율이 헤드의 1.39%에 불과해, 전체 압축률에 주는 영향은 미미합니다. 그 적은 비율을 지켜 내는 대가로 정확도가 크게 오르므로, 손익으로 보면 남기는 쪽이 이득입니다.
품질을 거의 양보할 수 없다면 6비트가 안전합니다. 두 모델 모두 FP32와의 차이가 소수점 둘째 자리에 그칩니다. 압축을 더 밀어붙여야 하는 상황이라면 4비트도 균일 INT8보다 낫지만, 특히 Kimi 4비트는 약 3포인트 손실을 감수해야 합니다. 모델·과제별로 소표본을 먼저 재 보고 정하는 편이 좋습니다.
상태 풀 병목은 문맥 길이가 아니라 동시 요청 수에서 옵니다. 메모장 크기 자체는 문맥이 길든 짧든 고정이라, 짧은 대화라도 동시 접속이 많으면 상태 풀이 불어납니다. 반대로 접속이 한산하면 문맥이 길어도 이 기술의 우선순위는 낮습니다.
대체 관계가 아닙니다. KV 캐시 양자화는 토큰 수에 비례해 자라는 소프트맥스 어텐션의 캐시를 겨냥하고, STEPQuant는 크기가 고정된 순환 상태를 겨냥합니다. 압축 대상 자체가 다르므로, 하이브리드 모델이라면 두 기법이 노리는 메모리 영역이 서로 겹치지 않습니다.