M3 Ultra에서 네이티브 DSpark MTP를 사용한 DeepSeek V4.1F Q4 성능 (40tps / 800tps)
DeepSeek V4.1F Q4 on M3 Ultra with native DSpark MTP (40tps / 800tps)
핵심 요약
M3 Ultra 환경에서 DeepSeek V4.1 Flash 모델의 추론 속도를 최적화한 커스텀 구현체 공개.
- 성능 최적화 — M3 Ultra의 하드웨어 특성에 맞춰 디스패치 및 커널을 최적화하여 추론 속도 대폭 향상
- DSpark 적용 — 멀티 토큰 드래프팅을 통해 디코드 단계의 처리량과 효율성 개선
- 디스크 KV 캐시 — 긴 컨텍스트 유지와 빠른 복원을 위한 체크포인트 및 캐시 관리 구현
- 정확도 유지 — 최적화 과정에서 연산 순서와 수학적 결과값을 원본과 동일하게 유지
DeepSeek V4.1 Flash를 에이전트 모델로 쓰는 건 맘에 들었는데, ds4에서 16 t/s로 돌리려니 실제 턴 하나 끝날 때마다 속 터져 죽는 줄 알았다. 레딧 형들이랑 m3 ultra 쓰는 사람들이 내 glm 53 flash 최적화 좋게 봐준 것 같길래, GLM 최적화하면서 배운 걸 V4.1 Flash에 적용해보려고 antirez/ds4를 포크 떴다. 배운 거 많이 써먹긴 했는데, 기대만큼 드라마틱하진 않더라.
스크린샷은 내 UI에서 실제로 91분 동안 돌아간 에이전트 턴이다: 101k 토큰 디코딩, 4.6M 토큰 프리필(캐시 히트 99.5%), 툴 콜 56번(오류 없음), 컨텍스트는 3k에서 127k까지 늘어남.
https://github.com/IngeniousIdiocy/ds4-v41-m3ultra#v41
업스트림 ds4랑 이번 브랜치 비교(같은 맥, Q4 가중치 기준):
디코드, 8k 컨텍스트: 16.6 → 31.3 t/s
디코드, 300k 컨텍스트: 14.0 → 28.3 t/s
프리필, 62k 프롬프트: 737 → 813 t/s
TTFT, 23k 시스템 프롬프트: 35.8 s → 31.1 s
디스크 KV 캐시로 동일 프롬프트 복구: 0.23 s
코드 작업 시 DSpark, 직렬 → 추론(speculative): 32.1 → 40.5 t/s
에이전트 턴 시 DSpark, 답변 단계: 31.3 → 41.3 t/s
그리디 디코드(greedy decode) 환경에서 DSpark를 켜든 끄든 업스트림이랑 출력값 바이트 단위로 똑같다. SHA-256 매니페스트랑 다시 돌려볼 수 있는 스크립트 다 레포에 올려놨음.
디코드: 모델이 토큰당 가중치를 14GB 정도 읽어 들인다. 700 GB/s 대역폭이면 디코드는 50 t/s 정도가 한계임. 업스트림은 16.6이었지. 성능 까먹던 주범은 matvec이 아니라 토큰당 수백 번씩 날아가는 자잘한 디스패치였다. 이제 모든 레이어를 하나의 커맨드 버퍼에 몰아넣음. Engram 로우 페치(row fetch)도 크리티컬 패스에서 빼서 워커 풀에서 돌리게 바꿨다. 384-expert 라우터도 9번 디스패치하던 거 한 번으로 줄임. 공유 expert gate+up+SwiGLU도 커널 하나로 합쳤다. BF16 반올림도 생성 커널 안에서 처리해서 불필요한 재반올림 디스패치 770개 정도 날려버림. 하이퍼 커넥션 예측도 프로젝션 커널 안에서 돌아가게 했다.
깊은 단계에서의 디코드: V4.1의 압축 어텐션은 전체 컨텍스트에서 레이어당 512개 블록을 뽑아 쓴다. 컨텍스트 길어질 때 속도 저하의 98%가 이 선택 과정 때문이었음. 이제 레이어는 자기 마스크가 허용하는 블록만 점수를 매기고, 허용된 인덱스를 로우당 한 번씩 압축한 뒤, 바운드된 radix select로 상위 512개를 뽑는다. 덕분에 300k 디코드도 8k 속도의 90%까지 나옴.
프리필: 프리필은 10%밖에 안 올랐는데, 사실 이게 한계임. 프리필은 연산량 싸움이라. 행렬 연산이 전체의 절반인데 업스트림 GEMM 커널이 이미 이론상 성능의 95~100%를 뽑아내고 있었거든. M3의 Metal GEMM이 이 정도 형태에선 23~24 TFLOPS가 한계고, 이걸 뚫어줄 Metal 4 TensorOps 경로는 M5 이전 하드웨어에선 막혀 있음. 그나마 10% 오른 것도 어텐션 코어랑 Engram 디스크 대기 시간, 그리고 자잘한 최적화 덕분이다. 이제 8k 청크마다 체크포인트를 저장해서, 긴 프롬프트도 처음부터 다시 안 돌리고 이어서 할 수 있게 바꿨다.
DSpark: V4.1은 자체 멀티 토큰 드래프터(drafter)를 쓴다. 이걸 켜면 디코드 단계가 matvec에서 6개 로우짜리 matmul로 바뀜. 그래서 목표가 직렬 t/s가 아니라 커밋된 토큰당 가중치 바이트 단위로 바뀐 거다. 6개 검증 로우는 Q8 프로젝션을 통해 가중치 스트림을 공유함. 6개 로우 전부 Engram 페치가 겹치게 만들었고, 검증 청크는 독립적으로 제출됨. 검증 속도가 블록당 177ms에서 112ms로, 가중치 대역폭은 213에서 337 GB/s로 뜀. 어드미션 컨트롤러는 내 GLM-5.3 브랜치에서 가져왔다. 요청당 실제 소요 시간을 측정해서 드래프터가 확신 없는 건 거르고, 드래프팅이 손해 보는 구간에선 알아서 뺀다. 그냥 켜두는 게 낫다. 온도(temperature) 0 초과일 땐 정확한 추론 샘플링(speculative sampling)을 수행함. 드래프터가 삑사리 나면 그냥 그 세션에선 DSpark 끄고 안전하게 간다.

