Skip to content

feat: add model cache and runtime footprint report - #359

Merged
Abhash-Chakraborty merged 5 commits into
Abhash-Chakraborty:canaryfrom
kamalsharma001:feat/model-footprint-report
Aug 3, 2026
Merged

feat: add model cache and runtime footprint report#359
Abhash-Chakraborty merged 5 commits into
Abhash-Chakraborty:canaryfrom
kamalsharma001:feat/model-footprint-report

Conversation

@kamalsharma001

@kamalsharma001 kamalsharma001 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Closes #345.

What

Adds a reproducible, read-only report of what each ML model pack downloads
and loads: configured identifier, on-disk cache footprint, loaded/unloaded
state, execution device, and last-use time.

  • find_api.core.model_footprint.build_report() — core report builder,
    one ModelSpec per model (siglip, florence-2, yolo, insightface,
    paddleocr), each with a best-effort local cache resolver.
  • GET /api/status/models/footprint — admin-only endpoint, include_paths=False.
    Never returns filesystem paths, host info, or media metadata.
  • backend/scripts/model_footprint_report.py — local CLI (--json,
    --no-paths); includes paths by default since it runs with the
    operator's own filesystem access.
  • docs/guides/model-footprint.md — usage guide, pack table, current
    approximate sizes for planning.
  • docs/overhaul/inventory/lane-f-ml.md — points future pack-size
    proposals at this report as the measurement source.

Why

#45 (installer model downloads/cache management) and model benchmark work
need real numbers instead of hand-estimated cache sizes. This gives both a
stable measurement source.

Design constraints

  • Never downloads model weights — every cache lookup is a local filesystem
    read or a local cache-index read (huggingface_hub.scan_cache_dir()
    reads on-disk metadata only, no network call).
  • Every resolver is wrapped so a missing library or unset cache dir
    degrades to "not cached" rather than raising.
  • Public API surface (/status/models/footprint) never exposes paths,
    credentials, or media metadata — path info is CLI-only.

Testing

  • backend/tests/test_model_footprint.py — new, covers each cache
    resolver against temporary fake cache dirs (no real downloads) and
    build_report() assembly/pack totals. Two symlink-dependent assertions
    skip cleanly on platforms without real symlink support (e.g. Windows
    without Developer Mode) rather than faking a huggingface_hub cache
    scan_cache_dir() wouldn't actually recognize.
  • backend/tests/test_status.py — new endpoint test asserting all 5
    model keys are reported, loaded state reflects ModelManager, and no
    path key appears anywhere in the response.

Out of scope

Summary by CodeRabbit

  • New Features

    • Added model footprint reports showing cached models, disk usage, load state, device, and last-use details.
    • Added an admin-only API endpoint and command-line report with human-readable or JSON output.
    • Added light, full, and proposed CPU model pack summaries.
    • Reports avoid exposing filesystem paths through the API and handle unavailable cache information gracefully.
  • Documentation

    • Added guidance for using, interpreting, and extending model footprint reports.

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown

PR Context Summary

Suggested issue links

  • No strong issue match found yet.

Use Fixes #123 or Closes #123 in the PR body when one of the suggestions is the intended issue.
Manual rerun: Actions > PR Context Triage > Run workflow > set pr_number and force_review=true.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0801b3e7-868c-47b7-b2c8-9a3df1edd69d

📥 Commits

Reviewing files that changed from the base of the PR and between 2b2ee8c and b0c703a.

📒 Files selected for processing (2)
  • backend/scripts/model_footprint_report.py
  • backend/tests/test_model_footprint.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/scripts/model_footprint_report.py

📝 Walkthrough

Walkthrough

Adds local model-cache inspection and runtime status reporting for five models. The report is available through a CLI and an admin-only API endpoint, with optional path exposure for local use and path suppression for the API.

Changes

Model footprint reporting

Layer / File(s) Summary
Cache resolution and model registry
backend/src/find_api/core/model_footprint.py
Adds cache metadata, local-only resolvers for Hugging Face, OpenCLIP, YOLO, InsightFace, and PaddleOCR, model specifications, pack membership, and proposed CPU pack metadata.
Report aggregation and runtime status
backend/src/find_api/core/model_footprint.py
Combines cache data with model-manager and Redis status to produce per-model, device, last-use, path-controlled, and pack report data.
CLI and admin API interfaces
backend/scripts/model_footprint_report.py, backend/src/find_api/routers/status.py
Adds human-readable and JSON CLI output plus an admin-protected path-free API endpoint.
Offline validation and usage documentation
backend/tests/test_model_footprint.py, backend/tests/test_status.py, docs/guides/model-footprint.md
Adds no-download cache and report tests, endpoint coverage, and documentation for usage, packs, measurements, and extensions.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Admin
  participant StatusAPI
  participant build_report
  participant LocalCaches
  participant RuntimeState
  Admin->>StatusAPI: GET /api/status/models/footprint
  StatusAPI->>build_report: build_report(include_paths=False)
  build_report->>LocalCaches: resolve local model caches
  LocalCaches-->>build_report: cache metadata
  build_report->>RuntimeState: read manager and Redis status
  RuntimeState-->>build_report: loaded, device, and last-use data
  build_report-->>StatusAPI: path-free report
  StatusAPI-->>Admin: JSON response
Loading

Suggested labels: documentation, testing, privacy, local-first

Suggested reviewers: abhash-chakraborty

Poem

A rabbit checks each cache with care,
Counts model bytes tucked everywhere.
Paths stay home when APIs speak,
Pack totals bloom in measured rows.
“No downloads,” says the bunny bright—
The report is ready, clear and light.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: adding a model cache and runtime footprint report.
Description check ✅ Passed The description provides detailed scope, rationale, implementation, testing, linked issue, and out-of-scope information, but omits several template checklist sections.
Linked Issues check ✅ Passed The implementation satisfies issue #345 by providing report fields, safe API and CLI access, pack totals, documentation, and offline temporary-cache tests.
Out of Scope Changes check ✅ Passed The changes remain focused on the model footprint report, including its API, CLI, documentation, tests, and explicitly scoped proposed CPU placeholder.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@macroscopeapp

macroscopeapp Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Macroscope skipped reviewing this pull request. Per-review cost limit exceeded (workspace setting).

This review would cost an estimated $2.19, which exceeds your per-review limit of $2.00.

The top 3 files driving up this estimate:

File Size Estimate
backend/src/find_api/core/model_footprint.py 18.30KB $0.92
backend/tests/test_model_footprint.py 12.73KB $0.64
docs/guides/model-footprint.md 5.54KB $0.28

Tip

To get this pull request reviewed, you can:

  1. Comment @macroscope-app on this PR to request a manual review (monthly spend limits still apply).
  2. Exclude the file(s) above from review by adding a pattern to your .macroscope/ignore.md — note that creating this file replaces Macroscope's built-in default ignores rather than extending them.
  3. Raise your cost limit in your workspace billing settings.

Turn off this reminder going forward

@macroscopeapp

macroscopeapp Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Unable to check for correctness in b0c703a. This PR introduces a new feature (model footprint reporting) with a new admin API endpoint, CLI tool, and substantial new logic. The author does not own any of the changed files, all of which have a designated code owner who should review this contribution.

You can customize Macroscope's approvability policy. Learn more.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
docs/guides/model-footprint.md (1)

44-44: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add a language specifier to the fenced code block.

The code block at line 44 has no language tag, triggering markdownlint MD040. Since it contains an HTTP endpoint reference, text is the most appropriate specifier.

♻️ Proposed fix
-```
+```text
 GET /api/status/models/footprint   (admin-only)
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @docs/guides/model-footprint.md at line 44, Update the fenced code block near
the HTTP endpoint reference in model-footprint.md to specify the text language,
preserving the existing endpoint content.


</details>

<!-- cr-comment:v1:399d9c73afe59788e848617d -->

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @backend/tests/test_model_footprint.py:

  • Around line 161-169: Replace the tautological assertion in
    test_not_found_reports_checked_locations with a direct assertion of the intended
    note content: verify that info.note is present and includes the expected “not
    found” text, preserving the existing exists and bytes_on_disk checks.

Nitpick comments:
In @docs/guides/model-footprint.md:

  • Line 44: Update the fenced code block near the HTTP endpoint reference in
    model-footprint.md to specify the text language, preserving the existing
    endpoint content.

</details>

<details>
<summary>🪄 Autofix (Beta)</summary>

Fix all unresolved CodeRabbit comments on this PR:

- [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended)
- [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: Organization UI

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `f00c403c-0f5e-4c92-a420-0212c9d219bc`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between de5f27900fcd35ab6232b1853ae003da2280ae21 and f0432f5156d2cd1c036c19f216ec57e0858418f6.

</details>

<details>
<summary>📒 Files selected for processing (7)</summary>

* `backend/scripts/model_footprint_report.py`
* `backend/src/find_api/core/model_footprint.py`
* `backend/src/find_api/routers/status.py`
* `backend/tests/test_model_footprint.py`
* `backend/tests/test_status.py`
* `docs/guides/model-footprint.md`
* `docs/overhaul/inventory/lane-f-ml.md`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment thread backend/tests/test_model_footprint.py
@Abhash-Chakraborty
Abhash-Chakraborty self-requested a review July 14, 2026 05:52
@Abhash-Chakraborty

Copy link
Copy Markdown
Owner

Please fix the CI.

@Abhash-Chakraborty

Copy link
Copy Markdown
Owner

Thanks for this — the report itself is well built, and the read-only/no-paths default on the API is exactly the boundary I wanted.

Three things before I can merge:

  1. Retarget to canary. This PR is opened against main. Contributor PRs go to canary; main only takes the maintainer promotion PR. You can change the base with the "Edit" button next to the title.
  2. The branch has conflicts with the base now. Please rebase onto latest canary once you've retargeted.
  3. backend-check is failing on formattingruff format --check wants src/find_api/core/model_footprint.py and tests/test_model_footprint.py reformatted. cd backend && uv run ruff format . will fix both.

Also, your branch is named main, which is what makes the rebase awkward. If it's easier, push the work to a fresh branch like feat/model-footprint-report off canary and repoint the PR there.

Ping me once CI is green and I'll take another pass.

@Abhash-Chakraborty Abhash-Chakraborty added under-review Maintainer needs to verify backend FastAPI, database, storage, and API work ml Model inference, embeddings, OCR, captions, and search relevance gssoc26 Related to GirlScript Summer of Code 2026. type:feature Feature PR. GSSoC type bonus. level:intermediate GSSoC difficulty level: intermediate. Base contributor points: 35. labels Jul 29, 2026
@github-actions

Copy link
Copy Markdown

@macroscope-app review

Please review this PR against its linked issue, local-first privacy rules, and the current Find repo instructions.
Linked issue(s): #345.
Trigger source: label-gated review (under-review).

@Abhash-Chakraborty Abhash-Chakraborty added stale Marked stale; auto-closed 7 days after labeling if not addressed. and removed under-review Maintainer needs to verify labels Jul 30, 2026
@github-actions

Copy link
Copy Markdown

This PR is marked as stale. It will close automatically after 7 days without renewed activity; remove the stale label when work resumes.

@Abhash-Chakraborty

Copy link
Copy Markdown
Owner

Checking in — no movement here since the 13th, and three things are red:

  1. Targets main. Contributor branches start from and target canary; main only moves through a maintainer promotion PR, so Branch policy fails by design. I can't just retarget it — main and canary have diverged enough that the diff would balloon to ~180 unrelated files. Cherry-pick onto a fresh branch off canary instead.
  2. Merge conflicts. The branch no longer applies cleanly, which the rebase above also solves.
  3. backend-check fails on formatting — uv run ruff format . from backend/ before you push.

Marking it stale so the queue reflects reality. Push anything and the label comes straight off — the underlying feature is still wanted, it just needs to be sitting on the right branch.

Shout if you want a hand with the rebase.

Maintainer merge to unblock the PR: it targeted main from a 50-commit-old base,
which is why it showed as conflicting and why backend-check failed.

Conflicts (2):
- backend/tests/test_status.py: append/append at the file tail. Canary added a
  worker_health assertion to the existing /status/models test while this branch
  appended a new footprint test. Both kept.
- docs/overhaul/inventory/lane-f-ml.md: canary deleted the whole
  docs/overhaul/inventory/ tree, so this branch's edit to it is dropped.

Fixes:
- ruff format on core/model_footprint.py and tests/test_model_footprint.py,
  which was the actual backend-check failure.
- Retargeted six dangling references. Three pointed at
  docs/overhaul/inventory/lane-f-ml.md, which no longer exists, and three cited
  "issue Abhash-Chakraborty#45" for the proposed CPU pack. Abhash-Chakraborty#45 is closed and is about installer
  model downloads; the CPU-only runtime profile is Abhash-Chakraborty#339. Left unchanged these
  would have sent a reader to a deleted file and a closed, unrelated issue.
- Added the missing language to a fenced block in docs/guides/model-footprint.md
  (CodeRabbit nitpick).

Verified against current canary: ruff check clean, ruff format clean (152
files), and the full suite at 635 passed / 8 skipped, up from canary's 619/6.
The two new skips are symlink-guarded huggingface_hub cache tests that do run on
the Linux CI runner.

Reviewed and left as-is: the route is registered before /status/{job_id} so
there is no path-matching shadowing; every integration point the module reaches
for still exists on canary (ModelManager.last_used, current_torch_device,
detect_capabilities, resolve_execution, get_redis_connection).
@Abhash-Chakraborty
Abhash-Chakraborty changed the base branch from main to canary August 1, 2026 16:52
@Abhash-Chakraborty Abhash-Chakraborty removed the stale Marked stale; auto-closed 7 days after labeling if not addressed. label Aug 2, 2026
@Abhash-Chakraborty

Copy link
Copy Markdown
Owner

This is the measurement source I wanted for #45 — the "never download weights, degrade to not-cached on any error" constraint is the right call, and keeping paths CLI-only while /status/models/footprint stays path-free is a good split.

Its been sitting since mid-July though and CI never completed on it (no backend-check run at all). Please rebase onto current canary and push so the full suite actually runs. One nit: the script docstring says the proposed CPU pack is tracked by #339 but the PR body says #45 — pick one. And build_report() walks the cache dirs plus scan_cache_dir() on every request; on a cold page cache with a full model set that is not a fast endpoint, so either note that in the docs or add a short TTL cache.

Rebase + green CI and I will merge this.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
backend/src/find_api/routers/status.py (1)

21-35: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Avoid a full cache scan on every request.

The route calls build_report() synchronously for each request. The report scans cache directories and Hugging Face indexes, which can slow repeated admin polling and increase filesystem I/O when the page cache is cold.

Add a short-lived, concurrency-safe TTL cache for cache-resolution data, or document the scan cost and expected polling interval.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/src/find_api/routers/status.py` around lines 21 - 35, Update
get_model_footprint and the underlying build_report cache-resolution flow to
avoid rescanning cache directories and Hugging Face indexes on every request.
Add a short-lived, concurrency-safe TTL cache for the resolved cache data while
preserving fresh model state in each report; alternatively, explicitly document
the scan cost and required polling interval if caching is not implemented.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@backend/src/find_api/routers/status.py`:
- Around line 21-35: Update get_model_footprint and the underlying build_report
cache-resolution flow to avoid rescanning cache directories and Hugging Face
indexes on every request. Add a short-lived, concurrency-safe TTL cache for the
resolved cache data while preserving fresh model state in each report;
alternatively, explicitly document the scan cost and required polling interval
if caching is not implemented.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a6033722-b174-431c-aefa-0cff59a5bc4a

📥 Commits

Reviewing files that changed from the base of the PR and between f0432f5 and 2b2ee8c.

📒 Files selected for processing (6)
  • backend/scripts/model_footprint_report.py
  • backend/src/find_api/core/model_footprint.py
  • backend/src/find_api/routers/status.py
  • backend/tests/test_model_footprint.py
  • backend/tests/test_status.py
  • docs/guides/model-footprint.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • backend/tests/test_status.py
  • docs/guides/model-footprint.md
  • backend/tests/test_model_footprint.py
  • backend/src/find_api/core/model_footprint.py

…ASCII

backend-check was failing on two of this PR's own tests. Root cause: the HF
cache tests build a real on-disk Hub cache and call the real
huggingface_hub, but the dev dependency group deliberately excludes the ML
extras, so huggingface_hub is not installed in CI. _hf_hub_cache_matches
bails out at the import and reports "not cached" — which is also what an
empty cache looks like, so test_finds_cached_repo_by_full_id failed and
test_pack_totals_sum_correctly saw 4 of 5 models cached instead of 5.

It only ever passed locally on Windows because both tests skip there for a
different reason (scan_cache_dir needs real symlinks, which need Developer
Mode). Two more tests in that class were passing for the wrong reason —
"not cached" is the expected result either way — so the whole HF path had
no real coverage anywhere.

Stub scan_cache_dir instead of building a real cache. That drops both the
huggingface_hub and the symlink requirement, so the needle-matching and
aggregation logic — the part that is ours — is now genuinely covered on
every platform. The real-library check is kept as a separate integration
test guarded by importorskip, and new cases cover case-insensitive
matching, multi-repo summing with its note text, and a corrupted cache
degrading to "not cached" rather than raising.

Separately, the CLI used an em dash as its "no value" placeholder. The
default Windows console codepage is cp1252, where that renders as mojibake,
and the project ships a Windows desktop build. The script is now ASCII-only,
with tests asserting the rendered output encodes as cp1252 and that the
source stays ASCII.

Verified: report contains no filesystem paths or host identifiers with
include_paths=False, --json and --no-paths both behave, and all three CLI
modes render. Full backend suite 688 passed, 7 skipped; ruff check and
format clean.

Not changed: the shared Redis client has no socket timeout, so the
cross-process loaded-model scan in _aggregate_manager_status can hang on an
unreachable-but-accepting Redis. That client is shared with the rq workers,
which rely on long blocking reads, so it needs its own change rather than
one buried in this PR.
@Abhash-Chakraborty Abhash-Chakraborty added the api API contract, endpoint behavior, and response shape label Aug 3, 2026
@Abhash-Chakraborty Abhash-Chakraborty added testing Automated tests or manual QA coverage documentation Documentation, README, guide, or text improvement. local-first Privacy-preserving local runtime and offline behavior performance Speed, startup, memory, image size, and runtime efficiency gssoc Related to GirlScript Summer of Code. gssoc:approved Valid GSSoC contribution approved for scoring. quality:exceptional Exceptional high-quality PR. GSSoC contributor multiplier: 1.5x. priority: medium Useful issue with moderate urgency ready-to-merge Fully approved, tested, and cleared for immediate merging. labels Aug 3, 2026

@Abhash-Chakraborty Abhash-Chakraborty left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

backend-check was red because the HF cache tests need huggingface_hub, which the dev group deliberately excludes — they only ever passed locally on Windows, where they skip for the unrelated symlink reason. Stubbed scan_cache_dir so that path is genuinely covered everywhere, and made the CLI ASCII-only since the em-dash placeholder was mojibake on a cp1252 console. 688 passed, ruff clean, no paths leak with include_paths=False — approving.

@Abhash-Chakraborty
Abhash-Chakraborty merged commit 76456e4 into Abhash-Chakraborty:canary Aug 3, 2026
34 of 36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api API contract, endpoint behavior, and response shape backend FastAPI, database, storage, and API work documentation Documentation, README, guide, or text improvement. gssoc:approved Valid GSSoC contribution approved for scoring. gssoc Related to GirlScript Summer of Code. gssoc26 Related to GirlScript Summer of Code 2026. level:intermediate GSSoC difficulty level: intermediate. Base contributor points: 35. local-first Privacy-preserving local runtime and offline behavior ml Model inference, embeddings, OCR, captions, and search relevance performance Speed, startup, memory, image size, and runtime efficiency priority: medium Useful issue with moderate urgency quality:exceptional Exceptional high-quality PR. GSSoC contributor multiplier: 1.5x. ready-to-merge Fully approved, tested, and cleared for immediate merging. testing Automated tests or manual QA coverage type:feature Feature PR. GSSoC type bonus.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add a model cache and runtime footprint report

2 participants