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):

  1. Bake the windowed positional embedding (constant for a fixed 1024Β² input) β€” removes the bicubic interpolate (GATHER_ND) and the tiled window embed (BROADCAST_TO).
  2. 4-D window partition / unpartition β€” the 6-D view+permute becomes split-H β†’ transpose β†’ split-W (ML Drift rejects > 4-D tensors).
  3. 4-D multi-scale attention β€” the 5-D fused qkv reshape 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
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for mlboydaisuke/SAM2-hiera-tiny-LiteRT

Finetuned
(8)
this model