Instructions to use mlboydaisuke/SAM2-hiera-tiny-LiteRT with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LiteRT
How to use mlboydaisuke/SAM2-hiera-tiny-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
- sam2
How to use mlboydaisuke/SAM2-hiera-tiny-LiteRT with sam2:
# Use SAM2 with images import torch from sam2.sam2_image_predictor import SAM2ImagePredictor predictor = SAM2ImagePredictor.from_pretrained(mlboydaisuke/SAM2-hiera-tiny-LiteRT) with torch.inference_mode(), torch.autocast("cuda", dtype=torch.bfloat16): predictor.set_image(<your_image>) masks, _, _ = predictor.predict(<input_prompts>)# Use SAM2 with videos import torch from sam2.sam2_video_predictor import SAM2VideoPredictor predictor = SAM2VideoPredictor.from_pretrained(mlboydaisuke/SAM2-hiera-tiny-LiteRT) with torch.inference_mode(), torch.autocast("cuda", dtype=torch.bfloat16): state = predictor.init_state(<your_video>) # add new prompts and instantly get the output on the same frame frame_idx, object_ids, masks = predictor.add_new_points(state, <your_prompts>): # propagate the prompts to get masklets throughout the video for frame_idx, object_ids, masks in predictor.propagate_in_video(state): ... - Notebooks
- Google Colab
- Kaggle
SAM 2.1 Hiera-Tiny β LiteRT (CompiledModel GPU)
SAM 2.1 (Segment Anything 2, Meta) Hiera-Tiny converted to
LiteRT and running fully on the GPU via the CompiledModel API (ML Drift). Tap a
point on an image and it returns a segmentation mask β the image encoder runs once per image,
the mask decoder runs per point.
Both graphs are fully GPU-accelerated on the Pixel 8a (Mali / ML Drift) and on Apple silicon (Metal), and the output is bit-exact (corr 1.0) vs the original PyTorch SAM 2.1.
Files
| File | Size (fp16) | Input | Output | Runtime |
|---|---|---|---|---|
sam2_encoder.tflite |
80 MB | [1, 3, 1024, 1024] NCHW |
flat [1, 4194304] (image_embed | fpn0 | fpn1) |
CompiledModel GPU |
sam2_decoder.tflite |
17 MB | flat [1, 4194816] (image_embed | sparse | fpn0 | fpn1) |
masks [1, 3, 256, 256] |
CompiledModel GPU |
sam2_prompt.bin |
3 KB | β | prompt-encoder constants for the Kotlin point encoder | β |
Preprocessing: resize to 1024Γ1024, ImageNet mean [0.485, 0.456, 0.406] / std
[0.229, 0.224, 0.225], NCHW.
GPU compatibility
The Hiera image encoder is made GPU-clean with three numerically-identical rewrites (done at conversion time; the SAM 2 mask decoder converts unchanged):
- Bake the windowed positional embedding (constant for a fixed 1024Β² input) β removes the
bicubic
interpolate(GATHER_ND) and the tiled window embed (BROADCAST_TO). - 4-D window partition / unpartition β the 6-D
view+permutebecomes split-H β transpose β split-W (ML Drift rejects > 4-D tensors). - 4-D multi-scale attention β the 5-D fused
qkvreshape becomes a channel-wise q/k/v slice.
Usage (Kotlin, LiteRT CompiledModel)
import com.google.ai.edge.litert.Accelerator
import com.google.ai.edge.litert.CompiledModel
val encoder = CompiledModel.create(
context.assets, "sam2_encoder.tflite", CompiledModel.Options(Accelerator.GPU), null)
val decoder = CompiledModel.create(
context.assets, "sam2_decoder.tflite", CompiledModel.Options(Accelerator.GPU), null)
// Encode once per image (input = normalized NCHW floats).
val encIn = encoder.createInputBuffers()
encIn[0].writeFloat(inputFloats) // 3 * 1024 * 1024
val flat = encoder.run(encIn)[0].readFloat() // [image_embed | fpn0 | fpn1]
// Build the flat decoder input [image_embed | sparse | fpn0 | fpn1] (sparse = point encoding
// from sam2_prompt.bin), then run the decoder per tap.
val decIn = decoder.createInputBuffers()
decIn[0].writeFloat(flatDecoderInput)
val masks = decoder.run(decIn)[0].readFloat() // (3, 256, 256) logits; mask > 0 = foreground
Usage (Python, verify the graph)
from ai_edge_litert.interpreter import Interpreter
import numpy as np
enc = Interpreter(model_path="sam2_encoder.tflite"); enc.allocate_tensors()
enc.set_tensor(enc.get_input_details()[0]["index"], pixels_nchw.astype(np.float32)) # [1,3,1024,1024]
enc.invoke()
flat = enc.get_tensor(enc.get_output_details()[0]["index"]).flatten() # image_embed | fpn0 | fpn1
Video tracking (SAM 2 video path)
The full SAM 2.1 tracking loop β memory attention, memory encoder, object pointers and the prompt-conditioned mask decoder β as four fixed-shape per-frame graphs on the CompiledModel GPU. The rolling memory bank and per-frame orchestration run on the host (Kotlin/Swift/Python); only tensor math touches the GPU. Tap once on the first frame and the mask follows the object.
| File | Size (fp16) | In β Out |
|---|---|---|
sam2v_encode.tflite |
80 MB | image [1,3,1024,1024] β pix_raw | hi0 | hi1 |
sam2v_memcond7.tflite / sam2v_memcond2.tflite |
26 MB | pix_raw | memory bank | temporal pos | pointers | key mask β pix_feat (7- / 2-slot bank) |
sam2v_decode.tflite |
18 MB | pix_feat | hi0 | hi1 | sparse | nomem β masks | iou | obj_ptr | obj_score |
sam2v_memorize.tflite |
3 MB | pix_raw | mask_for_mem | occ β spatial memory [4096, 64] |
sam2v_prompt.bin, sam2v_track_sparse.bin, sam2v_mtpe.bin, sam2v_no_obj_ptr.bin, sam2v_tpos_proj.bin |
β€64 KB | host-side constants (prompt encoder, temporal PE, pointer projection) |
Why it works on the GPU: SAM 2's memory attention runs its RoPE attention with the batch dim collapsed (rank 3), which the ML Drift delegate silently mis-computes β the graphs here are re-authored batch-first (rank 4), numerically identical on the host and correct on the GPU (exact under fp32 GPU compute). The residual fp16 accumulation over the memory keys does not reach the mask.
Fidelity: the assembled loop matches the PyTorch Sam2VideoModel reference at min
mask-IoU 0.9999 over a 10-frame clip (7- and 2-slot banks). All four graphs are fully
GPU-resident with no CPU fallback β Pixel 8a (Mali): encode 828/828, memcond 480/480, decode
462/462, memorize 145/145 nodes; iPhone 17 Pro (Metal): all fullyGPU.
Per tracked frame (encode + memcond + decode + memorize): iPhone 17 Pro ~471 ms (2-slot) / ~751 ms (7-slot); Pixel 8a ~1.0β1.5 s.
Usage (Python, CompiledModel)
import numpy as np
from ai_edge_litert.compiled_model import CompiledModel
enc = CompiledModel.from_file("sam2v_encode.tflite")
ins, outs = enc.create_input_buffers(0), enc.create_output_buffers(0)
ins[0].write(np.ascontiguousarray(frame_nchw.ravel().astype(np.float32)))
enc.run_by_index(0, ins, outs)
flat = outs[0].read(4_194_304, np.float32) # pix_raw | hi0 | hi1
# memcond -> decode -> memorize per frame; the full host loop (bank assembly,
# best-IoU pick, no-object handling) is verify_video.py in the recipe below.
Usage (Kotlin)
The Android tracker (Sam2VideoTracker.kt: filesDir load, rolling bank, per-frame loop) and
the demo app live in LiteRT-Models β sam2/.
The conversion + verification recipe is in litert-samples:
models/sam2/sam2_hiera_tiny_video/converted.
Conversion
Converted with litert-torch from the Hugging Face transformers SAM 2 model. The full
conversion script (and Android sample app) is in
LiteRT-Models β sam2/.
License & credits
Apache-2.0, following the original SAM 2 (Meta, Apache-2.0). Conversion by @john-rocky.
Want a different model on-device? Open a request β free, open weights only; the export and its measured numbers get published publicly.
- Downloads last month
- 34
Model tree for mlboydaisuke/SAM2-hiera-tiny-LiteRT
Base model
facebook/sam2.1-hiera-tiny