DeepSeek-V4
DeepSeek-V4
이 문서는 DeepSeek의 차세대 Mixture-of-Experts 모델인 DeepSeek-V4를 SGLang으로 배포하고 호출하는 방법을 설명해요. 하이브리드 CSA + HCA 어텐션, 1M 토큰 컨텍스트, 세 가지 추론 모드를 갖추고 있으며 MIT 라이선스로 출시됐어요. 원문 페이지에는 하드웨어 플랫폼과 모델 변형을 골라 명령을 자동 생성해 주는 배포 Playground가 포함되어 있어요.
출처: 문서
본문
1. 모델 소개
DeepSeek-V4는 DeepSeek의 차세대 Mixture-of-Experts 모델로, 2026-04-24에 MIT 라이선스로 출시됐어요. 0731 Flash와 0813 Pro 리프레시는 번들 DSpark draft head가 포함된 체크포인트를 추가했고, 실험적인 Flash Vision 체크포인트는 0731 Flash 베이스 위에 이미지 이해 기능을 추가했어요:
| 변형 | 총 파라미터 | 활성 (MoE) | 용도 |
|---|---|---|---|
| DeepSeek-V4-Flash | 284B | 13B | B200 / B300 / GB200 / GB300 / H200 (TP=4)에서 단일 노드 서빙; RTX PRO 6000 (TP=2); H100 (TP=8) |
| DeepSeek-V4-Flash-0731 | 304 | 13B | Flash Official (0731), 번들 DSpark draft head 포함; 8×B200, 4×GB300, 4×H200에서 검증됨 |
| DeepSeek-V4-Flash-Vision-Exp | 305B | 13B | Flash Vision (Exp) — 실험적 멀티모달(image-text-to-text): 0731 Flash 베이스 + 비전 인코더 & aligner; 4×B200 (TP=4)에서 검증됨, preview build 필요 |
| DeepSeek-V4-Pro | 1.6T | 49B | 고용량: B200 / B300 (TP=8) · GB300 (TP=4) · H200 FP4 (TP=8) · GB200 (2-node, TP=8) · H200 FP8 (2-node, TP=16) · H100 (2-node, TP=16) |
| DeepSeek-V4-Pro-0813 | 1.65T | 49B | Pro Official (0813), 번들 DSpark draft head 포함; 4×GB300 (TP=4) · B200 / B300 / H200 FP4 (TP=8) · GB200 (2-node, TP=8) · H100 (2-node, TP=16) · MI355X에서 검증됨 |
Instruct 체크포인트는 FP4 MoE 전문가 + FP8 attention / dense로 제공돼요(하나의 혼합 정밀도 체크포인트가 모든 FP4 지원 GPU를 커버). 일치하는 *-Base 저장소는 순수 FP8 혼합으로 제공되며 추가 사전 훈련 전용이에요 — 채팅이나 도구 호출용이 아니에요.
하이라이트: 하이브리드 CSA + HCA 어텐션(1M 컨텍스트에서 DSv3.2 대비 약 27% 추론 FLOPs / 약 10% KV cache), manifold-constrained hyper-connections(mHC), Muon 옵티마이저, 1M 토큰 컨텍스트(32T+ 사전 훈련 토큰), 세 가지 추론 모드(Non-think / Think High / Think Max — Think Max에는 384K 이상의 컨텍스트 사용), 그리고 전용 encoding_dsv4.encode_messages Python 인코더 + DSML 도구 호출 문법.
권장 생성 설정: temperature=1.0, top_p=1.0.
리소스: HuggingFace · Flash Official (0731) · Flash · Flash Vision (Exp) · Pro · Pro Official (0813) · ModelScope · Flash · Pro
2. 설정 팁
동시성 & DeepEP dispatch 버퍼
반드시 성립해야 해요: max-running-requests × MTP_draft_tokens ≤ SGLANG_DEEPEP_NUM_MAX_DISPATCH_TOKENS_PER_RANK. 이를 위반하면 안정 상태 부하에서 DeepEP의 dispatch 버퍼가 넘쳐요(deep_ep.cpp:1105). 튜닝할 때는 --cuda-graph-max-bs-decode, --max-running-requests, 그리고 환경 변수를 함께 옮기세요.
명령 생성기는 현재 보수적인 쪽의 값을 선택해요(내부 스트레스 테스트 매트릭스를 반영). 기본 상태로 안전하게 실행되지만 처리량을 남겨둘 가능성이 크므로, 실제 워크로드의 피크 동시성에 맞춰 값을 올리고 결과를 보고해 기본값을 수정할 수 있게 해 주세요.
추측 디코딩
원래 Flash와 Pro 레시피는 EAGLE을 사용해요. Flash Official (0731)과 Pro Official (0813)은 번들 DSpark draft head를 사용해요. 실행 및 튜닝 노트는 DSpark를 참고하세요.
경고 DSpark head가 번들된 체크포인트에는 EAGLE을 사용하지 마세요. 0813에서
--speculative-algorithm EAGLE은 오류 없이 시작되고 서빙되지만, 바인딩된 draft head는 아무것도 받아들이지 않아요 — 모든 decode 배치가accept len: 1.00, accept rate: 0.00을 기록하므로 드래프트 비용을 내고도 속도 향상이 0이에요. 출력은 올바르게 유지돼서 눈치채기 어려운 것이 문제예요.--speculative-algorithm DSPARK로 전환하세요. 그러면 시작 로그가Draft checkpoint bundles a DSpark head를 보고해요.
원래 Flash와 Pro 체크포인트의 경우:
low-latency: steps=3, draft-tokens=4 → bs=1에서 가장 큰 이득.balanced: steps=1, draft-tokens=2 → 더 부드러운 MTP, 더 높은 배치에서 처리량 저하를 줄여요.high-throughput: MTP 비활성화 — 포화 상태에서는 verify 단계가 절약보다 비용이 더 커요.- MTP는 v2 추측 경로에서 실행돼요.
DGX Spark (2x GB10): Flash Official FP4 / NVFP4, Flash Vision FP4
DGX Spark 행은 세 개의 레시피를 가지며, 모두 Balanced · Multi-Nodes예요: Flash Official (0731) · FP4, Flash Official (0731) · NVFP4, Flash Vision (Exp) · FP4. 이 체크포인트는 128GB GB10 하나에 맞지 않으므로, 모든 레시피는 ConnectX-7(RoCE)로 연결된 두 개의 DGX Spark에 걸쳐 TP=2로 실행돼요. 그 외의 DGX Spark 조합은 의도적으로 회색 처리되어 있어요.
- Docker 이미지 — 세 셀 모두
lmsysorg/sglang:dev-v4f-2dgx-v2를 사용해요. 이는 DGX Spark 전용으로 만들어진 프리뷰 빌드(브랜치b12x-vision@452239a74f)로, SM12xb12xMoE(W4A8)와 compressed-MLA attention 커널, Flash Vision 모델 지원, Flash Vision이 SM12x에서 이미지를 서빙하게 하는 b12x image-prefill 수정, NVFP4 MTP-layer dispatch 수정, 그리고 GB10 쌍이 필요로 하는 CuTeDSL 및 NCCL 핀을 포함해요. 다른 하드웨어에서는 사용하지 마세요. 패널의 Docker 모드를 사용하세요 — 순수 Python 명령은 이 이미지가 제공하는b12x커널 패키지를 필요로 해요. - 두 Spark에 같은 명령을 실행하되
--node-rank 0/--node-rank 1과 ConnectX-7 링크로 노드 0을 가리키는--dist-init-addr을 사용하세요. 패널이 내보내는docker run플래그(--network host --ulimit memlock=-1:-1 --cap-add IPC_LOCK --device /dev/infiniband)는 NCCL이 RDMA를 사용하게 해줘요. 이것이 없으면 NCCL은 조용히 TCP로 폴백해 decode가 약 40% 느려져요. - 셀의 환경 변수는 레시피의 일부예요:
SGLANG_SM120_FLASHMLA_BACKEND=b12x는 b12x attention 경로를 선택하고,SGLANG_B12X_MAX_TOKENS는--chunked-prefill-size와 같아야 하며,PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True는 GB10의 unified-memory 단편화 OOM을 피해요. - NVFP4 (
nvidia/DeepSeek-V4-Flash-0731-NVFP4) — routed 전문가만 NVFP4이고, attention, 공유 전문가, DSpark MTP 계층은 체크포인트의 네이티브 형식으로 유지돼요. SM12x에서는 세 가지 추가 플래그가 필요해요:--moe-runner-backend flashinfer_cutlass(b12x의 MoE는 MXFP4 전용이고 trtllm-gen 커널은 sm100 전용),--speculative-moe-runner-backend b12x(DSpark draft의 MTP 전문가는 MXFP4이고 b12x에서 실행),--disable-shared-experts-fusion(HashTopK는 cutlass 러너에서 fused 공유 전문가를 거부). 처리량과 DSpark 수용률은 FP4 셀과 오차 범위 내에서 일치해요. - Flash Vision — 이미지는 Flash Official과 같은 플래그로 b12x 레시피에서 네이티브로 서빙돼요(
/v1/chat/completions에image_url콘텐츠 전송, Vision 참고); 텍스트 전용 요청은 변경 없이 동작해요. 이 체크포인트에서는 Flash Official보다 텍스트 처리량이 약 15–20% 낮을 것으로 예상하세요 — 번들 DSpark head가 더 적은 draft를 수용해요(약 3.2 대 3.9) — 텍스트 정확도는 그대로예요.
DeepSeek-V4-Flash-Vision-Exp (실험적)
deepseek-ai/DeepSeek-V4-Flash-Vision-Exp는 DeepSeek의 첫 실험적 멀티모달 V4 체크포인트예요: 0731 Flash 베이스에 비전 인코더와 aligner를 더한 것으로, OpenAI 스타일 image_url 입력으로 동일한 sglang serve 흐름을 통해 서빙돼요(아래 Vision 참고). 레시피를 보려면 Deploy 패널에서 Flash Vision 변형을 선택하세요.
- 프리뷰 빌드 필요 — 지원은 sglang #37253을 통해 제공되며 아직 릴리스에 포함되지 않았어요. Flash Vision 셀의 Docker 모드는 이미 프리뷰 이미지
lmsysorg/sglang:dev-dsv4-flash-vision을 내보내요. Python 환경에서는 해당 PR 브랜치에서 SGLang을 설치하세요. DGX Spark Flash Vision 셀은 예외로 DGX Spark 이미지lmsysorg/sglang:dev-v4f-2dgx-v2를 사용해요. - 검증 매트릭스 —
temperature 1.0,top-p 0.95,--reasoning-effort max로 sgl-eval을 통한 MMMU-Pro. - 엔진 자동 구성 — 엔진은 이 체크포인트에 대해
flashinfer_mxfp4MoE 러너를 선택하고 공유 전문가 퓨전을 자동으로 비활성화해요(HashTopK 라우팅이 fused 공유 전문가를 거부);--enforce-shared-experts-fusion을 전달하지 마세요. - Chunked prefill & radix cache 활성 유지 — 스케줄러는 이미지 스팬을 자동으로 일관되게 유지해요: chunked-prefill 절단 지점은 span 정렬(이미지 스팬은 항상 단일 extend 내에서 prefill되며, 최대 한 스팬만큼 chunk 예산을 초과)되고, 이미지 스팬 깊숙이 끝나는 radix-cache prefix 일치는 스팬 시작부터 다시 발행돼요.
- 추측 디코딩 — 체크포인트는 DSpark head를 번들하며, low-latency 레시피는
--speculative-algorithm DSPARK로 활성화해요(B200에서 MMMU-Pro 라운드를 통해 이미지 배치로 검증됨; 다른 하드웨어 행은 검증 대기 중). balanced와 high-throughput 레시피는 target-only로 동작해요: DP Attention을 사용하는데, DSpark는 현재 릴리스에서 호환되지 않아요. 0731/0813 체크포인트와 마찬가지로 EAGLE 플래그를 전달하지 마세요.
공유 전문가 퓨전 (Shared experts fusion, Blackwell, flashinfer_mxfp4)
Blackwell fp4 레시피(--moe-runner-backend flashinfer_mxfp4)에서 공유 전문가는 기본적으로 대체 스트림의 별도 FP8 MLP로 실행돼요. 다음을 추가하면:
--enforce-shared-experts-fusion
하나의 추가 MXFP4 전문가로 같은 trtllm-gen MoE 커널을 통해 라우팅되므로, 전체 MoE가 단일 스트림에서 실행돼요(MoE 계층당 커널 실행 약 4회, 스트림 동기화 2회 감소). 공유 전문가는 로드 시 FP8에서 MXFP4로 재양자화돼요. GB200 tp4에서 측정: gsm8k와 AIME25 정확도는 퓨전 없는 기준선과 동등, QPS 1-8에서 평균 TTFT -13%에서 -21%, P99 ITL -15%에서 -53%, 처리량은 중립.
전문가 병렬화가 없는 배포(예: 단일 노드 low-latency 레시피)에만 해당해요: moe_ep_size > 1이면 시작 시 플래그가 거부돼요(DeepEP/MegaMOE의 per-rank 공유 슬롯 경로를 사용 중이 아닌 한). Flash Vision (Exp)에는 적용되지 않아요 — 엔진이 해당 체크포인트에서 퓨전을 자동으로 비활성화해요.
압축 어텐션 상태 dtype
DeepSeek-V4는 장문 맥락 효율을 위해 하이브리드 압축 어텐션을 사용해요. SGLANG_DSV4_COMPRESS_STATE_DTYPE은 C4 / C128 압축 어텐션 상태 풀의 dtype을 제어해요. 지원 값은 float32 / fp32(기본값: float32)와 bfloat16 / bf16이에요. 오프라인 압축 경로에서 BF16을 쓰려면:
SGLANG_DSV4_COMPRESS_STATE_DTYPE=bf16 \
sglang serve \
--model-path deepseek-ai/DeepSeek-V4-Flash \
<other args>
이 BF16 설정은 압축 어텐션 상태 풀에만 적용되며 각 압축 상태 슬롯의 GPU 메모리 사용량을 줄여요. 모델 가중치 정밀도나 메인 KV cache dtype은 변경하지 않아요. 자동 풀 크기 조정과 명시적 용량 상한이 없으므로, 같은 메모리 예산으로 더 많은 슬롯을 보유할 수 있고 시작 로그에 더 큰 c4_state와 c128_state 풀 크기가 표시돼요. 가장 보수적인 동작은 기본 float32 설정을 유지하세요.
EPLB + Waterfill (실험적)
기록된/정적 EPLB 재현을 위해, 먼저 MoE 모델에서 전문가 선택 분포를 캡처하는 방법을 따라 전문가 분포 파일을 기록하세요. 재현 실행에서는 생성된 expert_distribution_recorder_*.pt를 초기 전문가 위치로 사용하세요. 이 기능은 최신 main 브랜치를 체크아웃하세요.
비-PD 재현:
--moe-a2a-backend deepep \
--deepep-mode auto \
--init-expert-location /path/to/expert_distribution_recorder_*.pt \
--enable-waterfill
PD-Disagg 재현은 prefill 서버에서 normal 모드, decode 서버에서 low_latency 모드를 사용하세요. 두 명령에 동일한 --init-expert-location 플래그를 추가하세요:
# prefill
--moe-a2a-backend deepep \
--deepep-mode normal \
--init-expert-location /path/to/expert_distribution_recorder_*.pt \
--enable-waterfill
# decode
--moe-a2a-backend deepep \
--deepep-mode low_latency \
--init-expert-location /path/to/expert_distribution_recorder_*.pt \
--enable-waterfill
EPLB 배치를 커스터마이즈하려면 --ep-num-redundant-experts와 --eplb-algorithm을 추가할 수도 있어요.
Waterfill은 MegaMOE도 지원해요. MegaMOE 백엔드를 유지하면서 fused 공유 전문가 슬롯에 Waterfill을 적용하려면 --moe-a2a-backend megamoe --enable-waterfill을 사용하세요.
FP4 Indexer (실험적)
DeepSeek-V4는 --enable-deepseek-v4-fp4-indexer가 설정되지 않는 한 기본 indexer 경로를 사용해요. 이 플래그를 활성화하면 실험적 FP4 C4 indexer를 사용해요. 이 경로는 indexer 캐시 대역폭을 줄이는 것이 유익한 decode 중심 장문 맥락 워크로드를 위한 것이에요.
**NVIDIA (SM100 / SM120)**에서는 플래그를 DeepGEMM FP4 indexer 지원 및 FlashInfer MXFP4 MoE 러너와 함께 사용하세요:
# Please use the latest main branch for this feature.
sglang serve \
--model-path deepseek-ai/DeepSeek-V4-Flash \
--tp 4 \
--moe-runner-backend flashinfer_mxfp4 \
--enable-deepseek-v4-fp4-indexer
**AMD MI355X (gfx95)**에서는 AITER FP4 indexer 커널을 ROCm에서 사용할 수 있어요. 표준 MI355 레시피를 유지하고 indexer 플래그만 추가하세요. --moe-runner-backend flashinfer_mxfp4를 전달할 필요는 없어요:
# Please use the latest ROCm image for this feature.
sglang serve \
--model-path deepseek-ai/DeepSeek-V4-Pro \
--tp 8 \
--attention-backend dsv4 \
--enable-deepseek-v4-fp4-indexer \
<other args from the Deploy panel>
NVFP4 하이브리드 체크포인트
nvidia/DeepSeek-V4-Pro-NVFP4와
nvidia/DeepSeek-V4-Flash-NVFP4 체크포인트는
MoE 전문가를 NVFP4로 양자화하고 attention 및 dense 계층은
FP8로 유지해요. 공식 릴리스는
nvidia/DeepSeek-V4-Flash-0731-NVFP4와
nvidia/DeepSeek-V4-Pro-0813-NVFP4에
일치하는 NVFP4 체크포인트를 제공해요.
이들 모두 제공되지 않으면 자동으로 선택되는 --moe-runner-backend flashinfer_trtllm_routed가 필요해요.
sglang serve \
--model-path nvidia/DeepSeek-V4-Pro-NVFP4 \
--tp 8
또는
sglang serve \
--model-path nvidia/DeepSeek-V4-Flash-NVFP4 \
--tp 8
Blackwell(SM100+)이 필요해요. 이 체크포인트의 MTP 계층은 MXFP4-packed로 유지되며 Mxfp4FlashinferTrtllmMoEMethod 경로로 자동 라우팅돼요.
공식(0731 / 0813) NVFP4 체크포인트는 번들 DSpark draft head를 보존하므로, low-latency 레시피는 해당 원래 정밀도 공식 체크포인트와 마찬가지로 EAGLE/MTP 형태 플래그 대신 --speculative-algorithm DSPARK를 사용해요.
Hopper (H100 / H200) 노트
Hopper에서 DeepSeek-V4를 실행하는 두 가지 옵션:
- 원래 FP4 체크포인트 — MoE 전문가를 W4A16 커널(Marlin 또는 FlashInfer SM90 CUTLASS 러너)로 실행하며, 명령 생성기가 Hopper 셀에 대해 선택해요. FlashInfer >= 0.6.18에서는 대신 W4A8 경로를 선택할 수 있어요 —
--moe-runner-backend flashinfer_mxfp4에--flashinfer-mxfp4-moe-precision fp8을 추가해 MXFP4 가중치를 FP8 활성화와 함께 FlashInfer의 Humming 커널로 실행. low-latency Hopper 셀은 이제 이 형태를 생성해요. 둘 다 H100과 H200에서 동작해요; FP4는 H100의 유일한 옵션(FP8 경로 없음)이에요. TP 전용이며, H200에서는 Pro 변형이 단일 8-GPU 노드에 맞지만 H100 Pro는 2노드(TP=16)가 필요해요. - 변환된 FP8 체크포인트 (H100 및 H200 전용) — 사전 리패키징된 FP8 가중치가 DP-attention + DeepEP와 더 풍부한 병렬화를 열어줘요(예: 2노드에 걸친 Pro TP=16).
이 FP8 체크포인트에서는 SM90에서 all-FP8 MegaMoE 경로를 추가로 활성화해 더 높은 장문 맥락/대형 decode 처리량을 얻을 수 있어요 — 아래 Configuration Tips의 SM90 (Hopper) FP8 MegaMoE 노트를 참고하세요.
PD-Disagg 레시피는 H200에서 docker run --privileged --ulimit memlock=-1(또는 --device /dev/infiniband:/dev/infiniband --cap-add IPC_LOCK)이 필요할 수 있어요. mooncake가 IB HCA를 발견할 수 있게 하기 위함이며, IB 노출이 없으면 mooncake는 조용히 TCP로 폴백해 대형 체크포인트에서 KV 전송이 왜곡될 수 있어요.
RTX PRO 6000 (SM120 / Blackwell Desktop) 노트
RTX PRO 6000 (96 GB)은 FlashInfer MXFP4 MoE 러너로 Flash 전용을 실행해요. V4-Pro는 8× 96 GB에 맞지 않아요; Deploy 패널은 지원되지 않는 레시피를 회색 처리해요. HiCache와 MegaMoE는 RTX PRO 6000에서 지원되지 않아요.
AMD (MI300X / MI355X) 노트
- 모델 체크포인트 — 정확한 정확도를 위해 FP4 모델은 원본
deepseek-ai/DeepSeek-V4-{Flash,Pro}를, FP8 모델은 리패키징된sgl-project/DeepSeek-V4-{Flash,Pro}-FP8을 사용해요. - 지원 모델 — MI300X는 FP8의 DeepSeek-V4-Flash를 지원해요; MI355X는 FP4와 FP8 모두에서 DeepSeek-V4-Flash / Pro를 지원해요. 모든 레시피는 단일 노드로 실행돼요.
- TP / DP 설정 (MI355X) — TP=4와 TP=8 모두 지원돼요. 낮은 동시성에서는 TP 전용을, 높은 동시성에서는 TP + DP(balanced / high-throughput 레시피)를 권장해요. 검증된 MI355X DP 레시피는 추가로
--dp 8 --enable-dp-attention --enable-dp-attention-local-control-broadcast --tokenizer-worker-num 8 --stream-interval 20 --prefill-decode-interval 10을 설정해요. - MTP — 원래 Flash / Pro 체크포인트의 추측 디코딩;
--speculative-algorithm EAGLE --speculative-num-steps 3 --speculative-eagle-topk 1 --speculative-num-draft-tokens 4를 추가하세요. 0813 Pro Official 체크포인트도 MTP head를 유지하므로, DSpark의 폴백으로 동일한 플래그를 사용할 수 있어요. - DSpark (MI355X Pro Official 0813) — 0813 체크포인트는 DSpark draft head를 번들해요. 일반 서빙에서는 0813에서 EAGLE보다 이를 선호하세요:
--speculative-algorithm DSPARK(low-latency)를 활성화하고 장문 맥락 경로는 MI355X agentic recipe를 참고하세요. DSpark는 PD disaggregation에서도 실행돼요 — §3.8의 Pro Official 쌍을 참고하세요. - 커널 — Unified KV attention과 flydsl MoE를 사용해요.
- FP4 indexer (MI355X) — 표준 ROCm 레시피 위에
--enable-deepseek-v4-fp4-indexer로 FP4 C4 indexer가 지원돼요.
MoRI EP (AMD expert parallelism)
AMD에서 전문가 병렬화는 DeepEP가 아닌 MoRI all-to-all 백엔드(--moe-a2a-backend mori)를 사용해요. GPU 간 전문가를 샤딩할 때 검증된 레시피 위에 아래 플래그를 추가하세요; --ep-size를 EP 정도(일반적으로 한 노드의 GPU 수)로 설정하세요.
두 가지 선택적 환경 변수가 MoRI 처리량을 개선해요(둘 다 기본적으로 꺼짐):
export SGLANG_MORI_DISPATCH_DTYPE=mxfp8
export SGLANG_MORI_RECV_BOUND=1
sglang serve \
--model-path {MODEL_PATH} \
--tp 8 --dp 8 --enable-dp-attention \
--ep-size 8 --moe-a2a-backend mori --deepep-mode normal \
<other args from the Deploy panel>
- FP4: 두 환경 변수 모두 활성화.
- FP8:
SGLANG_MORI_RECV_BOUND=1만 사용;SGLANG_MORI_DISPATCH_DTYPE=mxfp8는 생략.
MegaMoE
MegaMoE는 MoE 계층에서 더 높은 처리량을 위해 전문가 dispatch + GEMM을 단일 커널로 융합해요. 활성화하려면 아래 Playground의 MegaMoE 칩을 사용하세요 — playground가 --moe-a2a-backend deepep을 --moe-a2a-backend megamoe로 교체하고 관련 실행 설정을 자동으로 추가해요.
두 가지 변형이 제공돼요:
- W4A8 — 기본 MegaMoE 커널(FP4 가중치, FP8 활성화).
- W4A4 —
--enable-w4a4-mxfp4-megamoe를 추가해 커스텀 W4A4 커널(FP4 활성화)을 실행해요. 이 플래그는 필요한 DeepGEMM 설정을 구성해요. 무시할 만한 정확도 저하로 더 높은 처리량(Pro에서 약 89.5 GPQA).
참고:
- 위 W4A8 / W4A4 변형은 Blackwell 전용(B200 / B300 / GB200 / GB300)이에요. **Hopper (SM90, H100 / H200)**에서는 아래 설명된 all-FP8 MegaMoE 경로를 대신 사용하세요.
- MegaMoE는 Blackwell에서
high-throughput레시피에만 연결돼요.low-latency와balanced에서는 칩이 숨겨져요 — 노출하려면high-throughput으로 전환하세요. - MegaMoE 실행 시
--moe-runner-backend을 수동으로 설정하지 마세요. - 작업 부하와 메모리 사용량에 따라
SGLANG_OPT_DEEPGEMM_MEGA_MOE_NUM_MAX_TOKENS_PER_RANK를 조정하세요. MegaMoE에 더 많은 토큰을 설정하려면 더 많은 HBM 공간이 필요해요(high-throughput에 권장: 8320).
SM90 (Hopper) FP8 MegaMoE (실험적)
SM90(Hopper, H100 / H200)에서 all-FP8 MegaMoE 경로는 FP8 체크포인트에서 더 높은 장문 맥락/대형 decode 처리량을 위해 MoE를 DeepGEMM mega_moe 러너로 라우팅해요. 위의 Blackwell W4A8 / W4A4 변형과 달리 전문가는 FP8로 유지돼요 — SGLANG_DSV4_FP4_EXPERTS=0을 유지하세요. SM90 FP8 MegaMoE 지원이 있는 sgl-deep-gemm 빌드가 필요해요. 이 기능은 최신 이미지를 사용하세요.
--moe-a2a-backend megamoe로 MegaMoE 경로를 활성화하세요
SGLANG_OPT_DEEPGEMM_MEGA_MOE_NUM_MAX_TOKENS_PER_RANK=4096 \
SGLANG_DSV4_FP4_EXPERTS=0 \
sglang serve \
--model-path sgl-project/DeepSeek-V4-Flash-FP8 \
--tp 8 \
--moe-a2a-backend megamoe \
--chunked-prefill-size 4096
SGLANG_OPT_DEEPGEMM_MEGA_MOE_NUM_MAX_TOKENS_PER_RANK은 MegaMoE 경로가 랭크당(즉 GPU당) 처리하는 토큰 수를 제한해요; MegaMoE 경로는 이 상한 이하의 배치에만 사용돼요. 올바른 값은 병렬화/토큰 분할 방식에 따라 달라지며, 더 큰 값은 더 많은 HBM을 예약해요.
GB300 PD-Disagg 크로스-포드 MNNVL
NVLink 위의 크로스-포드 KV 전송이 있는 일부 GB300 클러스터에서 mooncake가 nvlink_transport.cpp:497 Requested address ... not found!로 실패할 수 있어요. 이 경우 prefill과 decode sglang serve 명령 앞에 MC_FORCE_MNNVL=1 NCCL_MNNVL_ENABLE=1 NCCL_CUMEM_ENABLE=1을 붙이세요.
3. 고급 사용법
3.1 추론 (Reasoning)
위 Playground의 Parsers 카드에서 Reasoning Parser를 토글해 deepseek-v4 reasoning parser를 활성화하면 추론을 reasoning_content와 content로 구분해 최종 답변과 분리할 수 있어요.
사고 과정이 포함된 스트리밍 (Python):
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:30000/v1",
api_key="EMPTY"
)
response = client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Flash",
messages=[
{"role": "user", "content": "Solve this problem step by step: What is 15% of 240?"}
],
max_tokens=2048,
extra_body={"chat_template_kwargs": {"thinking": True}},
stream=True,
)
thinking_started = False
has_thinking = False
has_answer = False
for chunk in response:
if not chunk.choices:
continue
delta = chunk.choices[0].delta
if getattr(delta, "reasoning_content", None):
if not thinking_started:
print("=============== Thinking =================", flush=True)
thinking_started = True
has_thinking = True
print(delta.reasoning_content, end="", flush=True)
if delta.content:
if has_thinking and not has_answer:
print("\n=============== Content =================", flush=True)
has_answer = True
print(delta.content, end="", flush=True)
print()
출력 예시:
We are asked: "What is 15% of 240?" This is a simple percentage problem. I need to provide a step-by-step solution. The user wants the solution explained step by step. I'll calculate 15% of 240: 0.15 * 240 = 36. I'll break it down into steps: understand what percent means, convert percentage to decimal or fraction, then multiply. I'll present the answer clearly. responseTo find 15% of 240, follow these steps:
**Step 1: Understand the meaning of percent**
"Percent" means "per hundred," so 15% means 15 out of every100, or \( \frac{15}{100} \).
**Step2: Convert the percentage to a decimal or fraction**
\( 15\% = \frac{15}{100} = 0.15 \)
**Step3: Multiply by the given number**
Multiply the decimal form by 240:
\( 0.15 \times 240 \)
**Step4: Perform the multiplication**
\( 0.15 \times 240 = 36 \)
**Answer:** 15% of 240 is **36**.
3.2 도구 호출 (Tool Calling)
위 Playground의 Parsers 카드에서 Tool Call Parser를 토글해 deepseekv4 tool-call parser를 활성화하면 message.tool_calls를 통해 구조화된 도구 호출을 노출할 수 있어요.
사고 과정이 포함된 Python 예시:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:30000/v1",
api_key="EMPTY"
)
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "The city name"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["location"],
},
},
}
]
response = client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Flash",
messages=[{"role": "user", "content": "What's the weather in Beijing?"}],
tools=tools,
extra_body={"chat_template_kwargs": {"thinking": True}},
stream=True,
)
thinking_started = False
has_thinking = False
tool_calls_accumulator = {}
for chunk in response:
if not chunk.choices:
continue
delta = chunk.choices[0].delta
if getattr(delta, "reasoning_content", None):
if not thinking_started:
print("=============== Thinking =================", flush=True)
thinking_started = True
has_thinking = True
print(delta.reasoning_content, end="", flush=True)
if getattr(delta, "tool_calls", None):
if has_thinking and thinking_started:
print("\n=============== Content =================\n", flush=True)
thinking_started = False
for tool_call in delta.tool_calls:
index = tool_call.index
if index not in tool_calls_accumulator:
tool_calls_accumulator[index] = {"name": None, "arguments": ""}
if tool_call.function:
if tool_call.function.name:
tool_calls_accumulator[index]["name"] = tool_call.function.name
if tool_call.function.arguments:
tool_calls_accumulator[index]["arguments"] += tool_call.function.arguments
if delta.content:
print(delta.content, end="", flush=True)
for index, tool_call in sorted(tool_calls_accumulator.items()):
print(f"Tool Call: {tool_call['name']}")
print(f" Arguments: {tool_call['arguments']}")
print()
출력 예시:
The user wants to know the weather in Beijing. I'll use the get_weather function with Beijing as the location. I don't need to specify a unit, so I'll just use the default. response
Tool Call: get_weather
Arguments: {"location": "Beijing"}
3.3 HiCache (계층형 KV 캐싱)
HiCache는 다중 계층 KV cache 오프로딩(GPU → CPU → Storage)을 가능하게 해, 장문 맥락 및 다중 턴 시나리오에서 효과적인 컨텍스트 용량을 크게 확장해요. UnifiedRadixTree와 결합해 모든 계층에 걸쳐 지능적 prefix 캐싱을 제공해요.
HiCache를 활성화하려면 위 Playground에서 HiCache 카드를 열고 Enable을 켜세요:
- L2 (GPU + CPU) — Storage를
auto(기본)로 두세요. 콜드 KV 페이지는 CPU 고정 메모리로만 넘쳐요. - L3 (GPU + CPU + Storage) — Storage 백엔드(
file/mooncake/hf3fs/nixl)를 선택하세요; Playground는 표준page_first_directmem-layout +directIO 백엔드 +wait_completeprefetch 정책을 생성해요. HiCache best-practices 레시피와 일치해요.
AMD 기기의 경우:
- L2 (GPU + CPU) — Storage를
auto(기본)로 두세요. 콜드 KV 페이지는 CPU 고정 메모리로만 넘쳐요.directIO 백엔드 +page_first_direct또는layer-firstmem-layout을 사용하세요. - L3 (GPU + CPU + Storage) — Storage 백엔드(
file)를 선택하세요; Playground는 표준page_first_directmem-layout +directIO 백엔드 +wait_completeprefetch 정책을 생성해요. HiCache best-practices 레시피와 일치해요.
Write policy 노브는 기본적으로 write_through(업스트림 기본값)이에요. 스토리지 계층이 느리면 write_back / write_through_selective로 전환해 내구성을 쓰기 속도와 맞바꿀 수 있어요.
자세한 내용은 HiCache 문서를 참고하세요. 호스트 계층을 완전히 건너뛰는 대안은 §3.9 UMBP를 참고하세요 — HiCache의 형제이지 스토리지 백엔드가 아니며, 둘을 함께 활성화할 수 없어요.
3.4 DSpark (추측 디코딩)
Flash Official (0731)과 Pro Official (0813)은 deepseek-ai/DeepSeek-V4-Flash-0731과 deepseek-ai/DeepSeek-V4-Pro-0813에 DSpark draft head를 번들해요. 따라서 target과 draft 가중치가 같은 체크포인트에서 오며, --speculative-algorithm DSPARK로 DSpark를 활성화하고 별도의 --speculative-draft-model-path를 설정하지 마세요.
실험적 Flash Vision 체크포인트도 DSpark head를 번들하며 같은 방식으로 활성화돼요: Flash Vision low-latency 레시피는 --speculative-algorithm DSPARK와 함께 제공돼요(B200에서 MMMU-Pro 라운드를 통해 이미지 배치로 검증됨; 다른 하드웨어 행은 대기 중). balanced와 high-throughput Flash Vision 레시피는 DP Attention을 실행하므로 target-only로 유지돼요.
원래 Flash 및 Pro 체크포인트의 EAGLE 레시피와 달리, 이 레시피는 --speculative-num-steps, --speculative-eagle-topk, --speculative-num-draft-tokens를 생략해요. SGLang은 DSpark 형태를 체크포인트에서 읽어요.
Deploy 패널의 Pro Official(0813) low-latency 속도 수치는
SGLANG_SIMULATE_ACC_LEN=4로 측정된 것으로, DSpark accept 길이를 정확히 4.00으로 고정해요. 제공된 레시피는 같은 엔진에서 4.678을 얻으므로, 이 행들은 약간 보수적으로 읽혀요. 해당 셀의 GSM8K 수치는 제공된 명령에서 나온 것이에요.
검증된 4×GB300 FP4 low-latency 명령:
sglang serve \
--trust-remote-code \
--model-path deepseek-ai/DeepSeek-V4-Flash-0731 \
--tp 4 \
--moe-runner-backend flashinfer_mxfp4 \
--speculative-algorithm DSPARK \
--mem-fraction-static 0.90 \
--chunked-prefill-size 4096 \
--swa-full-tokens-ratio 0.1 \
--host 0.0.0.0 \
--port 30000
이 토폴로지에서는 batch-256 verify 그래프를 위한 충분한 여유를 남기기 위해 --mem-fraction-static 0.90을 유지하세요. 첫 콜드 스타트는 FlashInfer autotune과 SGLang의 draft·verify 그래프 캡처로 10-15분 걸릴 수 있어요; 이후 시작은 캐시를 재사용해요. 이 경로는 4×GB300에서 SGLang v0.5.16으로 종단간 검증됐어요.
제안 draft 토큰 튜닝. --speculative-dspark-block-size N은 DSpark가 단계당 N개의 토큰을 제안하게 해요; target은 N + 1 창을 검증해요. 플래그를 생략하면 SGLang이 체크포인트에서 값을 읽어요. 0731과 0813 체크포인트 모두 5개의 제안 토큰으로 해석돼요(시작 로그가 gamma=5, verify_num_draft_tokens=6을 보고), 이것이 검증된 기본값이에요. Playground의 DSpark Proposed Draft Tokens 슬라이더로 1부터 5까지 스윕할 수 있어요.
더 큰 블록은 수용률이 높게 유지될 때 decode 지연 시간을 개선할 수 있지만, 검증 작업과 그래프 메모리도 증가해요. 체크포인트 기본값에서 시작한 다음 실제 프롬프트 길이와 동시성 분포에서 아래로 스윕하세요. 이득은 일반적으로 짧은 대화형 트래픽에서 가장 크고 prefill이 지배할수록 좁아져요. 수용률만으로 선택하지 말고 P50/P99 TTFT와 TPOT, 총 처리량, accept 길이, GPU 메모리, stop rate를 추적하세요.
각 후보에 대해 --speculative-algorithm DSPARK 없는 같은 레시피와 비교하세요. DSpark와 비추측 실행 사이에 서버를 다시 시작하고, 요청 코퍼스, 샘플링, 동시성, 워밍업을 동일하게 유지하며, 각 bench_serving 실행에 자체 --flush-cache를 주세요. 별도의 프로파일링 실행이 override를 정당화하지 않는 한 --speculative-draft-attention-backend는 설정하지 마세요.
DSpark는 pp_size == 1이 필요해요. Playground에서 prefill 또는 decode 역할을 선택하면 상속된 DSpark 플래그가 두 역할 모두에 유지돼요. DSpark를 실행하는 PD-disaggregated 구성의 경우 B200 agentic recipe와 MI355X Pro Official PD pairs를 참고하세요. MI355X Flash Official 레시피는 target-only로 실행되며, Deploy 패널의 DP-Attention 레시피도 마찬가지예요 — DSpark를 실행하는 DP-Attention 구성은 B200 agentic recipe와 MI355X agentic recipe를 참고하세요. 더 큰 draft 블록이나 동시성이 그래프 캡처 OOM을 유발하면 --mem-fraction-static, draft 블록 크기, 또는 최대 실행 요청 수를 낮춘 다음 성능 및 정확도 게이트를 모두 다시 실행하세요.
3.5 비전 (이미지 입력)
실험적 DeepSeek-V4-Flash-Vision-Exp 체크포인트(Deploy 패널의 Flash Vision 변형 — 설정 노트 참고)는 공개 URL 또는 base64 data: URI로 OpenAI 호환 image_url 콘텐츠 유형을 통해 이미지를 받아요. 텍스트와 이미지는 한 메시지에서 자유롭게 섞여요. 비전 입력은 Deploy 패널이 생성하는 동일한 서버로 동작해요 — 추가 모델별 플래그가 필요 없어요.
이미지 이해 (Python):
from openai import OpenAI
client = OpenAI(base_url="http://localhost:30000/v1", api_key="EMPTY")
response = client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Flash-Vision-Exp",
messages=[{
"role": "user",
"content": [
{"type": "image_url",
"image_url": {"url": "https://raw.githubusercontent.com/sgl-project/sglang/main/examples/assets/example_image.png"}},
{"type": "text", "text": "Describe this image in a few sentences."},
],
}],
)
message = response.choices[0].message
if getattr(message, "reasoning_content", None):
print("=============== Thinking =================")
print(message.reasoning_content)
print("=============== Content =================")
print(message.content)
출력 예시:
Pending update...
3.6 HiCache DRAM 오프로드가 있는 Agentic Long-Context (B200 FP4, DSpark)
TP8, concurrency 1–8:
python3 -m sglang.launch_server \
--model-path deepseek-ai/DeepSeek-V4-Pro-0813 \
--trust-remote-code \
--tp 8 \
--moe-runner-backend flashinfer_mxfp4 \
--enable-deepseek-v4-fp4-indexer \
--disable-flashinfer-autotune \
--mem-fraction-static 0.90 \
--swa-full-tokens-ratio 0.1 \
--chunked-prefill-size 8192 \
--tool-call-parser deepseekv4 \
--reasoning-parser deepseek-v4 \
--speculative-algorithm DSPARK \
--speculative-dspark-block-size 6 \
--enable-hierarchical-cache \
--hicache-ratio 2.75 \
--hicache-write-policy write_through \
--hicache-io-backend direct \
--hicache-mem-layout page_first_direct
DSv4 HiCache는 --hicache-ratio(host/device 토큰 비율)로 호스트 계층의 크기를 정하며 --hicache-size가 아니에요.
DEP8 (DP Attention), concurrency 64–160:
SGLANG_OPT_DEEPGEMM_MEGA_MOE_NUM_MAX_TOKENS_PER_RANK=8320 \
python3 -m sglang.launch_server \
--model-path deepseek-ai/DeepSeek-V4-Pro-0813 \
--trust-remote-code \
--tp 8 \
--dp 8 \
--enable-dp-attention \
--enable-dp-lm-head \
--ep-size 8 \
--moe-a2a-backend megamoe \
--enable-w4a4-mxfp4-megamoe \
--enable-deepseek-v4-fp4-indexer \
--disable-shared-experts-fusion \
--disable-flashinfer-autotune \
--mem-fraction-static 0.88 \
--swa-full-tokens-ratio 0.02 \
--chunked-prefill-size 49152 \
--tool-call-parser deepseekv4 \
--reasoning-parser deepseek-v4 \
--speculative-algorithm DSPARK \
--speculative-dspark-block-size 6 \
--enable-hierarchical-cache \
--hicache-ratio 8 \
--hicache-write-policy write_through \
--hicache-io-backend direct \
--hicache-mem-layout page_first_direct
--chunked-prefill-size는 --dp로 나눠지는 전역 예산이므로, 이 설정은 랭크당 6144 토큰을 유지해요.
분리형 1P1D (DEP8 prefill / DEP8 decode), concurrency 64–128. Prefill, 단일 8-GPU 노드:
SGLANG_DSV4_MHC_PREWARM=1 \
SGLANG_OPT_DEEPGEMM_MEGA_MOE_NUM_MAX_TOKENS_PER_RANK=9216 \
NCCL_MNNVL_ENABLE=1 \
NCCL_CUMEM_ENABLE=1 \
python3 -m sglang.launch_server \
--model-path deepseek-ai/DeepSeek-V4-Pro-0813 \
--trust-remote-code \
--tp 8 \
--dp 8 \
--enable-dp-attention \
--enable-dp-lm-head \
--ep-size 8 \
--moe-dense-tp-size 1 \
--moe-a2a-backend megamoe \
--enable-w4a4-mxfp4-megamoe \
--enable-deepseek-v4-fp4-indexer \
--disable-flashinfer-autotune \
--mem-fraction-static 0.85 \
--page-size 256 \
--swa-full-tokens-ratio 0.01 \
--chunked-prefill-size 65536 \
--tool-call-parser deepseekv4 \
--reasoning-parser deepseek-v4 \
--speculative-algorithm DSPARK \
--speculative-dspark-block-size 6 \
--enable-hierarchical-cache \
--hicache-ratio 8 \
--hicache-write-policy write_back \
--hicache-io-backend direct \
--hicache-mem-layout page_first_direct \
--disaggregation-mode prefill \
--disaggregation-transfer-backend mooncake \
--disaggregation-ib-device mlx5_0,mlx5_1,mlx5_2,mlx5_3,mlx5_4,mlx5_5,mlx5_10,mlx5_11
Decode, 두 번째 8-GPU 노드:
SGLANG_DSV4_MHC_PREWARM=1 \
SGLANG_OPT_DEEPGEMM_MEGA_MOE_NUM_MAX_TOKENS_PER_RANK=4096 \
NCCL_MNNVL_ENABLE=1 \
NCCL_CUMEM_ENABLE=1 \
python3 -m sglang.launch_server \
--model-path deepseek-ai/DeepSeek-V4-Pro-0813 \
--trust-remote-code \
--tp 8 \
--dp 8 \
--enable-dp-attention \
--enable-dp-lm-head \
--ep-size 8 \
--moe-dense-tp-size 1 \
--moe-a2a-backend megamoe \
--enable-w4a4-mxfp4-megamoe \
--enable-deepseek-v4-fp4-indexer \
--disable-flashinfer-autotune \
--mem-fraction-static 0.90 \
--page-size 256 \
--swa-full-tokens-ratio 0.02 \
--tool-call-parser deepseekv4 \
--reasoning-parser deepseek-v4 \
--speculative-algorithm DSPARK \
--speculative-dspark-block-size 6 \
--disaggregation-mode decode \
--disaggregation-transfer-backend mooncake \
--disaggregation-ib-device mlx5_0,mlx5_1,mlx5_2,mlx5_3,mlx5_4,mlx5_5,mlx5_10,mlx5_11
Router:
python3 -m sglang_router.launch_router \
--pd-disaggregation \
--prefill http://<prefill-host>:30000 8998 \
--decode http://<decode-host>:30000 \
--host 0.0.0.0 --port 8000
HiCache는 prefill 역할에서만 실행되며, 집계 레시피의 write_through가 아닌 write_back을 사용해요. --disaggregation-ib-device를 노드 자체의 외부 HCA로 설정하세요.
Concurrency 256은 2P1D — 두 개의 prefill worker, 각각 한 노드, 두 번째 --prefill로 router에 추가 — 를 사용하며, prefill에는 --swa-full-tokens-ratio 0.02, decode에는 --mem-fraction-static 0.91 --swa-full-tokens-ratio 0.005를 적용해요.
3.7 HiCache DRAM 오프로드가 있는 Agentic Long-Context (MI355X FP4, DSpark)
DeepSeek-V4-Pro-0813은 DSpark head를 번들하므로 --speculative-draft-model-path가 필요 없어요. --speculative-dspark-block-size 6은 커밋된 골든 커브에서 AL-최적 draft 길이예요(verify 창 7).
TP8, concurrency 1–16:
SGLANG_OPT_UNIFIED_CACHE_FREE_OUT_OF_WINDOW_SLOTS=1 \
SGLANG_USE_ROCM700A=0 \
TORCH_BLAS_PREFER_HIPBLASLT=1 \
SGLANG_HACK_FLASHMLA_BACKEND=unified_kv_triton \
AITER_BF16_FP8_MOE_BOUND=0 \
SGLANG_OPT_USE_AITER_BATCHED_GEMM=1 \
python3 -m sglang.launch_server \
--model-path deepseek-ai/DeepSeek-V4-Pro-0813 \
--trust-remote-code \
--tp 8 \
--prefill-decode-interval 20 \
--attention-backend dsv4 \
--enable-deepseek-v4-fp4-indexer \
--page-size 256 \
--swa-full-tokens-ratio 0.1 \
--kv-cache-dtype fp8_e4m3 \
--enforce-shared-experts-fusion \
--mem-fraction-static 0.86 \
--chunked-prefill-size 16384 \
--tool-call-parser deepseekv4 \
--reasoning-parser deepseek-v4 \
--speculative-algorithm DSPARK \
--speculative-dspark-block-size 6 \
--watchdog-timeout 3600
Concurrency 32–48은 동일한 TP-only 명령을 유지하고 HiCache DRAM 오프로드를 추가해요. DSv4 HiCache는 --hicache-ratio(host/device 토큰 비율)로 호스트 계층의 크기를 정해요. 비율 1.5는 TP8에서 약 2.7 TB 호스트 DRAM 예산 아래를 유지하는 값이에요:
--enable-hierarchical-cache \
--hicache-ratio 1.5 \
--hicache-write-policy write_through \
--hicache-io-backend direct \
--hicache-mem-layout page_first_direct
DP8 (DP Attention), concurrency 128–256:
SGLANG_OPT_UNIFIED_CACHE_FREE_OUT_OF_WINDOW_SLOTS=1 \
SGLANG_USE_ROCM700A=0 \
TORCH_BLAS_PREFER_HIPBLASLT=1 \
SGLANG_HACK_FLASHMLA_BACKEND=unified_kv_triton \
AITER_BF16_FP8_MOE_BOUND=0 \
SGLANG_OPT_USE_AITER_BATCHED_GEMM=1 \
SGLANG_SHARED_EXPERT_TP1=1 \
SGLANG_DP_SHARED_EXPERT_LOCAL=1 \
SGLANG_DP_USE_GATHERV=1 \
SGLANG_DP_USE_REDUCE_SCATTER=1 \
python3 -m sglang.launch_server \
--model-path deepseek-ai/DeepSeek-V4-Pro-0813 \
--trust-remote-code \
--tp 8 \
--dp 8 \
--enable-dp-attention \
--enable-dp-lm-head \
--enable-prefill-delayer \
--enable-dp-attention-local-control-broadcast \
--tokenizer-worker-num 8 \
--stream-interval 20 \
--prefill-decode-interval 20 \
--prefill-delayer-token-usage-low-watermark 0.7 \
--attention-backend dsv4 \
--enable-deepseek-v4-fp4-indexer \
--page-size 256 \
--swa-full-tokens-ratio 0.1 \
--kv-cache-dtype fp8_e4m3 \
--enforce-shared-experts-fusion \
--mem-fraction-static 0.92 \
--chunked-prefill-size 65536 \
--tool-call-parser deepseekv4 \
--reasoning-parser deepseek-v4 \
--speculative-algorithm DSPARK \
--speculative-dspark-block-size 6 \
--enable-hierarchical-cache \
--hicache-ratio 1.5 \
--hicache-write-policy write_through \
--hicache-io-backend direct \
--hicache-mem-layout page_first_direct \
--watchdog-timeout 3600
--chunked-prefill-size는 --dp로 나눠지는 전역 예산이므로, 이 설정은 랭크당 8192 토큰을 유지해요. --enable-dp-lm-head는 DP attention 아래 DSpark에 필요해요. DP 랭크 앞에는 sglang_router --policy cache_aware를 두어 다중 턴 세션이 가장 긴 radix/HiCache prefix를 보유한 랭크에 도달하게 하세요; concurrency 160 이상에서는 --balance-abs-threshold 32를 추가하세요.
3.8 MI355X에서의 PD Disaggregation (MORI-IO)
ROCm에서 prefill과 decode 역할은 Mooncake나 NiXL이 아닌 MORI-IO로 통신하므로, 위 Playground의 PD Disagg 카드는 MI300X / MI355X가 선택되면 CUDA 전용 전송을 숨기고 IB 장치 목록을 ConnectX mlx5_* 이름 대신 노드의 rdmaN NIC로 기본 설정해요.
두 역할 모두 RDMA NIC를 컨테이너에 전달해야 하므로, Docker 출력은 Install 패널의 일반적인 ROCm 기기 접근 위에 아래 패브릭 플래그를 추가해요. /dev/infiniband는 rdma_cm과 per-NIC uverbs0…uverbs7 노드를 커버하며, memlock/IPC_LOCK 쌍은 MORI-IO가 NIC에 등록하는 버퍼를 고정할 수 있게 해줘요:
docker run \
--device=/dev/kfd --device=/dev/dri --device /dev/infiniband \
--group-add video --cap-add IPC_LOCK \
--cap-add=SYS_PTRACE --security-opt seccomp=unconfined \
--ulimit memlock=-1 --ulimit stack=67108864 \
--ulimit nofile=1048576:1048576 \
--network host --ipc=host --shm-size 32g \
-v ~/.cache/huggingface:/root/.cache/huggingface \
lmsysorg/sglang-rocm:v0.5.20-rocm720-mi35x-20260923 \
python3 -m sglang.launch_server <role args below>
Pro Official (0813) PD 쌍은 이 v0.5.20 빌드에서 종단간 실행됐으며, Playground의 Docker 출력은 해당 변형에 이를 사용해요. --network host는 두 역할이 호스트를 넘어 랑데부하므로 단일 노드 -p 매핑을 대체해요. 1.6T 체크포인트의 긴 agentic 실행은 --shm-size 32g보다 더 필요할 수 있어요. 가중치 로드 중 worker가 죽으면 올리세요.
MI355X에서 MORI로 역할을 선택하면 공유 MORI-IO 전송 환경 — SGLANG_MORI_COMBINE_DTYPE + RDMA 전송 큐 튜닝 MORI_IO_SQ_BACKOFF_TIMEOUT_US / MORI_IO_QP_MAX_SEND_WR — 이 그 역할의 크기 조정과 함께 생성돼요. --max-running-requests는 두 역할 모두 의도적으로 작아요: 쌍은 큰 실행 배치를 보유하기보다는 worker 간 KV를 스트리밍해요.
역할은 Strategy별로 크기가 정해지므로 Deploy 패널의 작동 지점이 PD 명령에 그대로 반영돼요:
- Low-Latency — TP-only,
--mem-fraction-static 0.86, 실행 요청 상한 8. Decode는 배치 1–8에 대한 그래프를 캡처해요. 오프로드 계층 없음: KV 풀이 전부예요.- **Pro Official (0813)**은 자체 low-latency 쌍이 있어요: TP4 prefill 앞에 TP8 decode, 둘 다 번들 DSpark head를
--speculative-dspark-block-size 6으로 유지(SGLang이 여기서 steps 1 / topk 1 / 7 draft 토큰을 유도). 상한은 두 역할 모두--max-running-requests 32이고 decode 사다리는 1–32예요. Prefill은 16384 chunked-prefill 예산,--optimistic-prefill-attempts 2,--enable-cache-report, 그리고 Playground가 기본으로 켜는 UMBP 계층(§3.9 참고)을 추가해요. 두 역할 모두 기본 셀의--prefill-decode-interval을 제거하는데, 이는 집계 서빙에만 적용되기 때문이에요.
- **Pro Official (0813)**은 자체 low-latency 쌍이 있어요: TP4 prefill 앞에 TP8 decode, 둘 다 번들 DSpark head를
- Balanced — 여전히 TP-only,
--max-running-requests 96의 상한과 16384 chunked-prefill 예산. DP가 없으면 서버 전체 상한이 바로 per-rank 배치이므로 decode는 96까지 사다리를 올려요. Prefill은 HiCache 호스트 계층(--hicache-ratio 2.5,page_first, write-through, best-effort prefetch)을 실행해요; decode는 MORI로 decode 역할에 HiCache가 권장되지 않으므로 그렇게 하지 않아요.- **Pro Official (0813)**은 balanced를 low-latency와 같은 비대칭 쌍으로 실행하는데 크기를 조정해요: TP4 prefill 앞에 TP8 decode, 둘 다 DSpark를
--speculative-dspark-block-size 3(steps 1 / topk 1 / 4 draft 토큰), 양쪽--max-running-requests 96의 상한, 1–96의 decode 사다리. Balanced 기본 셀은 target-only DP이므로 역할이--speculative-algorithm DSPARK을 다시 추가해요. Prefill은 16384 chunked-prefill 예산을 유지하고--optimistic-prefill-attempts 2와--enable-cache-report를 추가해요. 오프로드 계층은 HiCache가 아닌 UMBP이며, Playground에서 기본으로 켜져요. UMBP 카드를 끄면 위의 HiCache 계층으로 폴백해요.
- **Pro Official (0813)**은 balanced를 low-latency와 같은 비대칭 쌍으로 실행하는데 크기를 조정해요: TP4 prefill 앞에 TP8 decode, 둘 다 DSpark를
- High-Throughput — 기본 셀에서 TP8 / DP8과 65536 chunked-prefill 예산을 상속하고, 상한을
--max-running-requests 256과--mem-fraction-static 0.92로 올리며, decode 사다리를 32로 — DP 8에 걸쳐 남는 per-rank 배치 256.--enable-cache-report를 추가하는데, 이는 해당 동시성에서 오프로드 계층이 비용 대비 효과가 있는지 판단하는 데 필요한 prefix 히트율을 표면화해요.- **Pro Official (0813)**은 두 역할 모두 TP8 / DP8을 유지하고 DSpark를
--speculative-dspark-block-size 3로 추가해요(자신의 balanced 쌍과 같은 draft 형태), 그리고--enable-dp-lm-head를 추가해요. 상한은 양쪽--max-running-requests 512에--mem-fraction-static 0.92인데, 이는 DP 랭크당 64이므로 decode 사다리는 1–64예요. Prefill은 기본 셀의 65536 chunked-prefill 예산과--swa-full-tokens-ratio 0.15를 유지하고,--optimistic-prefill-attempts 2를 추가하며, Playground에서 다른 두 Pro Official 쌍과 같은 standalone 계층 서버에 대해 UMBP를 기본으로 실행해요. Decode는--chunked-prefill-size를 제거하고 두 역할 모두--prefill-decode-interval을 제거해요.
- **Pro Official (0813)**은 두 역할 모두 TP8 / DP8을 유지하고 DSpark를
오프로드 계층이 실제로 balanced와 high-throughput을 구분해요: balanced 쌍은 prefill을 HiCache의 계층형 GPU → 호스트 캐시와 결합하고, high-throughput 쌍은 radix 트리를 호스트 계층 없이 MORI에 직접 연결하는 UMBP와 결합해요. Pro Official은 예외로 두 TP-only 쌍을 포함해 세 쌍 모두에서 UMBP를 실행해요. HiCache와 UMBP는 둘 다 켤 수 없으며 Playground가 이를 강제해요.
low-latency와 balanced 역할은 TP-only이며, 그게 decode 사다리가 전체 상한까지 실행되는 이유예요. 역할을 선택하면 DP-Attention이 꺼지고 제어가 회색 처리돼요:
--max-running-requests는 서버 전체이고attn_dp_size로 나눠지므로, DP를 켜면 명령의 어느 플래그도 바꾸지 않고 per-rank 배치가 캡처된 그래프 아래로 잘려요. PD가 꺼지면 balanced 셀은 집계 서빙을 위해 DP 레시피로 유지돼요.
경고 추측 디코딩은 상한 크기 조정 방식을 바꿔요. 대상 동시성 N에 대해 두 역할 모두
--max-running-requests N*2로 설정하세요. N으로 크기를 조정하면 서빙 배치가 목표 동시성 아래로 제한돼요. 이는 DSpark와 EAGLE/MTP 모두에 적용돼요: Pro Official low-latency 쌍의 상한 32는 동시성 16에 맞춰지고, balanced 쌍의 96은 48, high-throughput 쌍의 512는 256에 맞춰져요.
--max-running-requests는 서버 전체이고attn_dp_size로 나눠지므로 decode 그래프 사다리는 남는 per-rank 배치 —N*2 / dp_size— 를 커버해야 해요. 그것이 위의 두 지점이 덜 차이나는 상한에서 다른 위치로 사다리를 올리는 이유예요: balanced는 TP-only이므로 96개 슬롯이 랭크당 96개인 반면, high-throughput은 256을 DP 8에 펼쳐 한 번에 32개만 보여요(Pro Official의 512 over DP 8은 64).
high-throughput prefill 역할이 UMBP가 속한 곳이에요 — UMBP가 그렇지 않으면 필요로 하는 DP attention이 이미 켜져 있고, 풀이 의미를 갖기엔 동시성이 충분히 높아요. Pro Official에서는 세 prefill 역할 모두 기본으로 UMBP를 활성화하며, low-latency와 balanced는 TP-only 예외로 DP 없이 그렇게 해요. 그 외에는 역할과 함께 UMBP 카드를 켜세요. 링커 플래그가 UMBP 소유이므로 그것은 역할의 일부가 아닌 별도 카드이며, 암시적으로 두면 의존성이 숨겨져요.
어느 지점을 선택하든 두 역할은 두 곳에서 갈라져요:
- Cuda 그래프. Prefill은 eager(
--disable-cuda-graph)로 실행돼요. FP4 indexer의 prefill 경로가 캡처되지 않기 때문이에요. Decode는 실행 요청 상한과 일치하는 작은 배치 사다리를 캡처해요(--cuda-graph-bs-decode 1 2 3 4 5 6 7 8). - MORI dispatch 예산.
SGLANG_MORI_NUM_MAX_DISPATCH_TOKENS_PER_RANK는 prefill에서16384로, 전체 chunked-prefill 배치에 맞춰지고, decode에서128로 설정돼요. 여기서 단계는 실행 요청당 토큰 하나를 초과해 dispatch하지 않아요.
역할을 선택하면 상속된 DSpark head를 두 역할 모두에 유지해요(§3.4 참고); --speculative-dspark-block-size를 두 역할 모두 동일하게 유지하세요. DSpark head가 없는 원본의 경우, 추측 PD 레시피는 EAGLE 경로를 통해 번들 MTP head를 대신 사용해요:
--speculative-algorithm EAGLE --speculative-eagle-topk 1 \
--speculative-num-steps 3 --speculative-num-draft-tokens 4
두 역할을 같은 전송과 IB 장치 선택으로 별도 노드에서 실행한 다음 카드가 출력하는 router로 앞세우세요. MI355X에서 그 router는 round-robin이 아닌 cache-aware예요: --policy consistent_hashing은 대화를 이미 prefix를 보유한 worker에 유지해요 — 이것이 agentic 재사용을 유효하게 만드는 것이며, --balance-abs-threshold 2 / --balance-rel-threshold 1.1은 실행 요청 상한이 아주 작다는 점을 감안해 그 선호도가 피어를 굶기지 않게 해요. Decode는 재사용 가능한 prefix를 보유하지 않으므로 --decode-policy round_robin이 decode 쪽을 고르게 분산해요. 긴 타임아웃으로 헬스 체크를 유지해 다중 분 prefill이 실패로 오인되지 않으면서도 막힌 worker는 여전히 잡히도록 해요.
--dp-aware는 worker가 DP attention을 실행할 때만 동작해요 — 효과를 보려면 Playground의 DP-Attention 카드를 켜세요. 그렇지 않으면 위의 TP-only 레시피에서 무용해요.
3.9 UMBP (직접 외부 KV 저장소)
UMBP는 KV를 GPU에서 넘치는 두 번째 방법이며, HiCache의 대안이지 내부 계층이 아니에요. HiCache는 계층 구조예요 — GPU, 그다음 고정 호스트 메모리, 그리고 선택적으로 스토리지 백엔드. UMBP는 통합 radix 트리를 중간에 호스트 캐시 계층 없이 MORI의 버퍼 풀에 직접 연결하므로, 페이지가 외부 저장소에 대해 직접 로드·오프로드돼요. SGLang은 둘을 함께 거부하므로 위 Playground에서 UMBP 카드를 활성화하면 명령에서 HiCache 플래그 계열 전체가 제거돼요:
--enable-unified-cache-external-linker \
--unified-cache-external-linker-backend mori
Store 노브는 링커 백엔드를 선택해요. mori는 UMBP 풀이고, mooncake는 Mooncake 스토어에 대해 동일한 직접 링커 경로를 구동해요.
DP Attention이 필요하며, 카드의 Enable 칩은 켤 때까지 회색으로 유지돼요. 이는 부드러운 선호가 아니에요. 링커는 랭크별로 객체를 키잉하고 MLA KV는 TP에 걸쳐 복제되므로, 순수 TP 아래 TP8 prefill worker는 같은 토큰의 8개 복사본을 보유한 8개의 별도 keyspace를 열어요 — 풀의 효과적 고유 토큰 용량이 바이트 예산이 시사하는 것의 8분의 1이 되며, 이는 실제 측정으로 오인하기 쉬워요. DP attention은 키를 단일 공유 keyspace로 축소해요.
예외는 §3.8의 low-latency와 balanced 쌍에 있는 MI355X Pro Official prefill 역할이에요. TP4에서 4개 복사본을 보유하며 8개가 아니고, 그 TP-only 형태가 종단간 실행됐으므로 카드는 DP 없이 해당 역할에 UMBP를 켜요. 모든 Pro Official prefill 역할(low-latency, balanced, DP8 high-throughput)은 standalone UMBP 계층을 사용해요: prefill 노드의 별도 umbp_standalone_server 프로세스가 DRAM 풀을 소유하고, prefill 서버는 Unix 소켓 위에서 연결돼요. 계층 서버를 먼저 시작하세요; 아래 1500 GB DRAM 예산은 검증된 실행이 사용한 값이에요:
mkdir -p /tmp/umbp_sa
UMBP_DRAM_CAPACITY=1500000000000 \
UMBP_DRAM_USE_HUGEPAGES=1 \
UMBP_SSD_ENABLED=0 \
MORI_UMBP_LOG_LEVEL=info \
<mori>/umbp_standalone_server unix:///tmp/umbp_sa/sa.grpc.sock
그런 다음 socket을 환경에 넣어 prefill 역할을 시작하세요. Playground는 두 줄을 모두 추가해요: 주소는 환경에서 나와야 하며, extra-config는 prefill이 포기하기 전에 계층 서버가 socket을 바인딩할 시간을 최대 2분 제공해요.
UMBP_STANDALONE_ADDRESS=unix:///tmp/umbp_sa/sa.grpc.sock \
sglang serve ... \
--hicache-storage-backend-extra-config '{"standalone_startup_timeout_ms":120000}'
실행 크기를 정하기 전에 두 가지 추가 제한을 알아두세요. 풀은 per-node 프로세스이므로, 노드를 가로지르는 prefill worker는 keyspace를 노드별로 샤딩해요. 그리고 prefill worker만 KV를 오프로드하고 decode 쪽은 건드리지 않아요.