Image Segmentation
LiteRT
LiteRT
android
on-device
gpu
portrait-matting
image-matting
background-removal
modnet
real-time
Instructions to use litert-community/MODNet-LiteRT with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LiteRT
How to use litert-community/MODNet-LiteRT with LiteRT:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
Upload README.md with huggingface_hub
Browse files
README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
library_name: litert
|
| 4 |
+
pipeline_tag: image-segmentation
|
| 5 |
+
tags:
|
| 6 |
+
- litert
|
| 7 |
+
- tflite
|
| 8 |
+
- android
|
| 9 |
+
- on-device
|
| 10 |
+
- gpu
|
| 11 |
+
- portrait-matting
|
| 12 |
+
- image-matting
|
| 13 |
+
- background-removal
|
| 14 |
+
- modnet
|
| 15 |
+
- real-time
|
| 16 |
+
---
|
| 17 |
+
|
| 18 |
+
# MODNet — LiteRT (trimap-free portrait matting, GPU)
|
| 19 |
+
|
| 20 |
+
On-device **real-time portrait matting** running **fully on the LiteRT `CompiledModel`
|
| 21 |
+
GPU** delegate (no CPU fallback). [MODNet](https://arxiv.org/abs/2011.11961) (AAAI 2022)
|
| 22 |
+
predicts a **soft alpha matte** for a person — no trimap, no green screen — for
|
| 23 |
+
background blur/replace (video calls, virtual backgrounds). ~79 ms/frame on a Pixel 8a.
|
| 24 |
+
|
| 25 |
+
- **Architecture:** MODNet — MobileNetV2 low-res branch + high-res + fusion branches (pure CNN).
|
| 26 |
+
- **Weights:** [ZHKKKe/MODNet](https://github.com/ZHKKKe/MODNet) · Apache-2.0 · ~6.5 M params.
|
| 27 |
+
- **Size:** 26 MB.
|
| 28 |
+
|
| 29 |
+

|
| 30 |
+
|
| 31 |
+
## I/O
|
| 32 |
+
|
| 33 |
+
- **Input:** `[1, 3, 512, 512]` NCHW, RGB, normalized to `[-1, 1]` (`(x/255 - 0.5) / 0.5`).
|
| 34 |
+
- **Output:** `[1, 1, 512, 512]` soft alpha matte in `[0, 1]` (composite: `fg·α + bg·(1-α)`).
|
| 35 |
+
|
| 36 |
+
## GPU conversion
|
| 37 |
+
|
| 38 |
+
MODNet is a pure CNN with `align_corners=False` interpolation. Two re-authoring
|
| 39 |
+
patches make it a **fully GPU-compatible graph — 0 tensors of rank > 4, 0 banned ops**:
|
| 40 |
+
|
| 41 |
+
1. **SE block `Linear` → `1×1 conv`** — the stock squeeze-excite `pool → Linear →
|
| 42 |
+
view(b,c,1,1) → x*w` confuses the NCHW↔NHWC layout (`mul` broadcast mismatch);
|
| 43 |
+
1×1 convs on the pooled tensor are identical and NCHW-clean.
|
| 44 |
+
2. **fp16-safe hierarchical-mean `InstanceNorm`** — MODNet's IBNorm runs
|
| 45 |
+
`InstanceNorm2d` over up to 512×512 spatial; on the Mali GPU (fp16) the variance
|
| 46 |
+
`sum(dd²)` overflows (≫ 65504) and the matte degrades (halos, blotchy interior,
|
| 47 |
+
corr 0.94). Computing the spatial mean via a cascade of `/2` average-pools
|
| 48 |
+
(magnitude-bounded, exact for power-of-2) + `dd·rsqrt(mean(dd²)+eps)` restores it
|
| 49 |
+
to GPU corr **0.99994** with clean edges.
|
| 50 |
+
|
| 51 |
+
CPU-exact vs PyTorch (corr 0.99999999999); device Mali GPU corr 0.99994.
|
| 52 |
+
|
| 53 |
+
## Minimal usage
|
| 54 |
+
|
| 55 |
+
### Kotlin (Android, LiteRT CompiledModel GPU)
|
| 56 |
+
|
| 57 |
+
```kotlin
|
| 58 |
+
val options = CompiledModel.Options(Accelerator.GPU)
|
| 59 |
+
val model = CompiledModel.create(context.assets, "modnet.tflite", options, null)
|
| 60 |
+
val inBufs = model.createInputBuffers()
|
| 61 |
+
val outBufs = model.createOutputBuffers()
|
| 62 |
+
|
| 63 |
+
inBufs[0].writeFloat(inputNCHW) // [1,3,512,512], RGB, (x/255-0.5)/0.5
|
| 64 |
+
model.run(inBufs, outBufs)
|
| 65 |
+
val alpha = outBufs[0].readFloat() // [512*512] soft matte in [0,1]
|
| 66 |
+
// composite: out = fg*alpha + bg*(1-alpha)
|
| 67 |
+
```
|
| 68 |
+
|
| 69 |
+
### Python (LiteRT / ai-edge-litert)
|
| 70 |
+
|
| 71 |
+
```python
|
| 72 |
+
from ai_edge_litert.interpreter import Interpreter
|
| 73 |
+
import numpy as np
|
| 74 |
+
|
| 75 |
+
it = Interpreter(model_path="modnet.tflite"); it.allocate_tensors()
|
| 76 |
+
inp, out = it.get_input_details(), it.get_output_details()
|
| 77 |
+
x = ((img[None].transpose(0,3,1,2) / 255.0 - 0.5) / 0.5).astype(np.float32) # [1,3,512,512]
|
| 78 |
+
it.set_tensor(inp[0]["index"], x); it.invoke()
|
| 79 |
+
alpha = it.get_tensor(out[0]["index"])[0, 0] # [512,512] in [0,1]
|
| 80 |
+
```
|
| 81 |
+
|
| 82 |
+
## Conversion
|
| 83 |
+
|
| 84 |
+
Converted with **litert-torch** (`build_modnet.py`): loads the trained MODNet weights,
|
| 85 |
+
applies the two patches (SE 1×1-conv, SafeInstanceNorm), and exports.
|
| 86 |
+
|
| 87 |
+
## License
|
| 88 |
+
|
| 89 |
+
Apache-2.0 (MODNet / ZHKKKe/MODNet).
|