aryan5v commited on
Commit
ddd1746
·
verified ·
1 Parent(s): d741544

Add pre-packed NVFP4 decoders and update docs

Browse files
Files changed (1) hide show
  1. README.md +79 -28
README.md CHANGED
@@ -30,10 +30,12 @@ original VAE, so no DiT or encoder changes are needed.
30
 
31
  ## Two tiers
32
 
33
- | Tier | Folder | Decoder blocks | Resident weights after packing | Use it when |
34
  |---|---|---:|---:|---|
35
- | Quality, **C-v4** | `quality-36L/` | 36 (full depth) | ~1.36 GB | you want output that looks the same as the original decoder |
36
- | Fast, **F8-v2** | `fast-8L/` | 8 | ~0.30 GB | decode time or memory matters most and you can accept some loss |
 
 
37
 
38
  For comparison, the original decoder's weights are 9.7 GB in fp32 or 4.8 GB in bf16.
39
 
@@ -47,8 +49,8 @@ LPIPS (AlexNet) against the original fp32 decoder on the same latents. Lower is
47
  | FastH3 OmniRef generations (20 clips) | 0.0039 / 46.0 dB | 0.0276 / 36.1 dB |
48
  | Real videos, VAE-encoded, held out (6 clips) | 0.0038 / 45.0 dB | 0.0330 / 34.3 dB |
49
 
50
- These numbers were reproduced from the released files through FastVideo's loader path,
51
- with weights packed to FP4 and the fused kernels.
52
 
53
  ### Blind side-by-side votes
54
 
@@ -86,8 +88,9 @@ through FlashInfer. The two produce bit-identical output. The fused decoder kern
86
  were benchmarked on GB200 and DGX Spark.
87
 
88
  On GPUs without FP4 tensor cores (Hopper, Ada, Ampere and older) or on CPU/MPS, the
89
- FP4 kernels are unavailable, so loading or decoding with these files fails. There is
90
- no automatic fallback. Use the original H3 VAE decoder on that hardware.
 
91
 
92
  ## How to use with FastVideo
93
 
@@ -98,28 +101,34 @@ no automatic fallback. Use the original H3 VAE decoder on that hardware.
98
  > Names and formats may change before the code is merged.
99
 
100
  1. Install FastVideo from the fork branch, with FlashInfer, on a Blackwell GPU.
101
- 2. Download a tier and convert it to the `.pt` format the loader reads. The
102
- conversion only regroups the tensors; values are unchanged.
103
 
104
  ```bash
105
- hf download FastVideo/FastH3-NVFP4-VAE-Decoder --local-dir fasth3-nvfp4-vae
106
- python fasth3-nvfp4-vae/convert_to_fastvideo_pt.py \
107
- fasth3-nvfp4-vae/quality-36L/decoder.safetensors quality-36L.pt
108
  ```
109
 
110
- 3. Point FastVideo at it and run any MiniMax-H3 / FastH3 pipeline as usual:
111
 
112
  ```bash
113
- export FASTVIDEO_H3_VAE_NVFP4_DECODER=$PWD/quality-36L.pt
114
  ```
115
 
 
 
 
116
  When the VAE loads, FastVideo:
117
 
118
- - replaces the decoder with the NVFP4 one;
 
 
119
  - skips the INT8 ConvRot decoder overlay;
120
- - packs the weights to FP4, so only the packed weights stay on the GPU;
121
  - runs the decode in bf16 autocast, the precision the decoders were trained in.
122
 
 
 
 
 
123
  Which host VAE each tier needs:
124
 
125
  - **Quality tier (36 blocks):** the stack's `vae/` folder must hold the full
@@ -139,21 +148,63 @@ Useful environment variables:
139
  ## Files
140
 
141
  ```
142
- quality-36L/decoder.safetensors # C-v4 weights
143
- quality-36L/config.json # architecture + NVFP4 settings
144
- fast-8L/decoder.safetensors # F8-v2 weights
 
 
145
  fast-8L/config.json
146
- convert_to_fastvideo_pt.py # safetensors -> FastVideo loader .pt
147
  ```
148
 
149
- Each `decoder.safetensors` holds `decoder.*` and `post_quant_conv.*` tensors. The
150
- safetensors header carries the NVFP4 settings (`format`, `nvfp4_metadata`). The
151
- quantized linear weights are stored as bf16 master weights. FastVideo turns them
152
- into NVFP4 at load with the same deterministic quantizer used in training, so the
153
- files on disk are larger than the resident sizes above:
154
-
155
- - quality tier: 4.86 GB on disk;
156
- - fast tier: 1.10 GB on disk.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
 
158
  ## Training
159
 
 
30
 
31
  ## Two tiers
32
 
33
+ | Tier | Folder | Decoder blocks | Decoder on the GPU | Use it when |
34
  |---|---|---:|---:|---|
35
+ | Quality, **C-v4** | `quality-36L/` | 36 (full depth) | 1.29 GiB | you want output that looks the same as the original decoder |
36
+ | Fast, **F8-v2** | `fast-8L/` | 8 | 0.31 GiB | decode time or memory matters most and you can accept some loss |
37
+
38
+ Each tier ships in two formats that decode **bit-identically**; see [Files](#files).
39
 
40
  For comparison, the original decoder's weights are 9.7 GB in fp32 or 4.8 GB in bf16.
41
 
 
49
  | FastH3 OmniRef generations (20 clips) | 0.0039 / 46.0 dB | 0.0276 / 36.1 dB |
50
  | Real videos, VAE-encoded, held out (6 clips) | 0.0038 / 45.0 dB | 0.0330 / 34.3 dB |
51
 
52
+ These numbers were reproduced from both released formats through FastVideo's loader,
53
+ with the fused kernels. The two formats produced bit-identical frames on all 35 clips.
54
 
55
  ### Blind side-by-side votes
56
 
 
88
  were benchmarked on GB200 and DGX Spark.
89
 
90
  On GPUs without FP4 tensor cores (Hopper, Ada, Ampere and older) or on CPU/MPS, the
91
+ FP4 kernels are unavailable, so decoding with either format fails. There is no
92
+ automatic fallback. Use the original H3 VAE decoder on that hardware. The bf16 file
93
+ is still useful there as a source for other quantization schemes.
94
 
95
  ## How to use with FastVideo
96
 
 
101
  > Names and formats may change before the code is merged.
102
 
103
  1. Install FastVideo from the fork branch, with FlashInfer, on a Blackwell GPU.
104
+ 2. Download one file. The packed file is the usual choice:
 
105
 
106
  ```bash
107
+ hf download FastVideo/FastH3-NVFP4-VAE-Decoder quality-36L/decoder-nvfp4.safetensors \
108
+ --local-dir fasth3-nvfp4-vae
 
109
  ```
110
 
111
+ 3. Point FastVideo at the file and run any MiniMax-H3 / FastH3 pipeline as usual:
112
 
113
  ```bash
114
+ export FASTVIDEO_H3_VAE_NVFP4_DECODER=$PWD/fasth3-nvfp4-vae/quality-36L/decoder-nvfp4.safetensors
115
  ```
116
 
117
+ The variable accepts either format, `decoder-nvfp4.safetensors` or
118
+ `decoder.safetensors`, directly.
119
+
120
  When the VAE loads, FastVideo:
121
 
122
+ - swaps the decoder on the CPU before the VAE moves to the GPU, so the dense
123
+ decoder it replaces never reaches the GPU;
124
+ - uses the packed FP4 weights as they are, or packs the bf16 weights at load;
125
  - skips the INT8 ConvRot decoder overlay;
 
126
  - runs the decode in bf16 autocast, the precision the decoders were trained in.
127
 
128
+ `convert_to_fastvideo_pt.py` is only needed with older checkouts of the branch,
129
+ whose loader read `.pt` files only. It converts `decoder.safetensors`; the packed
130
+ format needs the current loader.
131
+
132
  Which host VAE each tier needs:
133
 
134
  - **Quality tier (36 blocks):** the stack's `vae/` folder must hold the full
 
148
  ## Files
149
 
150
  ```
151
+ quality-36L/decoder-nvfp4.safetensors # C-v4, pre-packed NVFP4 (1.39 GB)
152
+ quality-36L/decoder.safetensors # C-v4, bf16 master weights (4.86 GB)
153
+ quality-36L/config.json # architecture, NVFP4 settings, both formats
154
+ fast-8L/decoder-nvfp4.safetensors # F8-v2, pre-packed NVFP4 (0.33 GB)
155
+ fast-8L/decoder.safetensors # F8-v2, bf16 master weights (1.10 GB)
156
  fast-8L/config.json
157
+ convert_to_fastvideo_pt.py # decoder.safetensors -> .pt, for older loaders
158
  ```
159
 
160
+ ### Which format to use
161
+
162
+ - **`decoder-nvfp4.safetensors` (packed):** pick this to run the model. It is the
163
+ smallest download and uses the least GPU memory while loading. It contains
164
+ Blackwell FP4 data, so it is Blackwell-only.
165
+ - **`decoder.safetensors` (bf16):** this is the reference copy. Use it to
166
+ re-quantize, fine-tune, run on a different FP4 kernel stack, or check the packed
167
+ file. FastVideo packs it at load with the same deterministic quantizer used in
168
+ training.
169
+
170
+ Peak memory while FastVideo loads the VAE (GB200; the encoder and the rest of the
171
+ VAE are included):
172
+
173
+ | | GPU, packed | GPU, bf16 | Host RAM (both formats) |
174
+ |---|---:|---:|---:|
175
+ | Quality tier, on the full 36-block VAE | 1.97 GiB | 9.78 GiB | about 23 GiB |
176
+ | Fast tier, on the 26-block light VAE | 0.99 GiB | 2.78 GiB | about 14 GiB |
177
+
178
+ The GPU memory after loading is the same for both formats. Host RAM peaks the same
179
+ way for both because the host VAE's own fp32 checkpoint is read in full.
180
+
181
+ ### Layout
182
+
183
+ Both formats store tensors under `decoder.*` and `post_quant_conv.*`. The
184
+ safetensors header carries `format` and `nvfp4_metadata`, a JSON string with the
185
+ block size, activation scale, number of NVFP4 linears and decoder depth.
186
+
187
+ - **`decoder.safetensors`**
188
+ - `format`: `fastvideo_h3_decoder_nvfp4_deploy_v1`.
189
+ - The quantized linears' weights and biases are bf16.
190
+ - Every other tensor is fp32, the dtype it has in the trained decoder.
191
+ - **`decoder-nvfp4.safetensors`**
192
+ - `format`: `fastvideo_h3_decoder_nvfp4_packed_v1`.
193
+ - `nvfp4_metadata` also describes the layout (`packed_layout`) and the GPU and
194
+ FlashInfer version used to pack.
195
+ - Each quantized linear `<name>` has these tensors:
196
+
197
+ | Tensor | Contents |
198
+ |---|---|
199
+ | `<name>.packed_weight` | uint8 `[out, in/2]`, two E2M1 codes per byte (FlashInfer `fp4_quantize` order) |
200
+ | `<name>.weight_inv_scale` | per-16-element E4M3 block scales, stored as uint8, in FlashInfer's swizzled `SfLayout.layout_128x4` |
201
+ | `<name>.weight_global_sf` | fp32 scalar |
202
+ | `<name>.bias` | bf16 |
203
+ | `<name>.input_amax` | fp32 static activation range, unused with the unit activation scale these decoders use |
204
+
205
+ - Norms, `proj_in`, `proj_out`, register tokens and `post_quant_conv` stay
206
+ fp32. That is the dtype the decoder was trained and validated with, so the
207
+ output stays bit-identical.
208
 
209
  ## Training
210