alexludens commited on
Commit
4a3c40c
Β·
verified Β·
1 Parent(s): 18d56c5

Improve discoverability: expanded tags, datasets, quickstart + comparison table

Browse files
Files changed (1) hide show
  1. README.md +58 -49
README.md CHANGED
@@ -2,24 +2,59 @@
2
  license: mit
3
  library_name: transformers.js
4
  pipeline_tag: image-segmentation
 
 
 
 
5
  tags:
6
  - background-removal
7
  - matting
8
  - onnx
9
  - webgpu
10
  - birefnet
11
- base_model: ZhengPeng7/BiRefNet_lite
 
 
 
 
 
 
 
12
  ---
13
 
14
  # BiRefNet_lite 512Γ—512 (browser-ready ONNX)
15
 
16
- An ONNX re-export of [ZhengPeng7/BiRefNet_lite](https://huggingface.co/ZhengPeng7/BiRefNet_lite) at **512Γ—512** input resolution, packaged for in-browser inference with [`@huggingface/transformers`](https://huggingface.co/docs/transformers.js). Works on both WebGPU and WASM backends in modern browsers.
17
 
18
- Used in production by [Repper](https://repper.app) for matte refinement on per-motif crops during foreground extraction.
19
 
20
- ## Why this exists
21
 
22
- The upstream **1024Γ—1024** BiRefNet_lite ONNX (including the pre-existing `onnx-community/BiRefNet_lite-ONNX` re-export) does not load in any browser backend. Every combination we tried OOM'd at inference time:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
  | Backend | Variant | Failure |
25
  |---------|---------|---------|
@@ -28,11 +63,11 @@ The upstream **1024Γ—1024** BiRefNet_lite ONNX (including the pre-existing `onnx
28
  | WASM | fp32, cascaded | `std::bad_alloc` during `OrtRun` |
29
  | WASM | fp32, original | `std::bad_alloc` during `OrtRun` |
30
 
31
- **Root cause:** BiRefNet_lite's decoder produces very large intermediate tensors at 1024Γ—1024 (multi-scale feature maps with 1024-way concatenations). The WASM heap in the compiled `onnxruntime-web` binary is hardcoded at ~2–4 GB and cannot be raised at runtime, so the peak working-set exceeds available memory regardless of backend or precision.
32
 
33
- Reducing the input resolution to **512Γ—512** shrinks the intermediate tensors by 4Γ— and brings the peak well under the heap limit. At 512Γ—512 the graph also naturally uses **max 7 storage buffers per shader stage**, comfortably inside WebGPU's `maxStorageBuffersPerShaderStage` limit (10 on older Apple Silicon adapters, 16 on Chrome β‰₯146), so no graph surgery is needed either.
34
 
35
- For crop-level matte refinement this is a fair trade: the crop is already small, and edge quality on matching-resolution crops is indistinguishable from the 1024 reference in our tests.
36
 
37
  ## Variants
38
 
@@ -46,28 +81,10 @@ For crop-level matte refinement this is a fair trade: the crop is already small,
46
  ## Input / output
47
 
48
  - **Input:** RGB image, resized to **512Γ—512**, ImageNet normalization (`mean = [0.485, 0.456, 0.406]`, `std = [0.229, 0.224, 0.225]`), rescale factor `1/255`. Layout `NCHW`, input tensor name `input_image`.
49
- - **Output:** Single-channel logits at 512Γ—512. **Apply `sigmoid` externally** to get the alpha matte in `[0, 1]`. Resize back to the original image dimensions with bilinear interpolation.
50
 
51
  The `preprocessor_config.json` uses `ViTFeatureExtractor`, so `AutoProcessor.from_pretrained(...)` works out of the box.
52
 
53
- ## Usage (transformers.js, WebGPU)
54
-
55
- ```ts
56
- import { AutoModel, AutoProcessor, RawImage } from '@huggingface/transformers';
57
-
58
- const model = await AutoModel.from_pretrained('studioludens/birefnet-lite-512', {
59
- dtype: 'fp16', // or 'fp32'
60
- device: 'webgpu', // falls back to 'wasm' on unsupported hardware
61
- });
62
- const processor = await AutoProcessor.from_pretrained('studioludens/birefnet-lite-512');
63
-
64
- const image = await RawImage.read('https://example.com/photo.jpg');
65
- const { pixel_values } = await processor(image);
66
-
67
- const { logits } = await model({ input_image: pixel_values });
68
- // Apply sigmoid, upscale back to original resolution, use as alpha matte.
69
- ```
70
-
71
  ## How it was built
72
 
73
  ### Export toolchain (why it's tricky)
@@ -86,7 +103,7 @@ BiRefNet uses `torchvision.ops.deform_conv2d` (deformable convolution), which ha
86
 
87
  ### Why Docker
88
 
89
- Installing PyTorch 2.0.1 locally on a modern machine is painful β€” the matching CUDA / CPU wheels are EOL, `pip install torch==2.0.1` tends to pull a binary that's incompatible with current Python / glibc / macOS versions, and the surrounding `torchvision` / `transformers` pins are finicky. We tried repeatedly and kept hitting import-time or ABI errors. The reliable path is a pinned Docker image:
90
 
91
  ```
92
  Python 3.10
@@ -95,8 +112,6 @@ torchvision (compatible with 2.0.1)
95
  transformers + deform-conv2d-onnx-exporter (Kazuhito00's patched version)
96
  ```
97
 
98
- Build once, export anywhere. Recipe below.
99
-
100
  ### Export recipe
101
 
102
  ```bash
@@ -117,42 +132,36 @@ The export script:
117
  3. Exports with `opset=17`, fixed 512Γ—512 input shape, constant folding enabled.
118
  4. Writes `model.onnx` (fp32, ~183 MB, 17,488 nodes, max 7 bindings, 80 GatherND ops).
119
 
120
- fp16 is produced separately via `onnxruntime.transformers.float16.convert_float_to_float16`, applied to the fp32 export.
121
 
122
  ### Validation
123
 
124
- Pixel-by-pixel comparison against the PyTorch forward pass on a set of reference images. The 512 export matches PyTorch exactly (zero pixel diff when both are resized to the same output resolution).
125
 
126
- ### What we tried that didn't work (for the record)
127
 
128
- - **Graph surgery on the 1024 model** β€” cascading Concat/Split ops into chains of ≀8 inputs/outputs. Mathematically identical output, passed the WebGPU binding-limit check, but the underlying OOM is about intermediate tensor size, not binding count.
129
- - **`onnxslim` optimization** β€” collapses cascaded ops back into the originals and inflates file size. Don't run it on a surgery output.
130
- - **Newer PyTorch exporters** (2.1.x, 2.6.x dynamo) β€” all fail to produce correct `deform_conv2d`. Pinning to 2.0.1 is the working configuration today.
131
- - **WebNN** β€” Chrome-only, still behind a flag, `GatherND` support unconfirmed, and would require bypassing transformers.js. Not viable yet.
132
 
133
- ## Differences from the upstream BiRefNet_lite
134
 
135
- - **Input resolution 512Γ—512** instead of 1024Γ—1024 (unblocks browser inference; see above).
136
- - **Proper `deform_conv2d` export** via patched exporter on PyTorch 2.0.1, so output matches the PyTorch reference exactly.
137
  - **fp16 variant** shipped alongside fp32.
138
- - **No graph surgery applied** β€” not needed at 512Γ—512.
139
 
140
  For full-image matting at 1024Γ—1024, prefer the upstream PyTorch model or server-side ONNX. This export is tuned for browser deployment.
141
 
142
  ## Limitations
143
 
144
  - 512Γ—512 input limits edge detail on large images β€” use on crops or smaller inputs for best results.
145
- - Adapters reporting fewer than ~10 storage buffers per shader stage will fall back to WASM; the model still runs, just slower.
146
- - No INT8 quantization yet. A quantized variant could cut the fp16 size roughly in half but hasn't been validated.
147
-
148
- ## License
149
-
150
- MIT, inherited from [ZhengPeng7/BiRefNet_lite](https://huggingface.co/ZhengPeng7/BiRefNet_lite). See the upstream repo for the original paper, weights, and training details.
151
 
152
  ## Citation
153
 
154
- If you use this model, please cite the original BiRefNet paper:
155
-
156
  ```bibtex
157
  @article{zheng2024birefnet,
158
  title={Bilateral Reference for High-Resolution Dichotomous Image Segmentation},
 
2
  license: mit
3
  library_name: transformers.js
4
  pipeline_tag: image-segmentation
5
+ base_model: ZhengPeng7/BiRefNet_lite
6
+ datasets:
7
+ - ZhengPeng7/DIS5K
8
+ inference: false
9
  tags:
10
  - background-removal
11
  - matting
12
  - onnx
13
  - webgpu
14
  - birefnet
15
+ - alpha-matting
16
+ - image-matting
17
+ - foreground-extraction
18
+ - salient-object-detection
19
+ - dichotomous-image-segmentation
20
+ - client-side
21
+ - transformers-js
22
+ - fp16
23
  ---
24
 
25
  # BiRefNet_lite 512Γ—512 (browser-ready ONNX)
26
 
27
+ A 512Γ—512 ONNX re-export of [ZhengPeng7/BiRefNet_lite](https://huggingface.co/ZhengPeng7/BiRefNet_lite) that actually runs in a browser β€” solving the OOM wall that blocks every 1024Γ—1024 variant from loading in `onnxruntime-web`. Drop it in with [`@huggingface/transformers`](https://huggingface.co/docs/transformers.js) to get high-quality alpha mattes entirely client-side, with no server round-trip.
28
 
29
+ Used in production by [Repper](https://repper.app) for per-motif matte refinement during foreground extraction.
30
 
31
+ ## Quickstart (transformers.js, WebGPU)
32
 
33
+ ```ts
34
+ import { AutoModel, AutoProcessor, RawImage } from '@huggingface/transformers';
35
+
36
+ const model = await AutoModel.from_pretrained('studioludens/birefnet-lite-512', {
37
+ dtype: 'fp16', // or 'fp32'
38
+ device: 'webgpu', // falls back to 'wasm' on unsupported hardware
39
+ });
40
+ const processor = await AutoProcessor.from_pretrained('studioludens/birefnet-lite-512');
41
+
42
+ const image = await RawImage.read('https://example.com/photo.jpg');
43
+ const { pixel_values } = await processor(image);
44
+
45
+ const { logits } = await model({ input_image: pixel_values });
46
+ // Apply sigmoid, upscale back to original resolution, use as alpha matte.
47
+ ```
48
+
49
+ ## Why this repo exists β€” variant comparison
50
+
51
+ | Variant | Input res | Runtime | Works in browser? |
52
+ |---------|-----------|---------|-------------------|
53
+ | `ZhengPeng7/BiRefNet_lite` | 1024Γ—1024 | PyTorch | β€” (not ONNX) |
54
+ | `onnx-community/BiRefNet_lite-ONNX` | 1024Γ—1024 | ONNX | No (OOM) |
55
+ | **`studioludens/birefnet-lite-512` (this repo)** | **512Γ—512** | **ONNX** | **Yes** |
56
+
57
+ The 1024Γ—1024 ONNX variants β€” including `onnx-community/BiRefNet_lite-ONNX` β€” fail in every browser backend we tested:
58
 
59
  | Backend | Variant | Failure |
60
  |---------|---------|---------|
 
63
  | WASM | fp32, cascaded | `std::bad_alloc` during `OrtRun` |
64
  | WASM | fp32, original | `std::bad_alloc` during `OrtRun` |
65
 
66
+ **Root cause:** BiRefNet_lite's decoder produces very large intermediate tensors at 1024Γ—1024 (multi-scale feature maps with 1024-way concatenations). The `onnxruntime-web` WASM heap is hardcoded at ~2–4 GB and cannot be raised at runtime, so peak working-set exceeds available memory regardless of backend or precision.
67
 
68
+ Reducing to **512Γ—512** shrinks intermediate tensors by 4Γ—. At 512Γ—512 the graph also naturally uses **max 7 storage buffers per shader stage**, comfortably inside WebGPU's `maxStorageBuffersPerShaderStage` limit (10 on older Apple Silicon adapters, 16 on Chrome β‰₯146), so no graph surgery is needed.
69
 
70
+ For crop-level matte refinement this is a fair trade: the crop is already small, and edge quality is indistinguishable from the 1024 reference in our tests.
71
 
72
  ## Variants
73
 
 
81
  ## Input / output
82
 
83
  - **Input:** RGB image, resized to **512Γ—512**, ImageNet normalization (`mean = [0.485, 0.456, 0.406]`, `std = [0.229, 0.224, 0.225]`), rescale factor `1/255`. Layout `NCHW`, input tensor name `input_image`.
84
+ - **Output:** Single-channel logits at 512Γ—512. **Apply `sigmoid` externally** to get the alpha matte in `[0, 1]`. Resize back to original image dimensions with bilinear interpolation.
85
 
86
  The `preprocessor_config.json` uses `ViTFeatureExtractor`, so `AutoProcessor.from_pretrained(...)` works out of the box.
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  ## How it was built
89
 
90
  ### Export toolchain (why it's tricky)
 
103
 
104
  ### Why Docker
105
 
106
+ Installing PyTorch 2.0.1 locally is painful β€” the matching wheels are EOL, `pip install torch==2.0.1` tends to pull a binary incompatible with current Python / glibc / macOS, and the surrounding `torchvision` / `transformers` pins are finicky. The reliable path is a pinned Docker image:
107
 
108
  ```
109
  Python 3.10
 
112
  transformers + deform-conv2d-onnx-exporter (Kazuhito00's patched version)
113
  ```
114
 
 
 
115
  ### Export recipe
116
 
117
  ```bash
 
132
  3. Exports with `opset=17`, fixed 512Γ—512 input shape, constant folding enabled.
133
  4. Writes `model.onnx` (fp32, ~183 MB, 17,488 nodes, max 7 bindings, 80 GatherND ops).
134
 
135
+ fp16 is produced separately via `onnxruntime.transformers.float16.convert_float_to_float16` applied to the fp32 export.
136
 
137
  ### Validation
138
 
139
+ Pixel-by-pixel comparison against the PyTorch forward pass on reference images. The 512 export matches PyTorch exactly (zero pixel diff when both are resized to the same output resolution).
140
 
141
+ ### What didn't work
142
 
143
+ - **Graph surgery on the 1024 model** β€” cascading Concat/Split ops into chains of ≀8 inputs/outputs passes the WebGPU binding-limit check, but the OOM is about intermediate tensor size, not binding count.
144
+ - **`onnxslim` optimization** β€” collapses cascaded ops back into the originals and inflates file size.
145
+ - **Newer PyTorch exporters** (2.1.x, 2.6.x dynamo) β€” all fail to produce correct `deform_conv2d`. PyTorch 2.0.1 is the working configuration.
146
+ - **WebNN** β€” Chrome-only, still behind a flag, `GatherND` support unconfirmed, and requires bypassing transformers.js.
147
 
148
+ ## Differences from upstream BiRefNet_lite
149
 
150
+ - **Input resolution 512Γ—512** instead of 1024Γ—1024 (unblocks browser inference).
151
+ - **Correct `deform_conv2d` export** via patched exporter on PyTorch 2.0.1 β€” output matches PyTorch reference exactly.
152
  - **fp16 variant** shipped alongside fp32.
153
+ - **No graph surgery** β€” not needed at 512Γ—512.
154
 
155
  For full-image matting at 1024Γ—1024, prefer the upstream PyTorch model or server-side ONNX. This export is tuned for browser deployment.
156
 
157
  ## Limitations
158
 
159
  - 512Γ—512 input limits edge detail on large images β€” use on crops or smaller inputs for best results.
160
+ - Adapters with fewer than ~10 storage buffers per shader stage fall back to WASM; the model still runs, just slower.
161
+ - No INT8 quantization yet. A quantized variant could roughly halve the fp16 size but hasn't been validated.
 
 
 
 
162
 
163
  ## Citation
164
 
 
 
165
  ```bibtex
166
  @article{zheng2024birefnet,
167
  title={Bilateral Reference for High-Resolution Dichotomous Image Segmentation},