kem-gov commited on
Commit
48a89ad
·
verified ·
1 Parent(s): ea3b5c8

Publish via hf-publish-experiment (6b90bfc5d6b6e56b6f85627641280de6f0fa7756)

Browse files
.gitattributes CHANGED
@@ -35,3 +35,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  deit_raspberry_executorch_fp32.pte filter=lfs diff=lfs merge=lfs -text
37
  deit_raspberry_executorch_optimized.pte filter=lfs diff=lfs merge=lfs -text
 
 
 
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  deit_raspberry_executorch_fp32.pte filter=lfs diff=lfs merge=lfs -text
37
  deit_raspberry_executorch_optimized.pte filter=lfs diff=lfs merge=lfs -text
38
+ deit_raspberry_executorch_original.pte filter=lfs diff=lfs merge=lfs -text
39
+ sample_input.jpg filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,8 +1,8 @@
1
  ---
2
  library_name: executorch
3
- license: apache-2.0
4
  base_model: facebook/deit-tiny-patch16-224
5
  base_model_relation: quantized
 
6
  tags:
7
  - image-classification
8
  - deit
@@ -12,7 +12,7 @@ tags:
12
  - arm
13
  - executorch
14
  - edge-ai
15
- - imagenet
16
  pipeline_tag: image-classification
17
  datasets:
18
  - imagenet-1k
@@ -32,195 +32,185 @@ model-index:
32
  evaluation_samples: 50000
33
  metrics:
34
  - type: accuracy
35
- value: 67.62
36
- name: Top-1 Accuracy (INT8)
37
  - type: accuracy
38
- value: 88.48
39
- name: Top-5 Accuracy (INT8)
40
  ---
41
 
42
  # DeiT-Tiny INT8 (ExecuTorch + XNNPACK)
43
 
44
- This is an INT8 symmetric post-training quantized version of [facebook/deit-tiny-patch16-224](https://huggingface.co/facebook/deit-tiny-patch16-224), exported to the ExecuTorch `.pte` format and accelerated with the XNNPACK delegate for deployment on ARM-based edge devices. The model was calibrated on 1,000 ImageNet samples and evaluated on the full 50,000-image ImageNet-1K validation set.
45
 
46
  ## Key Highlights
47
 
48
- - **3.32x smaller** — model file reduced from 22.00 MB (FP32) to 6.62 MB (INT8)
49
- - **1.34x faster on Raspberry Pi** — latency drops from 34.57 ms to 25.71 ms per image
50
- - **-1.34 pp Top-1 accuracy** — 67.62% INT8 vs 68.96% FP32 on ImageNet-1K val (50,000 images)
 
 
51
 
52
  ## Model Details
53
 
54
  ### Model Description
55
 
56
- DeiT-Tiny is a compact Data-efficient Image Transformer trained entirely on ImageNet without extra data. This variant applies INT8 symmetric static quantization via the PT2E (PyTorch 2 Export) pipeline and lowers the quantized graph to ExecuTorch with the XNNPACK delegate. XNNPACK covers 27.70% of operators and accounts for 63.81% of wall-clock inference time on the target device.
57
 
58
- - **Base model developed by:** Meta (FAIR)
59
- - **Quantized/exported artifact prepared by:** Marvik AI
60
- - **Model type:** Vision Transformer (ViT/DeiT) — image classification
61
- - **Base model:** [facebook/deit-tiny-patch16-224](https://huggingface.co/facebook/deit-tiny-patch16-224)
62
- - **Quantization:** INT8 symmetric, static, post-training (PT2E)
63
- - **Runtime:** ExecuTorch with XNNPACK delegate
64
- - **Target hardware:** ARM-based devices (Raspberry Pi, Android, Graviton, embedded)
65
- - **License:** Apache 2.0
66
 
67
  ### Model Sources
68
 
69
- - **Base model:** https://huggingface.co/facebook/deit-tiny-patch16-224
70
- - **Original paper:** [Training data-efficient image transformers & distillation through attention (Touvron et al., 2021)](https://arxiv.org/abs/2012.12877)
71
 
72
- ## How to Get Started
73
 
74
- ### 1. Install dependencies
75
 
76
  ```bash
77
- pip install executorch torchvision pillow
78
  ```
79
 
80
- ### 2. Download the model
81
 
82
- Download `deit_raspberry_executorch_optimized.pte` and `imagenet_classes.json` from the **Files** tab of this repository, then place them alongside `example.py`.
 
 
 
 
 
 
 
83
 
84
- ### 3. Run inference
85
 
86
  ```bash
87
  python example.py
88
  ```
89
 
90
- ### Inline example
91
 
92
  ```python
93
- """Minimal inference example for DeiT-Tiny INT8 using ExecuTorch."""
94
-
95
- import json
96
- from pathlib import Path
97
-
98
- import torch
99
  from executorch.runtime import Runtime
100
  from PIL import Image
101
  from torchvision import transforms
102
 
103
- MODEL_PATH = "deit_raspberry_executorch_optimized.pte"
104
- IMAGE_PATH = "sample_input.jpg"
105
- INPUT_SIZE = (224, 224)
106
- MEAN = [0.485, 0.456, 0.406]
107
- STD = [0.229, 0.224, 0.225]
108
- TOP_K = 5
109
-
110
- def load_model(pte_path):
111
- runtime = Runtime.get()
112
- program = runtime.load_program(pte_path)
113
- return program.load_method("forward")
114
-
115
- def preprocess(image_path):
116
- transform = transforms.Compose([
117
- transforms.Resize(256),
118
- transforms.CenterCrop(INPUT_SIZE),
119
- transforms.ToTensor(),
120
- transforms.Normalize(mean=MEAN, std=STD),
121
- ])
122
- image = Image.open(image_path).convert("RGB")
123
- return transform(image).unsqueeze(0)
124
-
125
- def run_inference(method, input_tensor):
126
- outputs = method.execute([input_tensor])
127
- return outputs[0]
128
-
129
- def postprocess(raw_output, labels):
130
- logits = raw_output.squeeze(0)
131
- probabilities = torch.softmax(logits, dim=-1)
132
- top_probs, top_indices = torch.topk(probabilities, TOP_K)
133
- return [{"class": labels[str(idx)], "probability": prob}
134
- for prob, idx in zip(top_probs.tolist(), top_indices.tolist())]
135
-
136
- def main():
137
- script_dir = Path(__file__).parent
138
- with open(script_dir / "imagenet_classes.json") as f:
139
- labels = json.load(f)
140
- method = load_model(str(script_dir / MODEL_PATH))
141
- input_tensor = preprocess(str(script_dir / IMAGE_PATH))
142
- raw_output = run_inference(method, input_tensor)
143
- results = postprocess(raw_output, labels)
144
- for i, r in enumerate(results, 1):
145
- print(f" {i}. {r['class']} ({r['probability']*100:.1f}%)")
146
-
147
- if __name__ == "__main__":
148
- main()
149
  ```
150
 
151
  ## Evaluation
152
 
153
- ### Testing Data and Metrics
 
 
 
 
 
 
154
 
155
- - **Dataset:** ImageNet-1K validation set
156
- - **Evaluation samples:** 50,000 images (full validation split)
157
- - **Calibration samples:** 1,000 ImageNet validation images (random shuffle)
158
- - **Metrics:** Top-1 Accuracy, Top-5 Accuracy, model file size, on-device latency (Raspberry Pi), peak memory usage
159
 
160
  ### Results
161
 
162
  #### Accuracy
163
 
164
- | Metric | FP32 | INT8 | Delta |
165
- |---|---|---|---|
166
- | Top-1 Accuracy | 68.96% | 67.62% | -1.34 pp |
167
- | Top-5 Accuracy | 89.17% | 88.48% | -0.70 pp |
 
 
168
 
169
- #### Efficiency (Raspberry Pi)
170
 
171
- | Metric | FP32 | INT8 | Improvement |
172
- |---|---|---|---|
173
- | Model size (.pte) | 22.00 MB | 6.62 MB | 3.32x smaller |
174
- | Inference latency | 34.57 ms | 25.71 ms | 1.34x faster |
175
- | Peak memory | 33.58 MB | 18.47 MB | 1.82x lower |
 
 
 
176
 
177
  ## Technical Specifications
178
 
179
  ### Objective
180
 
181
- Reduce model size and inference latency of DeiT-Tiny for deployment on resource-constrained ARM devices while preserving ImageNet classification accuracy within an acceptable margin.
182
 
183
  ### Quantization
184
 
185
- - **Method:** Post-training static quantization (PTQ), INT8 symmetric
186
- - **Framework:** PT2E (PyTorch 2 Export) quantization pipeline
187
- - **Calibration:** 1,000 randomly sampled ImageNet validation images
188
- - **Granularity:** Per-channel for weights, per-tensor for activations
189
- - **Layers kept in FP32:** `patch_embeddings` on the current ExecuTorch/XNNPACK recipe
190
- - **Delegate:** XNNPACK (covers 27.70% of operators, 63.81% of wall-clock time)
191
 
192
  ### Export Pipeline
193
 
194
- 1. The FP32 model is captured via `torch.export` to produce a portable FX graph.
195
- 2. XNNPACK-aware observers are inserted and calibrated on 1,000 ImageNet validation samples.
196
- 3. Observers are converted to INT8 quantize/dequantize (Q/DQ) pairs.
197
- 4. The quantized graph is lowered to ExecuTorch `.pte` format with the XNNPACK delegate.
 
 
 
198
 
199
  ### Preprocessing
200
 
201
- Inputs must be preprocessed before being passed to the model:
202
-
203
- | Step | Parameters |
204
  |---|---|
205
- | Resize (shorter side) | 256 px |
206
- | Center crop | 224 × 224 px |
207
- | To tensor | Scales pixel values to [0.0, 1.0] |
208
- | Normalize | mean = [0.485, 0.456, 0.406], std = [0.229, 0.224, 0.225] |
 
 
 
 
 
 
209
 
210
- - **Input shape:** `[1, 3, 224, 224]` (batch × channels × height × width)
211
- - **Input dtype:** `float32`
212
 
213
  ### Postprocessing
214
 
215
- The model outputs raw class logits of shape `[1, 1000]` (one logit per ImageNet class). To obtain class probabilities:
 
 
 
216
 
217
- 1. Apply `softmax` along the class dimension.
218
- 2. Take `top-k` (k = 5) to retrieve the most likely classes.
 
 
219
 
220
  ## Known Limitations
221
 
222
- - **Fixed input resolution:** The model expects exactly 224 × 224 inputs. Images of different sizes must be resized and cropped prior to inference.
223
- - **ImageNet classes only:** The model was trained and evaluated on ImageNet-1K (1,000 classes). It is not suitable for out-of-distribution domains without fine-tuning.
224
- - **Latency figures are Raspberry Pi-specific:** The speedup of 1.34x was measured on a Raspberry Pi using the ExecuTorch XNNPACK runtime. Results on other ARM devices (Android, AWS Graviton, embedded MCUs) may differ.
225
- - **INT8 accuracy drop:** A -1.34 pp Top-1 regression is typical for static PTQ on ViT-family models. Tasks requiring higher accuracy may benefit from quantization-aware training (QAT) or a larger DeiT variant.
226
- - **XNNPACK coverage:** 27.70% of operators are delegated to XNNPACK. Remaining operators run on the ExecuTorch portable kernel, which may limit speedup compared to a fully delegated CNN.
 
1
  ---
2
  library_name: executorch
 
3
  base_model: facebook/deit-tiny-patch16-224
4
  base_model_relation: quantized
5
+ license: apache-2.0
6
  tags:
7
  - image-classification
8
  - deit
 
12
  - arm
13
  - executorch
14
  - edge-ai
15
+ - imagenet-1k
16
  pipeline_tag: image-classification
17
  datasets:
18
  - imagenet-1k
 
32
  evaluation_samples: 50000
33
  metrics:
34
  - type: accuracy
35
+ value: 71.36
36
+ name: Top-1 Accuracy (ExecuTorch)
37
  - type: accuracy
38
+ value: 90.74
39
+ name: Top-5 Accuracy (ExecuTorch)
40
  ---
41
 
42
  # DeiT-Tiny INT8 (ExecuTorch + XNNPACK)
43
 
44
+ This is an INT8-quantized version of [facebook/deit-tiny-patch16-224](https://huggingface.co/facebook/deit-tiny-patch16-224) optimized for edge deployment on ARM devices using [ExecuTorch](https://github.com/pytorch/executorch) with the XNNPACK backend. The model was quantized using PT2E static symmetric per-channel quantization and exported to the `.pte` format for efficient inference on ARM Cortex-A processors (Raspberry Pi, mobile ARM, embedded).
45
 
46
  ## Key Highlights
47
 
48
+ Compared to the FP32 baseline:
49
+
50
+ - **3.32x smaller** — 22.00 MB to 6.62 MB (.pte)
51
+ - **1.34x faster** — 35.41 ms to 26.47 ms on Raspberry Pi
52
+ - **Minimal accuracy loss** — -0.78 pp Top-1 Accuracy
53
 
54
  ## Model Details
55
 
56
  ### Model Description
57
 
58
+ Quantized version of DeiT-Tiny (Data-efficient Image Transformer), a compact vision transformer model trained on ImageNet-1K using knowledge distillation. This INT8 version is optimized for efficient edge inference via PT2E static quantization and the ExecuTorch runtime.
59
 
60
+ - **Developed by:** Meta
61
+ - **Model type:** Image Classification
62
+ - **License:** Apache-2.0
63
+ - **Base model:** [facebook/deit-tiny-patch16-224](https://huggingface.co/facebook/deit-tiny-patch16-224) — quantized, not finetuned
 
 
 
 
64
 
65
  ### Model Sources
66
 
67
+ - **Repository:** https://huggingface.co/facebook/deit-tiny-patch16-224
 
68
 
69
+ ## How to Get Started with the Model
70
 
71
+ ### Install dependencies
72
 
73
  ```bash
74
+ pip install executorch torch torchvision pillow numpy
75
  ```
76
 
77
+ ### Download the model
78
 
79
+ ```python
80
+ from huggingface_hub import hf_hub_download
81
+
82
+ model_path = hf_hub_download(
83
+ repo_id="your-org/deit-tiny-patch16-224-int8-executorch",
84
+ filename="optimized.pte",
85
+ )
86
+ ```
87
 
88
+ ### Run inference
89
 
90
  ```bash
91
  python example.py
92
  ```
93
 
94
+ Or use the core inference loop directly:
95
 
96
  ```python
 
 
 
 
 
 
97
  from executorch.runtime import Runtime
98
  from PIL import Image
99
  from torchvision import transforms
100
 
101
+ # Load model
102
+ runtime = Runtime.get()
103
+ program = runtime.load_program("optimized.pte")
104
+ method = program.load_method("forward")
105
+
106
+ # Preprocess: resize to 256, center-crop 224x224, normalize with ImageNet mean/std
107
+ transform = transforms.Compose([
108
+ transforms.Resize(256, interpolation=transforms.InterpolationMode.BICUBIC),
109
+ transforms.CenterCrop((224, 224)),
110
+ transforms.ToTensor(),
111
+ transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
112
+ ])
113
+ image = Image.open("input.jpg").convert("RGB")
114
+ input_tensor = transform(image).unsqueeze(0) # [1, 3, 224, 224]
115
+
116
+ # Run inference
117
+ outputs = method.execute([input_tensor])
118
+
119
+ # outputs[0] shape: [1, 1000] — raw class logits
120
+ # Apply softmax for probabilities, then top-k for predictions
121
+ # See example.py for full postprocessing
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  ```
123
 
124
  ## Evaluation
125
 
126
+ ### Testing Data, Factors & Metrics
127
+
128
+ #### Testing Data
129
+
130
+ Evaluated on 50,000 images from ImageNet-1K val (validation split).
131
+
132
+ #### Metrics
133
 
134
+ - **Top-1 Accuracy** — percentage of images where the highest-probability predicted class matches the ground truth label
135
+ - **Top-5 Accuracy** — percentage of images where the ground truth label appears among the top 5 predicted classes
 
 
136
 
137
  ### Results
138
 
139
  #### Accuracy
140
 
141
+ | Metric | FP32 (Original) | INT8 (Optimized) | Delta |
142
+ |:---|:---:|:---:|:---:|
143
+ | Top-1 Accuracy (ExecuTorch) | 72.13% | 71.36% | -0.78 pp |
144
+ | Top-5 Accuracy (ExecuTorch) | 91.13% | 90.74% | -0.40 pp |
145
+ | Top-1 Accuracy (PyTorch) | 72.13% | 71.33% | -0.80 pp |
146
+ | Top-5 Accuracy (PyTorch) | 91.13% | 90.76% | -0.37 pp |
147
 
148
+ #### Efficiency
149
 
150
+ | Metric | FP32 (Original) | INT8 (Optimized) | Improvement |
151
+ |:---|:---:|:---:|:---:|
152
+ | Model Size (.pte) | 22.00 MB | 6.62 MB | **3.32x smaller** |
153
+ | Raspberry Pi Latency (mean) | 35.41 ms | 26.47 ms | **1.34x faster** |
154
+ | Raspberry Pi Latency (p50) | 35.34 ms | 26.40 ms | **1.34x faster** |
155
+ | Raspberry Pi Latency (p90) | 35.48 ms | 26.60 ms | **1.33x faster** |
156
+ | Raspberry Pi Peak Memory (USS) | 31.16 MB | 18.38 MB | **1.70x less** |
157
+ | Raspberry Pi Median Memory (USS) | 31.02 MB | 16.14 MB | **1.92x less** |
158
 
159
  ## Technical Specifications
160
 
161
  ### Objective
162
 
163
+ 1000-class image classification on ImageNet using a compact vision transformer (ViT) architecture trained with knowledge distillation.
164
 
165
  ### Quantization
166
 
167
+ - **Method**: PT2E Static Quantization via XNNPACKQuantizer
168
+ - **Precision**: INT8 symmetric, per-channel
169
+ - **Backend**: XNNPACK
170
+ - **Layers kept in FP32**: patch embeddings (`patch_embeddings`) — quantized patch-embedding attention patterns produce static transpose nodes that XNNPACK cannot compile
171
+ - **Calibration**: 1,000 images from ImageNet-1K val
 
172
 
173
  ### Export Pipeline
174
 
175
+ 1. Load pretrained FP32 DeiT-Tiny model from HuggingFace
176
+ 2. Wrap model to produce a single logits tensor output
177
+ 3. Capture model graph via `torch.export` (with `aten.linear` kept intact for XNNPACK delegation)
178
+ 4. Insert quantization observers (XNNPACKQuantizer, per-op mode, skip patch embeddings)
179
+ 5. Calibrate with representative data
180
+ 6. Convert observers to Q/DQ pairs
181
+ 7. Export to ExecuTorch `.pte` with XNNPACK backend
182
 
183
  ### Preprocessing
184
 
185
+ | Property | Value |
 
 
186
  |---|---|
187
+ | Input shape | `[1, 3, 224, 224]` (BCHW) |
188
+ | Data type | float32 |
189
+ | Value range | [0.0, 1.0] |
190
+ | Color space | RGB |
191
+
192
+ **Steps**:
193
+ 1. Resize shortest edge to 256 px (bicubic interpolation)
194
+ 2. Center-crop to 224×224
195
+ 3. Convert to tensor (`ToTensor()`: [0–255] uint8 → [0, 1] float32)
196
+ 4. Normalize with ImageNet mean `[0.485, 0.456, 0.406]` and std `[0.229, 0.224, 0.225]`
197
 
198
+ **Normalization**: ImageNet mean/std normalization is required.
 
199
 
200
  ### Postprocessing
201
 
202
+ | Property | Value |
203
+ |---|---|
204
+ | Output shape | `[1, 1000]` |
205
+ | Output format | Raw class logits (unnormalized) |
206
 
207
+ **Steps**:
208
+ 1. Squeeze batch dimension: `[1000]` logit vector
209
+ 2. Apply softmax to obtain class probabilities
210
+ 3. Take top-k (default: 5) predicted classes by probability
211
 
212
  ## Known Limitations
213
 
214
+ - Evaluated on the full 50,000-image ImageNet-1K validation set
215
+ - Fixed input size of 224×224 — images are resized without preserving aspect ratio
216
+ - XNNPACK operator coverage is 27.7% (by operator count); attention and layer norm operations fall back to the ExecuTorch portable kernel
 
 
benchmarks/deit-tiny-raspberrypi5-fp32.yaml CHANGED
@@ -2,29 +2,32 @@
2
  # Pairs with `deit-tiny-raspberrypi5-int8.yaml` to demonstrate the
3
  # baseline-comparison join documented in `docs/header-and-generic.md`.
4
  #
5
- # Source: Marvik delivery package `deit_raspberry_executorch.zip`, `report.json`
6
- # `original` fields (the un-quantised baseline measured under identical
7
- # target / runtime / dataset / benchmark conditions to the optimised record).
 
 
 
8
  #
9
  # Same target / runtime / dataset / benchmark as the INT8 record —
10
  # disambiguator is `weight_dtype`, and (once published) `model.id`.
11
  #
12
- # Known unknowns (Marvik pipeline does not currently surface these):
13
- # - context.benchmark.num_runs — required by schema; placeholder used
14
- # - context.benchmark.warmup_runs — optional
15
- # - context.runtime.version — optional but worth recording
16
- # - context.target.os_version — optional
17
- # - context.runtime.config.n_threads — optional
18
- # - context.model.baseline_checksum — optional
 
19
  # - context.model.base_model_revision — not yet a schema field; pinning
20
  # this artefact to a HF revision SHA
21
  # would close the last reproducibility
22
  # gap on the baseline.
23
- # - performance.end_to_end_latency_ms.p99 — optional; only p50/p90 reported
24
 
25
  version: 1.0.0
26
  task: vision-classification
27
- created_at: '2026-04-22T22:43:46Z'
28
  context:
29
  model:
30
  id: facebook/deit-tiny-patch16-224
@@ -43,30 +46,33 @@ context:
43
  cpu_clock_ghz: 2.4
44
  system_memory_gb: 8
45
  os: linux
 
46
  runtime:
47
  name: executorch
48
  execution_backend: cpu
 
49
  config:
50
  optimisations:
51
- - XNNPACK
52
- - KleidiAI
53
  dataset:
54
- name: imagenet-1k
55
- version: '1.0'
56
- slice: validation
57
  sample_count: 50000
58
- reference_url: https://image-net.org
59
  benchmark:
60
  batch_size: 1
61
  input_resolution: 224x224
62
- num_runs: 1 # PLACEHOLDER — not surfaced by Marvik pipeline; schema requires this field
 
63
  performance:
64
  end_to_end_latency_ms:
65
- p50: 34.54
66
- p90: 34.67
67
- peak_memory_mb: 33.58
68
- average_memory_mb: 31.08
69
- cold_start_time_ms: 52.39
 
70
  accuracy:
71
- top_1_accuracy_pct: 68.96
72
- top_5_accuracy_pct: 89.17
 
2
  # Pairs with `deit-tiny-raspberrypi5-int8.yaml` to demonstrate the
3
  # baseline-comparison join documented in `docs/header-and-generic.md`.
4
  #
5
+ # Source: Marvik delivery package `deit_raspberry_executorch_v2.zip`,
6
+ # `report.json` `original` fields (the un-quantised baseline measured under
7
+ # identical target / runtime / dataset / benchmark conditions to the
8
+ # optimised record). Refreshed from v1 after a preprocessing fix on Marvik's
9
+ # side (bicubic + ImageNet mean/std, replacing bilinear + 0.5/0.5) restored
10
+ # the FP32 baseline to the paper-reported ~72.13% Top-1.
11
  #
12
  # Same target / runtime / dataset / benchmark as the INT8 record —
13
  # disambiguator is `weight_dtype`, and (once published) `model.id`.
14
  #
15
+ # Hand-curated rather than redelivered: Marvik's pipeline only emits the
16
+ # optimised YAML, so this file is reconstructed from `report.json` on each
17
+ # refresh. Inline annotations here are durable.
18
+ #
19
+ # Outstanding unknowns:
20
+ # - context.runtime.config.n_threads — in flight, Marvik working on it (2026-05)
21
+ # - performance.end_to_end_latency_ms.p99 — in flight, Marvik working on it (2026-05)
22
+ # - context.model.baseline_checksum — optional; not yet surfaced, no ETA
23
  # - context.model.base_model_revision — not yet a schema field; pinning
24
  # this artefact to a HF revision SHA
25
  # would close the last reproducibility
26
  # gap on the baseline.
 
27
 
28
  version: 1.0.0
29
  task: vision-classification
30
+ created_at: '2026-05-04T16:01:20Z'
31
  context:
32
  model:
33
  id: facebook/deit-tiny-patch16-224
 
46
  cpu_clock_ghz: 2.4
47
  system_memory_gb: 8
48
  os: linux
49
+ os_version: Raspberry Pi OS
50
  runtime:
51
  name: executorch
52
  execution_backend: cpu
53
+ version: 1.1.0
54
  config:
55
  optimisations:
56
+ - XNNPACK
57
+ - KleidiAI
58
  dataset:
59
+ name: ImageNet-1k
60
+ slice: val
 
61
  sample_count: 50000
62
+ reference_url: https://www.image-net.org/
63
  benchmark:
64
  batch_size: 1
65
  input_resolution: 224x224
66
+ num_runs: 100
67
+ warmup_runs: 10
68
  performance:
69
  end_to_end_latency_ms:
70
+ p50: 35.34
71
+ p90: 35.48
72
+ peak_memory_mb: 31.156
73
+ average_memory_mb: 31.016
74
+ cold_start_time_ms: 56.41
75
+ model_load_time_ms: 19.27
76
  accuracy:
77
+ top_1_accuracy_pct: 72.132
78
+ top_5_accuracy_pct: 91.134
benchmarks/deit-tiny-raspberrypi5-int8.yaml CHANGED
@@ -1,34 +1,12 @@
1
- # Real measurement record — DeiT-Tiny INT8 on Raspberry Pi 5 via ExecuTorch + XNNPACK.
2
- # Source: Marvik delivery package `deit_raspberry_executorch.zip`, files
3
- # - report.json (machine-readable metrics)
4
- # - metadata.yaml (Marvik's portal metadata, now superseded by these schemas)
5
- # - huggingface/README.md (recipe prose)
6
- #
7
- # Known unknowns (Marvik pipeline does not currently surface these):
8
- # - context.benchmark.num_runs — required by schema; placeholder used
9
- # - context.benchmark.warmup_runs — optional
10
- # - context.runtime.version — optional but worth recording
11
- # - context.target.os_version — optional
12
- # - context.runtime.config.n_threads — optional
13
- # - context.model.baseline_checksum — optional
14
- # - performance.end_to_end_latency_ms.p99 — optional; only p50/p90 reported
15
- #
16
- # Mapping notes:
17
- # - cold_start_time_ms holds Marvik's "Time To First Inference" (37.39 ms — process
18
- # start to first output completing). Marvik separately reports "Cold Start" (21.84 ms,
19
- # process startup before any inference); this is not a separate schema field.
20
- # - base_model_id and id are identical here because the artefact is not yet uploaded
21
- # under arm/<slug>. Once published, id becomes the arm/* identifier and base_model_id
22
- # remains facebook/deit-tiny-patch16-224.
23
-
24
  version: 1.0.0
25
  task: vision-classification
26
- created_at: '2026-04-22T22:43:46Z'
27
  context:
28
  model:
29
  id: facebook/deit-tiny-patch16-224
30
  base_model_id: facebook/deit-tiny-patch16-224
31
  weight_dtype: int8
 
32
  quantization:
33
  method: PTQ-static
34
  weight_bits: 8
@@ -37,12 +15,11 @@ context:
37
  mode: static
38
  weight_granularity: per-channel
39
  fp32_layers:
40
- - patch_embeddings
41
  calibration:
42
- dataset_name: imagenet-1k
43
  sample_count: 1000
44
  selection: random
45
- profile: Arm-Optimized
46
  model_size_mb: 6.62
47
  parameter_count: 5717416
48
  format: pte
@@ -55,32 +32,35 @@ context:
55
  cpu_clock_ghz: 2.4
56
  system_memory_gb: 8
57
  os: linux
 
58
  runtime:
59
  name: executorch
60
  execution_backend: cpu
 
61
  config:
62
  optimisations:
63
- - XNNPACK
64
- - KleidiAI
65
  dataset:
66
- name: imagenet-1k
67
- version: '1.0'
68
- slice: validation
69
  sample_count: 50000
70
- reference_url: https://image-net.org
71
  benchmark:
72
  batch_size: 1
73
  input_resolution: 224x224
74
- num_runs: 1 # PLACEHOLDER — not surfaced by Marvik pipeline; schema requires this field
 
75
  performance:
76
  end_to_end_latency_ms:
77
- p50: 25.65
78
- p90: 25.84
79
- peak_memory_mb: 18.47
80
- delegation_pct: 63.81
81
- average_memory_mb: 16.21
82
- cold_start_time_ms: 37.39
83
- frames_per_second: 38.90
 
84
  accuracy:
85
- top_1_accuracy_pct: 67.62
86
- top_5_accuracy_pct: 88.48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  version: 1.0.0
2
  task: vision-classification
3
+ created_at: '2026-05-04T16:01:20Z'
4
  context:
5
  model:
6
  id: facebook/deit-tiny-patch16-224
7
  base_model_id: facebook/deit-tiny-patch16-224
8
  weight_dtype: int8
9
+ profile: Arm-Optimized
10
  quantization:
11
  method: PTQ-static
12
  weight_bits: 8
 
15
  mode: static
16
  weight_granularity: per-channel
17
  fp32_layers:
18
+ - patch_embeddings
19
  calibration:
20
+ dataset_name: ImageNet-1k
21
  sample_count: 1000
22
  selection: random
 
23
  model_size_mb: 6.62
24
  parameter_count: 5717416
25
  format: pte
 
32
  cpu_clock_ghz: 2.4
33
  system_memory_gb: 8
34
  os: linux
35
+ os_version: Raspberry Pi OS
36
  runtime:
37
  name: executorch
38
  execution_backend: cpu
39
+ version: 1.1.0
40
  config:
41
  optimisations:
42
+ - XNNPACK
43
+ - KleidiAI
44
  dataset:
45
+ name: ImageNet-1k
46
+ slice: val
 
47
  sample_count: 50000
48
+ reference_url: https://www.image-net.org/
49
  benchmark:
50
  batch_size: 1
51
  input_resolution: 224x224
52
+ num_runs: 100
53
+ warmup_runs: 10
54
  performance:
55
  end_to_end_latency_ms:
56
+ p50: 26.40
57
+ p90: 26.60
58
+ peak_memory_mb: 18.375
59
+ delegation_pct: 64.02
60
+ average_memory_mb: 16.14
61
+ cold_start_time_ms: 40.64
62
+ model_load_time_ms: 22.71
63
+ frames_per_second: 37.78
64
  accuracy:
65
+ top_1_accuracy_pct: 71.356
66
+ top_5_accuracy_pct: 90.738
config.yaml CHANGED
@@ -3,9 +3,9 @@ input:
3
  dtype: float32
4
  range: [0.0, 1.0]
5
  preprocessing:
6
- - resize: 256
7
  - center_crop: [224, 224]
8
- - to_tensor
9
  - normalize:
10
  mean: [0.485, 0.456, 0.406]
11
  std: [0.229, 0.224, 0.225]
 
3
  dtype: float32
4
  range: [0.0, 1.0]
5
  preprocessing:
6
+ - resize: 256 # bicubic interpolation (shortest edge)
7
  - center_crop: [224, 224]
8
+ - to_tensor # [0-255] uint8 -> [0.0, 1.0] float32
9
  - normalize:
10
  mean: [0.485, 0.456, 0.406]
11
  std: [0.229, 0.224, 0.225]
deit_raspberry_executorch_optimized.pte CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:c749ec3bb0ffabdf4b0364ef6020b28e5b4ea3897706a45f7fff24d571890205
3
  size 6941472
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4656bb08f25ceafd3945debd69d27fd4cbeff5b9be04828e6d057f1c24fcc0d0
3
  size 6941472
deit_raspberry_executorch_original.pte ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a2f06e1355d83b6d38c11bd7423cdd847e17a7c36b6d41128a1613ef347dc2cc
3
+ size 23073184
example.py CHANGED
@@ -1,4 +1,8 @@
1
- """Minimal inference example for DeiT-Tiny INT8 using ExecuTorch."""
 
 
 
 
2
 
3
  import json
4
  from pathlib import Path
@@ -8,75 +12,103 @@ from executorch.runtime import Runtime
8
  from PIL import Image
9
  from torchvision import transforms
10
 
11
- # Configuration
12
- MODEL_PATH = "deit_raspberry_executorch_optimized.pte"
 
13
  IMAGE_PATH = "sample_input.jpg"
14
  INPUT_SIZE = (224, 224)
 
15
  MEAN = [0.485, 0.456, 0.406]
16
  STD = [0.229, 0.224, 0.225]
17
  TOP_K = 5
18
 
19
 
 
20
  def load_model(pte_path: str):
 
21
  runtime = Runtime.get()
22
  program = runtime.load_program(pte_path)
23
  return program.load_method("forward")
24
 
25
 
 
26
  def preprocess(image_path: str) -> torch.Tensor:
27
- transform = transforms.Compose([
28
- transforms.Resize(256),
29
- transforms.CenterCrop(INPUT_SIZE),
30
- transforms.ToTensor(),
31
- transforms.Normalize(mean=MEAN, std=STD),
32
- ])
 
 
 
 
 
 
 
 
 
 
 
 
33
  image = Image.open(image_path).convert("RGB")
34
  tensor = transform(image)
35
- return tensor.unsqueeze(0)
36
 
37
 
 
38
  def run_inference(method, input_tensor: torch.Tensor) -> torch.Tensor:
 
39
  outputs = method.execute([input_tensor])
40
  return outputs[0]
41
 
42
 
 
43
  def postprocess(raw_output: torch.Tensor, labels: dict) -> list[dict]:
44
- logits = raw_output.squeeze(0)
 
 
 
 
 
45
  probabilities = torch.softmax(logits, dim=-1)
46
  top_probs, top_indices = torch.topk(probabilities, TOP_K)
47
- results = []
48
- for prob, idx in zip(top_probs.tolist(), top_indices.tolist()):
49
- results.append({
50
- "class": labels[str(idx)],
51
- "probability": prob,
52
- })
53
- return results
54
 
55
 
 
56
  def save_results(results: list[dict], script_dir: Path) -> None:
 
57
  output_path = script_dir / "predictions.json"
58
  with open(output_path, "w") as f:
59
  json.dump(results, f, indent=2)
 
60
 
61
 
 
62
  def main() -> None:
63
  script_dir = Path(__file__).parent
64
 
 
65
  labels_path = script_dir / "imagenet_classes.json"
66
  with open(labels_path) as f:
67
  labels = json.load(f)
68
 
 
69
  method = load_model(str(script_dir / MODEL_PATH))
70
  input_tensor = preprocess(str(script_dir / IMAGE_PATH))
71
  raw_output = run_inference(method, input_tensor)
72
  results = postprocess(raw_output, labels)
73
 
74
- print("Top-5 predictions:")
 
75
  for i, r in enumerate(results, 1):
76
- print(f" {i}. {r['class']} ({r['probability'] * 100:.1f}%)")
77
 
78
  save_results(results, script_dir)
79
- print(f"Saved predictions.json to {script_dir / 'predictions.json'}")
80
 
81
 
82
  if __name__ == "__main__":
 
1
+ """Minimal inference example for DeiT-Tiny INT8 using ExecuTorch.
2
+
3
+ Loads a quantized .pte model and runs inference on a single image,
4
+ printing the top-5 ImageNet class predictions with probabilities.
5
+ """
6
 
7
  import json
8
  from pathlib import Path
 
12
  from PIL import Image
13
  from torchvision import transforms
14
 
15
+
16
+ # ── Configuration ──────────────────────────────────────────────────────────────
17
+ MODEL_PATH = "optimized.pte"
18
  IMAGE_PATH = "sample_input.jpg"
19
  INPUT_SIZE = (224, 224)
20
+ RESIZE_SIZE = 256 # resize shorter edge before center crop
21
  MEAN = [0.485, 0.456, 0.406]
22
  STD = [0.229, 0.224, 0.225]
23
  TOP_K = 5
24
 
25
 
26
+ # ── Model Loading ──────────────────────────────────────────────────────────────
27
  def load_model(pte_path: str):
28
+ """Load ExecuTorch .pte model and return the forward method."""
29
  runtime = Runtime.get()
30
  program = runtime.load_program(pte_path)
31
  return program.load_method("forward")
32
 
33
 
34
+ # ── Preprocessing ──────────────────────────────────────────────────────────────
35
  def preprocess(image_path: str) -> torch.Tensor:
36
+ """Load and preprocess image for model input.
37
+
38
+ Pipeline:
39
+ 1. Resize shortest edge to 256 px (bicubic)
40
+ 2. Center-crop to 224x224
41
+ 3. Convert to float32 tensor in [0, 1]
42
+ 4. Normalize with ImageNet mean/std
43
+ """
44
+ transform = transforms.Compose(
45
+ [
46
+ transforms.Resize(
47
+ RESIZE_SIZE, interpolation=transforms.InterpolationMode.BICUBIC
48
+ ),
49
+ transforms.CenterCrop(INPUT_SIZE),
50
+ transforms.ToTensor(),
51
+ transforms.Normalize(mean=MEAN, std=STD),
52
+ ]
53
+ )
54
  image = Image.open(image_path).convert("RGB")
55
  tensor = transform(image)
56
+ return tensor.unsqueeze(0) # [1, 3, 224, 224]
57
 
58
 
59
+ # ── Inference ──────────────────────────────────────────────────────────────────
60
  def run_inference(method, input_tensor: torch.Tensor) -> torch.Tensor:
61
+ """Run forward pass and return the raw logits tensor."""
62
  outputs = method.execute([input_tensor])
63
  return outputs[0]
64
 
65
 
66
+ # ── Postprocessing ─────────────────────────────────────────────────────────────
67
  def postprocess(raw_output: torch.Tensor, labels: dict) -> list[dict]:
68
+ """Convert raw logits to top-k class predictions.
69
+
70
+ Applies softmax over the 1000-class logit vector, then returns the
71
+ top-k (class name, probability) pairs sorted by descending probability.
72
+ """
73
+ logits = raw_output.squeeze(0) # [1000]
74
  probabilities = torch.softmax(logits, dim=-1)
75
  top_probs, top_indices = torch.topk(probabilities, TOP_K)
76
+ return [
77
+ {"class": labels[str(idx.item())], "probability": round(prob.item(), 6)}
78
+ for prob, idx in zip(top_probs, top_indices, strict=False)
79
+ ]
 
 
 
80
 
81
 
82
+ # ── Save Results ───────────────────────────────────────────────────────────────
83
  def save_results(results: list[dict], script_dir: Path) -> None:
84
+ """Save top-k predictions to predictions.json in the script's directory."""
85
  output_path = script_dir / "predictions.json"
86
  with open(output_path, "w") as f:
87
  json.dump(results, f, indent=2)
88
+ print(f"Saved predictions to {output_path}")
89
 
90
 
91
+ # ── Main ───────────────────────────────────────────────────────────────────────
92
  def main() -> None:
93
  script_dir = Path(__file__).parent
94
 
95
+ # Load ImageNet class labels
96
  labels_path = script_dir / "imagenet_classes.json"
97
  with open(labels_path) as f:
98
  labels = json.load(f)
99
 
100
+ # Load model, run inference, decode results
101
  method = load_model(str(script_dir / MODEL_PATH))
102
  input_tensor = preprocess(str(script_dir / IMAGE_PATH))
103
  raw_output = run_inference(method, input_tensor)
104
  results = postprocess(raw_output, labels)
105
 
106
+ # Print top-k predictions
107
+ print(f"Top-{TOP_K} predictions:")
108
  for i, r in enumerate(results, 1):
109
+ print(f" {i}. {r['class']} ({r['probability'] * 100:.2f}%)")
110
 
111
  save_results(results, script_dir)
 
112
 
113
 
114
  if __name__ == "__main__":
metadata.yaml ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AI Portal Model Discovery Metadata
2
+ # Generated by ARM Model Optimization Pipeline
3
+ # Commented fields require manual input.
4
+
5
+ hardware:
6
+ # device: <hardware platform, e.g. Raspberry Pi, Graviton>
7
+ # arm_ip: <Arm IP, e.g. SME, NGP>
8
+ # classification: <Mobile, IoT, Server, GPU>
9
+ # mlia_profile: <MLIA configuration for the hardware>
10
+ # memory: <available memory on device, e.g. 4GB>
11
+
12
+ model_metadata:
13
+ origin: "https://huggingface.co/facebook/deit-tiny-patch16-224"
14
+ name: "Deit Tiny Patch16 224"
15
+ organisation: "Meta"
16
+ display_name: "facebook/deit-tiny-patch16-224"
17
+ filepath: "optimized.pte"
18
+ model_use_case: "Vision"
19
+ model_runtime: "ExecuTorch"
20
+ library: "transformers"
21
+ model_size: 6619903
22
+ vendor: "Meta"
23
+ precision: "INT8"
24
+ model_framework: "PyTorch"
25
+ base_model_relationship: "Quantised"
26
+ training_dataset: "ImageNet-1K"
27
+ training_dataset_license: "ImageNet Terms of Access"
28
+ # base_model: <base model this artefact is derived from>
29
+ # license: <SPDX ID, e.g. Apache-2.0>
30
+ # license_url: <URL to license if non-standard>
31
+ # deployment_license: <SPDX ID for production deployment>
32
+ # language: <supported language(s)>
33
+ # short_description: <summary for UI grid>
34
+ # long_description: <full model description>
35
+
36
+ model_performance:
37
+ analyser_type: "Hardware"
38
+ device: "Raspberry Pi"
39
+ compatible: true
40
+ # device: <hardware profile used during testing>
41
+ # analyser: <tool used to analyse the model>
42
+ # average_cpu_utilisation: <CPU utilisation % during inference>
43
+ # tosa_compliance: <TOSA compliance score>
44
+ # energy: <energy consumption in W>
45
+
46
+ latency:
47
+ # single_inference_latency: <latency in ms>
48
+ # single_inference_throughput: <throughput in inf/s>
49
+ # batch_size: <batch size used in analysis>
50
+ # batch_latency: <batch inference latency in ms>
51
+ # batch_throughput: <batch throughput in inf/s>
52
+ # max_throughput_batch_size: <batch size achieving peak throughput>
53
+ # max_throughput_latency: <latency at max throughput in ms>
54
+ # max_throughput: <maximum throughput in inf/s>
55
+ # sustained_batch_size: <batch size under sustained load>
56
+ # sustained_batch_latency: <latency under sustained load in ms>
57
+ # sustained_batch_throughput: <sustained throughput in inf/s>
58
+
59
+ memory:
60
+ model_weight_memory: 6.62
61
+ # runtime_overhead: <runtime memory overhead in MB>
62
+ # runtime_overhead_power: <runtime power usage in W>
63
+ # peak_activation_memory: <peak activation memory in MB>
64
+ # peak_activation_power: <peak power usage in W>
65
+ # idle_state_memory: <memory usage when idle in MB>
66
+ # idle_state_power: <power usage when idle in W>
67
+ # average_memory: <average runtime memory in MB>
68
+ # average_power: <average runtime power in W>
69
+
70
+ model_accuracy:
71
+ - name: "ImageNet"
72
+ url: "https://image-net.org"
73
+ value: 71.36
74
+ evaluation_criteria: "Top-1 Accuracy"
75
+ base_accuracy: 72.13
76
+ - name: "ImageNet"
77
+ url: "https://image-net.org"
78
+ value: 90.74
79
+ evaluation_criteria: "Top-5 Accuracy"
80
+ base_accuracy: 91.13
predictions.json CHANGED
@@ -1,22 +1,22 @@
1
  [
2
  {
3
- "class": "sea slug, nudibranch",
4
- "probability": 0.17416588962078094
5
  },
6
  {
7
- "class": "goldfish, Carassius auratus",
8
- "probability": 0.17416588962078094
9
  },
10
  {
11
- "class": "flatworm, platyhelminth",
12
- "probability": 0.10024614632129669
13
  },
14
  {
15
- "class": "conch",
16
- "probability": 0.041422367095947266
17
  },
18
  {
19
- "class": "hammerhead, hammerhead shark",
20
- "probability": 0.032009851187467575
21
  }
22
  ]
 
1
  [
2
  {
3
+ "class": "vault",
4
+ "probability": 0.686802
5
  },
6
  {
7
+ "class": "altar",
8
+ "probability": 0.027809
9
  },
10
  {
11
+ "class": "monastery",
12
+ "probability": 0.026528
13
  },
14
  {
15
+ "class": "church, church building",
16
+ "probability": 0.026528
17
  },
18
  {
19
+ "class": "dome",
20
+ "probability": 0.010829
21
  }
22
  ]
sample_input.jpg CHANGED

Git LFS Details

  • SHA256: 89563b713c0e2fae30e1dbf83f9b2f874f5b4adc49689032924b444510b2ec50
  • Pointer size: 131 Bytes
  • Size of remote file: 104 kB