From 81fcd691c4c253558a22d17186d4476165906a6d Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Thu, 27 Aug 2026 11:22:54 -0500 Subject: [PATCH] feat(amd): port DSR1 FP8 to srt-slurm --- .../dsr1/mi355x/fp8-disagg-fixed-seq.yaml | 305 ++++++++++++++++++ configs/amd-master.yaml | 121 +++++++ perf-changelog.yaml | 14 + 3 files changed, 440 insertions(+) create mode 100644 benchmarks/multi_node/srt-slurm-recipes/sglang/dsr1/mi355x/fp8-disagg-fixed-seq.yaml diff --git a/benchmarks/multi_node/srt-slurm-recipes/sglang/dsr1/mi355x/fp8-disagg-fixed-seq.yaml b/benchmarks/multi_node/srt-slurm-recipes/sglang/dsr1/mi355x/fp8-disagg-fixed-seq.yaml new file mode 100644 index 0000000000..31c0e45ffa --- /dev/null +++ b/benchmarks/multi_node/srt-slurm-recipes/sglang/dsr1/mi355x/fp8-disagg-fixed-seq.yaml @@ -0,0 +1,305 @@ +base: + name: "mi355x-dsr1-fp8-disagg-fixed-seq" + + model: + path: "hf:deepseek-ai/DeepSeek-R1-0528" + container: "sglang-rocm-v0.5.17-mi35x" + precision: "fp8" + + identity: + model: {repo: "deepseek-ai/DeepSeek-R1-0528"} + container: {image: "lmsysorg/sglang-rocm:v0.5.17-rocm720-mi35x-20260809"} + frameworks: + sglang: "0.5.17.dev20260809+g7120f3ee13" + sglang-router: "0.3.2" + amd-mori: "0.5.17.dev20260809+g7120f3ee13" + + slurm: {time_limit: "08:00:00"} + + resources: + gpu_type: "mi355x" + gpus_per_node: 8 + prefill_nodes: 1 + decode_nodes: 1 + prefill_workers: 1 + decode_workers: 1 + gpus_per_prefill: 8 + gpus_per_decode: 8 + + frontend: + type: sglang + enable_multiple_frontends: false + args: + policy: round_robin + prefill-policy: round_robin + decode-policy: round_robin + + backend: + type: sglang + prefill_environment: &common_environment + HF_HOME: "/hf_hub_cache" + HF_HUB_CACHE: "/hf_hub_cache/hub" + HUGGINGFACE_HUB_CACHE: "/hf_hub_cache/hub" + PYTHONUNBUFFERED: "1" + IBDEVICES: "rdma0,rdma1,rdma2,rdma3,rdma4,rdma5,rdma6,rdma7" + GLOO_SOCKET_IFNAME: "eno0" + NCCL_SOCKET_IFNAME: "eno0" + MORI_RDMA_TC: "104" + MORI_IO_TC: "104" + MORI_IO_SQ_BACKOFF_TIMEOUT_US: "50000" + MORI_IO_QP_MAX_SEND_WR: "16384" + MORI_IO_QP_MAX_CQE: "32768" + MORI_IO_QP_MAX_SGE: "2" + MORI_SHMEM_MODE: "ISOLATION" + SGLANG_USE_AITER: "1" + AITER_LOG_LEVEL: "ERROR" + SGLANG_MORI_DISPATCH_DTYPE: "auto" + SGLANG_MORI_QP_PER_TRANSFER: "4" + SGLANG_MORI_NUM_WORKERS: "4" + SGLANG_MORI_NUM_MAX_DISPATCH_TOKENS_PER_RANK: "8192" + SGLANG_MORI_DISPATCH_INTER_KERNEL_SWITCH_THRESHOLD: "1024" + SGLANG_DISAGGREGATION_NUM_PRE_ALLOCATE_REQS: "32" + SGLANG_DISAGGREGATION_BOOTSTRAP_TIMEOUT: "3600" + SGLANG_DISAGGREGATION_WAITING_TIMEOUT: "3600" + SGLANG_HEALTH_CHECK_TIMEOUT: "600" + decode_environment: + <<: *common_environment + SGLANG_MORI_NUM_MAX_DISPATCH_TOKENS_PER_RANK: "512" + sglang_config: + prefill: &prefill_tp8 + served-model-name: "deepseek-ai/DeepSeek-R1-0528" + trust-remote-code: true + tp-size: 8 + disaggregation-transfer-backend: mori + kv-cache-dtype: fp8_e4m3 + attention-backend: aiter + moe-dense-tp-size: 1 + load-balance-method: auto + watchdog-timeout: 3600 + decode-log-interval: 1000 + log-level: warning + mem-fraction-static: 0.80 + max-running-requests: 128 + chunked-prefill-size: 262144 + context-length: 16384 + disable-radix-cache: true + cuda-graph-bs: &cg128 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128] + enable-metrics: true + enable-cache-report: true + decode: + <<: *prefill_tp8 + mem-fraction-static: 0.85 + disable-radix-cache: false + prefill-round-robin-balance: true + cuda-graph-bs: *cg128 + + sbatch_directives: + cpus-per-task: "128" + mem: "0" + + srun_options: + mem: "0" + container-writable: "" + container-remap-root: "" + + health_check: {max_attempts: 720, interval_seconds: 5} + + benchmark: + type: custom + command: | + set -euo pipefail + result_root="/results/${SLURM_JOB_ID}/fixed-seq" + mkdir -p "${result_root}" + trap 'tar -C /logs -czf "'"${result_root}"'/runtime-logs.tar.gz" . 2>/dev/null || true' EXIT + chat_args=() + if [[ "${USE_CHAT_TEMPLATE}" == "1" ]]; then + chat_args+=(--use-chat-template) + fi + for concurrency in ${CONCURRENCY_LIST}; do + num_prompts=$((concurrency * 10)) + if (( num_prompts < 16 )); then num_prompts=16; fi + python3 /infmax-workspace/utils/bench_serving/benchmark_serving.py \ + --backend openai \ + --base-url "http://${SRT_FRONTEND_HOST}:${SRT_FRONTEND_PORT}" \ + --endpoint /v1/completions \ + --model deepseek-ai/DeepSeek-R1-0528 \ + --tokenizer deepseek-ai/DeepSeek-R1-0528 \ + --trust-remote-code \ + --dataset-name random \ + --random-input-len 8192 \ + --random-output-len 1024 \ + --random-range-ratio 1.0 \ + --random-num-workers 1 \ + "${chat_args[@]}" \ + --num-warmups "$((concurrency * 2))" \ + --num-prompts "${num_prompts}" \ + --max-concurrency "${concurrency}" \ + --request-rate inf \ + --ignore-eos \ + --disable-tqdm \ + --save-result \ + --result-dir "${result_root}" \ + --result-filename "dsr1-fp8-${BENCHMARK_VARIANT}-isl8192-osl1024-c${concurrency}.json" + env: + HF_HOME: /hf_hub_cache + HF_HUB_CACHE: /hf_hub_cache/hub + HUGGINGFACE_HUB_CACHE: /hf_hub_cache/hub + CONCURRENCY_LIST: "1" + BENCHMARK_VARIANT: "base" + USE_CHAT_TEMPLATE: "0" + +override_stp_2p1d_dep8: + name: "mi355x-dsr1-fp8-stp-2p1d-dep8-fixed-seq" + resources: + prefill_nodes: 2 + decode_nodes: 1 + prefill_workers: 2 + decode_workers: 1 + backend: + decode_environment: + SGLANG_MORI_NUM_MAX_DISPATCH_TOKENS_PER_RANK: "256" + SGLANG_MORI_DISPATCH_INTER_KERNEL_SWITCH_THRESHOLD: "512" + sglang_config: + prefill: &dep8_stp + ep-size: 8 + dp-size: 8 + enable-dp-attention: true + enable-dp-lm-head: true + ep-dispatch-algorithm: fake + moe-a2a-backend: mori + deepep-mode: normal + max-running-requests: 2048 + chunked-prefill-size: 65536 + cuda-graph-bs: [1, 2, 3] + decode: + <<: *dep8_stp + mem-fraction-static: 0.85 + disable-radix-cache: false + prefill-round-robin-balance: true + cuda-graph-bs: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160] + benchmark: + env: + CONCURRENCY_LIST: "1024 2048" + BENCHMARK_VARIANT: "stp-2p1d-dep8" + +override_stp_1p2d_tp8: + name: "mi355x-dsr1-fp8-stp-1p2d-tp8-fixed-seq" + resources: + prefill_nodes: 1 + decode_nodes: 2 + prefill_workers: 1 + decode_workers: 2 + benchmark: + env: + CONCURRENCY_LIST: "4 8 16 32 64 128 256" + BENCHMARK_VARIANT: "stp-1p2d-tp8" + +override_stp_1p1d_tp4_tp8: + name: "mi355x-dsr1-fp8-stp-1p1d-tp4-tp8-fixed-seq" + resources: + prefill_nodes: 1 + decode_nodes: 1 + prefill_workers: 1 + decode_workers: 1 + gpus_per_prefill: 4 + gpus_per_decode: 8 + backend: + sglang_config: + prefill: + tp-size: 4 + benchmark: + env: + CONCURRENCY_LIST: "1 2 4 8 16 32 64" + BENCHMARK_VARIANT: "stp-1p1d-tp4-tp8" + +override_mtp_2p1d_dep8: + name: "mi355x-dsr1-fp8-mtp1-2p1d-dep8-fixed-seq" + resources: + prefill_nodes: 2 + decode_nodes: 1 + prefill_workers: 2 + decode_workers: 1 + backend: + decode_environment: + SGLANG_MORI_NUM_MAX_DISPATCH_TOKENS_PER_RANK: "512" + SGLANG_MORI_DISPATCH_INTER_KERNEL_SWITCH_THRESHOLD: "512" + sglang_config: + prefill: &dep8_mtp1 + ep-size: 8 + dp-size: 8 + enable-dp-attention: true + enable-dp-lm-head: true + ep-dispatch-algorithm: fake + moe-a2a-backend: mori + deepep-mode: normal + speculative-algorithm: NEXTN + speculative-eagle-topk: 1 + speculative-num-steps: 1 + speculative-num-draft-tokens: 2 + max-running-requests: 2048 + chunked-prefill-size: 65536 + cuda-graph-bs: [1, 2, 3] + decode: + <<: *dep8_mtp1 + mem-fraction-static: 0.85 + disable-radix-cache: false + prefill-round-robin-balance: true + cuda-graph-bs: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160] + benchmark: + env: + CONCURRENCY_LIST: "1024 2048" + BENCHMARK_VARIANT: "mtp1-2p1d-dep8" + USE_CHAT_TEMPLATE: "1" + +override_mtp_1p2d_tp8: + name: "mi355x-dsr1-fp8-mtp2-1p2d-tp8-fixed-seq" + resources: + prefill_nodes: 1 + decode_nodes: 2 + prefill_workers: 1 + decode_workers: 2 + backend: + decode_environment: + SGLANG_MORI_NUM_MAX_DISPATCH_TOKENS_PER_RANK: "1536" + sglang_config: + prefill: &mtp2 + speculative-algorithm: NEXTN + speculative-eagle-topk: 1 + speculative-num-steps: 2 + speculative-num-draft-tokens: 3 + decode: *mtp2 + benchmark: + env: + CONCURRENCY_LIST: "2 4 8 16 32 64 128 256" + BENCHMARK_VARIANT: "mtp2-1p2d-tp8" + USE_CHAT_TEMPLATE: "1" + +override_mtp_1p1d_tp4_tp8: + name: "mi355x-dsr1-fp8-mtp2-1p1d-tp4-tp8-fixed-seq" + resources: + prefill_nodes: 1 + decode_nodes: 1 + prefill_workers: 1 + decode_workers: 1 + gpus_per_prefill: 4 + gpus_per_decode: 8 + backend: + decode_environment: + SGLANG_MORI_NUM_MAX_DISPATCH_TOKENS_PER_RANK: "1536" + sglang_config: + prefill: + tp-size: 4 + speculative-algorithm: NEXTN + speculative-eagle-topk: 1 + speculative-num-steps: 2 + speculative-num-draft-tokens: 3 + decode: + speculative-algorithm: NEXTN + speculative-eagle-topk: 1 + speculative-num-steps: 2 + speculative-num-draft-tokens: 3 + benchmark: + env: + CONCURRENCY_LIST: "1 2 4 8 16 32 64" + BENCHMARK_VARIANT: "mtp2-1p1d-tp4-tp8" + USE_CHAT_TEMPLATE: "1" diff --git a/configs/amd-master.yaml b/configs/amd-master.yaml index b47a07488e..aa990fdc11 100644 --- a/configs/amd-master.yaml +++ b/configs/amd-master.yaml @@ -856,3 +856,124 @@ qwen3-0.6b-fp16-mi355x-sglang-srt-disagg: # Production-scale migration of the existing Qwen3.5 FP8 MI355X P/D lane to # srt-slurm. One full TP8 node serves prefill, one TP8 node serves decode, and # the request/KV planes remain native SGLang Router + AMD MoRI. + +dsr1-fp8-mi355x-sglang-disagg: + image: lmsysorg/sglang-rocm:v0.5.17-rocm720-mi35x-20260809 + model: deepseek-ai/DeepSeek-R1-0528 + model-prefix: dsr1 + runner: cluster:mi355x-amds + precision: fp8 + framework: sglang-disagg + router: { name: sglang-router, version: "0.3.2" } + kv-p2p-transfer: mori + multinode: true + disagg: true + scenarios: + fixed-seq-len: + - isl: 8192 + osl: 1024 + search-space: + # Each matrix row selects one resolved topology from the shared + # srt-slurm recipe. The recipe owns the complete concurrency sweep in a + # single allocation so model initialization is paid once per topology. + - spec-decoding: "none" + conc-list: [1] + prefill: + num-worker: 2 + tp: 8 + ep: 8 + dp-attn: true + additional-settings: + - "CONFIG_FILE=recipes/sglang/dsr1/mi355x/fp8-disagg-fixed-seq.yaml:override_stp_2p1d_dep8" + decode: + num-worker: 1 + tp: 8 + ep: 8 + dp-attn: true + - spec-decoding: "none" + conc-list: [1] + prefill: + num-worker: 1 + tp: 8 + ep: 1 + dp-attn: false + additional-settings: + - "CONFIG_FILE=recipes/sglang/dsr1/mi355x/fp8-disagg-fixed-seq.yaml:override_stp_1p2d_tp8" + decode: + num-worker: 2 + tp: 8 + ep: 1 + dp-attn: false + - spec-decoding: "none" + conc-list: [1] + prefill: + num-worker: 1 + tp: 4 + ep: 1 + dp-attn: false + additional-settings: + - "CONFIG_FILE=recipes/sglang/dsr1/mi355x/fp8-disagg-fixed-seq.yaml:override_stp_1p1d_tp4_tp8" + decode: + num-worker: 1 + tp: 8 + ep: 1 + dp-attn: false + +dsr1-fp8-mi355x-sglang-disagg-mtp: + image: lmsysorg/sglang-rocm:v0.5.17-rocm720-mi35x-20260809 + model: deepseek-ai/DeepSeek-R1-0528 + model-prefix: dsr1 + runner: cluster:mi355x-amds + precision: fp8 + framework: sglang-disagg + router: { name: sglang-router, version: "0.3.2" } + kv-p2p-transfer: mori + multinode: true + disagg: true + scenarios: + fixed-seq-len: + - isl: 8192 + osl: 1024 + search-space: + - spec-decoding: "mtp" + conc-list: [1] + prefill: + num-worker: 2 + tp: 8 + ep: 8 + dp-attn: true + additional-settings: + - "CONFIG_FILE=recipes/sglang/dsr1/mi355x/fp8-disagg-fixed-seq.yaml:override_mtp_2p1d_dep8" + decode: + num-worker: 1 + tp: 8 + ep: 8 + dp-attn: true + - spec-decoding: "mtp" + conc-list: [1] + prefill: + num-worker: 1 + tp: 8 + ep: 1 + dp-attn: false + additional-settings: + - "CONFIG_FILE=recipes/sglang/dsr1/mi355x/fp8-disagg-fixed-seq.yaml:override_mtp_1p2d_tp8" + decode: + num-worker: 2 + tp: 8 + ep: 1 + dp-attn: false + - spec-decoding: "mtp" + conc-list: [1] + prefill: + num-worker: 1 + tp: 4 + ep: 1 + dp-attn: false + additional-settings: + - "CONFIG_FILE=recipes/sglang/dsr1/mi355x/fp8-disagg-fixed-seq.yaml:override_mtp_1p1d_tp4_tp8" + decode: + num-worker: 1 + tp: 8 + ep: 1 + dp-attn: false diff --git a/perf-changelog.yaml b/perf-changelog.yaml index f94f370b83..f6f2019f2d 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -6558,3 +6558,17 @@ - "Use the native SGLang router for request routing and AMD MoRI for disaggregated KV transfer, without Dynamo, NIXL, or the deleted amd_utils control plane." - "Remove the active and deprecated MI355X matrix entries that depended on amd_utils; configuration-specific child PRs reintroduce the active production lanes as native srt-slurm recipes." pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2542 + +- config-keys: + - dsr1-fp8-mi355x-sglang-disagg + - dsr1-fp8-mi355x-sglang-disagg-mtp + scenario-type: + - fixed-seq-len + description: + - "Replace the DeepSeek-R1 FP8 model-specific amd_utils launcher with native srt-slurm orchestration using SGLang Router and AMD MoRI on MI355X." + - "Preserve all six production STP/MTP topology families and every original 8k1k point: 2P1D DEP8/DPA at c1024/c2048, 1P2D TP8 at c4-c256 for STP and c2-c256 for MTP2, and 1P1D TP4-to-TP8 at c1-c64." + - "Use the current lmsysorg/sglang-rocm:v0.5.17-rocm720-mi35x-20260809 runtime, explicit role-specific MoRI dispatch limits, FP8 KV cache, AITer attention, and NEXTN draft depths matching the former MTP configurations." + - "Run the repository's unchanged benchmark_serving.py through srt-slurm's custom benchmark contract, with one allocation per topology to amortize model initialization across its concurrency sweep." + - "Expose the complete 163-shard legacy checkpoint as a zero-copy canonical Hugging Face cache seed rather than copying or downloading another 688.6 GB model tree." + - "Pin SemiAnalysisAI/srt-slurm PR #7 at 10a58d2ebb4d756c423424049c736b909b72e14f so every DP-attention P/D topology uses the validated SGLang rank-routing contract, multi-node rank-offset preservation, and ATOM recipe flag normalization." + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2631