Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
272 changes: 272 additions & 0 deletions benchmarks/single_node/agentic/dsv4_fp4_b200_sglang_mtp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
#!/usr/bin/env bash
set -eo pipefail
set -x

# Agentic trace replay for DeepSeek-V4-Pro FP4 on B200 with native EAGLE MTP.
# Throughput uses the committed golden synthetic AL; eval retains real target
# verification.
#
# KV_OFFLOADING=dram requires KV_OFFLOAD_BACKEND=hicache.

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INFERENCEX_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
export INFMAX_CONTAINER_WORKSPACE="${INFMAX_CONTAINER_WORKSPACE:-/workspace}"

# The B200 DeepSeek-V4 Blackwell image installs SGLang editable under
# /workspace, so its launcher mounts InferenceX at /ix instead. Resolve the
# agentic tooling and results against the actual repository mount so the image
# can keep its /workspace install and GitHub Actions can collect the outputs.
if [[ ! -d "$INFMAX_CONTAINER_WORKSPACE/utils/aiperf" ]]; then
export INFMAX_CONTAINER_WORKSPACE="$INFERENCEX_ROOT"
fi
if [[ "${RESULT_DIR:-}" == /workspace/* && "$INFMAX_CONTAINER_WORKSPACE" != /workspace ]]; then
export RESULT_DIR="$INFMAX_CONTAINER_WORKSPACE/${RESULT_DIR#/workspace/}"
fi
source "$INFERENCEX_ROOT/benchmarks/benchmark_lib.sh"

export AIPERF_REQUIRED_SERVER_METRIC_PREFIX="sglang:"

check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION EP_SIZE DP_ATTENTION

if [[ -n "${SLURM_JOB_ID:-}" ]]; then
echo "JOB $SLURM_JOB_ID running on ${SLURMD_NODENAME:-unknown}"
fi

if [[ -n "${MODEL_PATH:-}" ]]; then
if [[ ! -d "$MODEL_PATH" || -z "$(ls -A "$MODEL_PATH" 2>/dev/null)" ]]; then
hf download "$MODEL" --local-dir "$MODEL_PATH"
fi
else
hf download "$MODEL"
export MODEL_PATH="$MODEL"
fi
nvidia-smi

resolve_trace_source

# Keep AIPerf's Transformers-main dependency from replacing the older
# Transformers build pinned by the B200-specialized SGLang image. The server
# always launches with the image's original interpreter; AIPerf and result
# processing use the isolated environment when InferenceX is mounted at /ix.
SGLANG_PYTHON="$(command -v python3)"
if [[ "$INFMAX_CONTAINER_WORKSPACE" != /workspace ]]; then
AGENTIC_VENV="${AGENTIC_VENV:-/tmp/inferencex-agentic-venv}"
"$SGLANG_PYTHON" -m venv "$AGENTIC_VENV"
export PATH="$AGENTIC_VENV/bin:$PATH"
fi
install_agentic_deps
Comment on lines +50 to +57

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 In eval-only mode, the empty AGENTIC_VENV created at dsv4_fp4_b200_sglang_mtp.sh:52-56 shadows python3 before transformers is installed into it, so get_native_max_context_length's bare-python3 probe (benchmark_lib.sh:908) fails silently and falls back to a hardcoded 16384 instead of DeepSeek-V4-Pro's real native context. For this specific recipe the fallback is harmless in practice (the single-node agentic eval runs GSM8K, whose prompts/outputs fit well inside 16384), but the detection is still silently wrong and worth fixing, e.g. by creating the venv with --system-site-packages so the native-context probe still sees the system transformers.

Extended reasoning...

The mechanism is real. When INFMAX_CONTAINER_WORKSPACE != /workspace (the documented normal case for this B200 image, since it mounts InferenceX at /ix), the script runs "$SGLANG_PYTHON" -m venv "$AGENTIC_VENV" with no --system-site-packages, then prepends $AGENTIC_VENV/bin to PATH. This venv starts completely empty. install_agentic_deps (benchmark_lib.sh:1826) builds a separate AIPERF_VENV via uv --python "$AIPERF_PYTHON" and never touches AGENTIC_VENV, so the new venv stays empty until _install_lm_eval_deps eventually runs python3 -m pip install ... lm-eval[api] into it.

In EVAL_ONLY=true mode, run_eval (benchmark_lib.sh:1689-1690) calls compute_eval_context_length before _install_lm_eval_deps runs (that install happens later, inside run_lm_eval, at line 1008). compute_eval_context_length calls get_native_max_context_length (line 908), which shells out to a bare python3 -c '... from transformers import AutoConfig ...'. Since AGENTIC_VENV/bin is first on PATH and empty at this point, the import raises, the except swallows it, and the probe prints 0. Because MAX_MODEL_LEN is unconditionally unset for agentic callers (benchmark_lib.sh:77) and this recipe never calls setup_eval_context, compute_eval_context_length sees benchmark_ctx=0 and native_max=0 and falls through to eval_ctx=${MAX_MODEL_LEN:-16384}=16384 (line 946), emitting a WARN to stderr along the way.

Step-by-step proof:

  1. INFMAX_CONTAINER_WORKSPACE resolves to /ix (not /workspace) for this image, so the script hits the if branch and creates AGENTIC_VENV empty, then export PATH="$AGENTIC_VENV/bin:$PATH".
  2. EVAL_ONLY=true → the script calls run_eval --port "$PORT".
  3. run_eval sees EVAL_MAX_MODEL_LEN unset → calls compute_eval_context_length "$MODEL" "${MAX_MODEL_LEN:-0}" with MAX_MODEL_LEN unset (→ 0).
  4. compute_eval_context_length calls get_native_max_context_length, which runs bare python3 -c '...AutoConfig...'. python3 now resolves inside the empty AGENTIC_VENV, transformers isn't installed there yet, import fails, function prints 0.
  5. Both benchmark_ctx and native_max are 0 → fallback branch: eval_ctx=16384, EVAL_MAX_MODEL_LEN=16384.
  6. Later, run_lm_eval passes max_length=16384 and computes max_output_tokens=16384-4096=12288 for lm_eval --model_args/--gen_kwargs.
  7. Without the venv (the /workspace case), bare python3 resolves to the image's system Python, which already has transformers installed, so the probe would have returned DeepSeek-V4-Pro's real (larger) native context instead of 0.

Where the original framing overreaches (addressing the refutation). One verifier objection is correct and should be acknowledged: AGENTIC_VENV is not simply redundant dead weight. _install_lm_eval_deps (benchmark_lib.sh:870-887) and the lm_eval invocation itself (line 1029) use bare python3 -m pip install --break-system-packages ... / python3 -m lm_eval. Without something ahead of the system Python on PATH, those bare-python3 calls would install/upgrade lm-eval[api] (and transitively transformers) directly into the SGLang server's system interpreter — exactly the corruption the script's own comment says it's trying to avoid. So the venv does serve a real isolation purpose for the eval path; it isn't redundant with AIPERF_VENV.

The refutation's second point is also correct and matters for grading severity: this config has multinode: false, and per utils/matrix_logic/generate_sweep_configs.py:289-291/405-406, single-node agentic entries run their eval through the GSM8K lm-eval path, not SWE-bench. GSM8K prompts and chain-of-thought generations are far shorter than 16384 tokens, and max_output_tokens still comes out to 12288 either way, so for this recipe's actual eval point there is no truncation or observable score impact — the fallback happens to be harmless here.

Why it's still worth flagging. The detection is genuinely broken (a documented-intent violation per benchmark_lib.sh:70-71, "agentic replays must use the model's native context limit"), it fails silently (only a stderr WARN, no exit), and it's not obviously scoped to "harmless for GSM8K" from the call site — the same pattern will silently misconfigure any future agentic recipe/eval-task combination where the actual context matters, and it's easy to overlook since nothing crashes. A simple, low-risk fix: create AGENTIC_VENV with --system-site-packages (so the bare-python3 native-context probe still resolves transformers from the image's system install while pip installs continue to prefer the venv's own site-packages), or resolve the native-context probe via $SGLANG_PYTHON explicitly instead of a bare python3.


SERVER_LOG="$RESULT_DIR/server.log"
mkdir -p "$RESULT_DIR"

export SGLANG_ENABLE_UNIFIED_RADIX_TREE=1
export SGLANG_OPT_UNIFIED_CACHE_FREE_OUT_OF_WINDOW_SLOTS=1

CACHE_ARGS=()
if require_agentic_kv_offload_backend hicache; then
# DeepSeek V4 HiCache currently rejects --hicache-size and supports
# capacity control only through a host/device token-capacity ratio.
# DSv4 exposes capacity as a host/device token ratio rather than bytes.
# B200 ratio=8 stays below the configured host-memory capacity for the
# currently supported TP8 shape.
DEFAULT_HICACHE_RATIO=8
HICACHE_RATIO="${HICACHE_RATIO:-$DEFAULT_HICACHE_RATIO}"
if [ "$HICACHE_RATIO" -gt "$DEFAULT_HICACHE_RATIO" ]; then
echo "Error: HICACHE_RATIO=$HICACHE_RATIO exceeds configured limit $DEFAULT_HICACHE_RATIO" >&2
exit 1
fi
HICACHE_WRITE_POLICY="${HICACHE_WRITE_POLICY:-write_through}"
HICACHE_IO_BACKEND="${HICACHE_IO_BACKEND:-direct}"
HICACHE_MEM_LAYOUT="${HICACHE_MEM_LAYOUT:-page_first_direct}"
CACHE_ARGS=(
--enable-hierarchical-cache
--hicache-ratio "$HICACHE_RATIO"
--hicache-write-policy "$HICACHE_WRITE_POLICY"
--hicache-io-backend "$HICACHE_IO_BACKEND"
--hicache-mem-layout "$HICACHE_MEM_LAYOUT"
)
echo "HiCache DSv4 CPU tier: ratio=$HICACHE_RATIO, capacity=${TOTAL_CPU_DRAM_GB} GB, write_policy=$HICACHE_WRITE_POLICY, io_backend=$HICACHE_IO_BACKEND, mem_layout=$HICACHE_MEM_LAYOUT"
fi

USE_SGLANG_ROUTER=false
SGLANG_BACKEND_PORT="$PORT"
ROUTER_LOG="$RESULT_DIR/router.log"
if [ "$DP_ATTENTION" = "true" ]; then
USE_SGLANG_ROUTER=true
export AIPERF_HTTP_X_SMG_ROUTING_KEY_FROM_CORRELATION_ID=true
SGLANG_BACKEND_PORT=$((PORT + 1))
SGLANG_ROUTER_METRICS_PORT=$((PORT + 10000))
SGLANG_ROUTER_CMD=("$SGLANG_PYTHON" -m sglang_router.launch_router)
fi

PARALLEL_ARGS=(--tp "$TP")
METRICS_ARGS=(--enable-metrics --enable-cache-report)
CHUNKED_PREFILL_SIZE=8192
if [ "$DP_ATTENTION" = "true" ]; then
DEEPEP_CONFIG='{"normal_dispatch":{"num_sms":96},"normal_combine":{"num_sms":96}}'
export SGLANG_OPT_USE_DEEPGEMM_MEGA_MOE=1
export SGLANG_OPT_FIX_HASH_MEGA_MOE=1
export SGLANG_OPT_USE_FAST_MASK_EP=1
export SGLANG_OPT_FIX_MEGA_MOE_MEMORY=1
export SGLANG_OPT_DEEPGEMM_MEGA_MOE_NUM_MAX_TOKENS_PER_RANK=4096
export SGLANG_OPT_FIX_NEXTN_MEGA_MOE=1
export SGLANG_DEEPEP_NUM_MAX_DISPATCH_TOKENS_PER_RANK=0
PARALLEL_ARGS+=(
--dp "$TP"
--tokenizer-worker-num "$TP"
--enable-dp-attention
--enable-dp-attention-local-control-broadcast
--incremental-streaming-output
--stream-interval 20
--dist-init-addr "127.0.0.1:$((PORT + 2000))"
--ep-size "$EP_SIZE"
--moe-a2a-backend deepep
--deepep-config "$DEEPEP_CONFIG"
)
CHUNKED_PREFILL_SIZE=32768
else
PARALLEL_ARGS+=(
--moe-runner-backend flashinfer_mxfp4
--disable-flashinfer-autotune
)
fi

MODEL_ARGS=()
# The B200-specialized image deadlocks immediately after weight loading when
# forced through the B300 compressed-attention/page-size overrides.
# DeepGEMM's DSv4 indexer needs a multi-GiB temporary allocation at long
# contexts. Leave the same HBM headroom used by the B300 recipe so a nearly
# full GPU KV cache does not OOM while HiCache is spilling to host memory.
MEM_FRACTION_STATIC=0.88

# AgentX concurrency counts live session trees, not individual requests.
# Allow subagent fan-out to exceed CONC without clipping request bursts.
MAX_RUNNING_REQUESTS=$((2 * CONC))
CUDA_GRAPH_MAX_BS=$CONC
[ "$CUDA_GRAPH_MAX_BS" -gt 64 ] && CUDA_GRAPH_MAX_BS=64

export PYTHONNOUSERSITE=1
export TORCH_CUDA_ARCH_LIST=10.0
# Agentic warmup dispatches hundreds of large prompts at once. SGLang's
# tokenizer process can leave request bytes unacknowledged for longer than
# AIPerf's 30-second TCP_USER_TIMEOUT while it admits that initial burst,
# causing Linux to abort otherwise-live localhost connections. Keep the
# six-hour request timeout unchanged, but allow up to 15 minutes for TCP
# progress before declaring the connection dead.
export AIPERF_HTTP_TCP_USER_TIMEOUT=900000
# Outlast AIPerf's pooled connections so an inter-turn idle gap cannot race
# Uvicorn's five-second keep-alive closure.
export SGLANG_TIMEOUT_KEEP_ALIVE=900
export SGLANG_JIT_DEEPGEMM_FAST_WARMUP=1
export SGLANG_OPT_SWA_SPLIT_LEAF_ON_INSERT=1
export SGLANG_OPT_USE_JIT_NORM=1
export SGLANG_OPT_USE_JIT_INDEXER_METADATA=1
export SGLANG_OPT_USE_TOPK_V2=1
export SGLANG_OPT_USE_CUSTOM_ALL_REDUCE_V2=1
if [ "${EVAL_ONLY}" != "true" ]; then
export SGLANG_SIMULATE_ACC_LEN=2.49
export SGLANG_SIMULATE_ACC_METHOD=match-expected
export SGLANG_SIMULATE_ACC_TOKEN_MODE=real-draft-token
fi
TRITON_PTXAS_PATH=$(find \
/usr/local/cuda* \
/usr/local/lib/python*/dist-packages/nvidia \
/usr/local/lib/python*/site-packages/nvidia \
-type f -name ptxas -perm -u+x -print -quit 2>/dev/null || true)
if [ -n "$TRITON_PTXAS_PATH" ]; then
export TRITON_PTXAS_PATH
echo "Using ptxas for Triton: $TRITON_PTXAS_PATH"
fi
SGLANG_CMD=(
"$SGLANG_PYTHON" -m sglang.launch_server
--model-path "$MODEL_PATH"
--served-model-name "$MODEL"
--host 0.0.0.0
--port "$SGLANG_BACKEND_PORT"
--trust-remote-code
"${PARALLEL_ARGS[@]}"
--mem-fraction-static "$MEM_FRACTION_STATIC"
--swa-full-tokens-ratio 0.1
--max-running-requests "$MAX_RUNNING_REQUESTS"
--cuda-graph-max-bs "$CUDA_GRAPH_MAX_BS"
--chunked-prefill-size "$CHUNKED_PREFILL_SIZE"
--tool-call-parser deepseekv4
--reasoning-parser deepseek-v4
--chat-template "$SCRIPT_DIR/../chat_templates/deepseek_v4_thinking.jinja"
--watchdog-timeout 1800
--speculative-algorithm EAGLE
--speculative-num-steps 3
--speculative-eagle-topk 1
--speculative-num-draft-tokens 4
# The B200 checkpoint lives on Lustre. Partition sequential prefetching
# across local ranks so post-load weight repacking reads from page cache
# instead of issuing redundant fragmented mmap faults from every rank.
--weight-loader-prefetch-checkpoints
"${MODEL_ARGS[@]}"
"${METRICS_ARGS[@]}"
"${CACHE_ARGS[@]}"
)

write_command "$RESULT_DIR/sglang_command.txt" "${SGLANG_CMD[@]}"

{
echo "=== SGLANG_* env vars at launch ==="
env | grep -E '^SGLANG_' | sort
echo "==================================="
} | tee "$SERVER_LOG"

echo "Starting SGLang server for B200..."
"${SGLANG_CMD[@]}" >> "$SERVER_LOG" 2>&1 &
SERVER_PID=$!
echo "Server PID: $SERVER_PID"

capture_cache_metrics() {
{
echo "=== SGLang cache metrics snapshot $(date --iso-8601=seconds) ==="
curl -fsS "http://localhost:$SGLANG_BACKEND_PORT/metrics" 2>/dev/null \
| grep -E '^(sglang:(cache_hit_rate|cached_tokens_total|prompt_tokens_total|hicache_host_used_tokens|hicache_host_total_tokens|token_usage|num_requests_running|num_requests_waiting))' \
|| true
echo "============================================================"
} >> "$SERVER_LOG"
}

wait_for_ready \
--endpoint "http://localhost:$SGLANG_BACKEND_PORT/health" \
--log "$SERVER_LOG" \
--pid "$SERVER_PID"

if [ "$USE_SGLANG_ROUTER" = "true" ]; then
echo "Starting SGLang router on port $PORT for $TP DP ranks..."
"${SGLANG_ROUTER_CMD[@]}" \
--worker-urls "http://localhost:$SGLANG_BACKEND_PORT" \
--policy consistent_hashing \
--request-id-headers x-correlation-id \
--dp-aware \
--host 0.0.0.0 \
--port "$PORT" \
--prometheus-host 127.0.0.1 \
--prometheus-port "$SGLANG_ROUTER_METRICS_PORT" \
--connect-timeout-secs 900 \
--request-timeout-secs 14400 \
--disable-health-check \
--disable-retries > "$ROUTER_LOG" 2>&1 &
ROUTER_PID=$!
echo "Router PID: $ROUTER_PID"
wait_for_ready \
--endpoint "http://localhost:$PORT/health" \
--log "$ROUTER_LOG" \
--pid "$ROUTER_PID"
fi

if [ "${#METRICS_ARGS[@]}" -gt 0 ]; then
capture_cache_metrics
trap capture_cache_metrics EXIT
fi
Comment on lines +261 to +264

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 The EXIT trap guard if [ "${#METRICS_ARGS[@]}" -gt 0 ] at line 259 is always true, since METRICS_ARGS is set unconditionally at line 103 to a fixed 2-element array and is never emptied or reassigned on any path. It reads as though metrics capture is optional (mirroring the genuinely-conditional CACHE_ARGS pattern above it), but it isn't — either drop the guard or make METRICS_ARGS actually conditional.

Extended reasoning...

The bug: METRICS_ARGS is declared once, unconditionally, at line 103:

METRICS_ARGS=(--enable-metrics --enable-cache-report)

It is never reassigned, appended to, or emptied anywhere else in the script — a grep for METRICS_ARGS across the file turns up exactly three hits: the assignment at line 103, its expansion into SGLANG_CMD at line ~204, and the guard at line 259:

if [ "${#METRICS_ARGS[@]}" -gt 0 ]; then
    capture_cache_metrics
    trap capture_cache_metrics EXIT
fi

Since the array always has exactly 2 elements, ${#METRICS_ARGS[@]} is always 2, and the condition is always true. The if block is dead weight — capture_cache_metrics and the EXIT trap install unconditionally regardless of what this guard says.

Why it's misleading rather than merely redundant: the script has one real precedent for this shape a few lines earlier — CACHE_ARGS. That array starts empty (CACHE_ARGS=()) and is populated only inside the require_agentic_kv_offload_backend hicache branch, so a length check on it is a legitimate runtime conditional. METRICS_ARGS copies that visual pattern (an array-length guard right before use) without the underlying conditionality that makes the pattern meaningful. A reader skimming the script would reasonably assume metrics/cache-report capture is optional in some configuration, when in fact it is always on.

Step-by-step proof:

  1. Line 103 executes unconditionally on every invocation of the script: METRICS_ARGS=(--enable-metrics --enable-cache-report).
  2. No branch (HiCache on/off, DP-attention on/off, eval-only or not) touches METRICS_ARGS again before line 259.
  3. At line 259, ${#METRICS_ARGS[@]} evaluates to 2 in every possible run.
  4. [ 2 -gt 0 ] is always true, so capture_cache_metrics is always invoked immediately and the trap capture_cache_metrics EXIT is always installed.
  5. Therefore no execution path skips this block — the guard has no observable effect on behavior.

Impact: none functionally — this doesn't change program behavior since the branch is always taken anyway. It's purely a readability/maintainability nit: a future editor could plausibly try to make metrics capture conditional by clearing METRICS_ARGS somewhere, not realizing the guard already silently assumed that possibility without it ever occurring.

Fix: either (a) drop the if and call capture_cache_metrics/install the trap unconditionally, since metrics are always enabled, or (b) if optional metrics capture was actually intended, make METRICS_ARGS conditionally empty (e.g., only set it under a flag) so the guard reflects real behavior.


if [ "${EVAL_ONLY}" = "true" ]; then
run_eval --port "$PORT"
else
build_replay_cmd "$RESULT_DIR"
REPLAY_CMD+=" --server-metrics http://localhost:$SGLANG_BACKEND_PORT/metrics"
run_agentic_replay_and_write_outputs "$RESULT_DIR"
fi
17 changes: 17 additions & 0 deletions configs/nvidia-master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,23 @@ dsv4-fp4-b200-sglang:
# DP-attention (DP_ATTENTION=true) — max-throughput CONC range
- { tp: 8, ep: 8, dp-attn: true, conc-start: 256, conc-end: 1024 }

dsv4-fp4-b200-sglang-agentic-hicache-mtp:
image: lmsysorg/sglang:v0.5.17-cu130
model: deepseek-ai/DeepSeek-V4-Pro
model-prefix: dsv4
runner: cluster:b200-dgxc
precision: fp4
framework: sglang
multinode: false
scenarios:
agentic-coding:
- dram-utilization: 0.80
search-space:
- { tp: 8, kv-offloading: none, spec-decoding: mtp, conc-list: [1, 2, 3, 4, 5] }
- { tp: 8, kv-offloading: dram, kv-offload-backend: { name: hicache }, spec-decoding: mtp, conc-list: [8, 10, 16, 32, 40, 44] }
- { tp: 8, ep: 8, dp-attn: true, kv-offloading: none, spec-decoding: mtp, conc-list: [16, 24, 32, 38, 44, 48, 50, 52], router: { name: sglang-router, version: "0.3.2" } }
- { tp: 8, ep: 8, dp-attn: true, kv-offloading: dram, kv-offload-backend: { name: hicache }, spec-decoding: mtp, conc-list: [16, 32, 38, 44, 50, 56, 64, 66, 68], router: { name: sglang-router, version: "0.3.2" } }

dsv4-fp4-b200-vllm:
image: vllm/vllm-openai:v0.25.0
model: deepseek-ai/DeepSeek-V4-Pro
Expand Down
10 changes: 10 additions & 0 deletions perf-changelog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5918,6 +5918,16 @@
- "Add a TEP2 arm (tp 2, ep 2) to the qwen3.5-fp4-b200-sglang-mtp 8k/1k sweep at concurrency 16, 32, and 64"
- "Rides on the NVFP4-V2 checkpoint switch from #2205"
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2550

- config-keys:
- dsv4-fp4-b200-sglang-agentic-hicache-mtp
scenario-type:
- agentic-coding
description:
- "Refresh the purged B200 DeepSeek-V4-Pro SGLang AgentX resident, DP-attention, and HiCache grid on SGLang v0.5.17."
- "Use native EAGLE MTP (3 steps, top-k 1, 4 draft tokens) and golden synthetic acceptance length 2.49 for throughput; eval retains real verification."
- "Follow the official SGLang DeepSeek-V4 Blackwell recipe, require nonempty SGLang server metrics, and keep pooled AgentX connections alive across inter-turn gaps."
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2578

- config-keys:
- dsv4-fp4-b300-sglang-agentic-hicache-mtp
Expand Down