Qwen3.8-27B에서 비트 단위의 추측 디코딩: RTX PRO 6000 한 장비로 초당 106 토큰
요약
본 글은 Qwen3.8-27B 모델을 RTX PRO 6000 한 장비에서 비트 단위의 추측 디코딩(speculative decoding) 성능과 정확성을 비교 분석한 기술 보고서입니다. Speculation 사용 시 vLLM이 높은 속도를 보였으나, SGLang의 수정된 커널 및 DeepGEMM 최적화를 통해 모든 조건에서 일관되고 정확한 토큰 ID와 logprob를 재현하는 것이 핵심 목표였습니다.
핵심 포인트
- SGLang은 Verify attention과 DeepGEMM 수정을 통해 추측 없이도 높은 정확도를 확보했습니다.
- 최종적으로 SGLang의 최적화된 커널을 사용했을 때, 106.6 t/s로 안정적인 디코딩 속도를 달성했습니다.
- Speculative Decoding 성능 비교 시, 엔진 자체의 표류(drift) 문제를 해결하는 것이 중요합니다.
- 프리필 단계에서 vLLM 대비 SGLang이 더 빠른 초기 토큰 생성 시간을 보여주었습니다.
이전 Qwen3.8-27B 디코드 속도 게시물에 대한 후속 내용입니다: https://www.reddit.com/r/LocalLLaMA/comments/1vuli3h/ 일부 분들이 레시피를 요청하셔서, 아래에 적었습니다. 그 게시물에서 '손실 없음(lossless)'이라고 했었는데, 저는 BF16 가중치와 BF16 KV를 의미했고, 이 부분은 유효합니다. 하지만 출력 결과는 추측을 사용하지 않았을 때와 일치하지 않았습니다. 텍스트가 아닌 토큰 ID를 확인했습니다. vLLM nightly, DFlash2 k=9 + XQA, BF16, temp 0, 한 번에 하나의 요청, 로드되었지만 사용되지 않은 LoRA, 24개의 프롬프트, 10,496개 토큰: 추측 사용 시 vs 미사용 시: 24개 중 15개가 다름 --max-num-seqs 1 vs 32, 추측 없음: 24개 중 21개가 다름 다른 어텐션 백엔드: 24개 중 20개가 다름 따라서 용량 설정(capacity setting)이 추측보다 더 많은 출력을 변화시켰습니다. 저는 그 이유를 찾지 못했습니다.
SGLang에서는 결정론적 모드만으로는 충분하지 않습니다. 추측을 사용했을 때도 24개 프롬프트 중 19개가 여전히 다른 토큰을 반환했고, 24개 모두가 다른 logprob를 가졌습니다. 두 가지 변경 사항을 검증하여 문제를 해결했습니다: Verify는 GDN 재귀(recurrence)를 디코드 커널을 통해 실행합니다. 이전 verify 커널은 상태(state)를 다른 순서로 타일링하고 beta를 fp32로 유지했습니다. Verify attention은 디코드 행으로, 드래프트 위치당 하나씩 실행됩니다. 이 두 가지 모두 적용했을 때, 24개 프롬프트 모두 추측 없이 일치했으며, 모든 토큰 ID와 모든 logprob가 일치했습니다. 마찬가지로 모든 드래프트를 거부하도록 강제(24/24) 했을 때도, 8개의 요청이 진행 중일 때도 (24/24), 그리고 최대 128k까지의 긴 프롬프트 3개에 대해서도 (3/3) 일치했습니다. 같은 결과를 반복적으로 얻으려면 DeepGEMM 수정(fix)도 필요합니다. 이것 없이는 배치 크기 8로 전송된 1,200개 요청 중 25개가 다르게 나왔고, 560740 토큰 길이의 단일 프롬프트는 실행의 515%에서 다르게 나왔습니다. 결정론적 모드도 느렸습니다: 추측 없이 18.0 t/s였는데, 기본값은 26.4였습니다. DeepGEMM의 sm120 bf16 커널은 작은 배치 크기에서 DRAM 대역폭의 약 3분의 1에 가중치를 읽어옵니다. 제 PR은 이 GEMMs를 동일한 비트를 제공하는 Triton 타일로 보냅니다: https://github.com/sgl-project/sglang/pull/42145 . 이것을 적용하자, 추측 없이 정확한 디코딩 속도는 27.7 t/s가 되었습니다.
토큰 디코딩(t/s), 단일 스트림, 온도(temp) 0, RTX PRO 6000 Blackwell Max-Q 한 장비 기준: 짧은 프롬프트 2.2k 토큰 128k 토큰 SGLang, 추측 없음(no speculation) 26.4 26.6 23.2 vLLM, DFlash2 k=9 + XQA (정확하지 않음) 109.8 67.4 56.1 SGLang deterministic + DFlash 8 + patches + my PR (정확함) 106.6 73.9 42.6 정확한 수치는 짧은 프롬프트에서 vLLM보다 3% 낮고, 2k에서는 앞서며, 128k에서는 24% 낮습니다. 프리필(Prefill)도 더 느립니다: 128k 프롬프트에 첫 토큰이 나오기까지 68.5초가 걸린 반면, vLLM은 44.3초가 걸렸습니다. 저는 이 비교가 필요합니다. 왜냐하면 작업 품질에 대해 양자화(quants)와 엔진을 비교하기 때문입니다. 만약 엔진 자체가 표류한다면(drifts by itself), 제가 테스트하는 변화와 그것을 구별할 수 없습니다. 레시피: Qwen/Qwen3.8-27B (1d4bf0f2, BF16). 초안(Draft): incoai/Qwen3.8-27B-DFlash2 (015e7956) SGLang main (542a043), 그리고 두 가지 검증 변경 사항과 PR #42145를 측정하여 적용했습니다 DeepGEMM 0.2.0 및 sm120 fence. 상위(upstream) 수정 사항은 https://github.com/sgl-project/DeepGEMM/pull/93 이며, 이는 10-03에 dev 브랜치에 병합되었고 아직 릴리스에는 포함되지 않았습니다 세 가지 패치를 적용 단계와 함께: https://gist.github.com/bill-h-lin/d2d48e99073dec4bfb81996a1440054f SGLANG_BATCH_INVARIANT_OPS_SMALL_M_TRITON=16 실행: python -m sglang.launch_server --model-path Qwen/Qwen3.8-27B
--enable-deterministic-inference --attention-backend triton
--speculative-algorithm DFLASH --speculative-draft-model-path incoai/Qwen3.8-27B-DFlash2
--speculative-num-draft-tokens 8 --mamba-ssm-dtype float32
--max-running-requests 8 --chunked-prefill-size 8192 --mem-fraction-static 0.88
--context-length 262144 --disable-radix-cache /u/stargate425가 제출함 [링크] [댓글]
AI 자동 생성 콘텐츠
본 콘텐츠는 Reddit AI Engineering의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기