diff --git a/README.md b/README.md index 15c5891..1066e08 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # sskj — 多平台大模型推理性能基准测试项目 +> **更新(2026-07-21 14:00:30 +0800)** +> - adaptive 并发搜索新增可配置的 `C=1 OOM` 配置级短路:同一 TP/DP 在最小并发仍 OOM 时,直接跳过该组更长输入,避免把已经确定不可部署的长度继续压测;6000D DSV4-Flash SGLang tiny 已启用,并支持从已有结果恢复时识别此前的该边界。 + > **更新(2026-07-21 11:54:30 +0800)** > - 新增 RTX 6000D / DeepSeek-V4-Flash tiny 自适应并发实验:输出固定 1K,输入遍历 1K、2K、4K、8K、16K、32K、64K、128K,并发采用 `C=16` 起、每次加 16、首点失败时按 `16 -> 8 -> 1` 回退。 > - vLLM 覆盖 TP2/DP4、TP4/DP2、TP8/DP1,部署固定为 128K context、128 活跃请求、0.9 显存比例;SGLang 覆盖 TP4/DP2、TP8/DP1,固定为 128K、64、0.9,TP2/DP4 因 SM120 Marlin 权重加载 OOM 明确排除。 diff --git a/experiments/pro6000/dsv4_pro6000_sglang_tiny_1k_output/config.env b/experiments/pro6000/dsv4_pro6000_sglang_tiny_1k_output/config.env index 0eed7e1..d87a55e 100644 --- a/experiments/pro6000/dsv4_pro6000_sglang_tiny_1k_output/config.env +++ b/experiments/pro6000/dsv4_pro6000_sglang_tiny_1k_output/config.env @@ -39,6 +39,8 @@ MEM_FRACTION_STATIC="${MEM_FRACTION_STATIC:-0.90}" MOE_RUNNER_BACKEND="${MOE_RUNNER_BACKEND:-auto}" CONTEXT_LENGTH="${CONTEXT_LENGTH:-131072}" MAX_RUNNING_REQUESTS="${MAX_RUNNING_REQUESTS:-64}" +# A C=1 OOM establishes a hard context-length boundary for this TP/DP group. +SKIP_CONFIG_ON_MIN_CONCURRENCY_OOM="${SKIP_CONFIG_ON_MIN_CONCURRENCY_OOM:-1}" # Deployment switch. 0 = native sglang venv, 1 = Docker. USE_DOCKER="${USE_DOCKER:-1}" diff --git a/scripts/common/adaptive_bench_lib.sh b/scripts/common/adaptive_bench_lib.sh index e1e85ac..a9b7151 100755 --- a/scripts/common/adaptive_bench_lib.sh +++ b/scripts/common/adaptive_bench_lib.sh @@ -397,6 +397,7 @@ adaptive_run_shape() { ADAPTIVE_RESTART_NEEDED=0 ADAPTIVE_FATAL_WORKLOAD=0 ADAPTIVE_SKIP_CONFIG=0 + ADAPTIVE_SKIP_CONFIG_REASON="" while (( concurrency <= SEARCH_MAX_CONCURRENCY )); do local num_prompts=$((concurrency * NUM_PROMPTS_MULTIPLIER)) @@ -469,6 +470,7 @@ adaptive_run_shape() { stop_reason="TTFT_GROUP_SKIP_THRESHOLD" shape_status="TTFT_BOUNDARY" ADAPTIVE_SKIP_CONFIG=1 + ADAPTIVE_SKIP_CONFIG_REASON="$stop_reason" log "probe result c=1 total_tps=${current_tps} ttft_p95=${ttft_p95_ms}ms >= group_skip_threshold=${TTFT_GROUP_SKIP_MS}ms; skipping remaining shapes for tp=${tp} dp=${dp}" break fi @@ -536,6 +538,12 @@ adaptive_run_shape() { fi shape_status="OOM_BOUNDARY" stop_reason="OOM" + if (( concurrency == 1 )) && [[ "${SKIP_CONFIG_ON_MIN_CONCURRENCY_OOM:-0}" == "1" ]]; then + stop_reason="MIN_CONCURRENCY_OOM_GROUP_SKIP" + ADAPTIVE_SKIP_CONFIG=1 + ADAPTIVE_SKIP_CONFIG_REASON="$stop_reason" + log "probe result c=1 OOM; skipping remaining shapes for tp=${tp} dp=${dp}" + fi ADAPTIVE_RESTART_NEEDED=1 break elif (( point_rc == 21 )); then @@ -690,6 +698,35 @@ print(f"isl={best[1]} osl={best[2]} c=1 ttft_p95={best[0]:.3f}ms") PY } +adaptive_find_min_concurrency_oom_boundary() { + local tp="$1" + local dp="$2" + local shapes_jsonl="$3" + if [[ "${SKIP_CONFIG_ON_MIN_CONCURRENCY_OOM:-0}" != "1" ]] || [[ ! -f "$shapes_jsonl" ]]; then + return 1 + fi + "$PYTHON" - "$tp" "$dp" "$shapes_jsonl" <<'PY' +import json, sys + +tp, dp = int(sys.argv[1]), int(sys.argv[2]) +with open(sys.argv[3], "r", encoding="utf-8") as f: + for line in f: + try: + shape = json.loads(line) + except json.JSONDecodeError: + continue + if shape.get("tp") != tp or shape.get("dp") != dp: + continue + if shape.get("stop_probe_concurrency") != 1: + continue + if shape.get("stop_reason") not in {"OOM", "MIN_CONCURRENCY_OOM_GROUP_SKIP"}: + continue + print(f"isl={shape.get('isl')} osl={shape.get('osl')} c=1 OOM") + raise SystemExit(0) +raise SystemExit(1) +PY +} + adaptive_main() { local resume_mode=0 local resume_shapes_jsonl="" @@ -845,6 +882,12 @@ PY log "RESUME skip remaining config tp=${tp} dp=${dp}: prior ${prior_ttft_boundary} >= group_skip_threshold=${TTFT_GROUP_SKIP_MS}ms" continue fi + local prior_min_oom_boundary="" + if (( resume_mode == 1 )) && \ + prior_min_oom_boundary="$(adaptive_find_min_concurrency_oom_boundary "$tp" "$dp" "$ADAPTIVE_SHAPES_JSONL")"; then + log "RESUME skip remaining config tp=${tp} dp=${dp}: prior ${prior_min_oom_boundary}" + continue + fi config_root="${ADAPTIVE_RUN_ROOT}/tp${tp}_dp${dp}" mkdir -p "${config_root}/raw_outputs" "${config_root}/metrics" \ "${config_root}/logs" "${config_root}/gpu_logs" @@ -907,7 +950,7 @@ PY break fi if (( ADAPTIVE_SKIP_CONFIG == 1 )); then - log "TTFT group-skip threshold reached; skipping remaining shapes for tp=${tp} dp=${dp}" + log "config skip requested; reason=${ADAPTIVE_SKIP_CONFIG_REASON:-unknown}; skipping remaining shapes for tp=${tp} dp=${dp}" break fi if (( ADAPTIVE_RESTART_NEEDED == 1 )); then