bhanc commited on
Commit
e9fbad5
·
verified ·
1 Parent(s): f07a9d0

Add device-validated Vulkan FP16 and FP32 variants

Browse files
.gitattributes CHANGED
@@ -37,3 +37,5 @@ coreml/u2netp_coreml_fp16.pte filter=lfs diff=lfs merge=lfs -text
37
  coreml/u2netp_coreml_fp32.pte filter=lfs diff=lfs merge=lfs -text
38
  xnnpack/u2netp_xnnpack_fp32.pte filter=lfs diff=lfs merge=lfs -text
39
  xnnpack/u2netp_xnnpack_int8.pte filter=lfs diff=lfs merge=lfs -text
 
 
 
37
  coreml/u2netp_coreml_fp32.pte filter=lfs diff=lfs merge=lfs -text
38
  xnnpack/u2netp_xnnpack_fp32.pte filter=lfs diff=lfs merge=lfs -text
39
  xnnpack/u2netp_xnnpack_int8.pte filter=lfs diff=lfs merge=lfs -text
40
+ vulkan/u2netp_vulkan_fp16.pte filter=lfs diff=lfs merge=lfs -text
41
+ vulkan/u2netp_vulkan_fp32.pte filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -25,6 +25,8 @@ revision `ac7e1c817ecab7c7dff5ce6b1abba61cd213ff29`.
25
  | `coreml/u2netp_coreml_fp32.pte` | coreml | fp32 |
26
  | `xnnpack/u2netp_xnnpack_fp32.pte` | xnnpack | fp32 |
27
  | `xnnpack/u2netp_xnnpack_int8.pte` | xnnpack | selective int8 / fp32 |
 
 
28
 
29
  The exports take RGB float32 `[1,3,320,320]` input in `[0,1]` and return one
30
  float32 `[1,1,320,320]` foreground logit map. Image-maximum scaling and ImageNet
@@ -50,6 +52,14 @@ Full-network INT8 remains unpublished because it loses substantial foreground
50
  detail. See [XNNPACK precision notes](xnnpack/NOTES.md) for the selective recipe,
51
  calibration, validation and rejected alternatives.
52
 
 
 
 
 
 
 
 
 
53
  ## Repository structure
54
 
55
  ```
@@ -57,8 +67,12 @@ config.json 28 B
57
  coreml/config.json 1.5 kB
58
  coreml/u2netp_coreml_fp16.pte 3.3 MB
59
  coreml/u2netp_coreml_fp32.pte 5.5 MB
 
 
 
 
60
  xnnpack/config.json 1.5 kB
61
- xnnpack/NOTES.md 6.5 kB
62
  xnnpack/u2netp_xnnpack_fp32.pte 4.6 MB
63
  xnnpack/u2netp_xnnpack_int8.pte 4.0 MB
64
  LICENSE 11.4 kB
 
25
  | `coreml/u2netp_coreml_fp32.pte` | coreml | fp32 |
26
  | `xnnpack/u2netp_xnnpack_fp32.pte` | xnnpack | fp32 |
27
  | `xnnpack/u2netp_xnnpack_int8.pte` | xnnpack | selective int8 / fp32 |
28
+ | `vulkan/u2netp_vulkan_fp16.pte` | vulkan | fp16 with one fp32 convolution |
29
+ | `vulkan/u2netp_vulkan_fp32.pte` | vulkan | fp32 |
30
 
31
  The exports take RGB float32 `[1,3,320,320]` input in `[0,1]` and return one
32
  float32 `[1,1,320,320]` foreground logit map. Image-maximum scaling and ImageNet
 
52
  detail. See [XNNPACK precision notes](xnnpack/NOTES.md) for the selective recipe,
53
  calibration, validation and rejected alternatives.
54
 
55
+ Vulkan FP16 preserves input normalization and one sensitive convolution in FP32.
56
+ On a Galaxy S20+ (Android 13, Mali), native forward medians were 337 ms for this
57
+ variant and 403 ms for Vulkan FP32, versus 316 ms for XNNPACK FP32 and 189 ms
58
+ for selective INT8. Vulkan is optional; Android retains its XNNPACK FP32
59
+ default. Across 13 device-tested images, Vulkan FP16 averaged 0.9945 mask IoU
60
+ against FP32 (minimum 0.9854). See [Vulkan precision notes](vulkan/NOTES.md)
61
+ for the export recipe, phone validation and timing limitations.
62
+
63
  ## Repository structure
64
 
65
  ```
 
67
  coreml/config.json 1.5 kB
68
  coreml/u2netp_coreml_fp16.pte 3.3 MB
69
  coreml/u2netp_coreml_fp32.pte 5.5 MB
70
+ vulkan/config.json 1.5 kB
71
+ vulkan/NOTES.md 4.2 kB
72
+ vulkan/u2netp_vulkan_fp16.pte 2.4 MB
73
+ vulkan/u2netp_vulkan_fp32.pte 4.6 MB
74
  xnnpack/config.json 1.5 kB
75
+ xnnpack/NOTES.md 6.6 kB
76
  xnnpack/u2netp_xnnpack_fp32.pte 4.6 MB
77
  xnnpack/u2netp_xnnpack_int8.pte 4.0 MB
78
  LICENSE 11.4 kB
vulkan/NOTES.md ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Vulkan precision and Android validation
2
+
3
+ Both variants accept RGB float32 `[1,3,320,320]` in `[0,1]` and return float32
4
+ `[1,1,320,320]` foreground logits. Input normalization stays in FP32. Each
5
+ export contains one Vulkan delegate for the network and one portable input
6
+ `amax` reduction. Texture limits are capped at 2048 in each dimension.
7
+
8
+ ## FP16 with a sensitive FP32 convolution
9
+
10
+ The FP16 export fuses Conv/BatchNorm pairs before casting the network to half.
11
+ `stage2d.rebnconv1d.conv_s1` retains FP32 weights, bias and computation, with
12
+ casts around it inside the Vulkan delegate. Global `force_fp16` is deliberately
13
+ not used: it would also downcast this convolution and input normalization.
14
+
15
+ On the connected Galaxy S20+, an entirely FP16 export changed the bicycle mask
16
+ to 0.9418 IoU against XNNPACK FP32. Keeping this convolution in FP32 recovered
17
+ 0.9932 IoU. The entirely FP16 candidate is not published.
18
+
19
+ ## Device checks
20
+
21
+ Validation used Samsung Galaxy S20+ SM-G986B, Android 13, Mali GPU, arm64-v8a,
22
+ and the ExecuTorch 1.4.1 runtime/backend libraries shipped with RNE. A native
23
+ runner linked these exact libraries, loaded each actual `.pte`, checked float32
24
+ output type and element count, rejected non-finite output, and saved logits.
25
+ Exported method metadata was also checked against the config.
26
+
27
+ The comparison set is the same 13 images used for selective XNNPACK INT8
28
+ validation: `bike.jpg`, `boat.jpg`, `whisk.png`, plus COCO val2017 image IDs 139,
29
+ 285, 632, 724, 776, 785, 802, 872, 885 and 1000. All-black and all-white inputs
30
+ were also checked. These are agreement measurements against the shipped
31
+ XNNPACK FP32 `.pte`, not ground-truth segmentation accuracy.
32
+
33
+ | Variant | Mean mask IoU (13 images) | Minimum mask IoU | File size |
34
+ | --- | --- | --- | --- |
35
+ | Vulkan FP16 with one FP32 convolution | 0.9945 | 0.9854 | 2,437,516 B |
36
+ | Vulkan FP32 | 0.999999 | 0.999986 | 4,646,540 B |
37
+
38
+ The FP16 probability MAE was at most 0.00444 across those 13 images. Both
39
+ variants produced finite outputs on all 15 inputs.
40
+
41
+ Warm native forward measurements on the same bicycle input used three warm-up
42
+ runs followed by ten measured runs per variant:
43
+
44
+ | Variant | Median |
45
+ | --- | --- |
46
+ | XNNPACK FP32 | 315.6 ms |
47
+ | XNNPACK selective INT8 | 189.1 ms |
48
+ | Vulkan FP16 with one FP32 convolution | 337.2 ms |
49
+ | Vulkan FP32 | 403.1 ms |
50
+
51
+ These were sequential host-driven device checks, not interleaved benchmarks;
52
+ they exclude model loading, image preprocessing and rendering. Vulkan does not
53
+ win on this older Mali GPU. Android retains its existing XNNPACK FP32 default;
54
+ select INT8 for the faster CPU option. Performance on other GPUs must be
55
+ measured separately. A trial with only four half-precision convolutions was
56
+ also slower (421.9 ms) and is not published.
57
+
58
+ ## Reproducing the export environment
59
+
60
+ The Vulkan AOT implementation is pinned to software-mansion-labs/executorch
61
+ `@ms/separate-backends-1.4.1`, commit
62
+ `0de5ce9470e4a18d6d45585f69519267bbe218b9`. Torch is 2.14.0. The nested
63
+ `pyproject.toml` records the fork dependency; see the repository Vulkan skill
64
+ for the source-built environment used by other Vulkan models.
65
+
66
+ For AOT-only export, a compatible ExecuTorch 1.4.1 wheel can provide the common
67
+ serialization binaries while the fork supplies its Vulkan Python package.
68
+ No host GPU runtime is needed; Android validation still uses the shipped native
69
+ Vulkan library. Clone the fork into a directory named `executorch`, check out
70
+ the commit above, then from export-scripts run:
71
+
72
+ ```bash
73
+ uv run --project exporter_models/u2netp python - /path/to/executorch <<'PY'
74
+ import runpy
75
+ import sys
76
+ from pathlib import Path
77
+ import executorch.backends
78
+
79
+ fork = Path(sys.argv[1]).resolve()
80
+ executorch.backends.__path__.insert(0, str(fork / "backends"))
81
+ sys.argv = [
82
+ "exporter", "export", "u2netp", "--backend", "vulkan", "--all-variants",
83
+ "--output-dir", "exports/u2netp/vulkan",
84
+ ]
85
+ runpy.run_module("exporter.cli", run_name="__main__")
86
+ PY
87
+ ```
88
+
89
+ The release exports were byte-identical to the device-validated candidates.
90
+ The Python wheel's native runtime cannot execute Vulkan on this Mac; it was
91
+ not used as a substitute for phone validation.
vulkan/config.json ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "https://huggingface.co/software-mansion/react-native-executorch-spec/resolve/main/config.schema.json",
3
+ "model": "u2netp",
4
+ "family": "u2net",
5
+ "capabilities": [
6
+ "semantic-segmentation"
7
+ ],
8
+ "backend": "vulkan",
9
+ "license": "apache-2.0",
10
+ "variants": [
11
+ {
12
+ "file": "u2netp_vulkan_fp16.pte",
13
+ "precision": "fp16",
14
+ "methods": {
15
+ "forward": {
16
+ "inputs": [
17
+ {
18
+ "shape": [
19
+ 1,
20
+ 3,
21
+ 320,
22
+ 320
23
+ ],
24
+ "dtype": "float32"
25
+ }
26
+ ],
27
+ "outputs": [
28
+ {
29
+ "shape": [
30
+ 1,
31
+ 1,
32
+ 320,
33
+ 320
34
+ ],
35
+ "dtype": "float32"
36
+ }
37
+ ]
38
+ }
39
+ },
40
+ "size_bytes": 2437516
41
+ },
42
+ {
43
+ "file": "u2netp_vulkan_fp32.pte",
44
+ "precision": "fp32",
45
+ "methods": {
46
+ "forward": {
47
+ "inputs": [
48
+ {
49
+ "shape": [
50
+ 1,
51
+ 3,
52
+ 320,
53
+ 320
54
+ ],
55
+ "dtype": "float32"
56
+ }
57
+ ],
58
+ "outputs": [
59
+ {
60
+ "shape": [
61
+ 1,
62
+ 1,
63
+ 320,
64
+ 320
65
+ ],
66
+ "dtype": "float32"
67
+ }
68
+ ]
69
+ }
70
+ },
71
+ "size_bytes": 4646540
72
+ }
73
+ ]
74
+ }
vulkan/u2netp_vulkan_fp16.pte ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3c7c5697f204072f4d37269438a79578bb2893bf4cf0c1ebd871d9b20165793c
3
+ size 2437516
vulkan/u2netp_vulkan_fp32.pte ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:88523d0b54ec20e9129194f110955cbc6d2f5d90b2293c9a712636fb5d255212
3
+ size 4646540