[Fix] skip longer contexts after C1 OOM

This commit is contained in:
Quantong Qiu 2026-07-21 14:10:17 +08:00
parent 8e21d8a34f
commit 83f5ea2197
3 changed files with 49 additions and 1 deletions

View File

@ -1,5 +1,8 @@
# sskj — 多平台大模型推理性能基准测试项目 # 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** > **更新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` 回退。 > - 新增 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.9TP2/DP4 因 SM120 Marlin 权重加载 OOM 明确排除。 > - vLLM 覆盖 TP2/DP4、TP4/DP2、TP8/DP1部署固定为 128K context、128 活跃请求、0.9 显存比例SGLang 覆盖 TP4/DP2、TP8/DP1固定为 128K、64、0.9TP2/DP4 因 SM120 Marlin 权重加载 OOM 明确排除。

View File

@ -39,6 +39,8 @@ MEM_FRACTION_STATIC="${MEM_FRACTION_STATIC:-0.90}"
MOE_RUNNER_BACKEND="${MOE_RUNNER_BACKEND:-auto}" MOE_RUNNER_BACKEND="${MOE_RUNNER_BACKEND:-auto}"
CONTEXT_LENGTH="${CONTEXT_LENGTH:-131072}" CONTEXT_LENGTH="${CONTEXT_LENGTH:-131072}"
MAX_RUNNING_REQUESTS="${MAX_RUNNING_REQUESTS:-64}" 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. # Deployment switch. 0 = native sglang venv, 1 = Docker.
USE_DOCKER="${USE_DOCKER:-1}" USE_DOCKER="${USE_DOCKER:-1}"

View File

@ -397,6 +397,7 @@ adaptive_run_shape() {
ADAPTIVE_RESTART_NEEDED=0 ADAPTIVE_RESTART_NEEDED=0
ADAPTIVE_FATAL_WORKLOAD=0 ADAPTIVE_FATAL_WORKLOAD=0
ADAPTIVE_SKIP_CONFIG=0 ADAPTIVE_SKIP_CONFIG=0
ADAPTIVE_SKIP_CONFIG_REASON=""
while (( concurrency <= SEARCH_MAX_CONCURRENCY )); do while (( concurrency <= SEARCH_MAX_CONCURRENCY )); do
local num_prompts=$((concurrency * NUM_PROMPTS_MULTIPLIER)) local num_prompts=$((concurrency * NUM_PROMPTS_MULTIPLIER))
@ -469,6 +470,7 @@ adaptive_run_shape() {
stop_reason="TTFT_GROUP_SKIP_THRESHOLD" stop_reason="TTFT_GROUP_SKIP_THRESHOLD"
shape_status="TTFT_BOUNDARY" shape_status="TTFT_BOUNDARY"
ADAPTIVE_SKIP_CONFIG=1 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}" 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 break
fi fi
@ -536,6 +538,12 @@ adaptive_run_shape() {
fi fi
shape_status="OOM_BOUNDARY" shape_status="OOM_BOUNDARY"
stop_reason="OOM" 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 ADAPTIVE_RESTART_NEEDED=1
break break
elif (( point_rc == 21 )); then 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 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() { adaptive_main() {
local resume_mode=0 local resume_mode=0
local resume_shapes_jsonl="" 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" log "RESUME skip remaining config tp=${tp} dp=${dp}: prior ${prior_ttft_boundary} >= group_skip_threshold=${TTFT_GROUP_SKIP_MS}ms"
continue continue
fi 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}" config_root="${ADAPTIVE_RUN_ROOT}/tp${tp}_dp${dp}"
mkdir -p "${config_root}/raw_outputs" "${config_root}/metrics" \ mkdir -p "${config_root}/raw_outputs" "${config_root}/metrics" \
"${config_root}/logs" "${config_root}/gpu_logs" "${config_root}/logs" "${config_root}/gpu_logs"
@ -907,7 +950,7 @@ PY
break break
fi fi
if (( ADAPTIVE_SKIP_CONFIG == 1 )); then 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 break
fi fi
if (( ADAPTIVE_RESTART_NEEDED == 1 )); then if (( ADAPTIVE_RESTART_NEEDED == 1 )); then