mlboydaisuke commited on
Commit
307283c
·
verified ·
1 Parent(s): c3c5e19

Upload README.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. README.md +108 -0
README.md ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ library_name: litert
4
+ pipeline_tag: image-feature-extraction
5
+ base_model: timm/vit_pe_core_base_patch16_224.fb
6
+ tags:
7
+ - litert
8
+ - tflite
9
+ - on-device
10
+ - android
11
+ - gpu
12
+ - clip
13
+ - perception-encoder
14
+ - image-encoder
15
+ - vit
16
+ - rope
17
+ ---
18
+
19
+ # Perception Encoder (PE-Core-B16-224) — LiteRT (TFLite) GPU
20
+
21
+ On-device [LiteRT](https://ai.google.dev/edge/litert) (`.tflite`) conversion of
22
+ **Perception Encoder Core** (PE-Core, Meta 2025), the SOTA CLIP-style image tower,
23
+ converted from [`timm/vit_pe_core_base_patch16_224.fb`](https://huggingface.co/timm/vit_pe_core_base_patch16_224.fb)
24
+ (ViT-B/16, 94M params; original [facebook/PE-Core-B16-224](https://huggingface.co/facebook/PE-Core-B16-224)).
25
+
26
+ A single forward pass turns one RGB image into a **1024-d L2-normalized image
27
+ embedding** for zero-shot classification, retrieval, and similarity — running
28
+ **fully on the LiteRT `CompiledModel` GPU accelerator** (ML Drift): **all 1028
29
+ ops are GPU-native (`Replacing 1028 out of 1028 node(s) ... LITERT_CL`), no CPU
30
+ fallback, no Flex ops.**
31
+
32
+ ## Files
33
+
34
+ | File | Size | Description |
35
+ |------|------|-------------|
36
+ | `pe_core_base_224_fp16.tflite` | 187 MB | FP16 single-graph model, GPU full-residency |
37
+ | `convert_pecore.py` | — | Reproducible conversion script (timm → tflite) |
38
+
39
+ ## I/O
40
+
41
+ - **Input**: `[1, 3, 224, 224]` float32, **NCHW**, RGB normalized to **`[-1, 1]`**
42
+ i.e. `(pixel/255 - 0.5) / 0.5` (timm mean/std = `(0.5, 0.5, 0.5)`). Normalization
43
+ is applied by the caller (not baked into the graph).
44
+ - **Output**: `[1, 1024]` float32, **L2-normalized** image embedding.
45
+
46
+ ## Usage (Android, LiteRT CompiledModel)
47
+
48
+ ```kotlin
49
+ val model = CompiledModel.create(
50
+ context.assets, "pe_core_base_224_fp16.tflite",
51
+ CompiledModel.Options(Accelerator.GPU), null
52
+ )
53
+ val inputs = model.createInputBuffers()
54
+ val outputs = model.createOutputBuffers()
55
+ inputs[0].writeFloat(nchwFloatArray) // [1,3,224,224], RGB scaled to [-1,1]
56
+ model.run(inputs, outputs)
57
+ val embedding = outputs[0].readFloat() // [1024], already L2-normalized
58
+ ```
59
+
60
+ For zero-shot classification, precompute text-label embeddings with the PE-Core
61
+ text tower offline and take the dot product on device.
62
+
63
+ ## Performance
64
+
65
+ - **~66 ms / image steady-state** on a Pixel 8a (Mali-G615) GPU (best 12.5 ms),
66
+ full GPU residency, FP16.
67
+
68
+ ## Conversion notes
69
+
70
+ Converted with [litert-torch / ai-edge-torch](https://github.com/google-ai-edge/ai-edge-torch).
71
+ Making a RoPE ViT image tower **fully GPU-compatible** required three verbatim
72
+ (weights-exact, output corr ≈ 1.0) model-side rewrites:
73
+
74
+ 1. **Fused-qkv → 4D manual attention** — the fused `qkv` reshape emits a 5D
75
+ head-split (`RESHAPE` rank 5) that the GPU delegate rejects; decompose into
76
+ separate q/k/v projections so attention stays 4D.
77
+ 2. **Interleaved 2D-RoPE → rotate-half** — PE-Core's interleaved rotary uses a
78
+ strided `x[..., ::2]` that lowers to `GATHER_ND` (GPU-banned). Bake an
79
+ even→odd channel permutation into the q/k weights (preserves q·k exactly) and
80
+ apply the rotate-half form (slice + neg + concat) with constant cos/sin →
81
+ clean `MUL`/`ADD`/`SLICE`/`CONCAT`.
82
+ 3. **Attention-pool with constant query → constant-RHS matmul** — the pooling
83
+ query is a constant latent, so the `q·kᵀ` batch-matmul is `const @ non-const`,
84
+ which the delegate rejects; reorder as `k @ q_constᵀ` (constant RHS → the
85
+ fully-connected path). Self-attention uses `scaled_dot_product_attention`,
86
+ whose lowering keeps the batch-matmul 3D with a materialized transpose
87
+ (both required for GPU residency).
88
+
89
+ Verified: zero banned ops, zero >4D tensors, TFLite-vs-PyTorch output
90
+ correlation = 1.000000 (FP32 and FP16).
91
+
92
+ ## Training data & PII
93
+
94
+ PE-Core was pretrained by Meta on a large-scale **web-crawled image–text dataset**
95
+ (billions of image–caption pairs, CLIP-style contrastive objective). No new
96
+ training was performed for this conversion — it is a weights-exact format change
97
+ of the public `timm`/`facebook` checkpoint. Because the source data is
98
+ web-scraped, it may incidentally contain people, faces, text, and other PII;
99
+ no PII was deliberately collected, and this conversion adds none. Users deploying
100
+ the encoder should apply their own content/PII filtering as appropriate. See the
101
+ original [PE model card](https://huggingface.co/facebook/PE-Core-B16-224) and
102
+ [paper](https://arxiv.org/abs/2504.13181) for full dataset details.
103
+
104
+ ## License & attribution
105
+
106
+ - **Apache-2.0** (original [PE-Core](https://huggingface.co/facebook/PE-Core-B16-224) /
107
+ [timm checkpoint](https://huggingface.co/timm/vit_pe_core_base_patch16_224.fb)).
108
+ - This is a format conversion; all credit to the original authors (Meta / FAIR).