Skip to content

fix(services): bound scorer memory for long raw windows - #93

Merged
TheMeinerLP merged 1 commit into
mainfrom
fix/score-raw-memory
Oct 16, 2026
Merged

TheMeinerLP merged 1 commit into
mainfrom
fix/score-raw-memory

Conversation

@TheMeinerLP

@TheMeinerLP TheMeinerLP commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Since 0.5.0 raw windows default to max_packets 2048. PR #92 measured about 0.26 GiB of ONNX
inference memory per window at that size. The scorer batches up to score_batch_max (64) windows
into one ONNX run, so a 2048-packet raw model in shadow would request ~16 GiB per batch and get the
1 GiB score pods OOM-killed, taking all scoring down.

Fix

  • Raw-byte models: the micro-batch is split into ONNX runs of at most budget / per-window estimate
    rows (at least 1); the scores are concatenated in window order. Feature models are unaffected.
  • Per-window estimate: the inference formula of corvus_ml.membudget, evaluated for the default
    architecture with max_packets, max_tokens_per_packet and macro_windows from the feature spec
    (the spec does not carry the layer sizes; larger models need more).
  • Budget: CORVUS_SCORE_MEMORY_FRACTION (0.5) of the cgroup memory limit, or
    CORVUS_SCORE_MEMORY_BUDGET_MB.
  • At load: logs the estimate and rows per run, exports corvus_score_model_estimated_window_bytes
    and corvus_score_model_max_rows, and logs an ERROR when one window exceeds the budget. The model
    is still served.
  • Helm: score pods get a 1Gi request / 2Gi limit (was 512Mi / 1Gi), with the rule of thumb in
    values.yaml.

Rows per run for the default model:

max_packets 1 GiB limit 2 GiB limit
512 8 17
1024 4 8
2048 1 3

Tests

New services/tests/scoring/test_score_memory.py (fakes only, no ONNX model, no sleeps); ruff,
mypy, full services pytest, helm lint and helm unittest pass.

Raw windows default to 2048 packets, about 0.3 GiB of ONNX activations
per window. A micro-batch of 64 would request ~19 GiB and get the 1 GiB
score pod OOM-killed.

Split the micro-batch of a raw-byte model into ONNX runs whose estimate
fits a budget (half the cgroup memory limit, or
CORVUS_SCORE_MEMORY_BUDGET_MB). The estimate is the inference formula of
corvus_ml.membudget for the default architecture. At load the scorer logs
the estimate and the rows per run, exports
corvus_score_model_estimated_window_bytes and logs an error when a single
window exceeds the budget, but keeps serving.

Raise the score pod memory to 1Gi request / 2Gi limit.
@TheMeinerLP
TheMeinerLP merged commit 82226ea into main Oct 16, 2026
16 checks passed
@TheMeinerLP
TheMeinerLP deleted the fix/score-raw-memory branch October 16, 2026 14:11
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.

1 participant