feat(adaptive): add RESUME_RUN_ID resume support and rename DSL to OSL

- Add RESUME_RUN_ID env var for breakpoint resume in adaptive benchmarks.
  When set, the script reuses an existing result directory and skips
  already-tested (TP, DP, ISL, OSL) shapes based on adaptive_shapes.jsonl.
- Fix RUN_ID unbound variable in resume mode.
- Fix jq query to use -s (slurp) for jsonl files.
- Add resume skip logic to DRY_RUN mode as well.
- Rename DSL -> OSL across all adaptive benchmark files for consistency:
  - scripts/common/adaptive_bench_lib.sh
  - scripts/common/adaptive_concurrency.py
  - experiments/dsv4_h200_vllm_tp_dp_matrix/adaptive_config.env
  - experiments/dsv4_h200_vllm_tp_dp_matrix/run_adaptive_concurrency.sh
  - experiments/dsv4_h200_sglang_tp_dp_matrix/adaptive_config.env
  - experiments/dsv4_h200_sglang_tp_dp_matrix/run_adaptive_concurrency.sh
  - experiments/ADAPTIVE_CONCURRENCY_USAGE.md
This commit is contained in:
Quantong Qiu 2026-07-14 10:41:01 +00:00
parent 60826dda09
commit e0ae0715b1
7 changed files with 121 additions and 71 deletions

View File

@ -1,6 +1,6 @@
# 自适应并发 Benchmark 使用说明
这套脚本对每个固定的 `(TP, DP, ISL, DSL)` 依次测试
这套脚本对每个固定的 `(TP, DP, ISL, OSL)` 依次测试
`C=1,2,4,8,...`,直到 Total TPS 连续两次增长不足 2%,或达到并发上限、
发生 OOM。每个正式测点发送 `C * 5` 个请求,并先用相同并发 C warm-up。
@ -26,7 +26,7 @@ bash run_adaptive_concurrency.sh
## 2. 先 dry-run
只打印 TP/DP、ISL/DSL 和并发搜索计划,不加载模型:
只打印 TP/DP、ISL/OSL 和并发搜索计划,不加载模型:
```bash
DRY_RUN=1 bash run_adaptive_concurrency.sh
@ -34,13 +34,13 @@ DRY_RUN=1 bash run_adaptive_concurrency.sh
## 3. 单组合 smoke
只测 `TP=8, DP=1, ISL=1K, DSL=128`,并发搜索到 8
只测 `TP=8, DP=1, ISL=1K, OSL=128`,并发搜索到 8
```bash
RUN_ID=smoke-$(date +%Y%m%d-%H%M%S) \
TP_LIST="8" \
ISL_LIST="1024" \
DSL_LIST="128" \
OSL_LIST="128" \
GRID_LIMIT=1 \
SEARCH_MAX_CONCURRENCY=8 \
RESULT_BASE=/data3/yy/sskj_adaptive_results/smoke \
@ -97,8 +97,8 @@ bash run_adaptive_concurrency.sh
- vLLM 端口用 `VLLM_PORT`SGLang 端口用 `SGLANG_PORT`
- `TP_LIST="8"` 只跑 TP=8DP 使用 `config.env` 中对应的 TP/DP 组合。
- `ISL_LIST="1024 4096"``DSL_LIST="128 256"` 用来筛选长度。
- `GRID_LIMIT=1` 表示每组 TP/DP 只跑一个 ISL/DSL shape。
- `ISL_LIST="1024 4096"``OSL_LIST="128 256"` 用来筛选长度。
- `GRID_LIMIT=1` 表示每组 TP/DP 只跑一个 ISL/OSL shape。
- `BENCH_WARMUP_MAX_REQUESTS=0` 表示每个测点用完整并发 C warm-up正数表示上限。
- 正式基线保持 `BENCH_DATASET_NAME=random``RANDOM_RANGE_RATIO=1.0`
- `random-ids` 只用于检查链路,不与正式 ShareGPT-backed 结果混用。
@ -112,7 +112,7 @@ bash run_adaptive_concurrency.sh
```text
adaptive_points.csv 每个并发测点的 TPS、TTFT、TPOT 等
adaptive_summary.csv 每个 ISL/DSL/TP/DP 的饱和并发和最佳 TPS 并发
adaptive_summary.csv 每个 ISL/OSL/TP/DP 的饱和并发和最佳 TPS 并发
adaptive_summary.md 可直接阅读的汇总表
run_manifest.json 本次模型、数据集和搜索参数
logs/ 编排与服务日志

View File

@ -1,6 +1,6 @@
# Adaptive concurrency search settings.
#
# For each fixed (TP, DP, ISL, DSL), probe:
# For each fixed (TP, DP, ISL, OSL), probe:
# C = start, start * multiplier, ... up to max
# and stop after Total TPS has less than TPS_MIN_GAIN_PCT meaningful growth for
# PLATEAU_PATIENCE consecutive points.
@ -21,7 +21,7 @@ PLATEAU_PATIENCE="${PLATEAU_PATIENCE:-2}"
# random-ids to use generated token IDs without a ShareGPT seed dataset.
BENCH_DATASET_NAME="${BENCH_DATASET_NAME:-random}"
# SGLang interprets 0.0 as Uniform[1, requested_len]. Use 1.0 for fixed
# ISL/DSL points; lower values intentionally benchmark a length distribution.
# ISL/OSL points; lower values intentionally benchmark a length distribution.
RANDOM_RANGE_RATIO="${RANDOM_RANGE_RATIO:-1.0}"
# Before each measured point, warm up with the same concurrency so lazy kernel
# compilation and CUDA graph capture are excluded from TTFT/TPS. 0 means no
@ -39,11 +39,11 @@ SCENARIO_TIMEOUT_S="${SCENARIO_TIMEOUT_S:-1800}"
GPU_MEM_SAMPLE_INTERVAL_S="${GPU_MEM_SAMPLE_INTERVAL_S:-1}"
# Optional space-separated filters, useful for smoke tests:
# TP_LIST="8" ISL_LIST="1024" DSL_LIST="128"
# TP_LIST="8" ISL_LIST="1024" OSL_LIST="128"
TP_LIST="${TP_LIST:-}"
ISL_LIST="${ISL_LIST:-}"
DSL_LIST="${DSL_LIST:-}"
OSL_LIST="${OSL_LIST:-}"
DRY_RUN="${DRY_RUN:-0}"
# Counts ISL/DSL shapes per TP/DP config, not individual concurrency probes.
# Counts ISL/OSL shapes per TP/DP config, not individual concurrency probes.
GRID_LIMIT="${GRID_LIMIT:-0}"

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
# Find the Total-TPS saturation concurrency for each SGLang TP/DP/ISL/DSL shape.
# Find the Total-TPS saturation concurrency for each SGLang TP/DP/ISL/OSL shape.
set -Eeuo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@ -130,7 +130,7 @@ engine_detect_oom() {
engine_run_bench() {
local isl="$1"
local dsl="$2"
local osl="$2"
local concurrency="$3"
local num_prompts="$4"
local output_file="$5"
@ -142,7 +142,7 @@ engine_run_bench() {
--port "$ENGINE_PORT"
--dataset-name "$BENCH_DATASET_NAME"
--random-input-len "$isl"
--random-output-len "$dsl"
--random-output-len "$osl"
--random-range-ratio "$RANDOM_RANGE_RATIO"
--num-prompts "$num_prompts"
--max-concurrency "$concurrency"

View File

@ -1,6 +1,6 @@
# Adaptive concurrency search settings.
#
# For each fixed (TP, DP, ISL, DSL), probe:
# For each fixed (TP, DP, ISL, OSL), probe:
# C = start, start * multiplier, ... up to max
# and stop after Total TPS has less than TPS_MIN_GAIN_PCT meaningful growth for
# PLATEAU_PATIENCE consecutive points.
@ -21,7 +21,7 @@ PLATEAU_PATIENCE="${PLATEAU_PATIENCE:-2}"
# random-ids to use generated token IDs without a ShareGPT seed dataset.
BENCH_DATASET_NAME="${BENCH_DATASET_NAME:-random}"
# SGLang interprets 0.0 as Uniform[1, requested_len]. Use 1.0 for fixed
# ISL/DSL points; lower values intentionally benchmark a length distribution.
# ISL/OSL points; lower values intentionally benchmark a length distribution.
RANDOM_RANGE_RATIO="${RANDOM_RANGE_RATIO:-1.0}"
# Before each measured point, warm up with the same concurrency so lazy kernel
# compilation and CUDA graph capture are excluded from TTFT/TPS. 0 means no
@ -39,11 +39,11 @@ SCENARIO_TIMEOUT_S="${SCENARIO_TIMEOUT_S:-1800}"
GPU_MEM_SAMPLE_INTERVAL_S="${GPU_MEM_SAMPLE_INTERVAL_S:-1}"
# Optional space-separated filters, useful for smoke tests:
# TP_LIST="8" ISL_LIST="1024" DSL_LIST="128"
# TP_LIST="8" ISL_LIST="1024" OSL_LIST="128"
TP_LIST="${TP_LIST:-}"
ISL_LIST="${ISL_LIST:-}"
DSL_LIST="${DSL_LIST:-}"
OSL_LIST="${OSL_LIST:-}"
DRY_RUN="${DRY_RUN:-0}"
# Counts ISL/DSL shapes per TP/DP config, not individual concurrency probes.
# Counts ISL/OSL shapes per TP/DP config, not individual concurrency probes.
GRID_LIMIT="${GRID_LIMIT:-0}"

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
# Find the Total-TPS saturation concurrency for each vLLM TP/DP/ISL/DSL shape.
# Find the Total-TPS saturation concurrency for each vLLM TP/DP/ISL/OSL shape.
set -Eeuo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@ -111,7 +111,7 @@ engine_detect_oom() {
engine_run_bench() {
local isl="$1"
local dsl="$2"
local osl="$2"
local concurrency="$3"
local num_prompts="$4"
local output_file="$5"
@ -123,7 +123,7 @@ engine_run_bench() {
--port "$ENGINE_PORT"
--dataset-name "$BENCH_DATASET_NAME"
--random-input-len "$isl"
--random-output-len "$dsl"
--random-output-len "$osl"
--random-range-ratio "$RANDOM_RANGE_RATIO"
--num-prompts "$num_prompts"
--max-concurrency "$concurrency"

View File

@ -115,7 +115,7 @@ adaptive_append_point_from_metrics() {
local dp="$3"
local mark="$4"
local isl="$5"
local dsl="$6"
local osl="$6"
local concurrency="$7"
local num_prompts="$8"
local attempt="$9"
@ -133,7 +133,7 @@ adaptive_append_point_from_metrics() {
--argjson dp "$dp" \
--arg mark "$mark" \
--argjson isl "$isl" \
--argjson dsl "$dsl" \
--argjson osl "$osl" \
--argjson concurrency "$concurrency" \
--argjson num_prompts "$num_prompts" \
--argjson warmup_requests "$(adaptive_warmup_request_count "$concurrency")" \
@ -149,7 +149,7 @@ adaptive_append_point_from_metrics() {
dp: $dp,
mark: $mark,
isl: $isl,
dsl: $dsl,
osl: $osl,
concurrency: $concurrency,
num_prompts: $num_prompts,
warmup_requests: $warmup_requests,
@ -167,7 +167,7 @@ adaptive_append_failed_point() {
local dp="$2"
local mark="$3"
local isl="$4"
local dsl="$5"
local osl="$5"
local concurrency="$6"
local num_prompts="$7"
local attempt="$8"
@ -183,7 +183,7 @@ adaptive_append_failed_point() {
--argjson dp "$dp" \
--arg mark "$mark" \
--argjson isl "$isl" \
--argjson dsl "$dsl" \
--argjson osl "$osl" \
--argjson concurrency "$concurrency" \
--argjson num_prompts "$num_prompts" \
--argjson warmup_requests "$(adaptive_warmup_request_count "$concurrency")" \
@ -199,7 +199,7 @@ adaptive_append_failed_point() {
dp: $dp,
mark: $mark,
isl: $isl,
dsl: $dsl,
osl: $osl,
concurrency: $concurrency,
num_prompts: $num_prompts,
warmup_requests: $warmup_requests,
@ -221,7 +221,7 @@ adaptive_append_shape_summary() {
local dp="$2"
local mark="$3"
local isl="$4"
local dsl="$5"
local osl="$5"
local status="$6"
local stop_reason="$7"
local tested_points="$8"
@ -245,7 +245,7 @@ adaptive_append_shape_summary() {
--argjson dp "$dp" \
--arg mark "$mark" \
--argjson isl "$isl" \
--argjson dsl "$dsl" \
--argjson osl "$osl" \
--arg status "$status" \
--arg stop_reason "$stop_reason" \
--argjson tested_points "$tested_points" \
@ -263,7 +263,7 @@ adaptive_append_shape_summary() {
dp: $dp,
mark: $mark,
isl: $isl,
dsl: $dsl,
osl: $osl,
status: $status,
stop_reason: $stop_reason,
tested_points: $tested_points,
@ -281,7 +281,7 @@ adaptive_run_point() {
local tp="$1"
local dp="$2"
local isl="$3"
local dsl="$4"
local osl="$4"
local concurrency="$5"
local num_prompts="$6"
local config_root="$7"
@ -295,17 +295,17 @@ adaptive_run_point() {
for (( attempt = 1; attempt <= MAX_POINT_RETRIES + 1; attempt++ )); do
POINT_ATTEMPT="$attempt"
POINT_RAW_FILE="${config_root}/raw_outputs/${ENGINE}_adaptive_c${concurrency}_i${isl}_o${dsl}_a${attempt}.jsonl"
POINT_DETAIL_LOG="${config_root}/logs/${ENGINE}_c${concurrency}_i${isl}_o${dsl}_a${attempt}.log"
POINT_METRICS_FILE="${config_root}/metrics/${ENGINE}_c${concurrency}_i${isl}_o${dsl}_a${attempt}.json"
local gpu_csv="${config_root}/gpu_logs/gpu_c${concurrency}_i${isl}_o${dsl}_a${attempt}.csv"
POINT_RAW_FILE="${config_root}/raw_outputs/${ENGINE}_adaptive_c${concurrency}_i${isl}_o${osl}_a${attempt}.jsonl"
POINT_DETAIL_LOG="${config_root}/logs/${ENGINE}_c${concurrency}_i${isl}_o${osl}_a${attempt}.log"
POINT_METRICS_FILE="${config_root}/metrics/${ENGINE}_c${concurrency}_i${isl}_o${osl}_a${attempt}.json"
local gpu_csv="${config_root}/gpu_logs/gpu_c${concurrency}_i${isl}_o${osl}_a${attempt}.csv"
log "probe ${ENGINE} tp=${tp} dp=${dp} isl=${isl} dsl=${dsl} c=${concurrency} warmup=$(adaptive_warmup_request_count "$concurrency") n=${num_prompts} attempt=${attempt}"
log "probe ${ENGINE} tp=${tp} dp=${dp} isl=${isl} osl=${osl} c=${concurrency} warmup=$(adaptive_warmup_request_count "$concurrency") n=${num_prompts} attempt=${attempt}"
gpu_pid="$(adaptive_start_gpu_monitor "$gpu_csv")"
bench_rc=0
timeout "$SCENARIO_TIMEOUT_S" bash -c \
'engine_run_bench "$@"' _ \
"$isl" "$dsl" "$concurrency" "$num_prompts" "$POINT_RAW_FILE" \
"$isl" "$osl" "$concurrency" "$num_prompts" "$POINT_RAW_FILE" \
> "$POINT_DETAIL_LOG" 2>&1 || bench_rc=$?
adaptive_stop_gpu_monitor "$gpu_pid"
@ -316,7 +316,7 @@ adaptive_run_point() {
--output "$POINT_METRICS_FILE" \
--expected-prompts "$num_prompts" \
--isl "$isl" \
--dsl "$dsl" \
--osl "$osl" \
--input-tolerance-pct "$INPUT_LENGTH_TOLERANCE_PCT" \
--output-tolerance-pct "$OUTPUT_LENGTH_TOLERANCE_PCT" \
>> "$POINT_DETAIL_LOG" 2>&1 || parse_rc=$?
@ -350,7 +350,7 @@ adaptive_run_shape() {
local dp="$2"
local mark="$3"
local isl="$4"
local dsl="$5"
local osl="$5"
local config_root="$6"
local concurrency="$SEARCH_START_CONCURRENCY"
local previous_tps=""
@ -376,7 +376,7 @@ adaptive_run_shape() {
while (( concurrency <= SEARCH_MAX_CONCURRENCY )); do
local num_prompts=$((concurrency * NUM_PROMPTS_MULTIPLIER))
point_rc=0
adaptive_run_point "$tp" "$dp" "$isl" "$dsl" "$concurrency" "$num_prompts" "$config_root" || point_rc=$?
adaptive_run_point "$tp" "$dp" "$isl" "$osl" "$concurrency" "$num_prompts" "$config_root" || point_rc=$?
tested_points=$((tested_points + 1))
stop_probe_concurrency="$concurrency"
@ -409,7 +409,7 @@ adaptive_run_shape() {
max_successful_concurrency="$concurrency"
last_total_tps="$current_tps"
adaptive_append_point_from_metrics \
"$POINT_METRICS_FILE" "$tp" "$dp" "$mark" "$isl" "$dsl" \
"$POINT_METRICS_FILE" "$tp" "$dp" "$mark" "$isl" "$osl" \
"$concurrency" "$num_prompts" "$POINT_ATTEMPT" "$gain_pct" \
"$plateau_streak" "$POINT_RAW_FILE" "$POINT_DETAIL_LOG"
@ -422,7 +422,7 @@ adaptive_run_shape() {
previous_tps="$current_tps"
elif (( point_rc == 20 )); then
adaptive_append_failed_point \
"$tp" "$dp" "$mark" "$isl" "$dsl" "$concurrency" "$num_prompts" \
"$tp" "$dp" "$mark" "$isl" "$osl" "$concurrency" "$num_prompts" \
"$POINT_ATTEMPT" "OOM" "$POINT_ERROR_TYPE" "$POINT_RAW_FILE" "$POINT_DETAIL_LOG"
shape_status="OOM_BOUNDARY"
stop_reason="OOM"
@ -430,7 +430,7 @@ adaptive_run_shape() {
break
elif (( point_rc == 21 )); then
adaptive_append_point_from_metrics \
"$POINT_METRICS_FILE" "$tp" "$dp" "$mark" "$isl" "$dsl" \
"$POINT_METRICS_FILE" "$tp" "$dp" "$mark" "$isl" "$osl" \
"$concurrency" "$num_prompts" "$POINT_ATTEMPT" "" 0 \
"$POINT_RAW_FILE" "$POINT_DETAIL_LOG"
shape_status="INVALID_WORKLOAD"
@ -439,7 +439,7 @@ adaptive_run_shape() {
break
else
adaptive_append_failed_point \
"$tp" "$dp" "$mark" "$isl" "$dsl" "$concurrency" "$num_prompts" \
"$tp" "$dp" "$mark" "$isl" "$osl" "$concurrency" "$num_prompts" \
"$POINT_ATTEMPT" "FAILED" "$POINT_ERROR_TYPE" "$POINT_RAW_FILE" "$POINT_DETAIL_LOG"
shape_status="FAILED"
stop_reason="BENCHMARK_FAILED"
@ -464,11 +464,11 @@ adaptive_run_shape() {
done
adaptive_append_shape_summary \
"$tp" "$dp" "$mark" "$isl" "$dsl" "$shape_status" "$stop_reason" \
"$tp" "$dp" "$mark" "$isl" "$osl" "$shape_status" "$stop_reason" \
"$tested_points" "$max_successful_concurrency" "$saturation_concurrency" \
"$stop_probe_concurrency" "$best_concurrency" "$best_tps" "$last_total_tps"
log "shape done tp=${tp} dp=${dp} isl=${isl} dsl=${dsl} stop=${stop_reason} saturation_c=${saturation_concurrency:-none} best_c=${best_concurrency:-none} best_total_tps=${best_tps:-none}"
log "shape done tp=${tp} dp=${dp} isl=${isl} osl=${osl} stop=${stop_reason} saturation_c=${saturation_concurrency:-none} best_c=${best_concurrency:-none} best_total_tps=${best_tps:-none}"
}
adaptive_matches_filter() {
@ -507,19 +507,61 @@ adaptive_cleanup_active_server() {
fi
}
adaptive_shape_already_tested() {
local tp="$1"
local dp="$2"
local mark="$3"
local isl="$4"
local osl="$5"
local resume_shapes_jsonl="$6"
if [[ ! -f "$resume_shapes_jsonl" ]]; then
return 1
fi
local count
count="$(jq -s -r --argjson tp "$tp" --argjson dp "$dp" --arg mark "$mark" --argjson isl "$isl" --argjson osl "$osl" '
[ .[] | select(.tp == $tp and .dp == $dp and .mark == $mark and .isl == $isl and .osl == $osl) ] | length
' "$resume_shapes_jsonl" 2>/dev/null)"
if [[ -z "$count" ]]; then
return 1
fi
if (( count > 0 )); then
return 0
fi
return 1
}
adaptive_main() {
RUN_ID="${RUN_ID:-adaptive_$(date '+%Y%m%d-%H%M%S')}"
local resume_mode=0
local resume_shapes_jsonl=""
if [[ -n "${RESUME_RUN_ID:-}" ]]; then
ADAPTIVE_RUN_ROOT="${RESULT_BASE}/${RESUME_RUN_ID}"
if [[ ! -d "$ADAPTIVE_RUN_ROOT" ]]; then
log "ERROR: RESUME_RUN_ID=${RESUME_RUN_ID} does not exist under ${RESULT_BASE}"
return 1
fi
resume_mode=1
RUN_ID="$RESUME_RUN_ID"
resume_shapes_jsonl="${ADAPTIVE_RUN_ROOT}/adaptive_shapes.jsonl"
if [[ ! -f "$resume_shapes_jsonl" ]]; then
log "WARNING: no adaptive_shapes.jsonl found in ${ADAPTIVE_RUN_ROOT}; will resume with empty history"
fi
log "RESUME mode: continuing run_id=${RESUME_RUN_ID}"
else
RUN_ID="${RUN_ID:-adaptive_$(date '+%Y%m%d-%H%M%S')}"
ADAPTIVE_RUN_ROOT="${RESULT_BASE}/${RUN_ID}"
fi
RESULT_BASE="${RESULT_BASE:-${SCRIPT_DIR}/adaptive_results}"
MATRIX_FILE="${MATRIX_FILE:-${SCRIPT_DIR}/matrix.json}"
MATRIX_MODE="${MATRIX_MODE:-Y}"
ADAPTIVE_RUN_ROOT="${RESULT_BASE}/${RUN_ID}"
ADAPTIVE_LOG_DIR="${ADAPTIVE_RUN_ROOT}/logs"
ADAPTIVE_POINTS_JSONL="${ADAPTIVE_RUN_ROOT}/adaptive_points.jsonl"
ADAPTIVE_SHAPES_JSONL="${ADAPTIVE_RUN_ROOT}/adaptive_shapes.jsonl"
local shapes_tsv="${ADAPTIVE_RUN_ROOT}/shapes.tsv"
mkdir -p "$ADAPTIVE_LOG_DIR"
: > "$ADAPTIVE_POINTS_JSONL"
: > "$ADAPTIVE_SHAPES_JSONL"
if (( resume_mode == 0 )); then
: > "$ADAPTIVE_POINTS_JSONL"
: > "$ADAPTIVE_SHAPES_JSONL"
fi
log_init "${ADAPTIVE_LOG_DIR}/orchestrator.log"
adaptive_validate_config
@ -611,7 +653,7 @@ adaptive_main() {
trap 'adaptive_cleanup_active_server; exit 143' TERM
local abort_all=0
local cfg tp dp config_root server_args shape_count mark isl dsl
local cfg tp dp config_root server_args shape_count mark isl osl
for cfg in "${PARALLEL_CONFIGS[@]}"; do
read -r tp dp <<< "$cfg"
if ! adaptive_matches_filter "$tp" "$TP_LIST"; then
@ -626,15 +668,19 @@ adaptive_main() {
if [[ "$DRY_RUN" == "1" ]]; then
log "DRY_RUN server tp=${tp} dp=${dp}: ${server_args}"
shape_count=0
while IFS=$'\t' read -r mark isl dsl; do
while IFS=$'\t' read -r mark isl osl; do
[[ "$mark" == "mark" ]] && continue
adaptive_matches_filter "$isl" "$ISL_LIST" || continue
adaptive_matches_filter "$dsl" "$DSL_LIST" || continue
adaptive_matches_filter "$osl" "$OSL_LIST" || continue
if (( GRID_LIMIT > 0 && shape_count >= GRID_LIMIT )); then
break
fi
shape_count=$((shape_count + 1))
log "DRY_RUN tp=${tp} dp=${dp} isl=${isl} dsl=${dsl} C=[$(adaptive_print_sequence)]"
if (( resume_mode == 1 )) && adaptive_shape_already_tested "$tp" "$dp" "$mark" "$isl" "$osl" "$resume_shapes_jsonl"; then
log "DRY_RUN RESUME skip already tested shape tp=${tp} dp=${dp} isl=${isl} osl=${osl} mark=${mark}"
continue
fi
log "DRY_RUN tp=${tp} dp=${dp} isl=${isl} osl=${osl} C=[$(adaptive_print_sequence)]"
done < "$shapes_tsv"
continue
fi
@ -653,17 +699,21 @@ adaptive_main() {
}
shape_count=0
while IFS=$'\t' read -r mark isl dsl; do
while IFS=$'\t' read -r mark isl osl; do
[[ "$mark" == "mark" ]] && continue
adaptive_matches_filter "$isl" "$ISL_LIST" || continue
adaptive_matches_filter "$dsl" "$DSL_LIST" || continue
adaptive_matches_filter "$osl" "$OSL_LIST" || continue
if (( GRID_LIMIT > 0 && shape_count >= GRID_LIMIT )); then
log "GRID_LIMIT=${GRID_LIMIT} reached for tp=${tp} dp=${dp}"
break
fi
shape_count=$((shape_count + 1))
log "===== shape START tp=${tp} dp=${dp} isl=${isl} dsl=${dsl} mark=${mark} ====="
adaptive_run_shape "$tp" "$dp" "$mark" "$isl" "$dsl" "$config_root"
if (( resume_mode == 1 )) && adaptive_shape_already_tested "$tp" "$dp" "$mark" "$isl" "$osl" "$resume_shapes_jsonl"; then
log "RESUME skip already tested shape tp=${tp} dp=${dp} isl=${isl} osl=${osl} mark=${mark}"
continue
fi
log "===== shape START tp=${tp} dp=${dp} isl=${isl} osl=${osl} mark=${mark} ====="
adaptive_run_shape "$tp" "$dp" "$mark" "$isl" "$osl" "$config_root"
if (( ADAPTIVE_FATAL_WORKLOAD == 1 )); then
log "ERROR: invalid synthetic workload; aborting remaining searches"

View File

@ -17,7 +17,7 @@ POINT_FIELDS = [
"dp",
"mark",
"isl",
"dsl",
"osl",
"concurrency",
"num_prompts",
"warmup_requests",
@ -60,7 +60,7 @@ SHAPE_FIELDS = [
"dp",
"mark",
"isl",
"dsl",
"osl",
"status",
"stop_reason",
"tested_points",
@ -114,16 +114,16 @@ def command_shapes(args: argparse.Namespace) -> int:
mode = args.mode or data.get("mode", "Y")
print("mark\tinput_len\toutput_len")
for isl_text in sorted(data["matrix"], key=int):
dsl_map = data["matrix"][isl_text]
for dsl_text in sorted(dsl_map, key=int):
mark = dsl_map[dsl_text]
osl_map = data["matrix"][isl_text]
for osl_text in sorted(osl_map, key=int):
mark = osl_map[osl_text]
if mode == "Y" and mark != "Y":
continue
if mode == "Y+P" and mark not in ("Y", "P"):
continue
if mode != "all" and mark == "N":
continue
print(f"{mark}\t{int(isl_text)}\t{int(dsl_text)}")
print(f"{mark}\t{int(isl_text)}\t{int(osl_text)}")
return 0
@ -175,8 +175,8 @@ def command_parse_result(args: argparse.Namespace) -> int:
f"mean_input_tokens={mean_input:.2f}, expected_range={input_low:.2f}-{input_high:.2f}"
)
output_low = args.dsl * (1.0 - args.output_tolerance_pct / 100.0)
output_high = args.dsl * (1.0 + args.output_tolerance_pct / 100.0)
output_low = args.osl * (1.0 - args.output_tolerance_pct / 100.0)
output_high = args.osl * (1.0 + args.output_tolerance_pct / 100.0)
if not output_low <= mean_output <= output_high:
validation_errors.append(
f"mean_output_tokens={mean_output:.2f}, expected_range={output_low:.2f}-{output_high:.2f}"
@ -256,12 +256,12 @@ def command_summarize(args: argparse.Namespace) -> int:
with report.open("w", encoding="utf-8") as f:
f.write("# Adaptive concurrency search summary\n\n")
f.write(
"| Engine | TP | DP | ISL | DSL | Stop | Saturation C | Best TPS C | Best Total TPS | Max successful C |\n"
"| Engine | TP | DP | ISL | OSL | Stop | Saturation C | Best TPS C | Best Total TPS | Max successful C |\n"
)
f.write("|---|---:|---:|---:|---:|---|---:|---:|---:|---:|\n")
for row in shapes:
f.write(
"| {engine} | {tp} | {dp} | {isl} | {dsl} | {stop_reason} | "
"| {engine} | {tp} | {dp} | {isl} | {osl} | {stop_reason} | "
"{saturation_concurrency} | {best_tps_concurrency} | {best_total_tps} | "
"{max_successful_concurrency} |\n".format(**{k: row.get(k, "") for k in SHAPE_FIELDS})
)
@ -292,7 +292,7 @@ def build_parser() -> argparse.ArgumentParser:
parse_result.add_argument("--output", type=Path, required=True)
parse_result.add_argument("--expected-prompts", type=int, required=True)
parse_result.add_argument("--isl", type=int, required=True)
parse_result.add_argument("--dsl", type=int, required=True)
parse_result.add_argument("--osl", type=int, required=True)
parse_result.add_argument("--input-tolerance-pct", type=float, default=5.0)
parse_result.add_argument("--output-tolerance-pct", type=float, default=10.0)
parse_result.set_defaults(func=command_parse_result)