| --- |
| license: apache-2.0 |
| tags: |
| - executorch |
| - xnnpack |
| - pte |
| - on-device |
| - mask-generation |
| base_model: |
| - facebook/EdgeTAM |
| --- |
| # EdgeTAM β ExecuTorch XNNPACK (encoder + decoder) |
|
|
| Promptable segmentation in two `.pte` files: run the encoder once per image, the |
| decoder once per click. |
|
|
| - `edgetam_encoder_xnnpack_fp32.pte` (19.7 MB) β image (1,3,1024,1024) β |
| image_embed (1,256,64,64), feat_s0 (1,32,256,256), feat_s1 (1,64,128,128) |
| - `edgetam_decoder_xnnpack_fp32.pte` (24.7 MB) β (image_embed, feat_s0, feat_s1, |
| points (1,1,N,2) fp32 pixel coords in 1024-space, labels (1,1,N) int64 1=fg/0=bg) |
| β mask logits (1,1,3,256,256), iou scores (1,1,3) |
| - `edgetam_decoder_xnnpack_fp16.pte` (12.6 MB) β the same decoder at half the size, |
| corr 1.000000 against fp32 eager. It takes and returns fp32 tensors, so pairing it |
| with the fp32 encoder needs no app changes. |
|
|
| The encoder ships in fp32 only, and that is not an omission. Its backbone is RepViT, |
| which is convolutional, and XNNPACK serializes convolution weights as fp32 whatever |
| dtype the graph carries β fp16 came out at 19.8 MB (100.5%) and dynamic int8 at |
| 19.7 MB, so neither buys anything. At 19.7 MB the fp32 encoder is already smaller |
| than SAM 2.1 hiera-tiny's *fp16* encoder (55.6 MB). |
|
|
| EdgeTAM is Meta's on-device SAM 2 (CVPR 2025). Its encoder is **5.5Γ smaller than |
| SAM 2.1 hiera-tiny's** (19.7 MB vs 109.2 MB) for the same output contract, so an |
| app written against |
| [SAM2.1-hiera-tiny-ExecuTorch](https://huggingface.co/mlboydaisuke/SAM2.1-hiera-tiny-ExecuTorch) |
| swaps the two files and changes nothing else. |
|
|
| - **Source**: [facebook/EdgeTAM](https://huggingface.co/facebook/EdgeTAM), loaded |
| from the transformers-format mirror |
| [yonigozlan/EdgeTAM-hf](https://huggingface.co/yonigozlan/EdgeTAM-hf) |
| (`facebook/EdgeTAM` publishes only the original `edgetam.pt`) |
| - **License**: Apache-2.0 |
| - **Preprocess**: RGB/255, ImageNet norm (mean .485/.456/.406, std .229/.224/.225), |
| resize 1024Γ1024 |
| - **Postprocess**: take argmax(iou) of the 3 mask logits, threshold at > 0, upsample |
| 4Γ (256β1024) back to image space. The prompt encoder is inside the decoder β pass |
| raw click coordinates, no separate point-encoding code needed. |
|
|
| ## Verification (Mac arm64, executorch 1.4.0, torch 2.13.0) |
|
|
| Every output of both graphs matches torch fp32 eager at corr 1.000000, and the two |
| wrappers compose back to `EdgeTamModel.forward` exactly (max_abs_diff 0.000e+00). |
|
|
| | graph | output | shape | max_abs_diff | corr | |
| |-------|--------|-------|--------------|------| |
| | encoder | image_embed | [1, 256, 64, 64] | 0.000e+00 | 1.000000 | |
| | encoder | feat_s0 | [1, 32, 256, 256] | 0.000e+00 | 1.000000 | |
| | encoder | feat_s1 | [1, 64, 128, 128] | 0.000e+00 | 1.000000 | |
| | decoder | mask logits | [1, 1, 3, 256, 256] | 0.000e+00 | 1.000000 | |
| | decoder | iou | [1, 1, 3] | 0.000e+00 | 1.000000 | |
| |
| Median over 10 runs, Mac arm64 single process β a relative reference, not a device |
| number: encoder 32.3 ms (torch eager 103.5 ms), decoder 23.7 ms (eager 13.9 ms). |
| |
| XNNPACK delegate coverage: encoder 99.8% (one `upsample_nearest2d` on the portable |
| kernels), decoder 66.5% (the prompt encoder's `expand`/`where` bookkeeping stays on |
| portable; every convolution and matmul is delegated). |
|
|
| ## Conversion |
|
|
| torch.export β to_edge_transform_and_lower(XnnpackPartitioner) β .pte |
| (conversion script: [executorch-models](https://github.com/john-rocky/executorch-models)) |
|
|
| Two details matter for this split, both shared with the SAM 2.1 conversion. Encoder |
| outputs are forced `.contiguous()` β transformers hands back channels_last tensors, |
| and that layout at a `.pte` boundary makes the delegate's runtime shape propagation |
| read physical strides as logical dims. Identity `repeat_interleave(1, dim)` calls in |
| the decoder are dropped, since their lowered form mis-sizes on a single-point export. |
|
|
| The GPU-specific rewrites in the LiteRT build of this model (splitting the |
| squeeze-excite mean, replacing ConvTranspose2d) are ML Drift workarounds and are not |
| needed here β XNNPACK runs the stock graph. |
|
|
| <!-- funnel:v1 --> |
|
|
| --- |
|
|
| **More models in this format:** [ExecuTorch Model Zoo](https://huggingface.co/collections/mlboydaisuke/executorch-model-zoo-6a7ff328390b63075ffeae5e) β 31 models, each with the recipe that produced it. |
|
|
| **Want a different model on-device?** [Open a request](https://github.com/john-rocky/on-device-requests) β free, open weights only; the export and its measured numbers get published publicly. |
|
|
| <!-- /funnel:v1 --> |
|
|