{"id":50780800,"url":"https://github.com/kylefoxaustin/keyhole-sizer","last_synced_at":"2026-06-12T03:02:58.016Z","repository":{"id":360765528,"uuid":"1213191825","full_name":"kylefoxaustin/keyhole-sizer","owner":"kylefoxaustin","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-05T18:39:28.000Z","size":1186,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-05T20:16:50.788Z","etag":null,"topics":["computer-vision","edge-ai","npu","performance-modeling","python","sizing"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kylefoxaustin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-17T06:11:41.000Z","updated_at":"2026-06-05T18:39:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/kylefoxaustin/keyhole-sizer","commit_stats":null,"previous_names":["kylefoxaustin/keyhole-sizer"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/kylefoxaustin/keyhole-sizer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylefoxaustin%2Fkeyhole-sizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylefoxaustin%2Fkeyhole-sizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylefoxaustin%2Fkeyhole-sizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylefoxaustin%2Fkeyhole-sizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kylefoxaustin","download_url":"https://codeload.github.com/kylefoxaustin/keyhole-sizer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylefoxaustin%2Fkeyhole-sizer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34226630,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["computer-vision","edge-ai","npu","performance-modeling","python","sizing"],"created_at":"2026-06-12T03:02:56.979Z","updated_at":"2026-06-12T03:02:58.008Z","avatar_url":"https://github.com/kylefoxaustin.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# keyhole-sizer\n\n[![version](https://img.shields.io/badge/version-v1.1.1-blue)](https://github.com/kylefoxaustin/keyhole-sizer/releases/tag/v1.1.1)\n[![streamlit](https://img.shields.io/badge/streamlit-live-FF4B4B)](https://keyhole-sizer.streamlit.app)\n[![engine](https://img.shields.io/badge/engine-ratchet%20v0.2.4-green)](https://github.com/kylefoxaustin/ratchet)\n\nInteractive NPU sizing sandbox for the\n[Keyhole](https://github.com/kylefoxaustin/keyhole) edge-AI bake-off findings.\n\nA Streamlit app that wraps the measured bake-off data in tunable controls:\npick an NPU tier (or build a custom one), a vision pipeline, concurrent\nstream count, and whether an LLM co-exists on the same silicon — then\nwatch live FPS / tok/s / VRAM-fit / duty-cycle projections.\n\n**Companion app:**\n[personal-ai-assistant-sizer](https://github.com/kylefoxaustin/personal-ai-assistant-sizer)\n(LLM-only sizing for the Skippy assistant deployment). Both sizers share\nschema, source taxonomy, anchor-secrets mechanism, tab structure, and — as\nof v1.1.0 — the same shared engine. Pick the one that matches your\nworkload.\n\n**Engine:** As of v1.1.0 the canonical NPU tier registry, capability\ntaxonomy, `hw_with_memory` memory-upgrade clones, anchor loader, and\nHardware dataclass all live in the shared [`ratchet`](https://github.com/kylefoxaustin/ratchet)\npackage (pinned to v0.2.4). Surface-side keyhole-sizer keeps its UI,\nprojection layer, vision pipelines, LLM catalog, platform-budget, and\nKPI breakdown. The retrofit cut –496 lines net while keeping behavior\nparity on the canonical tiers + fixing the memory-upgrade anchor\ndiscontinuity (Mid + LPDDR6-14 now climbs from 37.85 → 63.08 tok/s\ninstead of dropping to cross-class projection). See the\n[v1.1.0 release notes](https://github.com/kylefoxaustin/keyhole-sizer/releases/tag/v1.1.0)\nfor the full diff.\n\nIf you've read the Keyhole deck and want to answer **\"what if my NPU had\na 96-bit bus instead of 128?\"** or **\"how many 480p streams can I run\nwith a 2 Hz LLM query rate?\"**, this is the tool.\n\n## Install \u0026 run\n\n```bash\ngit clone https://github.com/kylefoxaustin/keyhole-sizer.git\ncd keyhole-sizer\n\n# Option A — fresh venv with plain stdlib venv\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\n# Option B — virtualenvwrapper\nmkvirtualenv keyhole-sizer --python=/usr/bin/python3.10\npip install -r requirements.txt\n\n# Option C — reuse the Keyhole project's venv (has streamlit+plotly already)\nsource ~/.virtualenvs/keyhole/bin/activate\n\n# Launch\nstreamlit run app.py\n```\n\nBrowser opens to `http://localhost:8501`. No GPU needed — this app is\npure projection math on top of already-measured numbers.\n\n**Note on the ratchet engine dependency:** `requirements.txt` pulls\nratchet from its public GitHub source repo (not PyPI — the name\n`ratchet` on PyPI is an unrelated project). The pin is `ratchet @\ngit+https://github.com/kylefoxaustin/ratchet.git@v0.2.4`. Bumping\nratchet means editing that tag in the URL and pushing. If you're\nrunning locally with ratchet as an editable install (`pip install -e\n~/path/to/ratchet`), pip prefers your editable over the git pin —\nuseful for engine co-development.\n\n## Layout (horizontal — live since v2.0.0)\n\n`app.py` is the **horizontal-layout** app: no left sidebar, controls in a\ntop strip, full-width results. It began as a prototype judged against the\noriginal tall-sidebar layout (\"Step 3\" in earlier docs); v2.0.0 promoted it to\nbe the live app. The previous vertical-sidebar layout is preserved, runnable,\nat [`app_vertical_legacy.py`](app_vertical_legacy.py) (`git mv` of the old\n`app.py`); the last release with it live is tagged `v1.2.0`.\n\nWhat the horizontal layout does vs the old sidebar layout:\n\n- **No left sidebar.** All controls live in a horizontal **top control\n  strip**: NPU-tier pills, workload pills (Vision / LLM / VLA), camera\n  count, popovers for Pipeline / Model / Quant / Workload / Duty / Memory /\n  BW-share, and a single ⚙ Settings popover for the rarely-touched power\n  controls (custom-NPU builder, compiler quality, KPI toggle).\n- **Full-width results + charts**; KPIs visible onscreen, not download-only.\n- **Per-section scoped detail tabs** per workload — Vision (Pipeline-timing /\n  Stream-scaling / DRAM-bandwidth / Pipeline-flow), LLM (Accuracy / Precision /\n  Performance / Timing), VLA (Tier-scaling / Control-loop) — each wrapped in a\n  **collapsible \"🔎 … detail\" expander** so verbose tabs can be minimized.\n  Compact defaults: detail expanders collapsed, default workload Vision-only.\n- **Platform-budget** cross-workload view (vision FPS under concurrent LLM\n  load) when both Vision and LLM are active.\n- **Per-workload KPI section** — each active workload gets a collapsible KPI\n  block (cross-tier + cross-config tables), exportable individually or as one\n  **uber XLSX** with a sheet per active `(workload × view)` and a tier-scoped\n  filename.\n\nThe companion\n[personal-ai-assistant-sizer](https://github.com/kylefoxaustin/personal-ai-assistant-sizer)\ncarries a parallel horizontal shell (the LLM-only single-workload cut), so both\nsizers share the same layout.\n\n## Deployment (Streamlit Community Cloud)\n\nThe app is deployed at **https://keyhole-sizer.streamlit.app** with a\nshared-password gate. Auto-redeploys on every push to `main`.\n\nTo set up your own deployment:\n\n1. Go to [share.streamlit.io](https://share.streamlit.io), sign in with GitHub,\n   grant access to this repo.\n2. **New app** → pick `kylefoxaustin/keyhole-sizer`, branch `main`,\n   main file `app.py`.\n3. **Advanced settings → Secrets**:\n   ```toml\n   PASSWORD = \"your-shared-password-here\"\n   ```\n   (Optional — when absent, the password gate is bypassed so local dev\n   doesn't require typing it.)\n4. Deploy.\n\n**Note:** changes to `app.py` auto-reload; changes to files under `sizer/`\nrequire a manual reboot from the Streamlit Cloud console. (See\n[`memory/project_streamlit_deploy.md`](https://github.com/kylefoxaustin/personal-ai-framework)\nin the framework repo for the inotify-stuck-reload trap.)\n\n## What you can tune\n\n### Hardware\n\n| Tier preset | Memory | Effective BW | INT8 / FP path |\n|---|---|---:|---|\n| **i.MX 95** (ground truth) | 32-bit LPDDR5 @ 6.4 GT/s | 25.6 GB/s × 0.70 | INT8-only (Neutron) |\n| Low-LP5-64bit | 64-bit LPDDR5 @ 6.4 GT/s | 51.2 GB/s × 0.70 | INT8-only |\n| Low-LP5X | 64-bit LPDDR5X @ 8.4 GT/s | 67.2 GB/s × 0.70 | INT8-only |\n| NPU Mid | 128-bit LPDDR5X @ 8.4 GT/s | 134.4 GB/s × 0.70 | INT8-only |\n| **NPU High** *(default)* | 128-bit LPDDR5X @ 8.4 GT/s | 134.4 GB/s × 0.70 | FP-capable (FP16 / FP8 / BF16) |\n| RTX 5090 | GDDR7 @ 28 GT/s | reference cell | full FP + INT8 + INT4 |\n| Custom | configurable | computed | configurable |\n\nMid + High share memory bandwidth (Class 3b `LP5X-8.4-128b`); High\ndifferentiates on **compute** (1.375× TOPS), **capacity** (1.33× DRAM),\nand **TDP** (1.6×), NOT memory BW. FP recipes pin to High. Default tier\nis High to keep the default LLM (fp16 dense) compatible on first load.\n\n**Optional memory upgrade overlays** on Mid + High: LPDDR5T @ 11.2 GT/s\n(179 GB/s), LPDDR6 @ 12 GT/s (192 GB/s), LPDDR6 @ 14 GT/s (224 GB/s).\nBW-projected — flips the source badge to 🟡 same-class.\n\n**Custom mode:** bus width, memory type, data rate, BW efficiency, peak\nBF16/FP8 TOPS, compute efficiency, DRAM capacity, TDP.\n\n**NPU share** (sidebar): 100% / 75% / 50% / 25%. Models SoC bus contention\nfrom display / camera / audio paths. Default 75% for NPU tiers, 100% for\n5090 (dedicated VRAM). Scales BW-bound paths only.\n\n### Vision workload\n\n- **Pipelines (23 entries):** SAM 3 baseline, EfficientSAM-Small, Hybrid V2\n  variants, TRT FP8 shipping stack, YOLO-only, ResNet-50 vendor-compare\n  pipelines (INT8 + INT4), CLIP, ViT alternatives, EfficientSAM3,\n  YOLOE-26 — organized into 5 narrative tracks via the sidebar\n  pipeline picker.\n- **Resolution:** 720p / 1080p / 4K.\n- **Concurrent streams:** 1..16 (YOLO batching applied automatically).\n- **Compiler quality:** slider for projected pipelines (non-applicable\n  when measured-silicon anchor fires).\n\n### LLM workload\n\n- **17-model catalog** with role icons in the dropdown:\n  🚀 production (1) · 🔬 fine-tune (7) · 📚 stock base (6) · ⚙️ perf\n  reference (3). Default: 🚀 **Skippy 7B v4** (Qwen2.5-7B FT, current\n  production). Models incompatible with the selected NPU tier sink to\n  the bottom of the dropdown with a 🔴 prefix.\n- **Workload pattern:** plain_chat (reference) · long_form_reasoning ·\n  tool_use · rag_long_context · cold_start. Scales decode tok/s + TTFT\n  by reference multipliers (26× spread across categories). Disabled\n  when dtype-mismatch is in play (model won't actually run).\n- **Precision (quant):** Q4_K_M / Q5_K_M / Q8_0 / FP8 / FP16 — picker\n  shape depends on the model's `compute_dtype` and the NPU tier's\n  capability levels.\n- **Queries per minute** (slider) + **answer length** (short ~200 tok or\n  RAG 8K prompt + 2K response).\n\n## What you see\n\nThe app uses a tab strip below the headline metric row. Tab order adapts\nto which workloads are enabled:\n\n| Tab | Always | When |\n|---|---|---|\n| Overview | ✓ | metric tiles + headline cards |\n| Accuracy | | LLM on (Finding 4 cross-model + per-category) |\n| Precision | | LLM on (precision-axis ladder + capability levels) |\n| Performance | | LLM on (cross-tier comparison) |\n| Stream scaling | | Vision on (per-stream / total FPS curves) |\n| Duty-cycle | | Vision + LLM on (FPS vs queries/min) |\n| **KPIs** | ✓ | CSV exports + per-pipeline KPI spreadsheet preview |\n| Detail | ✓ | raw projection dicts, debug surface |\n\nHeadline metrics: Vision FPS per stream · Total system FPS · LLM decode\ntok/s · TTFT · End-to-end latency · Memory fit. Each tile carries a\nsource badge (🟢 measured / 🟢 measured_anchor / 🟡 same-class /\n🟠 cross-class projected) so users can see data pedigree at a glance.\n\n## Where the numbers come from\n\nThe sizer composes **three layers**, in priority order:\n\n1. **Measured-silicon anchor overlay** (🟢) — when a real-silicon\n   measurement exists for the selected (tier, precision, model) cell, it\n   hot-swaps the BW-projected baseline. NPU silicon measurements live in\n   `.streamlit/secrets.toml` (gitignored); see\n   [`.streamlit/secrets.toml.example`](.streamlit/secrets.toml.example)\n   for the schema. RTX 5090 measurements are in-tree (public bake-off\n   data).\n2. **Phase 1 measured override** (🟢) — `Hardware.measured_edge_ms` maps\n   `(pipeline, resolution) → ms` for vision; `Hardware.measured_llm` maps\n   `(model, quant) → {decode_tok_s, prefill_tok_s}` for LLMs. When a\n   tier has the cell, `project_*()` returns measured ms verbatim.\n3. **Phase 2 projection** — `max(bw_floor, compute_floor) + overhead` with\n   tier-specific calibration constants. Source badge `cross_class` 🟠\n   when no anchor in this tier_family; `same_class_anchor` 🟡 when\n   BW-scaled within family from a measured anchor.\n\nBake-off data origins:\n\n| Baseline | Source |\n|----------|--------|\n| YOLO-seg FP8 edge ms @ resolution | `keyhole/bakeoff_trt_yolo.py` |\n| CLIP FP8 edge ms | `keyhole/bakeoff_trt_clip.py` |\n| YOLO batching curve (B=1..16) | `keyhole/bakeoff_concurrency.py` |\n| ResNet-50 INT8/INT4 ncu DRAM | `keyhole/scripts/export_ncu_for_sizer.py` |\n| SAM 3 / EfficientSAM / MobileSAM edge ms | `keyhole/bakeoff_sam_variants.py`, `bakeoff_fp8.py` |\n| LLM 5090 perf cells (TTFT, decode) | `keyhole/bakeoff_llm.py` |\n| Qwen3-30B-A3B + Qwen2.5 dense GGUF sizes | `keyhole/bakeoff_llm.py` |\n| LLM accuracy (Finding 4 per-category) | `personal-ai-framework` eval harness |\n| NPU silicon anchors (Mid / High / Low-LP5X) | `.streamlit/secrets.toml` (gitignored) |\n\nVision pipelines on NPUs are **bandwidth-bound** in the common case, so\nedge ms scales inversely with effective bandwidth on un-anchored cells.\nLLM decode is bandwidth-bound on `active_params × bytes_per_param` (MoE\nwins — Qwen3-30B-A3B Q4_K_M streams only ~1.65 GB per token despite the\n30B total params). LLM prefill (TTFT) is compute-bound — bigger TOPS\nhelps TTFT, more BW does not.\n\n## Platform-budget CSV export\n\nThe **KPIs tab** carries two CSV download buttons + two KPI-spreadsheet\npreview buttons:\n\n- **💾 This config** — single platform-budget row for the current\n  (HW × pipeline × resolution × streams × LLM) configuration.\n- **📦 All configs** — full matrix (~585 rows) of every preset HW tier ×\n  pipeline × resolution × stream count × LLM (quant × workload ×\n  answer_kind). Custom HW is skipped — use \"This config\" for custom.\n- **📊 KPI spreadsheet (all models / this model)** — per-pipeline KPI\n  preview table + ⬇ Download XLSX. Vision-only (per-pipeline rows make\n  no sense LLM-only).\n\nCLI alternatives in `scripts/`:\n- `export_platform_budget.py` — one row for any specific config.\n- `export_platform_matrix.py` — full matrix to `data/platform_budget_matrix.csv`.\n\n**Schema:**\n- `ss_*` columns (duty cycle, DDR GB/s, TOPS, MB resident, watts,\n  throughput) are **additive** across rows at the platform level.\n- `peak_*` columns (per-frame ms, peak GB/s, peak TOPS) are NOT\n  additive — per-workload ceilings.\n- `hw_*` columns duplicated per row so each row is self-contained.\n- `sizer_commit_sha` + `export_timestamp_iso` trace a row back to the\n  sizer revision that emitted it.\n\n**Caveats baked into the CSV header `#` comments** (read before using\nfor procurement):\n- Power is `TDP × duty-cycle` approximation, NOT measured per-workload.\n- NPU Low/Mid/High vision numbers without anchors are BW-scaled from\n  RTX 5090 measurements, NOT measured on actual NPU silicon.\n\n**Consume in pandas:** `pd.read_csv(path, comment='#')`.\n\n## Anchor-secrets system (private silicon measurements)\n\nReal NPU silicon measurements for the LLM + CNN cells in the spec live\nin `.streamlit/secrets.toml` (gitignored). The loader at\n[`sizer/npu_anchors.py`](sizer/npu_anchors.py) reads them at runtime and\nhot-swaps them into projection results.\n\n**Discipline rule:** measurement values are NEVER committed, logged, or\nquoted in source / bus traffic / commit messages — refer by **KEY**\n(`npu_llm_anchors.mid_int8.qwen3_30b_a3b_moe.tokps`) not VALUE. Treat\nlike credentials.\n\nFor your own deployment, copy `.streamlit/secrets.toml.example` to\n`.streamlit/secrets.toml`, fill in your measurements, and the\nappropriate cells will flip from 🟠 projected to 🟢 measured. Cells\nwithout an anchor entry fall through to the projection path\ntransparently.\n\nCoverage at v1.1.0: **9/9 LLM + 6/6 CNN spec cells** reachable from the\nheadline tiles (unchanged from v1.0.0 — the retrofit kept anchor\nreachability identical).\n\n## Limitations\n\n- **Synthetic projection, not simulation** outside anchored cells. If\n  you push custom sliders way out of range (e.g. 2048-bit bus @ 100 GT/s),\n  the projection still linearly scales — the math doesn't model cache\n  hierarchies, tiling, or NoC topology.\n- **Pipeline list is fixed** to what Keyhole measured. Adding a new\n  pipeline requires three registrations (`PIPELINES` + `PIPELINE_TRACKS`\n  + `PIPELINE_STAGES`); startup assertion fires if any are missing.\n- **LLM catalog is fixed** to the 17 entries in `sizer/llm_models.py`.\n  Adding a new model requires a `LLMModel` entry + (optionally) a\n  `measurement_alias` pointing perf-anchor lookup at an existing entry,\n  + (optionally) a `.streamlit/secrets.toml` cell for the\n  measured-silicon overlay.\n- **NPU silicon vision anchors are sparse outside the i.MX 95 + Low-LP5X\n  measured cells.** Mid / High vision cells fall through to BW-scaling\n  from 5090 unless you populate `.streamlit/secrets.toml`. LLM cells\n  have broader coverage.\n\n## Related projects\n\n- **[personal-ai-assistant-sizer](https://github.com/kylefoxaustin/personal-ai-assistant-sizer)** —\n  LLM-only sizing for the Skippy assistant deployment. Same anchor-secrets\n  mechanism, same tab structure, same source taxonomy. Pick this one if\n  you don't care about the vision workload.\n- **[Keyhole](https://github.com/kylefoxaustin/keyhole)** — the edge-AI\n  video intelligence project that produced the bake-off data this sandbox\n  wraps. 63-slide deck of results + the raw measurement scripts.\n- **[personal-ai-framework](https://github.com/kylefoxaustin/personal-ai-framework)** —\n  the Skippy fine-tuning / evaluation framework. Source of the Finding 4\n  per-category accuracy data surfaced in the Accuracy tab.\n- **[keyhole-UI](https://github.com/kylefoxaustin/keyhole-UI)** — a\n  Next.js app that demos the Keyhole pipeline on real videos. Different\n  purpose: user-facing product demo vs. this hardware-sizing tool.\n\n## Version history\n\n| Version | Date | Highlights |\n|---|---|---|\n| **v1.1.1** | 2026-05-27 | Amendment 5 mirrored onto the CNN/vision overlay (`_maybe_anchor_overlay_cnn`) — the deferred follow-up from v1.1.0. Pre-fix the helper dropped the CNN anchor on any memory-upgrade clone, producing a measured→projection discontinuity (first upgrade tier could read lower fps than stock). Post-fix the helper BW-scales the measured anchor by `mem_bandwidth_gbs / stock_mem_bandwidth_gbs` for `bw_projected` clones; ms scales inversely, fps scales directly. Stock tiers unchanged. `app.py` only (18 insertions, 4 deletions); auto-reload-safe on Streamlit Cloud. |\n| **v1.1.0** | 2026-05-23 | Retrofit onto shared [`ratchet`](https://github.com/kylefoxaustin/ratchet) engine v0.2.4 (phase 3 of cross-repo engine consolidation). Adopted ratchet for `Hardware` / `TIERS` / `hw_with_memory` / `MEMORY_UPGRADE_OPTIONS` / anchor loader / capability tables. Net –496 lines. Surface-side adapters bridge keyhole's UI conventions to ratchet's typed data. Per-tier anchors re-attached at import via `measured.py::attach_keyhole_anchors_to_ratchet_tiers()`. Two intended behavior diffs vs v1.0.0: (1) NPU Low-LP5-64bit TDP 10 → 20 W (display only, no projection impact, ratchet's Amendment-4 TDP ladder); (2) memory-upgrade LLM anchor now BW-scales (Amendment 5 bug fix — Mid + LPDDR6-14 climbs from 37.85 → 63.08 tok/s instead of dropping to cross-class). `requirements.txt` pins ratchet via `git+https` URL (PyPI's \"ratchet\" is an unrelated package). |\n| **v1.0.0** | 2026-05-18 | First tagged release. Recovery point ahead of cross-repo engine-extraction work. Captures: 17-entry LLM catalog with role icons, 23-pipeline coverage (incl. 4-bit-weight CNN variants), anchor-secrets system (9/9 LLM + 6/6 CNN reachable), 8-tab UX mirroring PAI sizer (Overview · Accuracy · Precision · Performance · Stream · Duty · KPIs · Detail), 4-state source taxonomy + NPU_share third factor + Phase 2 compute-clamp, 5-state workload-pattern multipliers, capability-levels taxonomy, measurement_alias mechanism, category_deltas dict-of-dicts schema. |\n\n## License\n\nSame as Keyhole (see parent repo).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkylefoxaustin%2Fkeyhole-sizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkylefoxaustin%2Fkeyhole-sizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkylefoxaustin%2Fkeyhole-sizer/lists"}