Repository navigation
Commit 28c20a9
committed
Lower bf16 mean.dim to XNNPACK as an fp32 static mean
## Ulterior Motive
Keep bf16 RMSNorm in XNNPACK for bf16 models, such as the bf16 LeRobot policies in pytorch#24667, where bf16 ops that XNNPACK does not support fall back to the portable kernels.
## Rationale
**What**: With `enable_bf16=True`, lower a bf16 `mean.dim` to the `XNNStaticMean` from pytorch#24741. The serialized graph stays bf16; when the program loads, the runtime reduces in fp32 between a convert from bf16 and a convert back, as it already does for bf16 matmul.
**Why**: XNNPACK has no bf16 reduction, so `MeanDimConfig` rejected every bf16 mean, and a bf16 RMSNorm split the delegate around its mean. XNNPACK does convert between bf16 and fp32, and when the mean has lowered neighbours the two converts cost less than leaving the mean outside the delegate.
## Details
Stacked on pytorch#24741, which adds `XNNStaticMean`; only the last commit is new.
- `defineGenericReduceNode` adds the converts when the serialized input and output are bf16, next to `defineBf16MatMulResult`. The fp32 tensor definition is shared with the matmul path as `defineFp32Like`, and `convertBf16MatMulResult` becomes `convertBf16Result`. Because the program does not encode the converts, a runtime can switch to a native bf16 reduction if XNNPACK adds one, without re-exporting. The XNNPACK subgraph is the same as with the converts serialized: outputs are bitwise identical and latency is within noise. Each bf16 mean adds an fp32 copy of its input to the XNNPACK workspace (1 MiB for 1x128x2048).
- A bf16 mean never takes the Global Average Pooling path, which has no bf16 kernel. A 4D mean over dims [2, 3] with `keepdim=True` is a static mean like any other bf16 mean, so a channels-last input is copied to NCHW for it.
- bf16 means are lowered at any size, as fp16 and fp32 means are in pytorch#24741. fp32 and fp16 programs are byte-identical to pytorch#24741.
- Latency, branch time over main time (below 1 is faster), each a median over at least 1000 timed runs per program, alternating main and branch programs on one runtime, on an Apple M-series CPU (12 performance + 4 efficiency cores) with the default 16 threads: bf16 mean over the last dim of 1x128x2048 0.42x, bf16 RMSNorm 1x128x2048 0.56x, decode RMSNorm 1x1x2048 0.80x, 4 residual blocks of `x + Linear(RMSNorm(x))` at width 2048 0.87x for prefill (64 tokens) and 0.98x for decode (1 token). bf16 RMSNorm on 13 static shapes from 1x1x128 to 1x32x2048 is 0.47x to 0.96x at 1 thread. At 4 threads the shapes under 8K elements with several outputs are 1.19x to 1.57x (1.6 to 3.0 us more) and the rest 0.57x to 0.96x; at 16 threads those small shapes are 3.8x to 5.4x (22 to 24 us more) and the rest 0.70x to 0.99x, the same threadpool cost as for fp32 in pytorch#24741.
- A mean alone in its delegate, with nothing else lowered around it, pays the threadpool wake-up on its own and can be slower than the portable kernel at high thread counts. At 1x128x128 and 16 threads, a lone fp32 mean is 3.2x (as in pytorch#24741) and a lone bf16 mean 5.7x, because of its two converts; at 4 threads the bf16 mean is 1.35x, and at 1 thread it is faster. Any op lowered alone pays this, such as `add` (2.95x at 1x128x128 and 16 threads on main).
- Accuracy against fp32 eager is unchanged for single ops. It improves when the means were the only places a model's delegate split: for the 4 blocks above at prefill, max abs error drops from 4.6e-2 to 1.8e-2, because fewer intermediates are rounded to bf16 at delegate boundaries.
- An RMSNorm that casts to fp32 and back, as Hugging Face Llama does, already has an fp32 mean. Its remaining cost is the bf16 <-> fp32 casts, which pytorch#24745 lowers for programs exported with dim order, and pytorch#24768 for programs exported with `skip_dim_order`.
- `test_enable_bf16_leaves_ops_xnnpack_cannot_define_in_bf16` no longer lists `mean`, which is now delegated in bf16.
Test plan:
```
python -m pytest backends/xnnpack/test/ops/test_mean_dim.py
python -m pytest backends/xnnpack/test/ops backends/xnnpack/test/passes backends/xnnpack/test/test_xnnpack_partitioner.py backends/xnnpack/test/serialization backends/xnnpack/test/quantizer
```
Authored with AI using Claude Code.1 parent 9b5b8da commit 28c20a9
7 files changed
Lines changed: 205 additions & 61 deletions
File tree
- backends/xnnpack
- operators
- partition/config
- runtime
- test
- ops
- utils
- docs/source/backends/xnnpack
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
41 | 42 | | |
42 | 43 | | |
43 | 44 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
710 | 710 | | |
711 | 711 | | |
712 | 712 | | |
713 | | - | |
714 | 713 | | |
715 | 714 | | |
716 | 715 | | |
717 | 716 | | |
718 | | - | |
719 | | - | |
| 717 | + | |
| 718 | + | |
720 | 719 | | |
721 | 720 | | |
722 | 721 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
818 | 818 | | |
819 | 819 | | |
820 | 820 | | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
| 838 | + | |
| 839 | + | |
| 840 | + | |
| 841 | + | |
| 842 | + | |
| 843 | + | |
| 844 | + | |
| 845 | + | |
| 846 | + | |
| 847 | + | |
| 848 | + | |
| 849 | + | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
821 | 853 | | |
822 | 854 | | |
823 | 855 | | |
824 | | - | |
| 856 | + | |
825 | 857 | | |
826 | 858 | | |
827 | 859 | | |
| |||
844 | 876 | | |
845 | 877 | | |
846 | 878 | | |
847 | | - | |
848 | | - | |
849 | | - | |
850 | | - | |
851 | | - | |
852 | | - | |
853 | | - | |
854 | | - | |
855 | | - | |
856 | | - | |
857 | | - | |
858 | | - | |
859 | | - | |
860 | | - | |
861 | | - | |
862 | | - | |
863 | | - | |
864 | | - | |
865 | | - | |
866 | | - | |
867 | | - | |
| 879 | + | |
868 | 880 | | |
869 | 881 | | |
870 | 882 | | |
871 | | - | |
872 | | - | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
873 | 886 | | |
874 | | - | |
| 887 | + | |
875 | 888 | | |
876 | 889 | | |
877 | 890 | | |
| |||
934 | 947 | | |
935 | 948 | | |
936 | 949 | | |
937 | | - | |
| 950 | + | |
938 | 951 | | |
939 | 952 | | |
940 | 953 | | |
| |||
1793 | 1806 | | |
1794 | 1807 | | |
1795 | 1808 | | |
1796 | | - | |
| 1809 | + | |
1797 | 1810 | | |
1798 | 1811 | | |
1799 | 1812 | | |
| |||
2043 | 2056 | | |
2044 | 2057 | | |
2045 | 2058 | | |
2046 | | - | |
2047 | | - | |
| 2059 | + | |
| 2060 | + | |
| 2061 | + | |
2048 | 2062 | | |
2049 | 2063 | | |
2050 | 2064 | | |
2051 | 2065 | | |
2052 | | - | |
| 2066 | + | |
2053 | 2067 | | |
2054 | 2068 | | |
2055 | 2069 | | |
2056 | 2070 | | |
2057 | 2071 | | |
2058 | 2072 | | |
2059 | | - | |
| 2073 | + | |
| 2074 | + | |
| 2075 | + | |
| 2076 | + | |
| 2077 | + | |
| 2078 | + | |
| 2079 | + | |
| 2080 | + | |
| 2081 | + | |
| 2082 | + | |
| 2083 | + | |
| 2084 | + | |
| 2085 | + | |
| 2086 | + | |
| 2087 | + | |
| 2088 | + | |
| 2089 | + | |
| 2090 | + | |
| 2091 | + | |
| 2092 | + | |
| 2093 | + | |
| 2094 | + | |
| 2095 | + | |
| 2096 | + | |
| 2097 | + | |
2060 | 2098 | | |
2061 | 2099 | | |
2062 | 2100 | | |
2063 | 2101 | | |
2064 | | - | |
2065 | | - | |
| 2102 | + | |
| 2103 | + | |
2066 | 2104 | | |
2067 | 2105 | | |
2068 | 2106 | | |
2069 | 2107 | | |
2070 | 2108 | | |
2071 | | - | |
2072 | | - | |
| 2109 | + | |
| 2110 | + | |
2073 | 2111 | | |
2074 | 2112 | | |
2075 | | - | |
| 2113 | + | |
2076 | 2114 | | |
2077 | 2115 | | |
2078 | 2116 | | |
| |||
2081 | 2119 | | |
2082 | 2120 | | |
2083 | 2121 | | |
2084 | | - | |
2085 | 2122 | | |
2086 | 2123 | | |
2087 | 2124 | | |
2088 | 2125 | | |
2089 | 2126 | | |
2090 | | - | |
2091 | | - | |
| 2127 | + | |
| 2128 | + | |
2092 | 2129 | | |
2093 | 2130 | | |
2094 | 2131 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
12 | 14 | | |
13 | 15 | | |
14 | 16 | | |
| |||
30 | 32 | | |
31 | 33 | | |
32 | 34 | | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
33 | 44 | | |
34 | 45 | | |
35 | 46 | | |
| |||
73 | 84 | | |
74 | 85 | | |
75 | 86 | | |
| 87 | + | |
| 88 | + | |
76 | 89 | | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
77 | 102 | | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
| 103 | + | |
83 | 104 | | |
84 | 105 | | |
85 | | - | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
86 | 111 | | |
87 | 112 | | |
88 | | - | |
| 113 | + | |
89 | 114 | | |
90 | 115 | | |
91 | | - | |
| 116 | + | |
92 | 117 | | |
93 | 118 | | |
94 | 119 | | |
| |||
262 | 287 | | |
263 | 288 | | |
264 | 289 | | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
265 | 374 | | |
266 | 375 | | |
267 | 376 | | |
| |||
0 commit comments