Image Segmentation
LiteRT
LiteRT
android
on-device
gpu
drivable-area
lane-segmentation
adas
autonomous-driving
real-time
Instructions to use litert-community/TwinLiteNet-LiteRT with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LiteRT
How to use litert-community/TwinLiteNet-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
| license: mit | |
| library_name: litert | |
| pipeline_tag: image-segmentation | |
| tags: | |
| - litert | |
| - tflite | |
| - android | |
| - on-device | |
| - gpu | |
| - drivable-area | |
| - lane-segmentation | |
| - adas | |
| - autonomous-driving | |
| - real-time | |
| # TwinLiteNet β Drivable-area + lane segmentation (LiteRT GPU) | |
| On-device **drivable-area and lane-line segmentation** running **fully on the LiteRT | |
| `CompiledModel` GPU** delegate (no CPU fallback). [TwinLiteNet](https://github.com/chequanghuy/TwinLiteNet) | |
| (2023) is an ultra-light ESPNet-based network with two segmentation heads β the ADAS | |
| perception building block "where can I drive" + "where are the lanes". Only **3.1 MB**, | |
| ~44 ms/frame on a Pixel 8a. | |
| - **Architecture:** ESPNet-C encoder + two seg decoders β pure CNN. | |
| - **Weights:** [chequanghuy/TwinLiteNet](https://github.com/chequanghuy/TwinLiteNet) (BDD100K) Β· MIT. | |
| - **Size:** 3.1 MB. | |
|  | |
| *Drivable area (green) + lane lines (red) on a dashcam highway frame. Source: Wikimedia Commons (Public Domain).* | |
| ## I/O | |
| - **Input:** `[1, 3, 360, 640]` NCHW, RGB, `x/255`. | |
| - **Outputs:** two `[1, 2, 360, 640]` logit maps β `drivable_area` and `lane_line`. | |
| Take `argmax` over the class dim (2) β binary masks. | |
| ## GPU conversion | |
| TwinLiteNet is a pure CNN. It converts fully GPU-compatible (**270/270 nodes on the | |
| delegate, 1 partition**; device corr 0.99997 / 0.99998 on the two heads, ~44 ms) with | |
| **one patch**: the `ConvTranspose2d` upsamplers β **ZeroStuffConvT2d** (nearest-upsample | |
| + stride zero-stuff mask + flipped conv; the Mali delegate rejects `TRANSPOSE_CONV`). | |
| Exact. CPU-exact vs PyTorch (corr 1.0). | |
| ## Minimal usage | |
| ### Kotlin (Android, LiteRT CompiledModel GPU) | |
| ```kotlin | |
| val options = CompiledModel.Options(Accelerator.GPU) | |
| val model = CompiledModel.create(context.assets, "twinlite.tflite", options, null) | |
| val inBufs = model.createInputBuffers() | |
| val outBufs = model.createOutputBuffers() // [0] = drivable area, [1] = lane line | |
| inBufs[0].writeFloat(inputNCHW) // [1,3,360,640] RGB, x/255 | |
| model.run(inBufs, outBufs) | |
| val da = outBufs[0].readFloat() // [2*360*640]; argmax over the 2 classes -> drivable mask | |
| val ll = outBufs[1].readFloat() // [2*360*640]; argmax -> lane mask | |
| // per pixel p: class = if (da[p] > da[360*640 + p]) 0 else 1 | |
| ``` | |
| ### Python (LiteRT / ai-edge-litert) | |
| ```python | |
| import numpy as np | |
| from ai_edge_litert.interpreter import Interpreter | |
| it = Interpreter(model_path="twinlite.tflite"); it.allocate_tensors() | |
| inp, out = it.get_input_details(), it.get_output_details() | |
| it.set_tensor(inp[0]["index"], x) # [1,3,360,640] float32, RGB, x/255 | |
| it.invoke() | |
| outs = sorted(out, key=lambda o: o["index"]) | |
| da = it.get_tensor(outs[0]["index"])[0].argmax(0) # [360,640] drivable-area mask | |
| ll = it.get_tensor(outs[1]["index"])[0].argmax(0) # [360,640] lane mask | |
| ``` | |
| ## Conversion | |
| Converted with **litert-torch** (`build_twinlite.py`): loads the MIT BDD100K weights, | |
| swaps `ConvTranspose2d` β ZeroStuffConvT2d, and exports the two-head graph. | |
| ## License | |
| MIT (TwinLiteNet / chequanghuy). Trained on BDD100K. | |