Skip to content

Feat/benchmark metrics - #102

Open
Safaael25 wants to merge 16 commits into
vcache-project:masterfrom
Safaael25:feat/benchmark-metrics
Open

Feat/benchmark metrics#102
Safaael25 wants to merge 16 commits into
vcache-project:masterfrom
Safaael25:feat/benchmark-metrics

Conversation

@Safaael25

Copy link
Copy Markdown
Contributor

No description provided.

Safaael25 and others added 16 commits July 19, 2026 11:58
Track CPU/memory/GPU utilization and queries/tokens-per-second throughput
alongside the existing hit-rate/latency/accuracy metrics, write results to
CSV as well as JSON, and add fully offline unit/integration tests so the
instrumentation reruns on every commit without needing a full-scale, paid
benchmark run in CI. Also commits a sample results log as documented in
benchmarks/ReadMe.md.
benchmarks.benchmark.Benchmark subclasses unittest.TestCase and defines
test_run_benchmark(self, max_samples), an existing quirk unrelated to this
PR. Importing it at module level in a test_*.py file made pytest collect
and try to run it as its own bare test case, which fails because pytest
has no way to supply the required `vcache` constructor argument. Moving
the import inside setUp() keeps it out of the module's top-level namespace
so pytest's collector never sees it.
- Compute QPS/TPS from summed per-query latency instead of the benchmark
  loop's wall-clock time, which was dominated by harness overhead rather
  than simulated model latency
- Initialize NVML once and cache the device handle instead of calling
  nvmlInit() on every sample; shut it down via atexit
- Declare psutil as a project dependency (was used but undeclared)
- Shut down VerifiedDecisionPolicy's executor/callback thread in the
  benchmark smoke test's tearDown, fixing a background-thread leak
- Strengthen resource metrics and smoke tests to assert exact computed
  values instead of just presence/bounds
CostAwareEvictionPolicy never received a meaningful cost value during
benchmark runs: cost was measured as wall-clock time around
BenchmarkInferenceEngine.create(), which returns its pre-set response
instantly, so every cache miss recorded a near-zero cost regardless of
the dataset's actual recorded LLM latency.

- BenchmarkInferenceEngine.set_next_response() now accepts an optional
  cost, exposed as next_cost.
- VerifiedDecisionPolicy prefers the inference engine's reported cost
  over wall-clock measurement when available, falling back to the
  original wall-clock timing otherwise (no behavior change for live
  engines).
- benchmark.py now passes the dataset's recorded LLM generation
  latency through as the injected cost on cache misses.
- Added mean/p95/p99 latency and a hit_rate field to the results JSON,
  alongside the existing throughput metrics.
- Added a CostAwareEvictionPolicy vs. LRUEvictionPolicy comparison to
  RUN_COMBINATIONS: same dataset/model/sample count, with max_size set
  low enough to actually trigger eviction (unlike the existing
  combinations, which keep max_size far above sample count). LRU (not
  MRU) is the correct baseline since CostAwareEvictionPolicy reduces to
  plain LRU at cost_weight=0.
…tests

- RUN_COMBINATIONS now compares CostAwareEvictionPolicy against LRU, MRU,
  FIFO, and SCU (not just LRU), all on the same dataset/model/sample
  count/max_size, so the benchmark reports how cost-aware eviction
  stacks up against every eviction strategy in the codebase.
- Added deterministic unit tests for CostAwareEvictionPolicy covering
  the cost_weight=0/1 extremes (equivalence to LRU / pure cost-driven
  eviction), invalid cost_weight clamping, direct validation of the
  normalization/priority formulas, and negative/zero-cost inputs.
CI's ruff format --check step was failing on the two
_generate_and_measure_cost() call sites in process_request() (added in
the cost-signal fix) because they exceeded the line-length that would
have collapsed them onto one line. Reformatted with ruff 0.11.7 (the
version pinned in pyproject.toml/poetry.lock) to match CI exactly.
Addresses luis-gasparschroeder's remaining review comment: drop the
SCU-baseline aside and throughput-derivation comment in benchmark.py,
and trim the CI rationale paragraph in ReadMe.md.
Introduces ARCEvictionPolicy, splitting the cache into recency (T1)
and frequency (T2) lists with an adaptive victim split driven by a
promotion-based proxy for ARC's ghost-list hits. Wires it into the
package's public exports alongside the existing eviction strategies.
…tion

Wraps any EmbeddingEngine with thread- or process-pool dispatch that
coalesces duplicate in-flight requests and batches concurrent calls,
improving throughput for local/CPU-bound models and reducing redundant
computation under concurrent vcache.infer() load. Adds default
get_embeddings()/get_engine_factory() to the base EmbeddingEngine class
and batched get_embeddings() support to LangChain and OpenAI engines.
Add ConcurrentEmbeddingEngine for batched, concurrent embedding execution
Force-added despite the repo's blanket *.json gitignore rule so the workload backing the ARC vs LRU/MRU/FIFO/SCU/CostAware sweep is reproducible from the repo.
Adds `benchmarks/your_datasets/workload_short.json` and its companion `workload_short_INFO.json`.
Consolidates the generate_*/build_* dataset-builder scripts (previously
scattered in benchmarks/your_datasets/ alongside the run_* benchmarks)
into their own directory with a README documenting each script's output
and command. Output paths updated to still write into
benchmarks/your_datasets/; verified each script reproduces byte-identical
JSON after the move. Also gitignores the generated JSON files explicitly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces internal "advantage"/"cost" jargon with plain, real-world
terminology across the generator scripts in dataset_generators/ and the
run_*.py sweeps that consume their output (dataset filenames, results
directory names, and the benchmark.filepath provenance label):

  cost_advantage_demo(_200)      -> cost_sensitive_retention(_large)
  dual_advantage_dataset(_v2)    -> mixed_cost_recency_workload(_v2)
  full_repeat_dataset(_v2)       -> hot_cold_repeat_workload(_v2)
  high_locality                  -> temporal_locality_workload

Regenerated every renamed JSON output and diffed it byte-for-byte against
the pre-rename file before removing the old copy, so no dataset content
changed - only names.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Mirrors the Poetry dependency groups used in CI (dev, benchmarks) so
the repo can be built and its tests/benchmarks run without a manual
Python/Poetry setup, per the assignment's reproducibility deliverable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants