Qwen3.8-27B의 한계를 또다시 돌파함... Dflash2 적용으로 RTX 3090에서 138 tps 달성
I pushed Qwen3.8-27B limits again... Dflash2 - 134 tps on a RTX 3090
핵심 요약
RTX 3090에서 Qwen3.8-27B 모델의 추론 속도를 DFlash2와 룩업 기반 드래프팅 등으로 138 tps까지 끌어올렸습니다.
- 성능 최적화 — DFlash2 드래프팅 및 룩업 기반 드래프팅 도입으로 138 tps 달성
- 컨텍스트 처리 — 하이브리드 모델용 프리픽스 캐싱으로 긴 대화 응답 속도 대폭 개선
- 메모리 효율 — 64k 컨텍스트를 위한 할당기 수정 및 V2 러너 CUDA 그래프 최적화
- 배포 편의성 — Docker 지원 및 자동화된 모델 준비 스크립트 제공
수정: 제목에 134 tps라고 적었는데, 실제로는 138 tps임. 내 3090은 전력 제한을 250W로 걸어놨다는 점 참고해라.
3일 전에 RTX 3090용으로 개조한 Qwen3.8-27B 추론 엔진을 공개했었는데(단일 요청 82 tps, 피크 672 tps), 어제 업데이트로 단일 사용자 기준 약 114 tps, 64 동시 접속 시 약 1,000 tps까지 끌어올렸다.
오늘은 실제 채팅 프롬프트에서 기본 샘플링 기준 약 138 tps(기존 약 124 tps에서 상승), 64 동시 접속 시 942 tps(현재 스택에서 오늘 다시 측정함)를 찍었다. 그리고 진짜 만족스러운 건, 긴 대화에서 다음 턴으로 넘어갈 때 걸리는 시간이 23초에서 이제 1초 정도로 줄었다는 거다.
기존 구성:
- fp8 KV 캐시, lm_head + embed_tokens int8, fp16 순환 상태(recurrent state), int8 활성화 함수, 자체 출력 40k 드래프트 헤드를 갖춘 MTP-4 드래프트, GPTQ-int4 lm_head/MTP, split-KV 검증 어텐션, 샘플러 패치, 262k 컨텍스트용 KVarN
이번에 추가된 것:
- DFlash2 드래프팅. Inco가 이 모델 전용 블록 드래프터를 공개했는데(5개 레이어, 비자기회귀 패스 한 번으로 토큰 7개 예측 + 경로 선택기 포함), vLLM 메인 브랜치에는 아직 병합 안 된 PR이라 0.27.1 버전에 백포트했다. 그러면서 조용히 숨어있던 버그도 하나 잡았는데, 0.27.1은 온도(temperature)가 적용된 드래프트 로짓을 캐싱하는 반면 메인 브랜치는 원본을 캐싱해서, 0<T≠1일 때 검증 과정에서 잘못된 제안 분포를 사용할 뻔했다. 단계당 2.8 → 3.3 토큰으로 향상됨.
- 드래프터를 W4A16으로 재양자화함. bf16에서는 3.85GB라 24GB 카드에서는 오히려 손해(106 tps)였는데, 실제 트래픽에서 드래프터 자체 입력값으로 헤시안(Hessian)을 추출해 GPTQ int4로 돌리니까 1.19GB로 줄었고, 그리디(greedy) 수락 손실도 없어서 개이득임. python fetch_dflash2.py로 배포함.
- 룩업 증강 드래프팅(내 아이디어인데 이거 진짜 물건임). 블록 드래프터는 2,048 토큰 윈도우만 보지만, 긴 컨텍스트를 다루는 어시스턴트는 출력의 상당 부분을 이미 주어진 내용을 재현하는 데 씀. 문서 인용, 명령어 반복, 코드 유지하면서 문단 다시 쓰기 같은 거 말이다. 이런 토큰들은 드래프터가 볼 수 있는 범위보다 20k 토큰이나 더 앞선 프롬프트에 그대로 박혀 있음. 그래서 Triton 커널 하나가 요청의 토큰 기록을 훑어서 최근 생성된 6~12개 토큰이 이전에 어디서 나왔는지 찾고 그 뒤에 올 내용을 제안하게 만들었다. "모든 명령어 재현" 작업 시 단계당 토큰 +29%, 105 → 131 tps 향상, 일반 채팅에서는 +5%, 단계당 0.075ms 소요. 결과는 정확하고 그리디는 드래프트 분포를 읽지 않으며, 샘플링된 위치에는 점 질량(point-mass) q를 부여해서 거부 샘플러(rejection sampler)에 적합한 제안이 되도록 함.
- 하이브리드 모델용 프리픽스 캐싱. vLLM은 mamba/GDN 하이브리드 모델에서 이걸 선택 사항으로 둬서, 기본적으로는 채팅 턴마다 대화 전체를 다시 프리필(prefill)함. --mamba-cache-mode align 옵션을 켜면(마지막 캐시 블록 경계부터 순환 상태 재개) 24k 토큰 문서 기준, 2번째 턴부터 23초 걸리던 게 0.85~1.35초로 줄어들고 답변도 토큰 하나 안 틀리고 똑같이 나옴. 배치 모드에서도 효과는 엄청남: 5,820 토큰 시스템 프롬프트를 공유하는 64개 요청이 222초 → 16.9초(중앙값 지연 시간 95초 → 8초)로 단축됨. KV 풀의 약 14~16% 정도를 차지함.
- DFlash2를 적용한 64k 컨텍스트. 이건 할당기(allocator) 수정이 필요했음. vLLM은 하이브리드 모델의 KV 그룹 크기를 가장 작은 레이어 버킷에 맞추는데, 드래프터의 5개 슬라이딩 윈도우 레이어 때문에 타겟의 16개 어텐션 레이어를 20개로, 48개 GDN 레이어를 50개로 패딩해버림. 정작 문제가 아닌 레이어들을 패딩하느라 토큰당 메모리를 25%나 더 썼던 거임. 윈도우 그룹을 패딩하도록 바꿔서 토큰당 105 → 78 KB로 줄임. V2 러너의 CUDA 그래프 메모리도 명시적으로 바꿨는데, 업스트림에서는 0을 반환해서 설정한 --gpu-memory-utilization 위에 약 1.2GB가 추가로 얹히는 문제가 있었음.


