이건 DFlash나 EAGLE, n-gram, 별도의 드래프터(drafter)를 쓴 결과가 아니다. 두 시스템 모두 Qwen3.8 자체 내장 MTP를 사용했고, 각자 이 워크로드에서 측정된 최적의 깊이로 돌렸다. NInfer는 지원되는 최대 깊이인 5로, v100-skinny는 (QPN 덕분에) 7로 돌렸다.
재밌는 건 왜 동급 성능이 나오냐는 거다.
NInfer는 한 라운드를 19.9 ms에 처리한다. V100은 26.9 ms가 걸린다. 35% 더 느린 셈이다.
하지만 V100 시스템은 한 라운드당 5.89 토큰을 확정 짓는데, NInfer는 4.27 토큰이다. 38% 더 많다.
그러니까 라운드 속도가 느린 거랑 깊이가 깊은 게 거의 딱 맞아떨어지는 거다:
1.38 / 1.35 ≈ 1.02.
NInfer는 매 라운드마다 이기지만, v100-skinny는 라운드마다 더 유용한 작업을 뽑아낸다.
그 더 깊은 검증이 가능한 건 내가 짠 커널인 QPN 덕분이다.
내가 실제로 만든 것
V100에는 FP4 텐서 코어 명령어도 없고 FP8 텐서 코어 명령어도 없다.
QPN은 모델이 HBM에서 읽히는 동안 압축 상태를 유지하다가, 아주 작은 조각들을 Volta의 기존 텐서 코어가 처리할 수 있는 FP16 레지스터 형식으로 바로 번역해 버린다.
"모델을 먼저 FP16으로 역양자화"하는 거창한 단계 따위는 없다.
실제 Qwen3.8의 랭크별 형상에서, 이 카드들의 879 GB/s 읽기 전용 한계치를 기준으로 측정했을 때:
Path
Effective bandwidth
Measured read ceiling
QPN2 / NVFP4, M=1
679.5 GB/s
77%
QPN2 / NVFP4, M=8
619.8 GB/s
71%
QPN8 / FP8, M=1–4
~719 GB/s
82%
Native 4-bit lm_head
842.9 GB/s
96%
5090이랑 비교할 때 중요한 행은 M=8이다.
Volta의 텐서 명령어는 기본적으로 8행 타일에서 작동한다. v100-skinny는 k=7 추론 검증 라운드를 정확히 그 8행에 매핑하니까, 후보 토큰을 더 많이 확인하는 게 유독 저렴하게 먹히는 거다.
이게 핵심이다: Volta한테 Blackwell의 FP4 하드웨어를 줄 순 없지만, Volta가 가진 하드웨어에 맞춰 문제를 재구성할 수는 있다.
v1.0으로 여기까지 왔다. v1.1은 마지막 타협점까지 없앴다.
v1.0에서는 지원 안 되는 FP8 문제를 해결하려고 그 영역들을 NVFP4로 변환했다. Volta에는 그걸 실행할 경로가 없었으니까.
덕분에 V100에서도 최신 NVFP4 서빙이 가능해졌지만, 파생 체크포인트를 서빙해야 한다는 단점이 있었다.
v1.1은 그 FP8 영역들에도 진짜 SM70 실행 경로를 뚫어줬다. 이제 모델의 공개된 할당 상태를 그대로 유지할 수 있다:
published FP4 regions stay FP4 → QPN2
published FP8 regions stay FP8 → QPN8
activations → FP16
KV cache → FP16
그래서 체크포인트를 Volta에 맞추는 대신, 실행 엔진이 체크포인트에 적응하게 만든 거다.
왜 모델을 그대로 보존하는 게 중요한가
예전에 썼던 올-FP4 Qwen3.8 방식은 추론 디코딩에서 겉보기엔 끝내주게 보일 수 있었지만, 잘못된 이유 때문이었다. 모델을 훼손하니까 출력이 더 반복적으로 변했고, 반복적인 출력은 예측하기가 너무 쉽거든.
50개 항목 하드웨어 생성 테스트에서:
all-FP4 derivative
published mixed weights
Categories represented
1
12
Distinct names
4 / 50
50 / 50
Repeated brand entries
50
0
빠른 헛소리도 결국 헛소리다.
그래서 내가 합성 토큰/초(tok/s) 기록 하나 더 세우는 것보다, v1.1로 공개된 혼합 할당을 그대로 돌리는 게 훨씬 중요한 거다.
이건 GEMM 스크린샷이 아니라 서버다
이 결과에는 실제 27B 모델, 4-GPU 텐서 병렬 처리, 어텐션, 순환 상태, 네이티브 MTP, CUDA Graphs, 샘플링, 그리고 OpenAI 호환 엔드포인트가 전부 포함되어 있다.
이 작업을 하면서 완전히 별개의 SM70 관련 문제들도 몇 개 찾아냈다:
체크포인트의 FP8-KV 지시어가 Volta를 느린 스칼라 어텐션 경로로 보내버려서, 프로덕션에서는 FP16 KV를 씀.
SM70 드래프터(drafter) 기본 설정이 greedy/local-argmax 제안을 쓰는 대신 지 멋대로 자기 제안을 샘플링하고 있었음.
타겟 검증 경로에 불필요한 상태 동기화랑 복사가 덕지덕지 붙어 있었음.
선언된 최대 컨텍스트가 디코드 파티션 구조를 오염시키고 있었음.
이런 것들은 GEMM 벤치마크에서는 절대 안 보임. 모델 전체를 빠르게 돌리려고 할 때나 문제가 되는 거지.
65K 정도 되면 드래프터 단계가 하나 추가될 때마다 긴 KV 히스토리를 다 훑어야 하는데, k=7이 k=3보다 토큰을 거의 더 못 받아냄. 그냥 더 얕은 네이티브 MTP가 이기는 거임.
요청별로 깊이를 자동으로 고르는 건 나중에 할 일이고, 일단 지금 측정된 긴 컨텍스트 권장 사항은 k=7이 아니라 k=3임.
따로 말하자면, 이제 큰 컨텍스트 윈도우를 선언만 한다고 해서 짧은 요청에 부하가 걸리지 않음. 파티션 수정 덕분에, 측정된 짧은 컨텍스트 셀에서 --max-model-len 4096부터 262144까지 라운드 레이턴시가 0.25ms 이내로 일정함.
262K 전체 윈도우는 내 장비에서 메모리가 간당간당함. 244,608 토큰이 관찰된 두 메모리 프로필 모두에서 안정적으로 부팅되는 최대 설정임.
뻔한 주의사항들
GPU 4개 대 1개?
맞음. 이건 성능/가성비 결과지, 밀도 싸움에서 이긴 게 아님.
600달러짜리 컴퓨터?
아님. 내 V100 카드 4장이 가속기 하드웨어 값으로만 총 600 호주 달러 정도 든 거임. 서버, CPU, 램, 쿨링, 전기세는 별도임.
전력 효율?
절대 아님. 이거 300W짜리 데이터센터 카드임. 5090이 훨씬 쓰기 좋은 물건이지.
V100이 모든 면에서 5090을 바름?
아님. NInfer의 프리필(prefill)이 대략 4배는 더 빠를걸. 이 결과는 가중치 대역폭이 깡패인 단일 요청 디코드에 관한 거고, 거기선 구형 카드들도 비벼볼 만하다는 거임.
둘 다 같은 양자화 체크포인트 씀?
아님. Qwen3.8 베이스 모델은 같지만, 이건 '최고 시스템 vs 최고 시스템' 비교임. v100-skinny는 RadixArk가 공개한 혼합 체크포인트를 돌리고, NInfer 아티팩트는 Unsloth 기반임. 같은 가중치로 돌리는 인과 엔진 A/B 테스트라고 주장하는 거 아님.
추론 깊이 체리 피킹?
각 엔진은 이 워크로드에서 측정된 가장 좋은 네이티브 MTP 깊이로 보여준 거고, 레포에 깊이 조절이랑 원본 출력 다 들어있음.
왜 이걸 하냐고?
이제 27B 최신 혼합 FP4/FP8 모델을 약 600 호주 달러짜리 퇴역 V100 가속기 카드들로 대략 220 tok/s 단일 요청 디코드로 돌릴 수 있음.
그렇다고 V100이 5090보다 좋은 제품이라는 건 아님.
그냥 "최신 AI 돌리기엔 너무 늙었다"고 버려진 하드웨어들이 실리콘이 부족한 게 아니라 소프트웨어가 부족했던 거라는 뜻임.
5090은 양자화 포맷부터 네이티브 Blackwell 실리콘까지 NVFP4 지원을 다 받음.
~65K 라이브 컨텍스트 기준, 현재 V100에 맞는 설정은 k=3임: MTP 껐을 때 65.5 tok/s, k=7일 때 54.7 tok/s인 반면, k=3은 76.3 tok/s 나옴.
프리필(Prefill)은 동일 조건 아님: NInfer가 대략 4배 정도 더 빠름.
이번 맞대결은 같은 베이스 모델에 서로 다른 양자화 아티팩트를 쓴 거라, 동일 가중치 엔진 비교라기보다는 시스템 비교에 가까움.
V100 4장은 2017년산 데이터센터 하드웨어라 소음도 심하고 전력도 엄청 먹음. 이건 내가 숨기는 게 아니라 애초에 그게 포인트임.
Upstream credit: v100-skinny는 1Cat-vLLM을 기반으로 만들어졌고, 덕분에 SM70에서도 최신 vLLM과 FlashAttention을 쓸 수 있게 됐음. v100-skinny는 여기에 QPN2/QPN8 실행 아키텍처, 네이티브 혼합 체크포인트 로더/디스패치 경로, 그리고 리포에 설명된 SM70 서빙 수정 사항들을 추가한 거임.
주요 댓글
r/localllama
오래된 V100 하드웨어로 최신 5090과 대등한 성능을 구현해낸 기술적 성과에 대해 커뮤니티는 놀라움과 함께 직접 재현에 나서는 등 매우 뜨거운 반응을 보이고 있습니다.
91
너무 Claude 냄새가 나는데. 그래도 이게 작동한다면 대단하겠네. 예를 들어 3090에서도 같은 기술이 먹힐까?
8
3090은 이미 순정 vLLM으로 NVFP4 모델 돌릴 수 있어.
그냥 NVFP4 가중치에 0을 채워서 카드 bf16 엔진으로 돌리는 방식이지.
아주 잘 돌아가고, 딱히 새로운 것도 아님.
5
이런 커널 작업은 AI 도움 없이는, 아니면 적어도 내가 밀어붙인 속도로는 불가능했을 거야.
50
아니, 내 말은 게시물 자체를 말하는 거야.
그냥 네 방식대로 다시 써봐.
4
직접 쓴 글이라는 건 100% 가능함 (처음에 AI 사용 고지하는 데 3초 쓴 거 가산점 드림)
51
방금 V100 2개 더 샀으니까 한번 시도해 볼게. 흥미로운 작업이고 V100용 커스텀 커널도 마음에 들어. 좋은 라이선스 고마워.
안녕 클로드.
16
집에 4x V100 32GB 박스 있는데, 퇴근하고 시간 나면 시도해 보고 결과 알려드림. 이거 이론상 아무 NVFP4 모델에나 다 작동함?
8
압축 포맷이 달라서 생기는 문제들이 있음 (ModelOpt 혼합 FP8+NVFP4 vs 일반 compressed-tensors NVFP4). 일단 명시된 RadixArk 체크포인트가 QPN 커널로 제대로 라우팅되는 것만 보장할 수 있음. 간단한 수정일 테니 더 넓은 지원을 고려하기 전에 일단 이거부터 내놓고 싶었음.
12
진짜면 대박인데. V100은 5090 가격의 1/10 수준임.
11
이게 진짜라는 걸 증명하기 위해 더 어떤 자료를 제공해야 할지 모르겠네.
19
9
16GB V100은 여전히 싸지. 중국에서 파는 4x NVlink 보드에 4개 꽂으면 다른 dense 모델들도 엄청 빠르게 돌릴 수 있을 거임.
9
GCP에서 V100으로 약 12달러 정도 들여서 재현해 봤음. 커널 레벨에서 처리량 1% 오차 범위 내로 맞췄음. trunk QPN2 M=8: 620.5 GB/s (71%) vs 작성자님 619.8. lm_head M=1: 843.6 (96%) vs 842.9. QPN8 M=1: 718.2 (82%) vs 718.6. 측정된 읽기 한계치 875 GB/s vs 작성자님 879. Qwen3.8 서빙 시 decode 203.6 +/- 4.7 tok/s, 수락률 70.4%, 5.93 tok/round 나왔음. 추가 데이터 포인트: reasoning_effort를 설정 안 하면(템플릿 기본값) 똑같은 설정에서 166.7 tok/s, 55%로 떨어짐...
4
재현해 줘서 고마움! 100% 재현 가능하다니 정말 기쁘네!!! Qwen 3.8 기본값이 xhigh thinking이라서 성능 저하가 보이는 거임. 5090이랑 비교할 때는 thinking effort를 똑같이(medium) 맞췄음.