Add device-validated Vulkan FP16 and FP32 variants
Browse files- .gitattributes +2 -0
- README.md +15 -1
- vulkan/NOTES.md +91 -0
- vulkan/config.json +74 -0
- vulkan/u2netp_vulkan_fp16.pte +3 -0
- vulkan/u2netp_vulkan_fp32.pte +3 -0
.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.
|
| 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
|