Skip to content

Reap stale perf-eval containers before starting vLLM#26

Open
khluu wants to merge 2 commits into
mainfrom
claude/condescending-banach-4efa6b
Open

Reap stale perf-eval containers before starting vLLM#26
khluu wants to merge 2 commits into
mainfrom
claude/condescending-banach-4efa6b

Conversation

@khluu

@khluu khluu commented Jun 15, 2026

Copy link
Copy Markdown
Member

Problem

Build 222 failed on h200-ci-1 instantly with:

docker: Bind for 0.0.0.0:8000 failed: port is already allocated
🚨 Error: The command exited with status 125

This was not an eval failure. A leftover container perf-eval-kimi_k2_5-h200-3640085 from an earlier job was still running (up 9h, idle ~7.5h), pinning all 8 GPUs and port 8000. I removed it by hand to unblock the host; this PR prevents recurrence.

Root cause

  • run.sh cleans up via trap 'stop_server "$CONTAINER"' EXIT. When a job is SIGKILLed — the Buildkite 120-min step timeout, or an agent restart — the EXIT trap never fires, so the container survives.
  • The container name is perf-eval-${WORKLOAD_NAME}-$$ (PID-based, unique per run), so a later run's docker rm -f "$CONTAINER" only ever targets its own container — it never reaps a previous run's orphan.
  • The orphan keeps holding port 8000 and the GPUs, so docker run -p 8000:8000 collides on every subsequent run. One orphan wedges the host indefinitely until someone clears it manually.

Fix

Add reap_stale_servers() in lib/server.sh, called from start_server right before docker run. It removes any leftover container matching the perf-eval- name prefix, plus anything still publishing the target port. The server port is fixed at 8000, so two perf-eval runs can't coexist on one host — any pre-existing perf-eval container is by definition stale and safe to remove. The host now self-heals on the next run instead of dead-locking.

Testing

  • bash -n lib/run.sh && bash -n lib/server.sh && bash -n lib/run_lm_eval.sh — passes.
  • Verified the docker ps --filter name=perf-eval- and --filter publish=8000 filters return cleanly on h200-ci-1 (exit 0).
  • Real eval needs a GPU host; this path is exercised on the next Buildkite run.

This PR was authored with assistance from Claude Code (AI-assisted).

🤖 Generated with Claude Code

khluu and others added 2 commits May 28, 2026 17:33
Some vLLM release images don't include pytest, but cupy.testing._random
imports it unconditionally. When torch.compile traces through cupy modules
during model loading, this causes a ModuleNotFoundError that crashes the
server. Installing pytest after container startup fixes this.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
A job killed with SIGKILL (e.g. the Buildkite 120-min step timeout or an
agent restart) never runs run.sh's EXIT trap, so its vLLM container survives
and squats on the GPUs and port 8000. Because container names are PID-based
and unique, a later run's own cleanup never reaps the orphan, and `docker run
-p 8000:8000` then fails with "Bind for 0.0.0.0:8000 failed: port is already
allocated" -- wedging every subsequent run on that host until someone removes
the container by hand. This is what broke build 222 on h200-ci-1.

Add reap_stale_servers(), called from start_server before `docker run`, to
remove any leftover perf-eval container (by name prefix) or anything still
holding the target port. The server port is fixed, so two perf-eval runs
can't share a host -- any pre-existing perf-eval container is stale and safe
to remove, making the host self-heal on the next run.

This change was authored with assistance from Claude Code (AI-assisted).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant