SpecPilot이 배포 환경마다 추측 디코딩 병목을 스스로 찾아 10.87배까지 끌어올린다
SpecPilot: Autonomous Algorithm Discovery and Systems Optimization for Speculative Decoding
무엇인가
LLM 디코딩은 가중치를 읽는 메모리 대역폭에 묶여 있고, 추측 디코딩(speculative decoding)은 가벼운 drafter가 여러 토큰을 미리 던진 뒤 타깃 모델이 한 번의 순전파로 검증하는 방식으로 이를 가속한다. DFlash2·DSpark 같은 병렬 drafter는 8~16개 토큰 블록을 한 번에 초안하지만, 논문은 이들이 공개한 재현 시스템(stock)이 병렬 초안이 허용하는 속도 향상을 다 쓰지 못한다고 지적한다. 이유는 세 가지다. 단일 요청에서는 한 스텝에 받아들이는 토큰이 몇 개뿐인데도 타깃 가중치 전부를 읽어야 하고(측정된 23.61ms 스텝의 80%가 가중치 읽기), 배칭에서는 요청마다 attention·recurrent state·prefill 작업이 붙어 AR 대비 속도 향상이 대략 절반으로 줄며(FP8 Qwen3.8-27B에서 3.40배에서 1.89배로, 24요청), 최적화가 서빙 방식·drafter·타깃·GPU 조합마다 달라 보편해가 없다는 점이다.
어떻게 동작하나
SpecPilot은 이 배포별 최적화를 에이전트 루프로 자동화한다. 각 라운드는 비용 모델로 병목을 찾는 단계, 에이전트가 패치를 만들어 측정하는 단계, 보지 못한 요청으로 봉인 최종 평가를 하는 단계로 돈다. 비용 모델은 AR 대비 속도 향상을 S(N)=τ(N)/c(N), c(N)=T_step(N)/T_AR로 정의하고, 천장(ceiling)을 τ_best/τ · T_prof/T_floor · T_step/T_prof 세 인자로 분해한다. 각각 더 나은 트리가 받아들일 토큰의 여지, 커널이 바이트 하한(피크 대역폭 90%와 피크 dense 처리량 60% 중 큰 값)에서 얼마나 떨어졌는지, 프로파일 밖 오버헤드를 뜻한다. 매 라운드 가장 큰 인자가 다음 탐색 방향이 된다. 마스터 에이전트가 GPU별로 방향을 배분하고, 서브 에이전트가 옵션 뒤에 숨긴 패치로 구현하며, 에이전트가 수정할 수 없는 컨트롤러가 두 GPU에서 짝지은 실행(paired run)으로 이득의 95% 하한이 1% 더하기 잡음의 2배를 넘을 때만 승격시킨다. 출력이 기존 최선과 갈라지면 약 3%를 요구한다. 추가로 token forcing이 모든 출력 토큰을 stock과 통계적으로 대조해 보상 해킹(reward hacking)을 걸러내고, 검증된 메커니즘은 요구사항·코드 델타·증거와 함께 구조화 메모리에 저장돼 새 배포의 첫 라운드에 재사용된다(현재 140개 항목).
무엇과 다른가
루프가 찾아낸 것들은 다음과 같다. W12는 채널마다 가중치가 몰려 있는 16-binade 구간을 골라 부호 1비트, 지수 오프셋 4비트, mantissa 7비트로 12비트에 담고, 구간 밖 값·0·denormal은 채널별 sparse escape 목록으로 정확히 복원하는 무손실 포맷이다. 8개 dense 모델에서 평균 12.01~12.02비트/가중치로 압축되고 Qwen3.8-27B의 변환 레이어를 44.67GB에서 33.58GB로 줄인다. 핵심은 GEMM 커널이 레지스터에서 12비트 레코드를 디코드해 메모리 스트림 뒤에 디코딩을 숨긴다는 점과, stream-K로 결정적 GEMM을 유지한다는 점이다. H100에서는 LM head를 INT8과 Cauchy–Schwarz 오차 한계로 후보를 걸러내는 방식(878에서 482μs)으로 남기고, RTX PRO 6000에서는 그 방식이 더 느려서(2598 대 1750μs) W12로 변환한다. 하이브리드 타깃(Qwen3.8-27B는 64층 중 48층이 Gated DeltaNet)에서는 노드마다 recurrent state를 스냅샷하는 대신 경로별로 재계산하는 path verify 커널과, 수용된 경로를 48개 GDN 레이어에 재생하는 commit 커널을 쓴다. TreeWY를 따른 WY verify 커널은 rank-1 업데이트 체인을 행렬곱으로 바꿔 tensor core에서 모든 경로를 한 번에 풀고, FP32 상태를 BF16 세 조각으로 나눠 24비트 significand를 정확히 표현한다. TLV(two-level verification)는 W12 레코드 앞부분의 8비트 뷰로 Q pass를 돌려 드래프트 트리에서 일치하는 경로와 보너스 토큰을 얻고, 그 끝에서 다시 드래프트한 서브트리를 붙여 32노드 트리를 한 번의 exact pass로 검증한다. Q pass는 exact pass의 top-1과 98.7% 위치에서 일치한다. 배칭용으로는 요청 전체가 공유하는 노드 예산(FP8 24요청에서 192노드), 요청별 drafter 블록(16/12/8 위치), 프롬프트 편입(admission) 세 가지를 찾았다.
어떻게 쓰나
평가는 H100 SXM5와 RTX PRO 6000 Blackwell(sm_120) 두 플랫폼, 타깃 4종(Qwen3.8-27B, Muse-Glimmer-30B, Qwen3.5-4B, Gemma-4-12B), drafter 3종(DFlash2, DSpark, EAGLE-3), 벤치마크 5종(GSM8K, HumanEval, MATH500, MBPP, MT-Bench)에서 이뤄졌다. SGLang v0.5.20을 고정 빌드로 쓰고 에이전트는 Claude Code의 Claude Opus 5.5다. 학습 없이, 품질 손실 없이 AR 대비 속도 향상이 단일 요청에서 stock 4.46배에서 10.87배로, 배칭에서 1.94배에서 3.93배로 올라갔다. H100 단일 요청에서는 DDTree보다 1.84배 빠르다. 라운드별로는 1라운드가 best-first 트리로 270 tokens/s, 2라운드가 W12(짝지은 실행에서 1.076배로 승격), 3라운드가 TLV로 416 tokens/s에 도달했다. 비용 모델 없이 같은 설정에서 돌린 단일 에이전트 베이스라인은 3라운드 후 stock 대비 1.34배에 그쳤고, 스텝의 80%를 차지하는 타깃 가중치 읽기는 끝내 건드리지 못했다(SpecPilot은 2.13배).
전제와 한계
논문이 강조하는 실무적 발견은 같은 메커니즘이 서빙 방식에 따라 이득이 되기도 손실이 되기도 한다는 것이다. exact pass당 더 많은 검증 작업을 쓰는 메커니즘, 즉 넓은 트리·W12·TLV는 단일 요청에서 가중치 스트림이그 작업을 숨겨줘 이득이지만 배칭에서는 비용이 그대로 쌓인다. 24노드 트리는 FP8 타깃에서 14.9% 손실, BF16 Qwen3.8-27B에서는 24-position 블록이 9.9%, TLV가 13% 손실이었다. TLV의 Q pass가 스텝의 0.80~0.88을 차지해 손익분기하려면 토큰을 거의 두 배 받아들여야 한다. 반대로 행을 선택적으로 고르는 메커니즘은 배칭에서 이득이다. DSpark에서 공유 노드 예산은 같은 크기의 요청별 트리보다 6~14% 더 많은 토큰을 받아들였고, 요청별 drafter 블록은 1.040배, 대기 중인 프롬프트만 편입하는 것은 24요청에서 3.5%(비짝지음)를 얻었다.
저자들은 손실 여부를 태스크 정확도로 판정할 수 없다는 점도 실험으로 보인다. 2048 토큰 이후 7번째마다 vocabulary id에 logit bias 2를 더하는 결함 시스템 두 개와 무손실 시스템 두 개를 봉인 최종에 넣었을 때, Qwen3.8-27B의 정확도 변화는 무손실 -0.3점[-1.6, +0.7], 결함 -1.6점[-3.6, +0.3]으로 신뢰구간이 겹친다. 반면 token forcing은 무손실 두 개를 stock과 같은 수준의 불일치율(0.73%, 0.52% 대 stock 0.72%, 0.53%)로 통과시키고 결함 두 개를 2.0%, 2.4%로 거부했으며, 감사한 200개 큰 마진 이벤트 중 192개와 191개가 설명되지 않았다. 판정은 두 규칙을 쓴다. 불일치율이 95% 신뢰도에서 stock보다 0.5포인트 넘게 높으면 거부하고, 마진이 2δ를 넘는 사건이 stock보다 유의하게 많으면 이항 검정으로 거부한다. δ는 stock이 AR에서 처음 벗어난 지점의 최대 마진을 1/8 배수로 올림해 정한다. 참고로 stock도 커널 반올림 때문에 0.72%의 토큰에서 AR과 갈라지고, 첫 발산 지점의 log-prob 차이는 최대 0.232 nats다.
실무적으로 이 논문은 두 갈래로 읽힌다. 하나는 추측 디코딩을 쓰고 있다면 병목이 토큰 수용률인지, 가중치 바이트인지, 아니면 스텝 단위 가정인지를 τ/c 분해로 먼저 재라는 조언이다. 다른 하나는 W12가 추측 디코딩과 무관하게 쓸 수 있는 무손실 가중치 포맷이라는 점이다. SGLang에서 추측 없이 AR 디코딩만 해도 단일 요청 1.19~1.28배, 32요청 1.13~1.20배가 나오고, 가중치가 14~22% 줄어 Qwen3.8-27B에서 KV 풀이 2.0배, Muse-Glimmer-30B에서 2.5배 커진다. 저자들 주장으로는 H100에서 cuBLAS를 이기는 첫 무손실 포맷이며 1~32행에서 1.17~1.47배다. 다만 도입 전 확인할 것이 있다. 커널에 sm_120 이식이 필요한지(RTX PRO 6000에는 Hopper의 wgmma가 없다), 배칭 워크로드에서 넓은 트리와 TLV가 오히려 손해가 되지 않는지, LM head를 W12로 바꿀지 INT8 인증 헤드로 남길지는 GPU에 따라 답이 갈린다(메모리에 sm_120 전용 항목이 15개 있다는 점도 시사적이다).
한계와 전제도 분명하다. 손실 없음(lossless)의 정의 자체가 부동소수점 reduction 순서(GEMM 타일링, 트리 attention)에 따라 near-tie에서 토큰이 바뀔 수 있다는 것을 허용하며, 저자들은 이를 정적 검사 대신 token forcing이라는 통계적 검증으로 대체한다. 천장은 실측이 아니라 바이트 하한과 프로파일로 만든 추정치이므로 다음 라운드의 우선순위를 정하는 휴리스틱 이상이 아니다. 평가는 GPU 두 종류, 타깃 4종, drafter 3종에 한정되고, 서술된 상당수 튜닝은 특정 GPU·서빙 조합에서만 검증됐다. 메모리에 쌓인 140개 항목도 새 배포에서 다시 튜닝하고 재측정해야 하며 새 발견으로 치지 않는다. 결국 이 논문의 주장은 보편 최적화는 없다는 전제 위에서, 배포별 탐색을 자동화하면 사람이 손으로 하는 것보다 넓은 범위를 더 빨리 훑을 수 있다는 것이다.