Replace the purged `vllm-nightly-clean` pin (nightly-bf610c2f, now 404 on Docker Hub — so the launcher injected a dead image for every slug on it) with a v0.22.0 two-engine design: - `vllm-stable`: OVERLAY-FREE v0.22.0 — the broad successor to vllm-nightly-clean. Serves Qwen3-Next (hybrid 27b + MoE 35B-A3B), generic `dense` transformers, and uncurated derived-emission bases. Migrates vllm/qwen-35b-a3b-dual, vllm/dual, vllm/minimal (live-validated on stock v0.22.0: TP=2 + MTP + tool-call clean; marlin-pad confirmed unnecessary). Added as the first loads:true arch pin on the qwen + dense rows. - `vllm-gemma-stable`: KEPT as the OVERLAY-CARRYING v0.22.0 engine (#40391 per-head INT8 KV + #42006 tool-parser) — the Gemma 4 path. Unchanged. - `vllm-pip-baseline`: the renamed pip `dense` lower-bound (frees the `vllm-stable` name for the docker engine above). Why two engines and not one: `vendored_overlays` is LOAD-BEARING, not documentation. `derived_emittable` (CONTRACT-5) refuses any engine whose `vendored_overlays != []` as a derived-emission base, and `diagnose-profile` expects the Gemma overlay declared on its engine. A single engine cannot be both overlay-free (for derived/Qwen bases) and overlay-carrying (for Gemma provenance) — so the two stay split. Compose owns patch APPLICATION; engine owns provenance/compatibility. (An attempt to fold both into one engine broke 4 tests via exactly these two consumers; the split is the validated shape.) Also adds scripts/tests/test-compose-image-drift.sh: asserts every fixed `${VLLM_IMAGE:-<tag>}` compose default equals its engine's `install.spec` (catches bump-the-engine-forget-the-literal drift), and a docs/ADDING_MODELS.md "Coherence rules" section codifying the compose/engine/patch separation. 42/42 gate green; resolver emits v0.22.0 for all migrated Qwen + Gemma slugs. The remaining experimental/preview slugs still on vllm-nightly-clean migrate in follow-up as each is validated, then that engine is deprecated. Refs #254. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
82 lines
3.4 KiB
Bash
Executable File
82 lines
3.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Drift guard (Codex review, #254/#324): every vLLM compose whose
|
|
# `image: ${VLLM_IMAGE:-<literal>}` default is a FIXED docker image must match the
|
|
# install.spec of the engine its registry slug resolves to. This catches the
|
|
# "bump the engine spec but forget the compose literal" drift that would silently
|
|
# feed direct `docker compose` users a stale image (the launcher injects VLLM_IMAGE
|
|
# from the engine and is fine; the compose literal is the unguarded path).
|
|
#
|
|
# Skipped (by design):
|
|
# - templated literals like `…:nightly-${VLLM_NIGHTLY_SHA}` — self-sync via the
|
|
# launcher-injected var, so the literal is always in step with the engine.
|
|
# - pip-method engines (vllm-pip-baseline) — no docker image to match.
|
|
set -euo pipefail
|
|
ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
|
|
python3 - "$ROOT_DIR" <<'PY'
|
|
import sys, re, pathlib
|
|
ROOT = pathlib.Path(sys.argv[1])
|
|
sys.path.insert(0, str(ROOT))
|
|
from scripts.lib.profiles.compose_registry import COMPOSE_REGISTRY
|
|
from scripts.lib.profiles.compat import load_profiles
|
|
|
|
# Slugs whose ENGINE is itself pending the #254 migration off the purged
|
|
# vllm-nightly-clean nightly (the engine repoint needs its own stock-v0.22.0
|
|
# boot + tool-call/MTP validation — out of the #324 leg). Their compose literal
|
|
# was pre-bumped to v0.22.0, so they read as "drifted" against the dead nightly
|
|
# spec until the engine is repointed. Exempted + reported (NOT silently skipped);
|
|
# delete each from this set when it migrates to vllm-stable, and the guard then
|
|
# covers it. Tracked in #254.
|
|
PENDING_254 = set()
|
|
|
|
profiles = load_profiles()
|
|
pat = re.compile(r'image:\s*\$\{VLLM_IMAGE:-([^}]+)\}')
|
|
drift, checked, pending, deprecated = [], 0, [], 0
|
|
for slug, entry in COMPOSE_REGISTRY.items():
|
|
if entry.get("status") == "deprecated":
|
|
deprecated += 1
|
|
continue # on its way out — not drift-guarded
|
|
if slug in PENDING_254:
|
|
pending.append(slug)
|
|
continue
|
|
eng_id = entry.get("engine")
|
|
eng = profiles.engines.get(eng_id) if eng_id else None
|
|
if eng is None:
|
|
continue
|
|
install = getattr(eng, "install", None) or {}
|
|
if install.get("method") != "docker_image":
|
|
continue # pip baseline etc. — no docker image to compare against
|
|
spec = install.get("spec", "")
|
|
cpath = entry.get("compose_path")
|
|
if not cpath:
|
|
continue
|
|
p = ROOT / cpath
|
|
if not p.exists():
|
|
continue
|
|
m = pat.search(p.read_text())
|
|
if not m:
|
|
continue
|
|
literal = m.group(1).strip()
|
|
if "${" in literal:
|
|
continue # templated (e.g. nightly-${VLLM_NIGHTLY_SHA}) — self-syncs
|
|
checked += 1
|
|
if literal != spec:
|
|
drift.append(
|
|
f" {slug}: compose default `{literal}` != engine `{eng_id}` install.spec "
|
|
f"`{spec}` ({cpath})"
|
|
)
|
|
|
|
if drift:
|
|
print("IMAGE DRIFT — a fixed compose `${VLLM_IMAGE:-…}` default disagrees with the")
|
|
print("engine its slug resolves to (direct `docker compose` would serve a stale image):")
|
|
print("\n".join(drift))
|
|
print("Fix: bump the compose literal to the engine install.spec (or vice-versa).")
|
|
sys.exit(1)
|
|
if pending:
|
|
print(f"NOTE: {len(pending)} slug(s) exempt pending #254 engine migration: {', '.join(sorted(pending))}")
|
|
print(
|
|
f"test-compose-image-drift: ok ({checked} fixed-image vLLM composes match their engine spec; "
|
|
f"{deprecated} deprecated skipped, {len(pending)} pending-#254 exempt)"
|
|
)
|
|
PY
|