fix: harden DGR-001 performance contract evidence
This commit is contained in:
@@ -28,6 +28,7 @@ from __future__ import annotations
|
||||
import argparse
|
||||
import json
|
||||
import statistics
|
||||
import threading
|
||||
import time
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from dataclasses import asdict, dataclass, field
|
||||
@@ -443,7 +444,7 @@ def compute_drift(
|
||||
|
||||
|
||||
class _PeakMemory:
|
||||
"""Sample a driver's memory while requests are in flight."""
|
||||
"""Continuously sample a driver's memory while requests are in flight."""
|
||||
|
||||
def __init__(self, driver: RecipeDriver) -> None:
|
||||
self._driver = driver
|
||||
@@ -458,6 +459,12 @@ class _PeakMemory:
|
||||
self.peak_rss = max(self.peak_rss, rss)
|
||||
self.peak_vram = max(self.peak_vram, vram)
|
||||
|
||||
def sample_until(self, stop: threading.Event, interval_s: float = 0.01) -> None:
|
||||
"""Sample until ``stop`` is set, including one final post-request probe."""
|
||||
while not stop.wait(interval_s):
|
||||
self.sample()
|
||||
self.sample()
|
||||
|
||||
|
||||
def _run_request(
|
||||
driver: RecipeDriver,
|
||||
@@ -512,8 +519,6 @@ def measure_recipe(
|
||||
concurrency 4 still releases its weights before the next recipe loads.
|
||||
"""
|
||||
load = driver.load()
|
||||
memory = _PeakMemory(driver)
|
||||
memory.sample()
|
||||
measurement = RecipeMeasurement(recipe=recipe, load=load)
|
||||
|
||||
try:
|
||||
@@ -524,6 +529,17 @@ def measure_recipe(
|
||||
break
|
||||
|
||||
for concurrency in plan.concurrency_levels:
|
||||
# Measure each cell independently and sample while requests are in
|
||||
# flight; post-request probes alone miss transient KV/workspace peaks.
|
||||
memory = _PeakMemory(driver)
|
||||
memory.sample()
|
||||
stop_sampling = threading.Event()
|
||||
sampler = threading.Thread(
|
||||
target=memory.sample_until,
|
||||
args=(stop_sampling,),
|
||||
name=f"recipe-memory-{recipe.id}-c{concurrency}",
|
||||
daemon=True,
|
||||
)
|
||||
requests = [
|
||||
(prompt, repeat)
|
||||
for repeat in range(plan.repeats)
|
||||
@@ -531,13 +547,18 @@ def measure_recipe(
|
||||
for _ in range(concurrency)
|
||||
]
|
||||
started = time.monotonic()
|
||||
with ThreadPoolExecutor(max_workers=concurrency) as pool:
|
||||
outcomes = list(pool.map(
|
||||
lambda item: _run_request(
|
||||
driver, recipe, item[0], plan.sampling, concurrency, item[1], memory
|
||||
),
|
||||
requests,
|
||||
))
|
||||
sampler.start()
|
||||
try:
|
||||
with ThreadPoolExecutor(max_workers=concurrency) as pool:
|
||||
outcomes = list(pool.map(
|
||||
lambda item: _run_request(
|
||||
driver, recipe, item[0], plan.sampling, concurrency, item[1], memory
|
||||
),
|
||||
requests,
|
||||
))
|
||||
finally:
|
||||
stop_sampling.set()
|
||||
sampler.join()
|
||||
wall_ms = (time.monotonic() - started) * 1000
|
||||
|
||||
measurement.outcomes.extend(outcomes)
|
||||
|
||||
Reference in New Issue
Block a user