mlboydaisuke commited on
Commit
9875559
·
verified ·
1 Parent(s): 41bdf59

Upload README.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. README.md +102 -0
README.md ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ tags:
4
+ - executorch
5
+ - xnnpack
6
+ - pte
7
+ - on-device
8
+ - object-detection
9
+ - zero-shot-object-detection
10
+ base_model:
11
+ - IDEA-Research/grounding-dino-tiny
12
+ ---
13
+ # Grounding DINO tiny — ExecuTorch (open-vocabulary detection)
14
+
15
+ You name the thing in text and it finds it. No fixed class list: the prompt is
16
+ "a person. a car. a bicycle. a dog." today and "a fire hydrant. a traffic cone."
17
+ on the next call, with the same weights.
18
+
19
+ ```
20
+ (pixel_values (1,3,640,640), input_ids (1,32), token_type_ids (1,32),
21
+ attention_mask (1,32), text_masks (1,32,32), position_ids (1,32))
22
+ -> scores (1,900,256), boxes (1,900,4)
23
+ ```
24
+
25
+ | build | file | MB | scores corr | boxes corr | Mac ms* |
26
+ |---|---|---|---|---|---|
27
+ | fp32 | `grounding_dino_tiny_xnnpack_fp32.pte` | 690.3 | 0.999833 | 0.998992 | 584.1 |
28
+
29
+ \*Mac arm64, single process, median of 5 — a reference point for relative cost, not a
30
+ device number. Torch eager fp32 on the same machine: 376.7 ms. XNNPACK delegate
31
+ coverage 63.0% (3503/5559 ops).
32
+
33
+ **There is no Core ML build.** The graph reshapes to rank 6 and Core ML's ceiling is 5 —
34
+ the same wall RAFT-small hits with its correlation volume. This one is XNNPACK only, and
35
+ the same file runs on Android and on the Mac.
36
+
37
+ ## Running it
38
+
39
+ **1. The image.** RGB, divide by 255, ImageNet normalise (mean .485/.456/.406, std
40
+ .229/.224/.225), resize to 640×640.
41
+
42
+ **2. The prompt.** Lower-case phrases separated by `". "`, ending in a period. Tokenise
43
+ with the repo's tokenizer at `padding="max_length", max_length=32`. `input_ids`,
44
+ `token_type_ids` and `attention_mask` are int64 `(1,32)`.
45
+
46
+ **3. The two text tensors that are not the tokenizer's.** `text_masks` and `position_ids`
47
+ come from transformers' `generate_masks_with_special_tokens_and_transfer_map(input_ids)`
48
+ — the mask that keeps each phrase's tokens attending only to their own phrase. It is
49
+ built with `cummax`/`cummin`, which are not in the Core ATen opset, so it is lifted out of
50
+ the graph and passed in — `text_masks` is **bool** `(1,32,32)` and `position_ids` is int64
51
+ `(1,32)`, and ExecuTorch will not coerce either. Both depend on `input_ids` alone, never
52
+ on the image, so compute them once when the user types the prompt. The model stays
53
+ open-vocabulary; only the token count is fixed.
54
+
55
+ **4. Reading the answer.** `boxes` is `(cx, cy, w, h)` normalised to the input square.
56
+ `scores[0, q, t]` is how much query `q` points at text position `t`. A detection is a
57
+ query whose best score clears your threshold (0.3 is a reasonable default), and its label
58
+ is the `input_ids` token at that argmax.
59
+
60
+ Two things about that text axis. It is always 256 wide — the model's `max_text_len` — no
61
+ matter how long your prompt is, and every column past your prompt's tokens is exactly 0.
62
+ And the peak often lands on an article rather than the noun: a query for a person may
63
+ argmax on the `a` of "a person". Map the winning token back to the **phrase** it belongs
64
+ to, the way transformers' own post-processor does, rather than reading the single token
65
+ as the label.
66
+
67
+ ## What is measured
68
+
69
+ The number that decides is detections, not correlation. Against eager PyTorch on five
70
+ street photographs at threshold 0.3:
71
+
72
+ **26 of 26 of eager's detections are reproduced**, each at IoU > 0.5 with the same prompt
73
+ token. That includes a photo with 17 detections in it.
74
+
75
+ ```bash
76
+ python convert/audit_int8.py grounding_dino_tiny --variant fp32
77
+ python convert/verify_cards.py grounding_dino_tiny
78
+ ```
79
+
80
+ Correlation is in the table above for completeness, and the boxes figure (0.998992) is
81
+ below this shelf's usual fp32 bar of 0.999. It is not measuring what it looks like: the
82
+ largest box differences are on queries that fire at nothing, where a coordinate is free to
83
+ wander without changing any answer. The detection count is what was gated on.
84
+
85
+ ### The number that had this model filed as broken
86
+
87
+ Grounding DINO writes **-inf** into every text column the prompt does not use. The score
88
+ tensor is 900 queries × 256 columns; a four-phrase prompt uses 14 of them, so **94.5% of
89
+ the raw logits are -inf**. Correlation over that tensor is undefined, and subtracting two
90
+ builds gives NaN rather than a difference. Measured that way this conversion read "corr
91
+ 0.857, returns the stopword 'a' where eager finds four people" and sat parked. Both halves
92
+ were artefacts: eager returns that same `a` query at the same 0.385, and the detections
93
+ were identical all along.
94
+
95
+ The shipped graph ends in a `sigmoid`, so those positions are exactly 0, the output is in
96
+ the 0..1 an app wants, and the gate measures the model instead of its padding.
97
+
98
+ - **Source**: [IDEA-Research/grounding-dino-tiny](https://huggingface.co/IDEA-Research/grounding-dino-tiny)
99
+ - **License**: Apache-2.0
100
+
101
+ torch.export -> to_edge_transform_and_lower(partitioner) -> .pte
102
+ (conversion scripts: [executorch-models](https://github.com/john-rocky/executorch-models))