Files
aituner/patches/vllm-0.24.0-opprof/0006-Checkpoint-OpProf-accounting-across-hard-kills.patch
Gahow Wang d5b276180d Add OpProf campaign: protocols, results, patches, run evidence (P0-P6)
Workload-conditioned operator profiling on patched vLLM 0.24.0 +
Qwen3-30B-A3B/H20. H1b PASS (irregular patterns carry +23-45pp R64
raggedness, 8-45% token-efficiency loss vs rectangular controls);
mechanism decomposition kills the padding narrative and finds the
arrival-uniformization artifact (-12.9%); cross-version churn surface
shows TP2/MNS64 -29.4% across vLLM 0.20->0.24 while the argmax held.
Raw Layer-1 JSONL streams (507 MB) stay on disk, git-ignored; footer
sidecars and metrics are tracked.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 11:06:10 +08:00

307 lines
11 KiB
Diff

From f8b68f2452c424d22de4a69527a427207dcfbca5 Mon Sep 17 00:00:00 2001
From: Gahow Wang <gahow.wang@gmail.com>
Date: Sun, 12 Jul 2026 12:56:39 +0800
Subject: [PATCH] Checkpoint OpProf accounting across hard kills
---
tests/v1/core/test_opprof.py | 118 +++++++++++++++++++++++++++++++++++
vllm/v1/opprof.py | 84 ++++++++++++++++++++++---
2 files changed, 195 insertions(+), 7 deletions(-)
diff --git a/tests/v1/core/test_opprof.py b/tests/v1/core/test_opprof.py
index 0b8a8a1..007c5bb 100644
--- a/tests/v1/core/test_opprof.py
+++ b/tests/v1/core/test_opprof.py
@@ -5,6 +5,8 @@
import errno
import importlib.util
import logging
+import os
+import subprocess
import sys
import threading
from pathlib import Path
@@ -121,6 +123,12 @@ def read_jsonl(path):
return [msgspec.json.decode(line) for line in path.read_bytes().splitlines()]
+def read_sidecar(path):
+ return msgspec.json.decode(
+ path.with_name(f"{path.name}.footer.json").read_bytes()
+ )
+
+
def test_import_light_and_approved_constants():
assert "torch" not in sys.modules
assert "vllm" not in sys.modules
@@ -366,6 +374,116 @@ def test_shutdown_flush_is_idempotent(tmp_path):
assert path.stat().st_size > 0
+def test_sidecar_updates_are_atomic(tmp_path, monkeypatch):
+ writer = opprof.JSONLWriter(tmp_path / "atomic.jsonl", start=False)
+ writer._write_sidecar(
+ encoded_records=1,
+ written_records=1,
+ dropped_records=0,
+ last_step_index=0,
+ final=False,
+ )
+ original = writer.sidecar_path.read_bytes()
+ real_replace = os.replace
+ replacements = []
+
+ def inspect_replace(source, destination):
+ assert Path(destination) == writer.sidecar_path
+ assert writer.sidecar_path.read_bytes() == original
+ candidate = msgspec.json.decode(Path(source).read_bytes())
+ assert candidate["written_records"] == 2
+ replacements.append(candidate)
+ real_replace(source, destination)
+
+ monkeypatch.setattr(opprof.os, "replace", inspect_replace)
+ writer._write_sidecar(
+ encoded_records=3,
+ written_records=2,
+ dropped_records=1,
+ last_step_index=2,
+ final=False,
+ )
+ monkeypatch.setattr(opprof.os, "replace", real_replace)
+
+ assert len(replacements) == 1
+ assert read_sidecar(writer.path)["encoded_records"] == 3
+ assert not list(tmp_path.glob(".*.tmp-*"))
+ writer.close()
+
+
+def test_hard_kill_sidecar_balances_last_flush(tmp_path):
+ path = tmp_path / "hard-kill.jsonl"
+ child = """
+import importlib.util
+import sys
+import time
+from pathlib import Path
+
+source, output = sys.argv[1:]
+spec = importlib.util.spec_from_file_location("opprof_hard_kill", source)
+module = importlib.util.module_from_spec(spec)
+sys.modules[spec.name] = module
+spec.loader.exec_module(module)
+writer = module.JSONLWriter(Path(output))
+for step in range(3):
+ assert writer.submit({"schema": 1, "step_index": step})
+writer._queue.join()
+while not writer.sidecar_path.exists():
+ time.sleep(0.01)
+print("READY", flush=True)
+time.sleep(60)
+"""
+ process = subprocess.Popen(
+ [
+ sys.executable,
+ "-c",
+ child,
+ str(_ROOT / "vllm/v1/opprof.py"),
+ str(path),
+ ],
+ stdout=subprocess.PIPE,
+ text=True,
+ )
+ try:
+ assert process.stdout is not None
+ assert process.stdout.readline().strip() == "READY"
+ process.kill()
+ assert process.wait(timeout=5) < 0
+ finally:
+ if process.poll() is None:
+ process.kill()
+ process.wait(timeout=5)
+
+ records = read_jsonl(path)
+ sidecar = read_sidecar(path)
+ assert len(records) == 3
+ assert all(record.get("record_type") != "footer" for record in records)
+ assert sidecar["final"] is False
+ assert sidecar["written_records"] == len(records)
+ assert sidecar["encoded_records"] == (
+ sidecar["written_records"] + sidecar["dropped_records"]
+ )
+ assert sidecar["last_step_index"] == records[-1]["step_index"] == 2
+
+
+def test_clean_footer_and_final_sidecar_agree(tmp_path):
+ sched = scheduler({"decode": request(8, 9)})
+ rec, path = recorder(tmp_path)
+ assert emit(rec, sched, schedule_output({"decode": 1}))
+ rec.close()
+
+ record, footer = read_jsonl(path)
+ sidecar = read_sidecar(path)
+ assert sidecar["record_type"] == "footer_checkpoint"
+ assert sidecar["stream"] == path.name
+ assert sidecar["final"] is True
+ assert sidecar["last_step_index"] == record["step_index"] == 0
+ assert sidecar["checkpoint_wall_ns"] > 0
+ assert sidecar["flush_interval_seconds"] == opprof.FLUSH_INTERVAL_SECONDS
+ for counter in ("encoded_records", "written_records", "dropped_records"):
+ assert sidecar[counter] == footer[counter]
+
+
def test_piecewise_cudagraph_record_preserved(tmp_path):
sched = scheduler({"decode": request(4096, 4097)})
output = schedule_output({"decode": 1})
diff --git a/vllm/v1/opprof.py b/vllm/v1/opprof.py
index 75f63de..28d9635 100644
--- a/vllm/v1/opprof.py
+++ b/vllm/v1/opprof.py
@@ -7,6 +7,7 @@ import queue
import threading
import time
from bisect import bisect_left
+from contextlib import suppress
from pathlib import Path
from typing import Any
@@ -18,6 +19,7 @@ SCHEMA_VERSION = 1
CONTEXT_LENGTH_EDGES = tuple(1 << exponent for exponent in range(7, 18))
CHUNK_SIZE_EDGES = tuple(1 << exponent for exponent in range(4, 12))
DEFAULT_QUEUE_CAPACITY = 8192
+FLUSH_INTERVAL_SECONDS = 1.0
_CLOSE_TIMEOUT_SECONDS = 1.0
_STOP = object()
_PREFIX_FIELDS = ( # noqa: SIM905
@@ -69,6 +71,7 @@ class JSONLWriter:
) -> None:
self._queue: queue.Queue[Any] = queue.Queue(capacity)
self.path = path
+ self.sidecar_path = path.with_name(f"{path.name}.footer.json")
self._encoder = msgspec.json.Encoder()
self._file = path.open("xb", buffering=1 << 20)
self._thread = threading.Thread(target=self._run, daemon=True)
@@ -78,6 +81,9 @@ class JSONLWriter:
self.failure: Exception | None = None
self.encoded_records = self.written_records = 0
self.dropped_records = self._unreported_drops = 0
+ self._checkpoint_encoded_records = 0
+ self._checkpoint_dropped_records = 0
+ self._last_written_step_index: int | None = None
if start:
self.start()
@@ -119,33 +125,90 @@ class JSONLWriter:
if self._writer_unavailable():
return self._drop(pending)
try:
- self._queue.put_nowait(payload)
+ self._queue.put_nowait(
+ (
+ payload,
+ self.encoded_records,
+ self.dropped_records,
+ int(record["step_index"]),
+ )
+ )
except queue.Full:
return self._drop(pending)
self._unreported_drops = 0
return True
+ def _write_sidecar(
+ self,
+ *,
+ encoded_records: int,
+ written_records: int,
+ dropped_records: int,
+ last_step_index: int | None,
+ final: bool,
+ ) -> None:
+ sidecar = dict(
+ schema=SCHEMA_VERSION,
+ record_type="footer_checkpoint",
+ stream=self.path.name,
+ encoded_records=encoded_records,
+ written_records=written_records,
+ dropped_records=dropped_records,
+ last_step_index=last_step_index,
+ checkpoint_wall_ns=time.time_ns(),
+ flush_interval_seconds=FLUSH_INTERVAL_SECONDS,
+ final=final,
+ )
+ temporary_path = self.sidecar_path.with_name(
+ f".{self.sidecar_path.name}.tmp-{os.getpid()}-{threading.get_ident()}"
+ )
+ try:
+ with temporary_path.open("wb") as temporary_file:
+ temporary_file.write(self._encoder.encode(sidecar) + b"\n")
+ temporary_file.flush()
+ os.replace(temporary_path, self.sidecar_path)
+ finally:
+ with suppress(FileNotFoundError):
+ temporary_path.unlink()
+
+ def _flush_checkpoint(self) -> None:
+ self._file.flush()
+ self._write_sidecar(
+ encoded_records=self._checkpoint_encoded_records,
+ written_records=self.written_records,
+ dropped_records=self._checkpoint_dropped_records,
+ last_step_index=self._last_written_step_index,
+ final=False,
+ )
+
def _run(self) -> None:
buffered = 0
last_flush = time.monotonic()
try:
while True:
try:
- item = self._queue.get(timeout=1.0)
+ item = self._queue.get(timeout=FLUSH_INTERVAL_SECONDS)
except queue.Empty:
- self._file.flush()
+ self._flush_checkpoint()
buffered = 0
last_flush = time.monotonic()
continue
try:
if item is _STOP:
break
- self._file.write(item)
- buffered += len(item)
+ payload, encoded, dropped, step_index = item
+ self._file.write(payload)
+ buffered += len(payload)
self.written_records += 1
+ self._checkpoint_encoded_records = encoded
+ self._checkpoint_dropped_records = dropped
+ self._last_written_step_index = step_index
now = time.monotonic()
- if buffered >= 1 << 20 or now - last_flush >= 1.0:
- self._file.flush()
+ if (
+ buffered >= 1 << 20
+ or now - last_flush >= FLUSH_INTERVAL_SECONDS
+ ):
+ self._flush_checkpoint()
buffered = 0
last_flush = now
finally:
@@ -163,6 +226,13 @@ class JSONLWriter:
try:
self._file.write(self._encoder.encode(footer) + b"\n")
self._file.flush()
+ self._write_sidecar(
+ encoded_records=footer["encoded_records"],
+ written_records=footer["written_records"],
+ dropped_records=footer["dropped_records"],
+ last_step_index=self._last_written_step_index,
+ final=True,
+ )
except Exception as error:
self._record_failure(error)
finally:
--
2.43.0