{"id":33527195,"url":"https://github.com/felixgalindo/tinymldelta","last_synced_at":"2025-11-29T18:01:58.021Z","repository":{"id":325720145,"uuid":"1102086016","full_name":"felixgalindo/TinyMLDelta","owner":"felixgalindo","description":"TinyMLDelta is an incremental model-update system for TinyML and embedded AI devices.","archived":false,"fork":false,"pushed_at":"2025-11-22T23:51:21.000Z","size":43,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-23T01:16:38.328Z","etag":null,"topics":["edgeai","embedded-systems","tensorflow","tensorflow-lite","tinyml"],"latest_commit_sha":null,"homepage":"https://medium.com/@felixgalindo91/introducing-tinymldelta-incremental-ml-model-updates-for-tiny-devices-96663edd1991","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/felixgalindo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","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":"2025-11-22T19:44:21.000Z","updated_at":"2025-11-23T00:51:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/felixgalindo/TinyMLDelta","commit_stats":null,"previous_names":["felixgalindo/tinymldelta"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/felixgalindo/TinyMLDelta","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgalindo%2FTinyMLDelta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgalindo%2FTinyMLDelta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgalindo%2FTinyMLDelta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgalindo%2FTinyMLDelta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/felixgalindo","download_url":"https://codeload.github.com/felixgalindo/TinyMLDelta/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgalindo%2FTinyMLDelta/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080729,"owners_count":27282304,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-26T02:00:06.075Z","response_time":193,"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":["edgeai","embedded-systems","tensorflow","tensorflow-lite","tinyml"],"created_at":"2025-11-26T13:00:45.140Z","updated_at":"2025-11-29T18:01:58.015Z","avatar_url":"https://github.com/felixgalindo.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TinyMLDelta\n\nTinyMLDelta is an **incremental model-update system** for TinyML and embedded AI devices.\n\nInstead of shipping an entire TensorFlow Lite Micro model (often **20–200+ KB**),\nyou ship a **small binary patch** that mutates the existing model in flash into a new one.\n\nThis reduces:\n\n- OTA bandwidth  \n- Cellular / satellite data costs  \n- Flash wear  \n- Update latency  \n- Fleet fragmentation  \n- Bootloader complexity  \n\nTinyMLDelta performs **safe, atomic, guardrail-checked updates** on\nextremely low-resource MCUs.\n\n------------------------------------------------------------------------\n\n## Supported Today\n\n- TensorFlow Lite Micro  \n- POSIX/macOS simulated flash environment  \n- CRC32 integrity checking  \n- A/B slot updates  \n- Crash-safe journaling  \n\n## Planned\n\n- Edge Impulse frontend  \n- SHA-256 and AES-CMAC signatures  \n- Model versioning  \n- Vendor metadata  \n- MCU integrations (Zephyr, Arduino UNO R4 WiFi, Tachyon)\n\n------------------------------------------------------------------------\n\n## Patch vs Firmware Update --- What Requires What?\n\nTinyMLDelta can safely update models **only when the firmware remains\ncompatible** with the new model.\nCompatibility is enforced using **metadata TLVs** generated by PatchGen\nand validated by the MCU runtime.\n\n### ✔ Patch-friendly changes (safe, incremental)\n\nNo firmware update required:\n\n-   Weight updates\n-   Bias updates\n-   Quantization parameter changes\n-   Re-training the same architecture\n-   Minor graph edits without operator changes\n-   Same opset, same ABI, same I/O schema\n-   Similar tensor shapes\n-   Same input/output dtypes\n\nThese produce compact patches.\n\n## ❌ Changes requiring a full firmware update\n\n| Change Type | Firmware Update Required? | Why |\n|------------|---------------------------|-----|\n| **New operators** | ✔ Yes | Firmware must link kernels |\n| **Opset version changes** | ✔ Yes | Operator implementations differ |\n| **TFLM ABI changes** | ✔ Yes | Interpreter ABI mismatch |\n| **Arena requirement \u003e compiled arena** | ✔ Yes | Arena lives in static `.bss`; fixed at build |\n| **Tensor I/O schema changes** | ✔ Yes | Application code relies on shapes/dtypes |\n| **Flex ops / newer TFLite schema** | ✔ Yes | Requires Flex delegate or newer interpreter |\n\nTinyMLDelta rejects incompatible patches automatically.\n\n------------------------------------------------------------------------\n\n## Architecture Overview\n\nPatchGen (PC/CI) runs off-target and is **stateless**.\nTinyMLDelta Core enforces all safety on-device.\n\n### PatchGen (PC/CI)\n\n-   Loads the base \u0026 target models\n-   Computes byte-level differences\n-   Merges and compresses diff chunks\n-   Calculates integrity digests\n-   Extracts metadata (arena, ABI, opset hash, I/O hash)\n-   Assembles everything into a `.tmd` patch\n\n### TinyMLDelta Core (MCU)\n\n-   Parses the patch header \u0026 TLVs\n-   Verifies compatibility guardrails\n-   Copies active → inactive slot\n-   Applies diff chunks to the inactive slot\n-   Verifies CRCs / digests\n-   Atomically flips the active slot\n\n### High-Level Data Flow\n\n              ┌────────────────────────┐\n              │ Base Model (flash)     │\n              └──────────┬─────────────┘\n                         │ read\n                         ▼\n               ┌────────────────────────┐\n               │ Patch Generator (PC)   │\n               │  • diff engine         │\n               │  • metadata TLVs       │\n               │  • integrity checks    │\n               └──────────┬─────────────┘\n                         │ OTA send\n                         ▼\n               ┌────────────────────────┐\n               │ TinyMLDelta Core (MCU) │\n               │  • copy active→inactive│\n               │  • apply diff chunks   │\n               │  • verify CRC/digests  │\n               │  • enforce guardrails  │\n               └─────────┬───────────── ┘\n                         │ atomically flip\n                         ▼\n               ┌────────────────────────┐\n               │ Target Model (flash)   │\n               └────────────────────────┘\n\nThe MCU **never** receives a full model --- only a delta.\n\n------------------------------------------------------------------------\n\n## Wire Format\n\n### Patch Header (`tmd_hdr_t`)\n\n``` c\ntypedef struct __attribute__((packed)) {\n  uint8_t  v;\n  uint8_t  algo;\n  uint16_t chunks_n;\n  uint32_t base_len;\n  uint32_t target_len;\n  uint8_t  base_chk[32];\n  uint8_t  target_chk[32];\n  uint16_t meta_len;\n  uint16_t flags;\n} tmd_hdr_t;\n```\n\n### Metadata TLVs\n\nEach TLV is encoded as:\n\n    [tag][len][value...]\n\nCurrent TLVs:\n\n-   `REQ_ARENA_BYTES` (u32)\n-   `TFLM_ABI` (u16)\n-   `OPSET_HASH` (u32)\n-   `IO_HASH` (u32)\n\nPlanned TLVs:\n\n-   Model version, model family/architecture\n-   Certificate + signature blocks\n-   Dataset lineage\n-   Firmware feature flags\n-   Strict/relaxed validation modes\n\n### Chunk Header (`tmd_chunk_hdr_t`)\n\n``` c\ntypedef struct __attribute__((packed)) {\n  uint32_t off;\n  uint16_t len;\n  uint8_t  enc;      // 0 = RAW, 1 = RLE\n  uint8_t  has_crc;\n} tmd_chunk_hdr_t;\n```\n\n------------------------------------------------------------------------\n\n## Installation (CLI)\n\n``` bash\ncd cli/\n./install.sh\nsource .tinyenv/bin/activate\n```\n\nInstaller output example:\n\n    === TinyMLDelta CLI Installer ===\n    Creating virtual environment .tinyenv ...\n    Installing TinyMLDelta CLI requirements...\n    ...\n    TinyMLDelta CLI environment is ready!\n\n------------------------------------------------------------------------\n\n## Quickstart: Run the POSIX Demo\n\nThe POSIX demo simulates a full MCU update flow end-to-end:\nmodel generation → patch generation → flash creation → patch apply →\nverification.\n\nA **full standalone walkthrough** (with complete logs, explanations, and\nverification steps) is here:\n\n👉 **`examples/posix/README.md`**\n\nTo run the demo:\n\n``` bash\ncd cli\n./install.sh\nsource .tinyenv/bin/activate\n\ncd ../examples/posix\n./run_demo.sh\n```\n\n------------------------------------------------------------------------\n\n### Demo Results\n\n-   **Base model:** 66,368 bytes\n-   **Target model:** 66,368 bytes\n-   **Patch file:** 474 bytes total\n-   **Encoded diff data:** 382 bytes\n-   **Single diff chunk:** offset 62,728, length 382 bytes\n-   **Flash slots:** 131,072 bytes each (A/B)\n\n**Result:** patch applied successfully and flash matches the target\nmodel exactly.\n\n------------------------------------------------------------------------\n\n## Directory Layout\n\n```text\nTinyMLDelta/\n├── cli/\n│   ├── install.sh                 # Optional: create a local venv + install CLI deps\n│   ├── requirements.txt           # Python deps for PatchGen + demo tooling\n│   ├── tinymldelta_patchgen.py    # PatchGen: build .tmd patches from base/target models\n│   └── tinymldelta_meta_compute.py# (optional) TFLite-aware metadata helper (future use)\n│\n├── examples/\n│   ├── modelgen/\n│   │   ├── make_models.py         # Generates small TFLite sensor models for the demo\n│   │   ├── README.md              # Notes on model generation / usage\n│   │   └── (base.tflite, target.tflite are generated artifacts)\n│   │\n│   └── posix/\n│       ├── README.md              # Notes on running demo\n│       ├── Makefile               # Builds demo_apply using POSIX ports + core\n│       ├── run_demo.sh            # End-to-end demo: generate models → patch → apply → verify\n│       ├── make_flash.py          # Creates flash.bin with A/B slots + journal region\n│       ├── flash_layout.h         # Simulated flash layout (tmd_layout_t) for the demo\n│       ├── demo_apply.c           # TinyMLDelta POSIX sample app (patch applier)\n│       ├── tinymldelta_ports_posix.c # POSIX implementation of tmd_ports_t (flash/journal/log)\n│       ├── verify_flash.py        # Verifies flash.bin contains the exact target.tflite bytes\n│       └── (flash.bin, patch.tmd, *.o, demo_apply are build/generated artifacts)\n│\n├── runtime/\n│   ├── include/\n│   │   ├── tinymldelta.h          # Public C API for TinyMLDelta core\n│   │   ├── tinymldelta_config.h   # Build-time feature flags + firmware guardrail config\n│   │   ├── tinymldelta_internal.h # On-wire header / TLV / chunk structures\n│   │   └── tinymldelta_ports.h    # Platform abstraction: flash, digests, slots, journal, log\n│   └── src/\n│       └── tinymldelta_core.c     # Platform-agnostic patch application engine\n│\n├── LICENSE                        # Apache-2.0 license\n├── SECURITY.md                    # Security contact / disclosure policy\n└── README.md                      # Project overview and usage\n```\n------------------------------------------------------------------------\n\n## Contributing\n\nContributions welcome:\n\n- New front-ends (Edge Impulse)  \n- Optimized diff algorithms  \n- Additional MCU ports (Zephyr, Arduino, STM32, ESP32)  \n- Metadata TLV extensions  \n- Docs improvements  \n- Security signing pipeline  \n\n------------------------------------------------------------------------\n\n## License\n\nApache-2.0\\\n© 2024--2025 TinyMLDelta Project / Felix Galindo","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffelixgalindo%2Ftinymldelta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffelixgalindo%2Ftinymldelta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffelixgalindo%2Ftinymldelta/lists"}