Buckets:
| """agent-smith: per-step timeline probe (env-gated, STEPTIME=1). | |
| Wraps two seams in the worker process with perf_counter + CUDA event pairs: | |
| - vllm.v1.worker.gpu_model_runner.GPUModelRunner.execute_model | |
| -> per step: gap_ms (CPU time since previous call returned), | |
| cpu_ms (call wall), gpu_ms (CUDA-event elapsed inside the call) | |
| - vllm.v1.spec_decode.gemma4.Gemma4Proposer.propose | |
| -> draft_cpu_ms / draft_gpu_ms, attributed to the enclosing step | |
| Events are recorded at the python call boundary, OUTSIDE any CUDA-graph | |
| capture performed inside the call, so the loopgraph/onegraph machinery is | |
| undisturbed. Composes with the package's existing meta-path finders: our | |
| finder sits in front, re-resolves the spec through the remaining finders | |
| (their _busy-guard pattern), and applies our patch after theirs. | |
| Output goes to stdout (=> job_logs.txt): | |
| [steptime] raw i=<step> spec=<0|1> gap=.. cpu=.. gpu=.. dcpu=.. dgpu=.. | |
| (for a window of steps, default 40..200) | |
| [steptime] agg n=.. spec=<0|1> gap p50/p90/mean=.. cpu .. gpu .. dgpu .. | |
| (every STEPTIME_REPORT_EVERY resolved steps, cumulative, warmup excluded) | |
| No files are written; no behavior of the served model is altered. | |
| """ | |
| from __future__ import annotations | |
| import importlib.abc | |
| import importlib.util | |
| import os | |
| import sys | |
| import time | |
| from collections import deque | |
| from typing import Any | |
| STEPTIME = os.environ.get("STEPTIME", "0") == "1" | |
| RAW_START = int(os.environ.get("STEPTIME_RAW_START", "40")) | |
| RAW_COUNT = int(os.environ.get("STEPTIME_RAW_COUNT", "160")) | |
| REPORT_EVERY = int(os.environ.get("STEPTIME_REPORT_EVERY", "1024")) | |
| WARMUP_SKIP = int(os.environ.get("STEPTIME_WARMUP_SKIP", "64")) | |
| RUNNER_TARGET = "vllm.v1.worker.gpu_model_runner" | |
| PROPOSE_TARGET = "vllm.v1.spec_decode.gemma4" | |
| _state: dict[str, Any] = { | |
| "i": 0, # execute_model call index | |
| "last_ret": None, # perf_counter at previous execute_model return | |
| "cur_draft": None, # draft measurement of the in-flight step | |
| "pending": deque(), # unresolved records (with CUDA events) | |
| "agg": {}, # kind -> list of (gap, cpu, gpu, dcpu, dgpu) | |
| "reported": 0, | |
| } | |
| def _pct(vals: list[float], p: float) -> float: | |
| if not vals: | |
| return float("nan") | |
| s = sorted(vals) | |
| k = min(len(s) - 1, max(0, int(round(p / 100.0 * (len(s) - 1))))) | |
| return s[k] | |
| def _resolve_pending(force: bool = False) -> None: | |
| pend = _state["pending"] | |
| while pend: | |
| rec = pend[0] | |
| ev1 = rec["ev1"] | |
| dev1 = rec["dev1"] | |
| if not force and not ev1.query(): | |
| break | |
| if force: | |
| ev1.synchronize() | |
| gpu = rec["ev0"].elapsed_time(ev1) | |
| dgpu = rec["dev0"].elapsed_time(dev1) if dev1 is not None else 0.0 | |
| pend.popleft() | |
| i = rec["i"] | |
| kind = rec.get("kind", "exec") | |
| if i >= WARMUP_SKIP: | |
| _state["agg"].setdefault(kind, []).append( | |
| (rec["gap"], rec["cpu"], gpu, rec["dcpu"], dgpu) | |
| ) | |
| if RAW_START <= i < RAW_START + RAW_COUNT: | |
| print( | |
| f"[steptime] raw i={i} kind={kind} gap={rec['gap']:.3f} " | |
| f"cpu={rec['cpu']:.3f} gpu={gpu:.3f} dcpu={rec['dcpu']:.3f} " | |
| f"dgpu={dgpu:.3f}", | |
| flush=True, | |
| ) | |
| done = sum(len(v) for v in _state["agg"].values()) | |
| if done and done % REPORT_EVERY == 0 and done != _state["reported"]: | |
| _state["reported"] = done | |
| _report() | |
| def _report() -> None: | |
| for kind, rows in _state["agg"].items(): | |
| if not rows: | |
| continue | |
| cols = list(zip(*rows)) | |
| names = ("gap", "cpu", "gpu", "dcpu", "dgpu") | |
| parts = [] | |
| for name, vals in zip(names, cols): | |
| v = list(vals) | |
| parts.append( | |
| f"{name} p50={_pct(v,50):.3f} p90={_pct(v,90):.3f} " | |
| f"mean={sum(v)/len(v):.3f}" | |
| ) | |
| print( | |
| f"[steptime] agg n={len(rows)} kind={kind} " + " | ".join(parts), | |
| flush=True, | |
| ) | |
| def _wrap_execute_model(module: Any) -> None: | |
| import torch | |
| runner_cls = module.GPUModelRunner | |
| base = runner_cls.execute_model | |
| def execute_model(self: Any, *args: Any, **kwargs: Any) -> Any: | |
| now = time.perf_counter() | |
| gap = 0.0 if _state["last_ret"] is None else (now - _state["last_ret"]) * 1e3 | |
| _state["cur_draft"] = [0.0, None, None] # dcpu, dev0, dev1 | |
| ev0 = torch.cuda.Event(enable_timing=True) | |
| ev1 = torch.cuda.Event(enable_timing=True) | |
| ev0.record() | |
| try: | |
| out = base(self, *args, **kwargs) | |
| finally: | |
| ev1.record() | |
| ret = time.perf_counter() | |
| dcpu, dev0, dev1 = _state["cur_draft"] | |
| _state["pending"].append( | |
| { | |
| "i": _state["i"], | |
| "gap": gap, | |
| "cpu": (ret - now) * 1e3, | |
| "ev0": ev0, | |
| "ev1": ev1, | |
| "dcpu": dcpu, | |
| "dev0": dev0, | |
| "dev1": dev1, | |
| } | |
| ) | |
| _state["i"] += 1 | |
| _state["last_ret"] = ret | |
| _state["cur_draft"] = None | |
| _resolve_pending() | |
| return out | |
| runner_cls.execute_model = execute_model | |
| print("[steptime] execute_model wrapper active", flush=True) | |
| def _wrap_propose(module: Any) -> None: | |
| import torch | |
| proposer_cls = module.Gemma4Proposer | |
| base = proposer_cls.propose | |
| def propose(self: Any, *args: Any, **kwargs: Any) -> Any: | |
| cur = _state["cur_draft"] | |
| if cur is None: | |
| # v1 finding: this wheel calls propose OUTSIDE execute_model — | |
| # record it as a standalone 'draft' record instead. | |
| t0 = time.perf_counter() | |
| dev0 = torch.cuda.Event(enable_timing=True) | |
| dev1 = torch.cuda.Event(enable_timing=True) | |
| dev0.record() | |
| try: | |
| return base(self, *args, **kwargs) | |
| finally: | |
| dev1.record() | |
| _state["pending"].append( | |
| { | |
| "i": _state["i"], | |
| "kind": "draft", | |
| "gap": 0.0, | |
| "cpu": (time.perf_counter() - t0) * 1e3, | |
| "ev0": dev0, | |
| "ev1": dev1, | |
| "dcpu": 0.0, | |
| "dev0": None, | |
| "dev1": None, | |
| } | |
| ) | |
| t0 = time.perf_counter() | |
| dev0 = torch.cuda.Event(enable_timing=True) | |
| dev1 = torch.cuda.Event(enable_timing=True) | |
| dev0.record() | |
| try: | |
| return base(self, *args, **kwargs) | |
| finally: | |
| dev1.record() | |
| cur[0] += (time.perf_counter() - t0) * 1e3 | |
| if cur[1] is None: | |
| cur[1] = dev0 | |
| cur[2] = dev1 | |
| proposer_cls.propose = propose | |
| print("[steptime] propose wrapper active", flush=True) | |
| class _ChainLoader(importlib.abc.Loader): | |
| def __init__(self, inner: importlib.abc.Loader, patch_fn: Any) -> None: | |
| self._inner = inner | |
| self._patch_fn = patch_fn | |
| def create_module(self, spec: Any) -> Any: | |
| return self._inner.create_module(spec) | |
| def exec_module(self, module: Any) -> None: | |
| self._inner.exec_module(module) | |
| self._patch_fn(module) | |
| class _ChainFinder(importlib.abc.MetaPathFinder): | |
| def __init__(self, target: str, patch_fn: Any) -> None: | |
| self._target = target | |
| self._patch_fn = patch_fn | |
| self._busy = False | |
| def find_spec(self, fullname: str, path: Any = None, target: Any = None) -> Any: | |
| if fullname != self._target or self._busy: | |
| return None | |
| self._busy = True | |
| try: | |
| spec = importlib.util.find_spec(fullname) | |
| finally: | |
| self._busy = False | |
| if spec is None or spec.loader is None: | |
| return None | |
| spec.loader = _ChainLoader(spec.loader, self._patch_fn) | |
| return spec | |
| if STEPTIME: | |
| sys.meta_path.insert(0, _ChainFinder(RUNNER_TARGET, _wrap_execute_model)) | |
| sys.meta_path.insert(0, _ChainFinder(PROPOSE_TARGET, _wrap_propose)) | |
| print("[steptime] finders registered", flush=True) | |
Xet Storage Details
- Size:
- 8.38 kB
- Xet hash:
- f0cbe3274c2eb8c4b178f82f3b06bd0f529489b49705da757637ca3d6aa7bc48
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.