{"slug": "show-hn-shrinkray-handbrake-for-tinyml", "title": "Show HN: ShrinkRay – HandBrake for TinyML", "summary": "ShrinkRay, a new open-source command-line tool, compresses and quantizes small neural networks for microcontrollers, providing a fit verdict against a 12-chip database before firmware builds. The tool, installable via `pip install shrinkray-cli`, supports Keras/TFLite, scikit-learn, and ONNX models, outputs chip-ready artifacts (TFLite, C byte arrays, C99 headers, .espdl), and generates self-contained reports, all fully local with no network calls or telemetry. ShrinkRay's fit analysis measures actual artifact bytes on disk for flash and performs tensor-liveness analysis for peak RAM, issuing FITS, TIGHT, or TOO BIG verdicts per chip.", "body_md": "**HandBrake for TinyML** — one tool that takes any small model and produces a\nchip-ready artifact, with a report proving it fits.\n\n📖 **New here? Read the full user guide** — installation,\nevery command, and troubleshooting.\n\nShrinkRay compresses/quantizes small neural networks for microcontrollers and tells you — before you touch a firmware build — whether the result fits your target chip's flash and RAM.\n\n- ✅\n**FITS**/⚠️ **TIGHT**/ ❌** TOO BIG**verdict per chip - Keras/TFLite → int8/int16/float TFLite + C byte array (\n`.cc`\n\n/`.h`\n\n) for LiteRT-M / CMSIS-NN - scikit-learn → single portable\n**C99 header**(via emlearn; works even on ATmega328P) - ONNX →\n`.espdl`\n\nvia ESP-PPQ (optional extra) - Self-contained\n`report.md`\n\n+`report.html`\n\nafter every conversion - 100% local:\n**no network calls, no telemetry, no account**\n\n```\npip install shrinkray-cli\n\nshrinkray chips                                # the 12-chip database\nshrinkray inspect model.keras                  # params, size, ops, FLOPs\nshrinkray convert model.keras --target esp32s3 --method int8 --data cal.npy\n```\n\nOutput:\n\n```\nwrote outputs/model_int8.tflite (2.7 KiB)\nwrote outputs/model_int8.cc\nwrote outputs/model_int8.h\naccuracy max-abs-error 0.002717, top-1 agreement 100.0%\nesp32s3: ✅ FITS — flash 2.7 KiB / 8192.0 KiB (0.0%), est. RAM 0.1 KiB / 512.0 KiB (0.0%)\nwrote outputs/report.md\nwrote outputs/report.html\n```\n\n`--data cal.npy`\n\nis a small float32 array of representative samples\n(`numpy.save(\"cal.npy\", x[:100].astype(\"float32\"))`\n\n). With it you get\nfull-integer quantization **and** an accuracy-delta check; without it, int8\nfalls back to dynamic-range quantization.\n\n| Command | What it does |\n|---|---|\n`shrinkray inspect <model>` |\nFormat, parameter count, file size, operator histogram, FLOP estimate for `.keras` / `.h5` / `.tflite` / `.onnx` / `.pkl` |\n`shrinkray chips [--chips extra.json]` |\nPrint the chip database; merge your own chips from JSON |\n`shrinkray convert <model> --target <chip>` |\nConvert + fit verdict + reports |\n\nUseful `convert`\n\nflags:\n\n| Flag | Meaning |\n|---|---|\n`--method int8|int16|float|inline` |\nint16 needs `--data` ; `inline` is for scikit-learn `.pkl` |\n`--data cal.npy` |\nCalibration samples (full-integer quant + accuracy check) |\n`--out DIR` |\nOutput directory (default: `outputs/` ) |\n`--all-chips` |\nFit-check against the whole database, ranked by headroom (always exits 0) |\n`--chips mychips.json` |\nMerge custom chip definitions |\n\nExit codes: `0`\n\nok · `1`\n\nmodel error · `2`\n\nmissing optional dependency ·\n`3`\n\nconverted but doesn't fit the target.\n\nDrop a `shrinkray.toml`\n\nin your project directory to stop repeating flags\n(CLI flags always win over the file):\n\n```\n[defaults]\ntarget = \"esp32s3\"\ndata = \"cal.npy\"\nout = \"build\"\n```\n\nShips with 12 chips: esp32, esp32s3, esp32p4, stm32f407, stm32h743, stm32u575, nrf52840, nrf5340, rp2040, rp2350, nano33ble, atmega328p. Each entry: flash KiB, SRAM KiB, clock MHz, feature flags (dsp / simd / ai-instructions), preferred runtime (litert-m / cmsis-nn / esp-dl / emlearn).\n\nExtend it with your own JSON (`--chips mychips.json`\n\n; your entries override\nbuilt-ins on name collision):\n\n```\n{\"chips\": [{\"name\": \"myboard\", \"flash_kb\": 512, \"sram_kb\": 128,\n            \"clock_mhz\": 100, \"features\": [\"dsp\"], \"runtime\": \"cmsis-nn\"}]}\n```\n\n**Flash**= actual artifact bytes measured on disk.** Peak RAM**= tensor-liveness analysis of the TFLite graph: the largest sum of concurrently live activation tensors × 1.2 safety factor.**Verdicts**: FITS = flash ≤ 90% and RAM ≤ 70%; TIGHT = flash ≤ 100% and RAM ≤ 90%; otherwise TOO BIG.\n\nOn PyPI the package is\n\n(the name`shrinkray-cli`\n\n`shrinkray`\n\nwas already taken by an unrelated project). The command it installs is still`shrinkray`\n\n.\n\n| Method | Command | Notes |\n|---|---|---|\n| pip (Win/Linux/macOS) | `pip install shrinkray-cli` |\nPython 3.10–3.12, CPU-only is fine |\n| pip + ESP-DL pipeline | `pip install shrinkray-cli[espdl]` |\nadds ESP-PPQ (heavier deps) |\n| pipx | `pipx install shrinkray-cli` |\nisolated CLI install |\n| Standalone binary | GitHub Releases | experimental; bundles TF, so it's big — pip is recommended |\n| winget / brew | planned | not published yet |\n\n**No GUI, no training**— input is an already-trained model ≤ ~100 MB.- Pipeline A (Keras→TFLite) requires TensorFlow (CPU build is fine). Everything else — TFLite inspect, sklearn pipeline, chips, reports — works without it.\n- RAM estimates are heuristics, not measurements: TFLite liveness ×1.2 for Pipeline A; not estimable for emlearn C code (reported as n/a).\n- Quantizing an already-\n`.tflite`\n\nfile is not supported — pass the original`.keras`\n\n/`.h5`\n\n(or use`--method float`\n\nto repackage as a C array). - Pipeline C requires\n`pip install shrinkray-cli[espdl]`\n\n; without it the command prints install instructions and exits 2 — everything else keeps working. - No ONNX Runtime quantization, no RISC-V paths, no model zoo (v0.2+).\n\n```\npip install -e \".[dev]\"\npytest --cov=shrinkray.core --cov=shrinkray.pipelines   # coverage gate: 80%\n```\n\nCI runs pytest on Windows / Ubuntu / macOS × Python 3.10 / 3.11 / 3.12\n(`.github/workflows/test.yml`\n\n); tag pushes build standalone binaries\n(`.github/workflows/release.yml`\n\n).\n\nTest fixtures (tiny Keras net, sklearn forest, ONNX graph) are generated at runtime — no binary models in the repo.\n\nGNU Affero General Public License v3.0 (AGPL-3.0-only) — see [LICENSE](/tarulahsan/ShrinkRay/blob/main/LICENSE).\n\nFree for everyone to use, study, and modify — including commercial internal use. If you distribute ShrinkRay or a modified version, or offer it as a network service, you must share your source under the same license. Commercial closed-source licensing is available on request; contact the maintainer.", "url": "https://wpnews.pro/news/show-hn-shrinkray-handbrake-for-tinyml", "canonical_source": "https://github.com/TarulAhsan/ShrinkRay", "published_at": "2026-08-25 05:46:09+00:00", "updated_at": "2026-08-25 06:12:55.181232+00:00", "lang": "en", "topics": ["developer-tools", "machine-learning", "artificial-intelligence"], "entities": ["ShrinkRay", "LiteRT-M", "CMSIS-NN", "ESP-PPQ", "emlearn", "PyPI", "ATmega328P", "ESP32-S3"], "alternates": {"html": "https://wpnews.pro/news/show-hn-shrinkray-handbrake-for-tinyml", "markdown": "https://wpnews.pro/news/show-hn-shrinkray-handbrake-for-tinyml.md", "text": "https://wpnews.pro/news/show-hn-shrinkray-handbrake-for-tinyml.txt", "jsonld": "https://wpnews.pro/news/show-hn-shrinkray-handbrake-for-tinyml.jsonld"}}