yy-fighting 8652a685e6 rewrite README, add new platform onboarding guide, fix broken scripts/common paths
- rewrite README with project purpose, standard workflow, corrected index
- add docs/NEW_PLATFORM_GUIDE.md (new GPU onboarding SOP, GLM5.2 reuse)
- fix ../../scripts/common -> ../../../scripts/common in 42 experiment scripts
- refresh stale docs (EXPERIMENT_GUIDE, H200_QUICKSTART, ADAPTIVE_CONCURRENCY_USAGE, BENCHMARK_WORKFLOW)
- remove dead code (dp_proxy.py) and .bak leftovers
- add p800 adaptive results (tp4_dp2/tp8_dp1 metrics + summary)
- gitignore envs/charts and .tmp_charts
2026-07-17 06:18:05 +00:00

246 lines
8.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Max context length exploration for P800 SGLang INT8.
set -Eeuo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
EXPERIMENT_NAME="$(basename "$SCRIPT_DIR")"
# shellcheck source=/dev/null
source "${SCRIPT_DIR}/../../../scripts/common/lib.sh"
# shellcheck source=/dev/null
source "${SCRIPT_DIR}/../../../scripts/common/platform.sh"
# shellcheck source=/dev/null
source "${SCRIPT_DIR}/config.env"
RUN_ID="${RUN_ID:-$(date '+%Y%m%d-%H%M%S')}"
RESULT_ROOT="${RESULT_ROOT:-${SCRIPT_DIR}/results/${RUN_ID}}"
LOG_DIR="${RESULT_ROOT}/logs"
RAW_DIR="${RESULT_ROOT}/raw_outputs"
CONTAINER_NAME="${CONTAINER_NAME:-sglang-dsv4-flash}"
CONTAINER_PYTHON="${CONTAINER_PYTHON:-/root/miniconda/envs/python310_torch25_cuda/bin/python}"
ensure_result_root "$RESULT_ROOT"
log_init "${LOG_DIR}/orchestrator.log"
log "experiment=${EXPERIMENT_NAME}"
log "run_id=${RUN_ID}"
log "result_root=${RESULT_ROOT}"
log "platform=${PLATFORM}"
log "hardware=${HARDWARE}"
log "model=${MODEL_PATH}"
log "candidate_lengths=${CANDIDATE_LENS[*]}"
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
is_server_healthy() {
curl --fail --silent --show-error --max-time 5 "http://127.0.0.1:${PORT}/health" >/dev/null 2>&1
}
stop_server() {
log "stopping container ${CONTAINER_NAME}"
docker rm -f "$CONTAINER_NAME" 2>/dev/null || true
pkill -9 -f 'sglang.launch_server' 2>/dev/null || true
sleep 2
}
start_server() {
local target_len="$1"
log "starting server (target_len=${target_len})"
bash "${SCRIPT_DIR}/start_server.sh" "$target_len" >> "${LOG_DIR}/start_server_${target_len}.log" 2>&1
}
build_server_args() {
local target_len="$1"
local max_context_len=$(( target_len + CONTEXT_PAD ))
echo "python -m sglang.launch_server --host 0.0.0.0 --port ${PORT} --model-path /models --attention-backend nsa --nsa-prefill klxdsa --nsa-decode klxdsa --trust-remote-code --disable-custom-all-reduce --chunked-prefill-size 8192 --page-size 64 --mem-fraction-static 0.8 --max-prefill-tokens ${max_context_len} --max-running-requests 64 --tensor-parallel-size 8 --ep-size 8 --disable-shared-experts-fusion --quantization w8a8_int8 --kv-cache-dtype float16 --disable-piecewise-cuda-graph --cuda-graph-max-bs 32 --watchdog-timeout 3000000 --tool-call-parser deepseekv4 --reasoning-parser deepseek-v4 --speculative-algorithm EAGLE --speculative-num-steps 3 --speculative-eagle-topk 1 --speculative-num-draft-tokens 4 --constrained-json-disable-any-whitespace --enable-metrics --enable-request-time-stats-logging --context-length ${max_context_len}"
}
append_scenario() {
local scenario_json="$1"
python3 - "$RESULT_JSON" "$scenario_json" <<'PY'
import json
import sys
results_path, scenario_json = sys.argv[1], sys.argv[2]
with open(results_path, "r", encoding="utf-8") as f:
data = json.load(f)
data["scenarios"].append(json.loads(scenario_json))
with open(results_path, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
PY
}
# Build a scenario JSON blob safely with Python.
build_scenario_json() {
local target_len="$1"
local max_context_len="$2"
local success="$3"
local server_args="$4"
local error_msg="$5"
local metrics_json="${6:-null}"
python3 - "$target_len" "$max_context_len" "$success" "$server_args" "$error_msg" "$metrics_json" <<'PY'
import json
import sys
target_len, max_context_len, success, server_args, error_msg, metrics_json = sys.argv[1:7]
metrics = json.loads(metrics_json) if metrics_json not in ("null", "") else None
print(json.dumps({
"backend": "sglang",
"target_len": int(target_len),
"max_context_len": int(max_context_len),
"success": success == "true",
"server_args": server_args,
"metrics": metrics,
"error": error_msg or None,
}, ensure_ascii=False))
PY
}
run_length() {
local target_len="$1"
local max_context_len=$(( target_len + CONTEXT_PAD ))
local output_file="${RAW_DIR}/sglang_ctx_${target_len}.jsonl"
local container_output="/tmp/bench_outputs/sglang_ctx_${target_len}.jsonl"
local detail_log="${LOG_DIR}/sglang_ctx_${target_len}.log"
log "trying sglang target_len=${target_len} (context-length=${max_context_len})"
stop_server
local server_args
server_args="$(build_server_args "$target_len")"
if ! start_server "$target_len"; then
local err="server failed to start"
log "ERROR: ${err}"
append_scenario "$(build_scenario_json "$target_len" "$max_context_len" "false" "$server_args" "$err")"
return 1
fi
docker exec "$CONTAINER_NAME" mkdir -p "$(dirname "$container_output")"
local bench_rc=0
docker exec "$CONTAINER_NAME" \
env HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 HF_DATASETS_OFFLINE=1 \
"${CONTAINER_PYTHON}" -m sglang.bench_serving \
--backend sglang \
--host 127.0.0.1 \
--port "$PORT" \
--model "$MODEL_PATH" \
--dataset-name random \
--dataset-path /workspace/dummy_sharegpt.json \
--random-input-len "$target_len" \
--random-output-len "$OUTPUT_LEN" \
--random-range-ratio 1.0 \
--num-prompts "$NUM_PROMPTS" \
--max-concurrency "$MAX_CONCURRENCY" \
--request-rate "$REQUEST_RATE" \
--output-file "$container_output" \
--output-details \
> "$detail_log" 2>&1 || bench_rc=$?
if [[ "$bench_rc" -ne 0 ]]; then
local err="bench_serving exited with code ${bench_rc}; see ${detail_log}"
log "ERROR: sglang target_len=${target_len} failed; ${err}"
append_scenario "$(build_scenario_json "$target_len" "$max_context_len" "false" "$server_args" "$err")"
stop_server
return 1
fi
docker cp "${CONTAINER_NAME}:${container_output}" "$output_file" || {
local err="failed to copy output from container"
log "ERROR: ${err}"
append_scenario "$(build_scenario_json "$target_len" "$max_context_len" "false" "$server_args" "$err")"
stop_server
return 1
}
# Verify the request actually completed.
local completed
completed="$(python3 -c "
import json
with open('${output_file}') as f:
for line in f:
data = json.loads(line)
print(data.get('completed', 0))
break
")"
if [[ "${completed:-0}" -lt "$NUM_PROMPTS" ]]; then
local err="only ${completed}/${NUM_PROMPTS} requests completed"
log "ERROR: sglang target_len=${target_len} ${err}"
append_scenario "$(build_scenario_json "$target_len" "$max_context_len" "false" "$server_args" "$err")"
stop_server
return 1
fi
local metrics_json
metrics_json="$(python3 "${SCRIPT_DIR}/extract_metrics.py" "$output_file")"
append_scenario "$(build_scenario_json "$target_len" "$max_context_len" "true" "$server_args" "" "$metrics_json")"
log "sglang target_len=${target_len} succeeded"
stop_server
}
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
mkdir -p "$RAW_DIR" "$LOG_DIR"
RESULT_JSON="${RESULT_ROOT}/results.json"
write_metadata_json \
"$RESULT_JSON" \
"$EXPERIMENT_NAME" \
"$RUN_ID" \
"$MODEL_PATH" \
"sglang" \
"sglang-xpu" \
"$HARDWARE" \
"$ACCELERATOR" \
"$CHIP" \
"experiments/${EXPERIMENT_NAME}/run_bench.sh" \
"" \
"P800 max context length exploration for DeepSeek-V4-Flash-INT8"
# Embed config.
python3 - "$RESULT_JSON" <<'PY'
import json
import sys
path = sys.argv[1]
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
data["config"] = {
"tp": 8,
"ep": 8,
"xpu_visible_devices": "0,1,2,3,4,5,6,7",
"output_len": 1,
"num_prompts": 1,
"max_concurrency": 1,
"request_rate": 10000,
"context_pad": 1024,
}
with open(path, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
PY
stop_server
for target_len in "${CANDIDATE_LENS[@]}"; do
if ! run_length "$target_len"; then
log "stopping exploration after first failure at target_len=${target_len}"
break
fi
done
log "parsing results"
python3 "${SCRIPT_DIR}/parse_results.py" "$RESULT_ROOT" >> "${LOG_DIR}/parse.log" 2>&1 || {
log "WARNING: parse_results.py failed; see ${LOG_DIR}/parse.log"
}
log "all results saved to ${RESULT_ROOT}"