4.8 KiB
Replay, Trace, Profile, and Bisect
Use this reference after the first live checks. The goal is to turn the problem into something repeatable.
Save Requests
Request dump
python3 -m sglang.srt.managers.configure_logging \
--url http://127.0.0.1:30000 \
--dump-requests-folder /tmp/sglang_request_dump \
--dump-requests-threshold 100
Use this when:
- the problem is intermittent
- you need the real request shape
- you do not want to restart the server
Crash dump
If the server already runs with:
--crash-dump-folder /tmp/crash_dump
SGLang saves recent requests before a crash. Treat that dump as the best starting point.
Summarize it first:
python3 scripts/incident_artifact_tool.py summarize-dump \
--input-file /path/to/crash_dump.pkl
Current crash-dump tests show at least:
server_argsrequestslaunch_command
Replay
Use the stock replay tool:
python3 scripts/playground/replay_request_dump.py \
--input-file /path/to/crash_dump.pkl \
--host 127.0.0.1 \
--port 30000 \
--parallel 128
Or replay a folder:
python3 scripts/playground/replay_request_dump.py \
--input-folder /path/to/request_dump_dir \
--file-number 10 \
--parallel 128
If safe_pickle_load blocks a locally captured trusted dump, use:
python3 scripts/replay_trusted_request_dump.py \
--input-file /path/to/request_dump.pkl \
--host 127.0.0.1 \
--port 30000 \
--parallel 1
If that happens, the allowlist is the problem, not the dump.
Use replay before profiling when:
- the issue depends on workload mix
- it only appears after some number of requests
- you need to compare two builds on the same traffic
CUDA Restart-And-Replay
If replay points to a CUDA crash path, restart the same build with coredumps:
SGLANG_CUDA_COREDUMP=1 \
SGLANG_CUDA_COREDUMP_DIR=/tmp/sglang_cuda_coredumps \
python -m sglang.launch_server \
--model-path ... \
--crash-dump-folder /tmp/sglang_crash_dump \
...
Then inspect the coredump:
cuda-gdb "$(which python3)" \
-ex "target cudacore /tmp/sglang_cuda_coredumps/cuda_coredump_<host>.<pid>.<ts>"
Good first commands:
whereinfo cuda kernelsx/10i <pc>
Use the coredump to find the failing kernel, not automatically the root-cause kernel.
See:
Trace
Tracing must be enabled at startup:
python -m sglang.launch_server \
--enable-trace \
--otlp-traces-endpoint localhost:4317 \
...
Optional router command:
python -m sglang_router.launch_router \
--enable-trace \
--otlp-traces-endpoint localhost:4317 \
...
Useful environment variables:
export SGLANG_OTLP_EXPORTER_SCHEDULE_DELAY_MILLIS=500
export SGLANG_OTLP_EXPORTER_MAX_EXPORT_BATCH_SIZE=64
If tracing is already enabled, change the level without restart:
curl "http://127.0.0.1:30000/set_trace_level?level=1"
curl "http://127.0.0.1:30000/set_trace_level?level=2"
curl "http://127.0.0.1:30000/set_trace_level?level=3"
Use tracing for:
- router vs. worker delay
- tokenizer / scheduler / detokenizer timing
- PD transfer timing
- request timing across processes
If you already have OTEL JSON or JSONL, convert it for timeline inspection:
python3 scripts/convert_otel_2_perfetto.py \
--input /tmp/otel_trace.json \
--output /tmp/sglang_trace_perfetto.json
Torch Profiler
Switch to llm-torch-profiler-analysis when:
- replay already reproduces the issue
- metrics and loads do not explain it
- the problem now looks compute-side
This skill should decide when to profile, not duplicate the profiler workflow.
Bisect
If one commit is known-good and a newer commit is known-bad:
- build a deterministic harness from the problem
- prefer replay-based harnesses when the failure depends on request mix
- use
git bisect run <harness> - only then go back to trace or profile if needed
Example:
git bisect start <bad> <good>
git bisect run bash ./repro_or_check.sh
Common Paths
Crash
- crash dump
- summarize dump
- replay
- CUDA coredump plus
cuda-gdb debug-cuda-crashor narrower instrumentation
TTFT regression
- baseline metrics and loads
- request dump
- replay the slow request
- trace if stage ownership is unclear
llm-torch-profiler-analysisif it still looks compute-side
See:
Distributed hang
- healthy baseline bundle
- save the trigger request
- replay on a clean target
- collect replay-time bundle and stacks
- identify the NCCL or collective path
- switch to
debug-distributed-hang
See:
Throughput regression after deploy
- compare
server_info - compare
/metricsand/v1/loads - replay stable workload
- bisect if one older commit is known-good
- profile only if compute still looks suspicious