Files
hao-ai-lab-FastVideo/v2/extend/observers.py
T
SolitaryThinker a9e5f6ee7a [refactor] rename package mini_fastvideo → v2
Directory rename (git mv, history preserved) plus rewrite of all references: absolute imports in
tests, the zero-dep runner, docstrings, comments, and the README. No behavior change.

Run: python3 -m pytest v2/tests/ -q ; python3 v2/run_tests.py ; python3 -m v2.examples
2026-07-04 17:15:34 +00:00

65 lines
2.6 KiB
Python

"""Built-in read-only observers (design_v3 §11): Profiler, NaNWatch.
ParityAligner lives in ``parity/`` (it is a first-class package, §18) but also implements
the Observer ``observe`` protocol so it attaches to the same bus.
"""
from __future__ import annotations
from typing import Any
import numpy as np
class Profiler:
"""Per-step wall/CUDA timing; calibrates the cost model (design_v3 §6.1, §11).
Here it accumulates (work_units, actual_seconds) samples and can fit a card's
CostModel coefficients — the online calibration the conservative baseline refines.
"""
def __init__(self) -> None:
self.samples: list[tuple[str, float, float]] = [] # (batch_key_repr, work_units, seconds)
def observe(self, event: str, **kw) -> None:
if event == "step_complete":
plan, result = kw.get("plan"), kw.get("result")
if plan is not None and result is not None:
self.samples.append((repr(plan.shape_sig.batch_key),
float(plan.shape_sig.work_units),
float(result.actual_seconds)))
def calibrate(self, cost_model) -> None:
"""Fit base + per_unit seconds from observed samples (least squares)."""
if len(self.samples) < 2:
return
x = np.array([s[1] for s in self.samples], dtype=np.float64)
y = np.array([s[2] for s in self.samples], dtype=np.float64)
if np.ptp(x) == 0:
cost_model.base_seconds = float(y.mean())
return
slope, intercept = np.polyfit(x, y, 1)
cost_model.per_unit_seconds = float(max(slope, 0.0))
cost_model.base_seconds = float(max(intercept, 0.0))
class NaNWatch:
"""First-NaN/Inf localization (design_v3 §11). Request-fatal → SPMD-consistent abort (§6.4)."""
def __init__(self) -> None:
self.first: tuple[str, int] | None = None # (tap/output name, step)
def observe(self, event: str, **kw) -> None:
if event == "step_complete" and self.first is None:
plan, result = kw.get("plan"), kw.get("result")
if result is None:
return
for name, val in result.output.items():
arr = np.asarray(val) if hasattr(val, "__array__") or isinstance(val, (list, tuple)) else None
if arr is not None and arr.dtype.kind == "f" and not np.all(np.isfinite(arr)):
self.first = (name, getattr(plan, "label", "") or name)
return
@property
def tripped(self) -> bool:
return self.first is not None