Image-Text-to-Video
Diffusers
Safetensors
orbitquant
comfyui
w4
w4a4
native-w4a4-transformer-runtime
text-to-video
audio-video-generation
8-bit precision
Instructions to use WaveCut/MiniMax-H3-OrbitQuant-W4A4 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use WaveCut/MiniMax-H3-OrbitQuant-W4A4 with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("WaveCut/MiniMax-H3-OrbitQuant-W4A4", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
Valeriy Selitskiy commited on
Commit ·
478202c
1
Parent(s): fa2d87b
Publish CUDA 13 inference profiles and ComfyUI proof
Browse files- .gitattributes +3 -0
- README.md +155 -118
- SHA256SUMS +119 -112
- comfyui/examples/h264/comfyui-balanced-t2va-608x480.mp4 +3 -0
- comfyui/examples/hevc/comfyui-balanced-t2va-608x480-crf10.mp4 +3 -0
- comfyui/examples/masters/comfyui-balanced-t2va-608x480-crf1.mp4 +3 -0
- comfyui/examples/review/comfyui-balanced-adjacent-triplets.jpg +3 -0
- comfyui/examples/review/comfyui-balanced-audio-spectrum.png +3 -0
- comfyui/examples/review/comfyui-balanced-frame-120.png +3 -0
- comfyui/examples/timelines/comfyui-balanced-t2va-608x480.jpg +3 -0
- comfyui/report.json +111 -66
- comfyui/workflow-export.png +2 -2
- comfyui/workflows/MiniMax-H3-OrbitQuant-Ref2VA-api.json +2 -1
- comfyui/workflows/MiniMax-H3-OrbitQuant-T2VA-api.json +3 -2
- comfyui/workflows/MiniMax-H3-OrbitQuant-T2VA.json +6 -4
- comfyui_orbitquant.json +2 -1
- quantization_manifest.json +16 -8
- runtime-requirements.txt +1 -1
- scripts/decode_h3_latents.py +126 -37
- scripts/manual_stage_offload.py +14 -5
- scripts/run_quantized_example.py +152 -4
.gitattributes
CHANGED
|
@@ -50,3 +50,6 @@ comfyui/examples/hevc/comfyui-t2va-608x480.mp4 filter=lfs diff=lfs merge=lfs -te
|
|
| 50 |
comfyui/examples/timelines/comfyui-ref2va-608x480.png filter=lfs diff=lfs merge=lfs -text
|
| 51 |
comfyui/examples/timelines/comfyui-t2va-608x480.png filter=lfs diff=lfs merge=lfs -text
|
| 52 |
comfyui/workflow-export.png filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
comfyui/examples/timelines/comfyui-ref2va-608x480.png filter=lfs diff=lfs merge=lfs -text
|
| 51 |
comfyui/examples/timelines/comfyui-t2va-608x480.png filter=lfs diff=lfs merge=lfs -text
|
| 52 |
comfyui/workflow-export.png filter=lfs diff=lfs merge=lfs -text
|
| 53 |
+
comfyui/examples/**/*.mp4 filter=lfs diff=lfs merge=lfs -text
|
| 54 |
+
comfyui/examples/**/*.png filter=lfs diff=lfs merge=lfs -text
|
| 55 |
+
comfyui/examples/**/*.jpg filter=lfs diff=lfs merge=lfs -text
|
README.md
CHANGED
|
@@ -16,172 +16,209 @@ tags:
|
|
| 16 |
- audio-video-generation
|
| 17 |
---
|
| 18 |
|
| 19 |
-
# MiniMax H3 —
|
| 20 |
|
| 21 |
-
OrbitQuant conversion of
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
-
Eligible linear weights in `transformer`, `transformer_ref`, and the Qwen3-VL
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
-
##
|
| 26 |
-
|
| 27 |
-
Download the ready-to-import [MiniMax H3 OrbitQuant T2VA workflow](comfyui/workflows/MiniMax-H3-OrbitQuant-T2VA.json). It is derived from Comfy-Org's bundled [`video_minimax_h3_t2v.json`](https://github.com/Comfy-Org/workflow_templates/blob/7653f1cdef1d92394b6ef9946018c0a8aa4136b8/templates/video_minimax_h3_t2v.json), preserving its human-readable composition: model and usage notes on the left, generation in the center, and the standard ComfyUI `SaveVideo` output on the right.
|
| 28 |
-
|
| 29 |
-

|
| 30 |
-
|
| 31 |
-
The 6120×2620 PNG above comes from ComfyUI's `Workflow Image → Export → png`
|
| 32 |
-
action rather than a browser screenshot. It embeds the loadable workflow in its
|
| 33 |
-
`tEXtworkflow` metadata.
|
| 34 |
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
### ComfyUI T2VA — generic public workflow
|
| 40 |
-
|
| 41 |
-
<video controls playsinline preload="metadata" width="608" aria-label="MiniMax H3 OrbitQuant ComfyUI T2VA proof">
|
| 42 |
-
<source src="https://huggingface.co/WaveCut/MiniMax-H3-OrbitQuant-W4A4/resolve/main/comfyui/examples/hevc/comfyui-t2va-608x480.mp4" type="video/mp4; codecs="hvc1"">
|
| 43 |
-
<source src="https://huggingface.co/WaveCut/MiniMax-H3-OrbitQuant-W4A4/resolve/main/comfyui/examples/h264/comfyui-t2va-608x480.mp4" type="video/mp4">
|
| 44 |
-
<a href="https://huggingface.co/WaveCut/MiniMax-H3-OrbitQuant-W4A4/resolve/main/comfyui/examples/h264/comfyui-t2va-608x480.mp4">MiniMax H3 OrbitQuant ComfyUI T2VA proof MP4</a>
|
| 45 |
</video>
|
| 46 |
|
| 47 |
-
[H.265
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
<a href="https://huggingface.co/WaveCut/MiniMax-H3-OrbitQuant-W4A4/resolve/main/comfyui/examples/h264/comfyui-ref2va-608x480.mp4">MiniMax H3 OrbitQuant ComfyUI Ref2VA proof MP4</a>
|
| 55 |
-
</video>
|
| 56 |
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
-
##
|
| 60 |
-
|
| 61 |
-
1. Move the W4 text encoder onto the GPU only for prompt/reference conditioning.
|
| 62 |
-
2. Offload the text encoder to RAM before denoising.
|
| 63 |
-
3. Move the selected W4 denoiser onto the GPU and run native packed W4A4 with BF16 activations.
|
| 64 |
-
4. Use the official default schedule: **50 sigma-grid points / 49 denoiser forwards**.
|
| 65 |
-
5. Persist every scheduler-step checkpoint atomically.
|
| 66 |
-
6. After denoising exits and releases the GPU, decode the saved latents with the original FP32 visual and audio VAEs.
|
| 67 |
-
|
| 68 |
-
The earlier eight-point shortcut was the principal quality failure: even the untouched BF16 source produced broken faces, lost temporal detail, and damaged audio with that schedule. VAE loading was separately falsified as the cause by decoding identical bad latents with the exact source VAE.
|
| 69 |
-
|
| 70 |
-
The apparent native-W4 slowdown had a separate cause: a prequantized Diffusers model loaded without an explicit compute dtype left its non-quantized modules in FP32. All 300 OrbitQuant linears then rejected the BF16/FP16 packed W4 kernel and fell back to the generic FP32 path. OrbitQuant 0.9.1 makes BF16 the default compute dtype for prequantized Diffusers artifacts while preserving an explicitly requested dtype. On the exact 50-block, 11,264-token transformer profile this changed one forward from **114.12 s** to **2.87 s** (39.8×); the package-default load measured **2.87 s** with all 300 linears on `triton_cuda_packed_w4`.
|
| 71 |
-
|
| 72 |
-

|
| 73 |
-
|
| 74 |
-
Rows from top to bottom: source BF16 control, W4A4 text-only isolation control, final native W4A4 text + transformer. Columns sample frames 0, 31, 62, 92, and 123.
|
| 75 |
|
| 76 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
|
| 78 |
-
|
| 79 |
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
<a href="https://huggingface.co/WaveCut/MiniMax-H3-OrbitQuant-W4A4/resolve/main/examples/h264/source-bf16-control.mp4">Source BF16 control — dynamic zoom and dialogue MP4</a>
|
| 84 |
-
</video>
|
| 85 |
|
| 86 |
-
|
| 87 |
-
|
|
|
|
|
|
|
|
|
|
| 88 |
|
| 89 |
-
|
| 90 |
-
<source src="https://huggingface.co/WaveCut/MiniMax-H3-OrbitQuant-W4A4/resolve/main/examples/hevc/w4-text-control.mp4" type="video/mp4; codecs="hvc1"">
|
| 91 |
-
<source src="https://huggingface.co/WaveCut/MiniMax-H3-OrbitQuant-W4A4/resolve/main/examples/h264/w4-text-control.mp4" type="video/mp4">
|
| 92 |
-
<a href="https://huggingface.co/WaveCut/MiniMax-H3-OrbitQuant-W4A4/resolve/main/examples/h264/w4-text-control.mp4">OrbitQuant W4A4 text encoder, BF16 denoiser MP4</a>
|
| 93 |
-
</video>
|
| 94 |
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
<a href="https://huggingface.co/WaveCut/MiniMax-H3-OrbitQuant-W4A4/resolve/main/examples/h264/w4a4-native-t2va.mp4">Final native W4A4 text + W4A4 T2VA transformer MP4</a>
|
| 102 |
-
</video>
|
| 103 |
|
| 104 |
-
|
| 105 |
|
| 106 |
-
|
|
|
|
|
|
|
| 107 |
|
| 108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
| `vae` | `source_copy` | 9.70 | exact source copy | 0 | 0 |
|
| 116 |
-
| `audio_vae` | `source_copy` | 0.56 | exact source copy | 0 | 0 |
|
| 117 |
|
| 118 |
-
|
|
|
|
|
|
|
| 119 |
|
| 120 |
-
##
|
| 121 |
|
| 122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
|
| 124 |
-
|
| 125 |
-
|---|---|---:|---:|---:|---:|
|
| 126 |
-
| `source-bf16-control` | `t2va` | 451.58 | 63.76 | 19.56 | 11.31 |
|
| 127 |
-
| `w4-text-control` | `t2va` | 381.57 | 63.76 | 13.15 | 11.31 |
|
| 128 |
-
| `w4a4-native-t2va` | `t2va` | 114.67 | 43.18 | 4.71 | 11.31 |
|
| 129 |
-
| `comfyui-t2va` | `t2va` | 137.14 | 18.91 | 5.48 | 11.29 |
|
| 130 |
-
| `comfyui-ref2va` | `ref2va` | 318.86 | 30.46 | 5.50 | 11.29 |
|
| 131 |
|
| 132 |
-
|
|
|
|
|
|
|
| 133 |
|
| 134 |
-
|
| 135 |
|
| 136 |
-
|
|
|
|
|
|
|
| 137 |
|
| 138 |
-
|
| 139 |
|
| 140 |
```bash
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
```
|
| 145 |
|
| 146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
|
| 148 |
```bash
|
| 149 |
python scripts/run_quantized_example.py \
|
| 150 |
--release . \
|
| 151 |
-
--output
|
| 152 |
-
--save-latents
|
| 153 |
-
--prompt "
|
| 154 |
-
--
|
|
|
|
| 155 |
--manual-stage-offload \
|
|
|
|
|
|
|
| 156 |
--transformer-runtime-mode auto_fused \
|
| 157 |
-
--checkpoint-dir checkpoints/
|
| 158 |
```
|
| 159 |
|
| 160 |
-
|
| 161 |
|
| 162 |
```bash
|
| 163 |
python scripts/decode_h3_latents.py \
|
| 164 |
-
--latents
|
| 165 |
-
--vae vae
|
| 166 |
-
--audio-vae audio_vae
|
| 167 |
-
--output
|
|
|
|
| 168 |
```
|
| 169 |
|
| 170 |
-
|
|
|
|
|
|
|
| 171 |
|
| 172 |
-
##
|
| 173 |
|
| 174 |
-
|
| 175 |
-
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 183 |
- Exact artifact hashes are in [`SHA256SUMS`](SHA256SUMS).
|
|
|
|
|
|
|
| 184 |
|
| 185 |
## License and modifications
|
| 186 |
|
| 187 |
-
The original
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
- audio-video-generation
|
| 17 |
---
|
| 18 |
|
| 19 |
+
# MiniMax H3 — OrbitQuant W4A4 with source FP32 VAEs
|
| 20 |
|
| 21 |
+
OrbitQuant conversion of
|
| 22 |
+
[MiniMaxAI/MiniMax-H3](https://huggingface.co/MiniMaxAI/MiniMax-H3), pinned to
|
| 23 |
+
source revision
|
| 24 |
+
[`73372e6cf53e414edd3ab03e357717fb0602e758`](https://huggingface.co/MiniMaxAI/MiniMax-H3/tree/73372e6cf53e414edd3ab03e357717fb0602e758).
|
| 25 |
|
| 26 |
+
Eligible linear weights in `transformer`, `transformer_ref`, and the Qwen3-VL
|
| 27 |
+
`text_encoder` are stored and executed through OrbitQuant's native packed W4A4
|
| 28 |
+
path. Non-quantized boundaries use BF16 compute. The visual `vae` and
|
| 29 |
+
`audio_vae` are byte-for-byte FP32 source copies and are never quantized.
|
| 30 |
|
| 31 |
+
## Final 608×480 example
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
|
| 33 |
+
<video controls playsinline preload="metadata" width="608" aria-label="MiniMax H3 OrbitQuant balanced ComfyUI proof">
|
| 34 |
+
<source src="https://huggingface.co/WaveCut/MiniMax-H3-OrbitQuant-W4A4/resolve/main/comfyui/examples/hevc/comfyui-balanced-t2va-608x480-crf10.mp4" type="video/mp4; codecs="hvc1"">
|
| 35 |
+
<source src="https://huggingface.co/WaveCut/MiniMax-H3-OrbitQuant-W4A4/resolve/main/comfyui/examples/h264/comfyui-balanced-t2va-608x480.mp4" type="video/mp4">
|
| 36 |
+
<a href="https://huggingface.co/WaveCut/MiniMax-H3-OrbitQuant-W4A4/resolve/main/comfyui/examples/h264/comfyui-balanced-t2va-608x480.mp4">MiniMax H3 OrbitQuant proof MP4</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
</video>
|
| 38 |
|
| 39 |
+
[H.265 10-bit CRF 10](comfyui/examples/hevc/comfyui-balanced-t2va-608x480-crf10.mp4)
|
| 40 |
+
· [H.264 fallback](comfyui/examples/h264/comfyui-balanced-t2va-608x480.mp4)
|
| 41 |
+
· [CRF 1 yuv444p master](comfyui/examples/masters/comfyui-balanced-t2va-608x480-crf1.mp4)
|
| 42 |
+
· [16-frame overview](comfyui/examples/timelines/comfyui-balanced-t2va-608x480.jpg)
|
| 43 |
+
· [adjacent-frame review](comfyui/examples/review/comfyui-balanced-adjacent-triplets.jpg)
|
| 44 |
+
· [audio spectrum](comfyui/examples/review/comfyui-balanced-audio-spectrum.png)
|
| 45 |
|
| 46 |
+
This live ComfyUI run uses 608×480, 124 frames at 24 FPS, seed 42, and 24
|
| 47 |
+
sigma points / 23 denoiser forwards. All 300 eligible denoiser linears use the
|
| 48 |
+
native packed W4A4 path with no exact INT8 weight cache. Source FP32 tiled visual
|
| 49 |
+
decode produced the retained CRF 1 master; the HEVC card copy was derived from
|
| 50 |
+
that master at CRF 10. The output contains AAC stereo at 32 kHz.
|
|
|
|
|
|
|
| 51 |
|
| 52 |
+
Full-resolution frames and adjacent triplets were reviewed for face geometry,
|
| 53 |
+
eyes, lips, grid artifacts, ghosting, texture breakup, and abrupt section
|
| 54 |
+
redraw. The macro-to-face shot remains coherent. The audio spectrum is broadband
|
| 55 |
+
without a persistent narrow electronic whistle.
|
| 56 |
|
| 57 |
+
## ComfyUI workflow
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
+
Download the ready-to-import
|
| 60 |
+
[MiniMax H3 OrbitQuant T2VA workflow](comfyui/workflows/MiniMax-H3-OrbitQuant-T2VA.json).
|
| 61 |
+
It is based on Comfy-Org's bundled
|
| 62 |
+
[`video_minimax_h3_t2v.json`](https://github.com/Comfy-Org/workflow_templates/blob/7653f1cdef1d92394b6ef9946018c0a8aa4136b8/templates/video_minimax_h3_t2v.json)
|
| 63 |
+
and preserves the official preset's readable composition.
|
| 64 |
|
| 65 |
+

|
| 66 |
|
| 67 |
+
The PNG above is a 3060×1310 ComfyUI Workflow Image Export, not a browser
|
| 68 |
+
screenshot. Its `tEXt` `workflow` chunk contains the same six-node graph with
|
| 69 |
+
`balanced`, 608×480, 124 frames, 24 steps, and the detailed example prompt.
|
|
|
|
|
|
|
| 70 |
|
| 71 |
+
Install [ComfyUI-OrbitQuant](https://github.com/iamwavecut/ComfyUI-OrbitQuant)
|
| 72 |
+
into `ComfyUI/custom_nodes`, restart ComfyUI, import the workflow, and set
|
| 73 |
+
`OrbitQuant Release Loader.model_path` to this downloaded model directory. The
|
| 74 |
+
graph uses only the generic public nodes `OrbitQuant Release Loader` and
|
| 75 |
+
`OrbitQuant Generate Video`; there are no MiniMax-specific public node classes.
|
| 76 |
|
| 77 |
+
On the RunPod ComfyUI image, launch ComfyUI with:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
|
| 79 |
+
```bash
|
| 80 |
+
python main.py --listen 0.0.0.0 --port 8188 \
|
| 81 |
+
--disable-cuda-malloc \
|
| 82 |
+
--disable-dynamic-vram \
|
| 83 |
+
--disable-async-offload
|
| 84 |
+
```
|
| 85 |
|
| 86 |
+
These supported flags let the OrbitQuant subprocess enforce its own allocator
|
| 87 |
+
cap instead of competing with ComfyUI's global DynamicVRAM and async-offload
|
| 88 |
+
layers.
|
|
|
|
|
|
|
| 89 |
|
| 90 |
+
## Inference profiles
|
| 91 |
|
| 92 |
+
All numbers use CUDA 13, 608×480, 124 frames, 24 sigma points / 23 forwards,
|
| 93 |
+
native-auto Torch Flash SDPA, no weight cache, sequential CUDA text conditioning,
|
| 94 |
+
and source FP32 VAEs.
|
| 95 |
|
| 96 |
+
| Profile | GPU | Task | Placement | Process peak | Denoise | Generation |
|
| 97 |
+
| --- | --- | --- | --- | ---: | ---: | ---: |
|
| 98 |
+
| `balanced` (default) | RTX PRO 6000 | T2VA | streamed leaf offload, 12 GiB cap | 6.36 GiB child; 6.90 GiB incl. idle ComfyUI | 46.68 s | — |
|
| 99 |
+
| `speed` | RTX PRO 6000 | T2VA | resident transformer | 21.14 GiB | 46.84 s | 51.10 s |
|
| 100 |
+
| `minimum_vram` | RTX 4090 | T2VA | low-CPU-memory streamed leaf offload, 8 GiB cap | 4.07 GiB | 154.25 s | 188.70 s |
|
| 101 |
+
| `speed` | RTX PRO 6000 | Ref2VA | resident `transformer_ref` | 24.06 GiB | 118.48 s | 155.42 s |
|
| 102 |
|
| 103 |
+
`balanced` is the recommended Pareto recipe. On the tested PRO 6000, streamed
|
| 104 |
+
weight movement overlaps denoising closely enough to match the resident path
|
| 105 |
+
while cutting the child process's physical CUDA peak by about 70%.
|
| 106 |
+
`minimum_vram` is the verified absolute-minimum endpoint. `speed` removes
|
| 107 |
+
transformer transfers when VRAM is available.
|
|
|
|
|
|
|
| 108 |
|
| 109 |
+
SageAttention2's available CUDA 13 binary did not include SM120 code for this
|
| 110 |
+
PRO 6000, and forced cuDNN attention was slower. Native-auto Torch Flash SDPA is
|
| 111 |
+
therefore the shipped supported attention path.
|
| 112 |
|
| 113 |
+
## Install
|
| 114 |
|
| 115 |
+
```bash
|
| 116 |
+
pip install "orbitquant[hf,kernels]>=0.9.2,<0.10"
|
| 117 |
+
pip install "diffusers @ git+https://github.com/huggingface/diffusers.git@abc5e9bf71fd38f53cd471bc3acaa84bc5ecbfdc"
|
| 118 |
+
pip install "transformers>=5.13,<6" accelerate av soundfile
|
| 119 |
+
```
|
| 120 |
|
| 121 |
+
Or install all pinned runtime requirements from this repository:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
|
| 123 |
+
```bash
|
| 124 |
+
pip install -r runtime-requirements.txt
|
| 125 |
+
```
|
| 126 |
|
| 127 |
+
## Direct runner
|
| 128 |
|
| 129 |
+
The runner writes each scheduler checkpoint atomically and saves the latent
|
| 130 |
+
bundle before decode. The examples below keep the prompt in a file to avoid
|
| 131 |
+
shell quoting a multi-kilobyte description.
|
| 132 |
|
| 133 |
+
Balanced T2VA:
|
| 134 |
|
| 135 |
```bash
|
| 136 |
+
python scripts/run_quantized_example.py \
|
| 137 |
+
--release . \
|
| 138 |
+
--output balanced.mp4 \
|
| 139 |
+
--save-latents balanced.latents.pt \
|
| 140 |
+
--prompt "$(cat prompt.txt)" \
|
| 141 |
+
--seed 42 --width 608 --height 480 --num-frames 124 --steps 24 \
|
| 142 |
+
--manual-stage-offload \
|
| 143 |
+
--text-encoder-sequential-offload \
|
| 144 |
+
--transformer-group-offload-type leaf_level \
|
| 145 |
+
--group-offload-use-stream \
|
| 146 |
+
--cuda-memory-cap-gib 12 \
|
| 147 |
+
--transformer-runtime-mode auto_fused \
|
| 148 |
+
--checkpoint-dir checkpoints/balanced
|
| 149 |
```
|
| 150 |
|
| 151 |
+
Maximum-speed T2VA: remove the group-offload and allocator-cap options while
|
| 152 |
+
keeping `--manual-stage-offload --text-encoder-sequential-offload`.
|
| 153 |
+
|
| 154 |
+
Minimum-VRAM T2VA: use the balanced command with
|
| 155 |
+
`--group-offload-low-cpu-mem-usage --cuda-memory-cap-gib 8`.
|
| 156 |
+
|
| 157 |
+
Ref2VA speed:
|
| 158 |
|
| 159 |
```bash
|
| 160 |
python scripts/run_quantized_example.py \
|
| 161 |
--release . \
|
| 162 |
+
--output ref2va.mp4 \
|
| 163 |
+
--save-latents ref2va.latents.pt \
|
| 164 |
+
--prompt "$(cat prompt.txt)" \
|
| 165 |
+
--task ref2va --reference reference.png \
|
| 166 |
+
--seed 42 --width 608 --height 480 --num-frames 124 --steps 24 \
|
| 167 |
--manual-stage-offload \
|
| 168 |
+
--text-encoder-sequential-offload \
|
| 169 |
+
--reference-vae-sequential-offload --reference-vae-tile-size 128 \
|
| 170 |
--transformer-runtime-mode auto_fused \
|
| 171 |
+
--checkpoint-dir checkpoints/ref2va
|
| 172 |
```
|
| 173 |
|
| 174 |
+
Decode only after the latent-producing process exits:
|
| 175 |
|
| 176 |
```bash
|
| 177 |
python scripts/decode_h3_latents.py \
|
| 178 |
+
--latents balanced.latents.pt \
|
| 179 |
+
--vae vae \
|
| 180 |
+
--audio-vae audio_vae \
|
| 181 |
+
--output balanced.master-crf1.mp4 \
|
| 182 |
+
--preview-output balanced.mp4
|
| 183 |
```
|
| 184 |
|
| 185 |
+
The decoder always loads the release's untouched source FP32 visual and audio
|
| 186 |
+
VAEs. The visual VAE is tiled and sequentially offloaded; the audio VAE enters
|
| 187 |
+
GPU only for the audio stage.
|
| 188 |
|
| 189 |
+
## Component precision and size
|
| 190 |
|
| 191 |
+
| Component | Stored mode | Artifact GiB | Eligible linear coverage | OrbitQuant modules | AdaLN INT4 |
|
| 192 |
+
| --- | --- | ---: | ---: | ---: | ---: |
|
| 193 |
+
| `transformer` | W4A4 | 17.03 | 97.45% | 300 | 50 |
|
| 194 |
+
| `transformer_ref` | W4A4 | 17.03 | 97.45% | 300 | 50 |
|
| 195 |
+
| `text_encoder` | W4A4 | 18.55 | 95.80% | 448 | 0 |
|
| 196 |
+
| `vae` | source FP32 copy | 9.70 | exact source copy | 0 | 0 |
|
| 197 |
+
| `audio_vae` | source FP32 copy | 0.56 | exact source copy | 0 | 0 |
|
| 198 |
+
|
| 199 |
+
Input/output projections, time/context/refiner boundaries, embeddings, norms,
|
| 200 |
+
and language-head boundaries excluded by the pinned H3/Qwen policy remain in
|
| 201 |
+
source precision. “Four bit” describes eligible packed linear weights, not
|
| 202 |
+
every tensor in the architecture.
|
| 203 |
+
|
| 204 |
+
## Validation and provenance
|
| 205 |
+
|
| 206 |
+
- OrbitQuant 0.9.2 revision `cd58b4ecf77f22b8c4116b3d0b7d4af258e16ba3`.
|
| 207 |
+
- Diffusers revision `abc5e9bf71fd38f53cd471bc3acaa84bc5ecbfdc`.
|
| 208 |
+
- The live ComfyUI workflow reached terminal `pass` through `/prompt` and
|
| 209 |
+
produced the standard `VIDEO` output.
|
| 210 |
+
- All 23 denoiser checkpoints and the final latent were persisted before
|
| 211 |
+
source-FP32 decode.
|
| 212 |
+
- Visual/audio VAE weight SHA256 values match the pinned source revision; see
|
| 213 |
+
[`validation/source_component_copy_audit.json`](validation/source_component_copy_audit.json).
|
| 214 |
- Exact artifact hashes are in [`SHA256SUMS`](SHA256SUMS).
|
| 215 |
+
- Full machine-readable profile and media evidence is in
|
| 216 |
+
[`comfyui/report.json`](comfyui/report.json).
|
| 217 |
|
| 218 |
## License and modifications
|
| 219 |
|
| 220 |
+
The original
|
| 221 |
+
[MiniMax H3 Community License Agreement](https://huggingface.co/MiniMaxAI/MiniMax-H3/blob/73372e6cf53e414edd3ab03e357717fb0602e758/LICENSE)
|
| 222 |
+
is copied as [`LICENSE`](LICENSE). See [`NOTICE`](NOTICE),
|
| 223 |
+
[`MODIFICATIONS.md`](MODIFICATIONS.md), and the upstream
|
| 224 |
+
[`QA-about-License`](docs/QA-about-License.md).
|
SHA256SUMS
CHANGED
|
@@ -1,112 +1,119 @@
|
|
| 1 |
-
|
| 2 |
-
59b99642b95ea21630e311198ddbfffbfe05aadba0c2f5d884cbdf4efcc90f44 LICENSE
|
| 3 |
-
e6685eda9517bad6751f538dcc0ed967a1a08cacd000a20fe12a3fdd01023b83 MODIFICATIONS.md
|
| 4 |
-
154fe7fbdf198395d53c57d6786b2fbf7e63a083ff70843c5ef78c0c7303d91a NOTICE
|
| 5 |
-
34fc76ba3797f5d4dbc5e956dde7d1d0e84cfd01c6922094ca1202b05a8bd319 PERFORMANCE.md
|
| 6 |
-
|
| 7 |
-
804780f7133477067bd6bbfbc02dc8b3cf9feeb400f97c08f5b1d5f6cbab3840 audio_scheduler/scheduler_config.json
|
| 8 |
-
9a3c645ff892b376c6f5f4c8685964cd75474731af594ff058492a0000caabb6 audio_vae/config.json
|
| 9 |
-
52c59e67ba8de5477c81bfbced0327aabf500f1bfdeefd5ee754529241cb26cb audio_vae/diffusion_pytorch_model.safetensors
|
| 10 |
-
c088e81b20500cdfcc77da8589f7b1408d080ebabf2051acae8c2f3426ffe1e7 benchmarks/astronaut-w4both-w4a16-early-gate.json
|
| 11 |
-
415a42c8f0c2146ec7cf4bd70c582e5420d87517bef33135cebdd11593d62c9e benchmarks/astronaut-w4both-w4a16-step001-health.json
|
| 12 |
-
3d3a387b791332d68260f01dcc7c47f2944b21b55a5cbbcc7d966fc095dafa19 benchmarks/early-gate/native-dynamic-zoom-early.metrics.json
|
| 13 |
-
32b73981afb8f5a3deacebf42631b673365ef423f7a6bea2ab41edb42cdf4c73 benchmarks/early-gate/native-vs-w4a16-step001.json
|
| 14 |
-
6422124c7a9fff01207f0f3a0d31c48ee17670def930a27705d98a212c728bc6 benchmarks/early-gate/w4a16-dynamic-zoom-early.metrics.json
|
| 15 |
-
064de721be4f0401f6e852fc4f426375c8d595ab6b30d232fdf270ba0e75747a benchmarks/example_metrics.csv
|
| 16 |
-
eeff4d8dda3228614ec753d184f908ff9425fd90ca97c6c9e2edcba9b406751d benchmarks/example_metrics.json
|
| 17 |
-
281bdb716d3e4db82e2e90e74c6bf74f05c483702502ce7df30dd448012dad02 benchmarks/media_probe.json
|
| 18 |
-
47a26334e37b41f5d20068f7131409c0b2fa508ea358a18902e90140837d873c benchmarks/profiles/native-full-forward-bf16-load.json
|
| 19 |
-
b7a97b2c0d19bcc6bb6e052ec5a552c725083354be375ad12ee6afee38dc4130 benchmarks/profiles/native-full-forward-fp32-load.json
|
| 20 |
-
72c7369bb28fffa42ca6a017c16d63aa86908be2b8f8ff9bc146c4473d394a60 benchmarks/profiles/native-full-forward-package-default.json
|
| 21 |
-
22513428f1923473bae58d43de4b2a9f4bad05e062fa7911b035a6808a49d09e benchmarks/profiles/native-full-forward-transformer-ref-cold.json
|
| 22 |
-
05e2ed4075c91e75d9834a16dcf0a81397be49639372efe8b2360c73206bb2a9 benchmarks/profiles/native-full-forward-transformer-ref-hot.json
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
eac2b97122aeab6cb7a324fd8b451e4ad021777d6137d285e2098b089bafb926
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
127932208cc61680a73ed835cdbf971a8190c7c275668864a855a15c614cb765
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
24c2039a0ccb86c392e9fefe8a26b135b4cf46da58a0a7d14729c62196a75ddc ./.gitattributes
|
| 2 |
+
59b99642b95ea21630e311198ddbfffbfe05aadba0c2f5d884cbdf4efcc90f44 ./LICENSE
|
| 3 |
+
e6685eda9517bad6751f538dcc0ed967a1a08cacd000a20fe12a3fdd01023b83 ./MODIFICATIONS.md
|
| 4 |
+
154fe7fbdf198395d53c57d6786b2fbf7e63a083ff70843c5ef78c0c7303d91a ./NOTICE
|
| 5 |
+
34fc76ba3797f5d4dbc5e956dde7d1d0e84cfd01c6922094ca1202b05a8bd319 ./PERFORMANCE.md
|
| 6 |
+
eaaff934eda5b84c4c5bb1c007e53817fe401231e42b958152810be4798dd1d4 ./README.md
|
| 7 |
+
804780f7133477067bd6bbfbc02dc8b3cf9feeb400f97c08f5b1d5f6cbab3840 ./audio_scheduler/scheduler_config.json
|
| 8 |
+
9a3c645ff892b376c6f5f4c8685964cd75474731af594ff058492a0000caabb6 ./audio_vae/config.json
|
| 9 |
+
52c59e67ba8de5477c81bfbced0327aabf500f1bfdeefd5ee754529241cb26cb ./audio_vae/diffusion_pytorch_model.safetensors
|
| 10 |
+
c088e81b20500cdfcc77da8589f7b1408d080ebabf2051acae8c2f3426ffe1e7 ./benchmarks/astronaut-w4both-w4a16-early-gate.json
|
| 11 |
+
415a42c8f0c2146ec7cf4bd70c582e5420d87517bef33135cebdd11593d62c9e ./benchmarks/astronaut-w4both-w4a16-step001-health.json
|
| 12 |
+
3d3a387b791332d68260f01dcc7c47f2944b21b55a5cbbcc7d966fc095dafa19 ./benchmarks/early-gate/native-dynamic-zoom-early.metrics.json
|
| 13 |
+
32b73981afb8f5a3deacebf42631b673365ef423f7a6bea2ab41edb42cdf4c73 ./benchmarks/early-gate/native-vs-w4a16-step001.json
|
| 14 |
+
6422124c7a9fff01207f0f3a0d31c48ee17670def930a27705d98a212c728bc6 ./benchmarks/early-gate/w4a16-dynamic-zoom-early.metrics.json
|
| 15 |
+
064de721be4f0401f6e852fc4f426375c8d595ab6b30d232fdf270ba0e75747a ./benchmarks/example_metrics.csv
|
| 16 |
+
eeff4d8dda3228614ec753d184f908ff9425fd90ca97c6c9e2edcba9b406751d ./benchmarks/example_metrics.json
|
| 17 |
+
281bdb716d3e4db82e2e90e74c6bf74f05c483702502ce7df30dd448012dad02 ./benchmarks/media_probe.json
|
| 18 |
+
47a26334e37b41f5d20068f7131409c0b2fa508ea358a18902e90140837d873c ./benchmarks/profiles/native-full-forward-bf16-load.json
|
| 19 |
+
b7a97b2c0d19bcc6bb6e052ec5a552c725083354be375ad12ee6afee38dc4130 ./benchmarks/profiles/native-full-forward-fp32-load.json
|
| 20 |
+
72c7369bb28fffa42ca6a017c16d63aa86908be2b8f8ff9bc146c4473d394a60 ./benchmarks/profiles/native-full-forward-package-default.json
|
| 21 |
+
22513428f1923473bae58d43de4b2a9f4bad05e062fa7911b035a6808a49d09e ./benchmarks/profiles/native-full-forward-transformer-ref-cold.json
|
| 22 |
+
05e2ed4075c91e75d9834a16dcf0a81397be49639372efe8b2360c73206bb2a9 ./benchmarks/profiles/native-full-forward-transformer-ref-hot.json
|
| 23 |
+
6c17fa38c5fee6a396a58d7f55981d1cdb644fae5cbbac87a2eb8d4194ad4d2f ./comfyui/examples/h264/comfyui-balanced-t2va-608x480.mp4
|
| 24 |
+
02233da18b3c01761889df2206181e0fc7b9f120165b37a0fe4c9f7bbdda0096 ./comfyui/examples/h264/comfyui-ref2va-608x480.mp4
|
| 25 |
+
4cceecedd28dfc593cf5e61145836405d18475bd8109b2ef7a984d96d91a13e6 ./comfyui/examples/h264/comfyui-t2va-608x480.mp4
|
| 26 |
+
1bbc05a09f3f49d1564afb1b0c0f49a5f3c3a05a34a28e4f8b28f1d3295f5335 ./comfyui/examples/hevc/comfyui-balanced-t2va-608x480-crf10.mp4
|
| 27 |
+
0c3040f81aefdb14b30047a5c972347d012d72dbfa026b8a9b2e245e555b7996 ./comfyui/examples/hevc/comfyui-ref2va-608x480.mp4
|
| 28 |
+
bc31c456f9fdfae29c4e89d063baa953bbd73141c05a237ed43006336661eaab ./comfyui/examples/hevc/comfyui-t2va-608x480.mp4
|
| 29 |
+
32711ef0f3a3a341340ab88e31537b26eefd486909154b0ba03ada49896f7f21 ./comfyui/examples/masters/comfyui-balanced-t2va-608x480-crf1.mp4
|
| 30 |
+
a1114d1ba23da74c0ee1d911599cdd50cab3deef5e2de9e9ff9b9ff9167f97db ./comfyui/examples/review/comfyui-balanced-adjacent-triplets.jpg
|
| 31 |
+
36b4c549e3bf39716325a81ea14417be811ac8b5dd7a71bfe596aef8288ab385 ./comfyui/examples/review/comfyui-balanced-audio-spectrum.png
|
| 32 |
+
5a5139474ed5aed90706a002bef1d574b2e737b24164e2367e008167bde34f48 ./comfyui/examples/review/comfyui-balanced-frame-120.png
|
| 33 |
+
f081bb49aa12d73c108f8fef963c51c387662590cc41c6b069a0c7a47e7552e5 ./comfyui/examples/timelines/comfyui-balanced-t2va-608x480.jpg
|
| 34 |
+
78d579a40bf159ed3039900d6503d992843b4ec67662eb777751be908e9237d4 ./comfyui/examples/timelines/comfyui-ref2va-608x480.png
|
| 35 |
+
7adf6cc9259ae6eb367f8217912bf76ec9cd88ef358150d80b4742d57b50bf01 ./comfyui/examples/timelines/comfyui-t2va-608x480.png
|
| 36 |
+
c4eec7582b072e752e0491b7c79c3e76a1fc207a6cf3f1e86d95be13155b7782 ./comfyui/report.json
|
| 37 |
+
164ac2cd2dd51a1aa7a99c213e6777585b48b9efdbe6ad742e39cad8a5143caf ./comfyui/workflow-export.png
|
| 38 |
+
497dede417244161108ed46cfe0be2c183cba7851863f492ae67f6f92e66871c ./comfyui/workflows/MiniMax-H3-OrbitQuant-Ref2VA-api.json
|
| 39 |
+
83fc4ee22497d42cac1dbc49d68c51260c795c5b12a21a41fff5ac296b866c6b ./comfyui/workflows/MiniMax-H3-OrbitQuant-T2VA-api.json
|
| 40 |
+
e519ae3cd3763b9b832cee341eb4f982681a834ae0d3f80237b6d30a05350f92 ./comfyui/workflows/MiniMax-H3-OrbitQuant-T2VA.json
|
| 41 |
+
ec9ad075deab2f51b96d96f90f747db410440c65fe16ced65bf8d910deb58f5b ./comfyui_orbitquant.json
|
| 42 |
+
26900a2868636f886d241efe94002ad11d858b3c3eb005e58c0c2ad60f0de7ae ./docs/QA-about-License.md
|
| 43 |
+
87044e59a72a2b8ed3df285de044a097d7366f3004dcfc26ffd11fc71ed32d17 ./examples/h264/source-bf16-control.mp4
|
| 44 |
+
513f09b20cb4e59a47a2f4ff19e544cb29d41870ee2c4759ad0a2ff6cb16fe0c ./examples/h264/w4-text-control.mp4
|
| 45 |
+
679c0b690fce47ed2dd19ba7fa185d0cea69ee3a3b308a84faa909ce0762d24b ./examples/h264/w4a4-native-t2va.mp4
|
| 46 |
+
eb4eb5d19d231887c6dfba5be70ac3d9107fe076a5f7c69e6fa77ecc0ad5ced9 ./examples/hevc/source-bf16-control.mp4
|
| 47 |
+
ea89a3cc2a37c4294da4142f22d9d3778f1d086efb6125d73e1d5ccf392c6cbb ./examples/hevc/w4-text-control.mp4
|
| 48 |
+
0bef87dbecbd9963e6febb43fb44cc2caf142192e59f7deee13950e55789b235 ./examples/hevc/w4a4-native-t2va.mp4
|
| 49 |
+
cc97132c8132fa431d375c1e0b0dc8a85b536a91bc13bd5494e789e592126426 ./examples/quality-timeline-matrix.webp
|
| 50 |
+
b1257de01d8440baea06865ea35ce557d885b6dda700281ba25202193c58285c ./examples/reference/astronaut.png
|
| 51 |
+
1c33ff3ec4f637b15496b01130cd83c7393f742fce45b5986d158e6970cfdd27 ./examples/reviews/source-bf16-control.json
|
| 52 |
+
fad45c95f068f9abfc5125e1e0993004fe036b793803eebc3e28255827200a25 ./examples/reviews/w4-text-control.json
|
| 53 |
+
9740fde8102c96aaa2bb9f41ecfbf3eaea651d2393944a21107889789d21f6e7 ./examples/reviews/w4a4-native-t2va.json
|
| 54 |
+
efa068559ff6c2b7d0f6fbf2c835ba4d1b654f4cd016e7be737e27b50c0c380e ./examples/timelines/source-bf16-control.png
|
| 55 |
+
367855aa5fd90e4a6b6baece0894a3f4343a6a6ffc6b16750711d14a05bb82fe ./examples/timelines/w4-text-control.png
|
| 56 |
+
a69f89026fde4cacf6a52047ccdf5909a9ba218658d13b9b514a9fd11ece4482 ./examples/timelines/w4a4-native-t2va.png
|
| 57 |
+
a6c5f6fca6c2c92726ddb03407ff11d9c1287bbfa164e489e58fb84376073faa ./modular_model_index.json
|
| 58 |
+
5c72a170d2a4a1a3bc5adad2e689ae28138a9700e5b8c96c0266331e86c0acce ./processor/chat_template.json
|
| 59 |
+
599bab54075088774b1733fde865d5bd747cbcc7a547c5bc12610e874e26f5e3 ./processor/merges.txt
|
| 60 |
+
27225450ac9c6529872ee1924fcb0962ff5634834f817040f444118116f4e516 ./processor/preprocessor_config.json
|
| 61 |
+
a5d85b6dcc535e6b93115a9ef287e6132fdbf30270da6218194ba742261173c7 ./processor/tokenizer.json
|
| 62 |
+
a07e942ac874baa13758de8d1fbdb186683cc03416b5589e1b6671c6b3057c68 ./processor/tokenizer_config.json
|
| 63 |
+
7768af27c1fafa9cc9011c1dc20067e03f8915e03b63504550e11d5066986d13 ./processor/video_preprocessor_config.json
|
| 64 |
+
ca10d7e9fb3ed18575dd1e277a2579c16d108e32f27439684afa0e10b1440910 ./processor/vocab.json
|
| 65 |
+
432518f56fa7e8fc1b6f48f98d1a93606eb1d3ba3aabb028343bcb7f960a1b2a ./prompts.json
|
| 66 |
+
576410ac684295f68af5f2d64cb236452afc0d7dfab7989d786f2a0e1126ba14 ./quantization_manifest.json
|
| 67 |
+
1637243cc87dc53123f28988cc72c9fb1ac986af4995ba47d07ddc4b4f161af7 ./runtime-requirements.txt
|
| 68 |
+
8fa6c3aa70dc9e691e1a6df899fd1b6f75f70481a27cee6e18a303817075c304 ./scheduler/scheduler_config.json
|
| 69 |
+
075a3208f5fba960a4eae3003a5b7fcc57ad3d6a0ba9e8d91391f0d7b64cae04 ./scripts/audit_source_component_copies.py
|
| 70 |
+
5f970b7f378349add8381ad5fa809d711ef315966d0c3a6f4aa36ae7b72665f9 ./scripts/checkpoint_io.py
|
| 71 |
+
2a742dc0234370ad1ebfd909e00e4a9bad18e0b554b26a34c71aff6802f9c68e ./scripts/decode_h3_latents.py
|
| 72 |
+
5f58a74b4408abf18e0617dd35a999ce0f8b8d238fd69f45e163ae0171421145 ./scripts/decode_precision_policy.py
|
| 73 |
+
e9ea546b28f1fc4ec01f1270072280be684d6d92cea3546e268b9b5d3e5b1c2d ./scripts/latent_io.py
|
| 74 |
+
fcd00e50a8230c185f63c33fa09d5b111507df800011b9a6d33b6acf033a1d88 ./scripts/manual_stage_offload.py
|
| 75 |
+
5d1fb5bc4f429447d68f7647a566e90320d55f7ac6b630a320be39642e1f202f ./scripts/media_packaging.py
|
| 76 |
+
655098f3ec10bdbb41bb79b2d38a326d5d7aad115beec90edbfd46611446676a ./scripts/offload_policy.py
|
| 77 |
+
64b2b294d46ce22b3fe9a3e7642e3b1344a190f4a83dd9bb44a3a48204b541d5 ./scripts/orbitquant_h3_compat.py
|
| 78 |
+
8eb302a23053b6d96ecea86974cb55cc5193eb295fc41c314a34c452779f9a07 ./scripts/quality_gate.py
|
| 79 |
+
cfa82c50292f1b62cd95cb201b67a191c65e972f55a9b026b71feaded49dba3e ./scripts/run_quantized_example.py
|
| 80 |
+
841b69c59e4eff19737414b9547599c138581dded744467ab8c6b86d9005a009 ./scripts/runtime_cache_policy.py
|
| 81 |
+
496abd4859f92b354ae9b34d2028864ea1a3c13d92f7067164aea5465d4ba61d ./scripts/verification_policy.py
|
| 82 |
+
de100ce1d13e83fe378b1a8543b2e906ce2cecc4e7153d126864975c5378a7ed ./scripts/verify_components.py
|
| 83 |
+
a2b186303b94eeb97750e4cc498103217c1888794e160c7c6b79dd39220267a9 ./text_encoder/config.json
|
| 84 |
+
19c0e38d660f3366f146fba332780419eab679529fb6381783b1cacc7b863d53 ./text_encoder/generation_config.json
|
| 85 |
+
7461c06c1ee7f5e606bd014e1825183407fcbc18893ef3ec7099398b8274a20f ./text_encoder/model-00001-of-00005.safetensors
|
| 86 |
+
c510d3757606e1cf375e983bf54ff1c2c0ba470c83b74679224bcf8d51745a5f ./text_encoder/model-00002-of-00005.safetensors
|
| 87 |
+
988e2362f4fbe353b761afddff94c69a64eb821409fe226fe835d252edb056ec ./text_encoder/model-00003-of-00005.safetensors
|
| 88 |
+
bfb4cb2a0c7e64ee2960596a5049a797e6a45776c96913e06ee8c1964d11125d ./text_encoder/model-00004-of-00005.safetensors
|
| 89 |
+
3cf949a827326855d2dc847557c2f71bb0d464c9a9cafb444b6c2e0aac86b742 ./text_encoder/model-00005-of-00005.safetensors
|
| 90 |
+
36b2d7912dffc98f6f5e0bd7b11234c451f6c99f351f5f28a87ce30979f73271 ./text_encoder/model.safetensors.index.json
|
| 91 |
+
599bab54075088774b1733fde865d5bd747cbcc7a547c5bc12610e874e26f5e3 ./tokenizer/merges.txt
|
| 92 |
+
a5d85b6dcc535e6b93115a9ef287e6132fdbf30270da6218194ba742261173c7 ./tokenizer/tokenizer.json
|
| 93 |
+
a07e942ac874baa13758de8d1fbdb186683cc03416b5589e1b6671c6b3057c68 ./tokenizer/tokenizer_config.json
|
| 94 |
+
ca10d7e9fb3ed18575dd1e277a2579c16d108e32f27439684afa0e10b1440910 ./tokenizer/vocab.json
|
| 95 |
+
eac2b97122aeab6cb7a324fd8b451e4ad021777d6137d285e2098b089bafb926 ./transformer/config.json
|
| 96 |
+
fa30399f163a85ab89d7e23a93237d8188ea1bf09a6bbd489e0f82102796daa7 ./transformer/diffusion_pytorch_model-00001-of-00005.safetensors
|
| 97 |
+
6d929ad9edbedd0eacde8ecac20f227ce543b1f63edaf7b283340a485e319bdc ./transformer/diffusion_pytorch_model-00002-of-00005.safetensors
|
| 98 |
+
65a6880aad54e1dac2aa64bbe29fbf1199f179a5f6d5b16dd0e9e3448322811f ./transformer/diffusion_pytorch_model-00003-of-00005.safetensors
|
| 99 |
+
8cc4dd8cd6e5dbe8d7610a361ef6fcbbfd7a2a0e4a61fffc73b116f88aad13a7 ./transformer/diffusion_pytorch_model-00004-of-00005.safetensors
|
| 100 |
+
def316191099ee999ee21c7a34b6954c74ffe18d4b7faf92847457afab494cc9 ./transformer/diffusion_pytorch_model-00005-of-00005.safetensors
|
| 101 |
+
127932208cc61680a73ed835cdbf971a8190c7c275668864a855a15c614cb765 ./transformer/diffusion_pytorch_model.safetensors.index.json
|
| 102 |
+
eac2b97122aeab6cb7a324fd8b451e4ad021777d6137d285e2098b089bafb926 ./transformer_ref/config.json
|
| 103 |
+
357baa234bc04ed4843eefe19ce98a23995e24f012bcfc5117b464c9fc649815 ./transformer_ref/diffusion_pytorch_model-00001-of-00005.safetensors
|
| 104 |
+
60b0663b551b9cf1ccc62c14571689c3cf54de8efef0971b1687cbbed9ba2149 ./transformer_ref/diffusion_pytorch_model-00002-of-00005.safetensors
|
| 105 |
+
ee2c6a0690df2c2d13e21c82cd6c25ef499a5e317d71944ce70cb83f1747b1b0 ./transformer_ref/diffusion_pytorch_model-00003-of-00005.safetensors
|
| 106 |
+
a353924509eff7dd7be99f3efc8c57eecf4d87e24976ab2b02e2367141891651 ./transformer_ref/diffusion_pytorch_model-00004-of-00005.safetensors
|
| 107 |
+
006e19769149a3f3d96a5df7341bca346cfb0113d6e2b1b984167acd3daf5e12 ./transformer_ref/diffusion_pytorch_model-00005-of-00005.safetensors
|
| 108 |
+
127932208cc61680a73ed835cdbf971a8190c7c275668864a855a15c614cb765 ./transformer_ref/diffusion_pytorch_model.safetensors.index.json
|
| 109 |
+
78f67deec3d63aae807f2bfe7154bc1e26f6372cb20b63265fcbae1b62bb5745 ./vae/config.json
|
| 110 |
+
72f4c6be84ac0674f27398cde991dd9d719762f3952c4921aa66b2ce542f6374 ./vae/diffusion_pytorch_model-00001-of-00003.safetensors
|
| 111 |
+
2e05e8bc23fa4071043e17fd242be8acd0685e781a43987432b2eae925be4198 ./vae/diffusion_pytorch_model-00002-of-00003.safetensors
|
| 112 |
+
c05d6ac4b1a33de372799d708531da6320f6a3ce6d1ce6d895e770988e004a39 ./vae/diffusion_pytorch_model-00003-of-00003.safetensors
|
| 113 |
+
15f6d44553c3c616b0dc999920aa784f92ecee7e4201f1f99ac405cfbf3061ca ./vae/diffusion_pytorch_model.safetensors.index.json
|
| 114 |
+
d79d95cb98ff188056ff93668935f434cde9374f64ac7f683141d868e23a7ffe ./validation/audio_vae.json
|
| 115 |
+
bb84e8c4b30042de4306035ac8c7b401bddc6fcadb33336bd9933993d9c8bb3a ./validation/source_component_copy_audit.json
|
| 116 |
+
43e8558e13737d94de0e5739adf10c4e371b00149d5c5965eb8557042749a6fc ./validation/text_encoder.json
|
| 117 |
+
34b7c710e3a1a13ae078f497064703f898b10d782a67d3861efb29c7a0a14c02 ./validation/transformer.json
|
| 118 |
+
8ac5758c586d3b2ac170e6766f0fc5c191ad6e3e7d8de2a372961df29308eda6 ./validation/transformer_ref.json
|
| 119 |
+
18e908a81caf2a84520fd1813b40948867bcc9d1a74f6029f800779cf1417a77 ./validation/vae.json
|
comfyui/examples/h264/comfyui-balanced-t2va-608x480.mp4
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:6c17fa38c5fee6a396a58d7f55981d1cdb644fae5cbbac87a2eb8d4194ad4d2f
|
| 3 |
+
size 946049
|
comfyui/examples/hevc/comfyui-balanced-t2va-608x480-crf10.mp4
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1bbc05a09f3f49d1564afb1b0c0f49a5f3c3a05a34a28e4f8b28f1d3295f5335
|
| 3 |
+
size 4102196
|
comfyui/examples/masters/comfyui-balanced-t2va-608x480-crf1.mp4
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:32711ef0f3a3a341340ab88e31537b26eefd486909154b0ba03ada49896f7f21
|
| 3 |
+
size 14540221
|
comfyui/examples/review/comfyui-balanced-adjacent-triplets.jpg
ADDED
|
Git LFS Details
|
comfyui/examples/review/comfyui-balanced-audio-spectrum.png
ADDED
|
Git LFS Details
|
comfyui/examples/review/comfyui-balanced-frame-120.png
ADDED
|
Git LFS Details
|
comfyui/examples/timelines/comfyui-balanced-t2va-608x480.jpg
ADDED
|
Git LFS Details
|
comfyui/report.json
CHANGED
|
@@ -3,18 +3,20 @@
|
|
| 3 |
"date": "2026-08-04",
|
| 4 |
"hardware": {
|
| 5 |
"provider": "RunPod",
|
| 6 |
-
"
|
| 7 |
-
"
|
| 8 |
-
"
|
| 9 |
-
"
|
|
|
|
| 10 |
},
|
| 11 |
"revisions": {
|
| 12 |
"comfyui": "9a9fdb10ed144ce760d9682cb247526ea23cc525",
|
| 13 |
"comfyui_frontend": "1.47.12",
|
| 14 |
-
"
|
| 15 |
"model_release_tested": "e434bbea523349576e7c3d2f6090744aa4597123",
|
| 16 |
"source_model": "73372e6cf53e414edd3ab03e357717fb0602e758",
|
| 17 |
-
"orbitquant": "0.9.
|
|
|
|
| 18 |
"diffusers": "abc5e9bf71fd38f53cd471bc3acaa84bc5ecbfdc",
|
| 19 |
"official_workflow_templates": "7653f1cdef1d92394b6ef9946018c0a8aa4136b8"
|
| 20 |
},
|
|
@@ -24,73 +26,116 @@
|
|
| 24 |
"release_type": "ORBITQUANT_RELEASE",
|
| 25 |
"output_type": "VIDEO",
|
| 26 |
"model_specific_public_nodes": false,
|
| 27 |
-
"adapter": "minimax_h3"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
},
|
| 29 |
-
"
|
| 30 |
-
"
|
| 31 |
-
"
|
| 32 |
-
"
|
| 33 |
-
"
|
| 34 |
-
"
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
"steps": 50
|
| 43 |
-
},
|
| 44 |
-
"terminal_prompt_id": "823b3407-ae85-43fd-b51a-129ea7a11f4d",
|
| 45 |
-
"save_video_output": {
|
| 46 |
-
"codec": "h264",
|
| 47 |
-
"width": 608,
|
| 48 |
-
"height": 480,
|
| 49 |
-
"frames": 124,
|
| 50 |
-
"fps": 24,
|
| 51 |
-
"audio": "aac stereo 32000 Hz",
|
| 52 |
-
"duration_seconds": 5.175
|
| 53 |
-
}
|
| 54 |
},
|
| 55 |
-
"
|
| 56 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
"status": "pass",
|
| 58 |
-
"
|
| 59 |
-
"
|
| 60 |
-
"
|
| 61 |
-
"
|
| 62 |
-
"
|
| 63 |
-
"
|
| 64 |
-
"
|
| 65 |
-
"
|
| 66 |
-
"
|
| 67 |
-
"
|
| 68 |
-
"audio_vae_dtype": "fp32",
|
| 69 |
-
"semantic_review": "pass: stable face, eyes, lips, wet-hair and jacket texture; no grid, ghosting, or temporal collapse"
|
| 70 |
},
|
| 71 |
-
"
|
| 72 |
"status": "pass",
|
| 73 |
-
"
|
| 74 |
-
"
|
| 75 |
-
"
|
| 76 |
-
"
|
| 77 |
-
"
|
| 78 |
-
"
|
| 79 |
-
"
|
| 80 |
-
"
|
| 81 |
-
"
|
| 82 |
-
"
|
| 83 |
-
"
|
| 84 |
-
|
| 85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
}
|
| 87 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
"media": {
|
| 89 |
-
"
|
| 90 |
-
"
|
| 91 |
-
"
|
| 92 |
-
"
|
| 93 |
-
"
|
| 94 |
-
"
|
|
|
|
|
|
|
| 95 |
}
|
| 96 |
}
|
|
|
|
| 3 |
"date": "2026-08-04",
|
| 4 |
"hardware": {
|
| 5 |
"provider": "RunPod",
|
| 6 |
+
"speed_and_comfy_gpu": "NVIDIA RTX PRO 6000 Blackwell Workstation Edition",
|
| 7 |
+
"speed_and_comfy_gpu_memory_mib": 97887,
|
| 8 |
+
"minimum_vram_gpu": "NVIDIA GeForce RTX 4090",
|
| 9 |
+
"cuda": "13.0",
|
| 10 |
+
"template": "runpod-torch-v280"
|
| 11 |
},
|
| 12 |
"revisions": {
|
| 13 |
"comfyui": "9a9fdb10ed144ce760d9682cb247526ea23cc525",
|
| 14 |
"comfyui_frontend": "1.47.12",
|
| 15 |
+
"comfyui_orbitquant_branch": "main",
|
| 16 |
"model_release_tested": "e434bbea523349576e7c3d2f6090744aa4597123",
|
| 17 |
"source_model": "73372e6cf53e414edd3ab03e357717fb0602e758",
|
| 18 |
+
"orbitquant": "0.9.2",
|
| 19 |
+
"orbitquant_revision": "cd58b4ecf77f22b8c4116b3d0b7d4af258e16ba3",
|
| 20 |
"diffusers": "abc5e9bf71fd38f53cd471bc3acaa84bc5ecbfdc",
|
| 21 |
"official_workflow_templates": "7653f1cdef1d92394b6ef9946018c0a8aa4136b8"
|
| 22 |
},
|
|
|
|
| 26 |
"release_type": "ORBITQUANT_RELEASE",
|
| 27 |
"output_type": "VIDEO",
|
| 28 |
"model_specific_public_nodes": false,
|
| 29 |
+
"adapter": "minimax_h3",
|
| 30 |
+
"inference_profiles": [
|
| 31 |
+
"balanced",
|
| 32 |
+
"speed",
|
| 33 |
+
"minimum_vram"
|
| 34 |
+
]
|
| 35 |
},
|
| 36 |
+
"common_recipe": {
|
| 37 |
+
"width": 608,
|
| 38 |
+
"height": 480,
|
| 39 |
+
"num_frames": 124,
|
| 40 |
+
"fps": 24,
|
| 41 |
+
"sigma_points": 24,
|
| 42 |
+
"denoiser_forwards": 23,
|
| 43 |
+
"native_w4_modules": "300/300",
|
| 44 |
+
"attention": "native_auto_torch_flash_sdpa",
|
| 45 |
+
"int8_weight_cache_modules": 0,
|
| 46 |
+
"conditioner": "sequential_cuda_layers_then_cpu",
|
| 47 |
+
"vae": "untouched_source_fp32_tiled_decode",
|
| 48 |
+
"audio_vae": "untouched_source_fp32_cuda_only_during_audio_stage"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
},
|
| 50 |
+
"profiles": {
|
| 51 |
+
"balanced": {
|
| 52 |
+
"status": "pass",
|
| 53 |
+
"task": "t2va",
|
| 54 |
+
"gpu": "NVIDIA RTX PRO 6000 Blackwell Workstation Edition",
|
| 55 |
+
"offload": "streamed_leaf_group_offload",
|
| 56 |
+
"cuda_memory_cap_gib": 12.0,
|
| 57 |
+
"live_comfyui_terminal_prompt_id": "b23d25f6-3b6c-4be5-89c7-b3f2604159d0",
|
| 58 |
+
"api_harness_elapsed_seconds": 105.09174448787235,
|
| 59 |
+
"load_seconds": 10.83373383898288,
|
| 60 |
+
"denoise_seconds": 46.68325518886559,
|
| 61 |
+
"generation_torch_peak_gib": 1.9883627891540527,
|
| 62 |
+
"full_run_sampled_child_process_peak_gib_approx": 6.04,
|
| 63 |
+
"four_forward_delivery_gate_child_peak_gib": 6.365,
|
| 64 |
+
"four_forward_delivery_gate_total_device_peak_gib": 6.902344,
|
| 65 |
+
"comfyui_idle_context_gib": 0.537,
|
| 66 |
+
"rss_peak_gib": 42.852699279785156,
|
| 67 |
+
"video_decode_seconds": 31.002969308989123,
|
| 68 |
+
"video_decode_torch_peak_gib": 1.0246772766113281,
|
| 69 |
+
"audio_decode_seconds": 0.1771434131078422,
|
| 70 |
+
"audio_decode_torch_peak_gib": 0.9356474876403809,
|
| 71 |
+
"audio_std": 0.17499302327632904,
|
| 72 |
+
"semantic_review": "pass: coherent macro-to-face shot; aligned eyes and lips; no grid, ghosting, texture collapse, section redraw, narrow whistle, NaN, Inf, or clipping failure"
|
| 73 |
+
},
|
| 74 |
+
"speed_t2va": {
|
| 75 |
"status": "pass",
|
| 76 |
+
"gpu": "NVIDIA RTX PRO 6000 Blackwell Workstation Edition",
|
| 77 |
+
"offload": "resident_transformer",
|
| 78 |
+
"process_peak_gib": 21.136719,
|
| 79 |
+
"torch_peak_gib": 19.136168,
|
| 80 |
+
"rss_peak_gib": 21.008953,
|
| 81 |
+
"median_warm_forward_seconds": 2.036486,
|
| 82 |
+
"denoise_seconds": 46.839179,
|
| 83 |
+
"generation_seconds": 51.09528,
|
| 84 |
+
"harness_seconds": 57.535302,
|
| 85 |
+
"semantic_review": "pass: source-FP32 decode retains final face, wet hair, skin texture, hard-surface rings, and broadband storm audio without a persistent squeal"
|
|
|
|
|
|
|
| 86 |
},
|
| 87 |
+
"minimum_vram_t2va": {
|
| 88 |
"status": "pass",
|
| 89 |
+
"gpu": "NVIDIA GeForce RTX 4090",
|
| 90 |
+
"offload": "low_cpu_memory_streamed_leaf_group_offload",
|
| 91 |
+
"cuda_memory_cap_gib": 8.0,
|
| 92 |
+
"process_peak_gib": 4.066406,
|
| 93 |
+
"torch_peak_gib": 2.108679,
|
| 94 |
+
"rss_peak_gib": 35.763912,
|
| 95 |
+
"median_warm_forward_seconds": 6.706353,
|
| 96 |
+
"denoise_seconds": 154.246112,
|
| 97 |
+
"generation_seconds": 188.701789,
|
| 98 |
+
"harness_seconds": 206.821594,
|
| 99 |
+
"semantic_review": "pass: independently decoded streamed-order latent retains the dynamic sequence and final face without a grid, collapse, or persistent narrow squeal"
|
| 100 |
+
},
|
| 101 |
+
"speed_ref2va": {
|
| 102 |
+
"status": "pass",
|
| 103 |
+
"gpu": "NVIDIA RTX PRO 6000 Blackwell Workstation Edition",
|
| 104 |
+
"offload": "resident_transformer_ref",
|
| 105 |
+
"process_peak_gib": 24.058594,
|
| 106 |
+
"torch_peak_gib": 21.026865,
|
| 107 |
+
"rss_peak_gib": 22.914082,
|
| 108 |
+
"median_warm_forward_seconds": 5.151465,
|
| 109 |
+
"denoise_seconds": 118.483702,
|
| 110 |
+
"generation_seconds": 155.421968,
|
| 111 |
+
"harness_seconds": 161.40482,
|
| 112 |
+
"semantic_review": "pass: source-FP32 reference and output VAE stages; all-frame face, rigid-edge, boundary, playback, and audio gates passed"
|
| 113 |
}
|
| 114 |
},
|
| 115 |
+
"workflow": {
|
| 116 |
+
"source": "Comfy-Org/workflow_templates/templates/video_minimax_h3_t2v.json",
|
| 117 |
+
"ui_file": "workflows/minimax-h3-t2va-ui.json",
|
| 118 |
+
"api_file_from_live_graph": "workflows/minimax-h3-public-ui-api.json",
|
| 119 |
+
"workflow_image_export": "workflow-export.png",
|
| 120 |
+
"export_method": "ComfyUI Workflow Image Export action",
|
| 121 |
+
"export_width": 3060,
|
| 122 |
+
"export_height": 1310,
|
| 123 |
+
"embedded_workflow": true,
|
| 124 |
+
"embedded_node_count": 6,
|
| 125 |
+
"embedded_link_count": 2,
|
| 126 |
+
"embedded_profile": "balanced",
|
| 127 |
+
"embedded_steps": 24,
|
| 128 |
+
"embedded_prompt_characters": 1909,
|
| 129 |
+
"missing_nodes_after_png_import": []
|
| 130 |
+
},
|
| 131 |
"media": {
|
| 132 |
+
"balanced_master_crf1_sha256": "32711ef0f3a3a341340ab88e31537b26eefd486909154b0ba03ada49896f7f21",
|
| 133 |
+
"balanced_hevc_crf10_sha256": "1bbc05a09f3f49d1564afb1b0c0f49a5f3c3a05a34a28e4f8b28f1d3295f5335",
|
| 134 |
+
"balanced_h264_preview_sha256": "6c17fa38c5fee6a396a58d7f55981d1cdb644fae5cbbac87a2eb8d4194ad4d2f",
|
| 135 |
+
"balanced_timeline_sha256": "f081bb49aa12d73c108f8fef963c51c387662590cc41c6b069a0c7a47e7552e5",
|
| 136 |
+
"balanced_adjacent_triplets_sha256": "a1114d1ba23da74c0ee1d911599cdd50cab3deef5e2de9e9ff9b9ff9167f97db",
|
| 137 |
+
"balanced_frame_120_sha256": "5a5139474ed5aed90706a002bef1d574b2e737b24164e2367e008167bde34f48",
|
| 138 |
+
"balanced_audio_spectrum_sha256": "36b4c549e3bf39716325a81ea14417be811ac8b5dd7a71bfe596aef8288ab385",
|
| 139 |
+
"workflow_image_export_sha256": "164ac2cd2dd51a1aa7a99c213e6777585b48b9efdbe6ad742e39cad8a5143caf"
|
| 140 |
}
|
| 141 |
}
|
comfyui/workflow-export.png
CHANGED
|
Git LFS Details
|
|
Git LFS Details
|
comfyui/workflows/MiniMax-H3-OrbitQuant-Ref2VA-api.json
CHANGED
|
@@ -17,12 +17,13 @@
|
|
| 17 |
],
|
| 18 |
"prompt": "Single continuous cinematic shot of the referenced astronaut. The astronaut turns toward the camera and raises one gloved hand as the camera makes a fast smooth push-in toward the helmet visor. The face, eyes, visor reflections, suit patches, and fabric texture remain coherent during motion. No cuts.",
|
| 19 |
"task": "ref2va",
|
|
|
|
| 20 |
"reference_path": "/workspace/evidence/astronaut.png",
|
| 21 |
"seed": 314159,
|
| 22 |
"width": 608,
|
| 23 |
"height": 480,
|
| 24 |
"num_frames": 124,
|
| 25 |
-
"steps":
|
| 26 |
"filename_prefix": "orbitquant/minimax-h3-ref2va"
|
| 27 |
},
|
| 28 |
"_meta": {
|
|
|
|
| 17 |
],
|
| 18 |
"prompt": "Single continuous cinematic shot of the referenced astronaut. The astronaut turns toward the camera and raises one gloved hand as the camera makes a fast smooth push-in toward the helmet visor. The face, eyes, visor reflections, suit patches, and fabric texture remain coherent during motion. No cuts.",
|
| 19 |
"task": "ref2va",
|
| 20 |
+
"inference_profile": "speed",
|
| 21 |
"reference_path": "/workspace/evidence/astronaut.png",
|
| 22 |
"seed": 314159,
|
| 23 |
"width": 608,
|
| 24 |
"height": 480,
|
| 25 |
"num_frames": 124,
|
| 26 |
+
"steps": 24,
|
| 27 |
"filename_prefix": "orbitquant/minimax-h3-ref2va"
|
| 28 |
},
|
| 29 |
"_meta": {
|
comfyui/workflows/MiniMax-H3-OrbitQuant-T2VA-api.json
CHANGED
|
@@ -16,14 +16,15 @@
|
|
| 16 |
},
|
| 17 |
"105": {
|
| 18 |
"inputs": {
|
| 19 |
-
"prompt": "
|
| 20 |
"task": "t2va",
|
|
|
|
| 21 |
"reference_path": "",
|
| 22 |
"seed": 42,
|
| 23 |
"width": 608,
|
| 24 |
"height": 480,
|
| 25 |
"num_frames": 124,
|
| 26 |
-
"steps":
|
| 27 |
"filename_prefix": "orbitquant/minimax-h3-t2va",
|
| 28 |
"release": [
|
| 29 |
"119",
|
|
|
|
| 16 |
},
|
| 17 |
"105": {
|
| 18 |
"inputs": {
|
| 19 |
+
"prompt": "Create one uninterrupted five-second photorealistic cinematic shot inside a vast abandoned Victorian astronomical conservatory during a midnight thunderstorm. Begin centimetres above a flooded mosaic floor on an extreme macro view of a scratched silver compass as a raindrop creates concentric ripples through reflected amber lamps. In the background, the same young female astronomer with dark hazel eyes, a small scar through her right eyebrow, rain-darkened curls and a burgundy wool coat runs toward an antique brass orrery. The camera performs one fast but smooth backward-and-upward crane with a clockwise half-orbit, passes cleanly between rotating copper rings, racks focus from the compass to her face, then transitions into a controlled push-in. Preserve strong physical parallax, straight architecture, attached compass parts, stable orrery topology, readable glass planets, plausible splashes, coherent wet fabric, fixed facial identity, aligned eyes, natural lips, five stable fingers and consistent hairline throughout every frame. A blue-white lightning flash crosses the dome and illuminates the woman, water, brass and glass coherently, followed by physically delayed thunder. In the final close-up she catches her breath, looks into the lens, grips a small brass lever and says clearly in Russian: «Не бойся грома — смотри, как небо запоминает нас». Synchronize her lips and preserve a single natural voice. Build continuous stereo sound from rain, footsteps, brass gears, wind through cracked glass, lightning and thunder; no electronic squeal, duplicated speech or clipping. Use believable anamorphic photography, restrained halation, realistic skin, natural motion blur, coherent reflections and subtle sensor grain. No cuts, temporal resets, face morphing, crossed eyes, melting mouth, texture crawling, checkerboard grids, duplicated limbs, subtitles, logos, watermarks or black frames.",
|
| 20 |
"task": "t2va",
|
| 21 |
+
"inference_profile": "balanced",
|
| 22 |
"reference_path": "",
|
| 23 |
"seed": 42,
|
| 24 |
"width": 608,
|
| 25 |
"height": 480,
|
| 26 |
"num_frames": 124,
|
| 27 |
+
"steps": 24,
|
| 28 |
"filename_prefix": "orbitquant/minimax-h3-t2va",
|
| 29 |
"release": [
|
| 30 |
"119",
|
comfyui/workflows/MiniMax-H3-OrbitQuant-T2VA.json
CHANGED
|
@@ -32,7 +32,7 @@
|
|
| 32 |
"outputs": [],
|
| 33 |
"title": "Note: MiniMax H3 OrbitQuant",
|
| 34 |
"properties": {},
|
| 35 |
-
"widgets_values": ["MINIMAX H3 — ORBITQUANT W4A4\n\nThis workflow follows ComfyUI's bundled\nMiniMax H3 Text to Video preset.\n\nLayout:\n- model and usage notes on the left\n- compact generation in the center\n- core Save Video on the right\n\nOfficial preset:\nComfy-Org/workflow_templates\nvideo_minimax_h3_t2v.json\n\nKEY INPUTS\n\nprompt\nDescribe the shot, camera motion, dialogue,\nsound effects, and music in one block.\n\ntask\nt2va for text-to-video. Use ref2va plus a\nlocal reference_path for reference-to-video.\n\nwidth / height\nVerified at 608 × 480.\n\nnum_frames\n124 frames: the shortest verified\nfive-second H3 packing sequence.\n\nsteps\
|
| 36 |
"color": "#222",
|
| 37 |
"bgcolor": "#000"
|
| 38 |
},
|
|
@@ -65,6 +65,7 @@
|
|
| 65 |
{"name": "release", "type": "ORBITQUANT_RELEASE", "link": 1},
|
| 66 |
{"name": "prompt", "type": "STRING", "widget": {"name": "prompt"}, "link": null},
|
| 67 |
{"name": "task", "type": "COMBO", "widget": {"name": "task"}, "link": null},
|
|
|
|
| 68 |
{"name": "reference_path", "type": "STRING", "widget": {"name": "reference_path"}, "link": null},
|
| 69 |
{"name": "seed", "type": "INT", "widget": {"name": "seed"}, "link": null},
|
| 70 |
{"name": "width", "type": "INT", "widget": {"name": "width"}, "link": null},
|
|
@@ -80,14 +81,15 @@
|
|
| 80 |
"title": "Generate Video (Verified 608 × 480)",
|
| 81 |
"properties": {"Node name for S&R": "OrbitQuantGenerateVideo", "previewExposures": []},
|
| 82 |
"widgets_values": [
|
| 83 |
-
"
|
| 84 |
"t2va",
|
|
|
|
| 85 |
"",
|
| 86 |
42,
|
| 87 |
608,
|
| 88 |
480,
|
| 89 |
124,
|
| 90 |
-
|
| 91 |
"orbitquant/minimax-h3-t2va"
|
| 92 |
]
|
| 93 |
},
|
|
@@ -120,7 +122,7 @@
|
|
| 120 |
"outputs": [],
|
| 121 |
"title": "Note: Verified Profile",
|
| 122 |
"properties": {},
|
| 123 |
-
"widgets_values": ["VERIFIED 480P PROFILE\n\nwidth 608\nheight 480\nframes 124\nfps 24\nsigma points
|
| 124 |
"color": "#222",
|
| 125 |
"bgcolor": "#000"
|
| 126 |
}
|
|
|
|
| 32 |
"outputs": [],
|
| 33 |
"title": "Note: MiniMax H3 OrbitQuant",
|
| 34 |
"properties": {},
|
| 35 |
+
"widgets_values": ["MINIMAX H3 — ORBITQUANT W4A4\n\nThis workflow follows ComfyUI's bundled\nMiniMax H3 Text to Video preset.\n\nLayout:\n- model and usage notes on the left\n- compact generation in the center\n- core Save Video on the right\n\nOfficial preset:\nComfy-Org/workflow_templates\nvideo_minimax_h3_t2v.json\n\nKEY INPUTS\n\nprompt\nDescribe the shot, camera motion, dialogue,\nsound effects, and music in one block.\n\ntask\nt2va for text-to-video. Use ref2va plus a\nlocal reference_path for reference-to-video.\n\ninference_profile\nbalanced is the safe default; speed keeps the\ntransformer resident; minimum_vram streams\nweights with low-CPU-memory loading.\n\nwidth / height\nVerified at 608 × 480.\n\nnum_frames\n124 frames: the shortest verified\nfive-second H3 packing sequence.\n\nsteps\n24 sigma points / 23 denoiser forwards.\n\nOFFLOAD AND PRECISION\n\nThe text encoder executes sequentially on GPU\nfor conditioning and returns to CPU afterward.\nRef2VA reference encoding uses tiled sequential\nGPU VAE execution. Visual and audio decode use\nuntouched source FP32 VAEs."],
|
| 36 |
"color": "#222",
|
| 37 |
"bgcolor": "#000"
|
| 38 |
},
|
|
|
|
| 65 |
{"name": "release", "type": "ORBITQUANT_RELEASE", "link": 1},
|
| 66 |
{"name": "prompt", "type": "STRING", "widget": {"name": "prompt"}, "link": null},
|
| 67 |
{"name": "task", "type": "COMBO", "widget": {"name": "task"}, "link": null},
|
| 68 |
+
{"name": "inference_profile", "type": "COMBO", "widget": {"name": "inference_profile"}, "link": null},
|
| 69 |
{"name": "reference_path", "type": "STRING", "widget": {"name": "reference_path"}, "link": null},
|
| 70 |
{"name": "seed", "type": "INT", "widget": {"name": "seed"}, "link": null},
|
| 71 |
{"name": "width", "type": "INT", "widget": {"name": "width"}, "link": null},
|
|
|
|
| 81 |
"title": "Generate Video (Verified 608 × 480)",
|
| 82 |
"properties": {"Node name for S&R": "OrbitQuantGenerateVideo", "previewExposures": []},
|
| 83 |
"widgets_values": [
|
| 84 |
+
"Create one uninterrupted five-second photorealistic cinematic shot inside a vast abandoned Victorian astronomical conservatory during a midnight thunderstorm. Begin centimetres above a flooded mosaic floor on an extreme macro view of a scratched silver compass as a raindrop creates concentric ripples through reflected amber lamps. In the background, the same young female astronomer with dark hazel eyes, a small scar through her right eyebrow, rain-darkened curls and a burgundy wool coat runs toward an antique brass orrery. The camera performs one fast but smooth backward-and-upward crane with a clockwise half-orbit, passes cleanly between rotating copper rings, racks focus from the compass to her face, then transitions into a controlled push-in. Preserve strong physical parallax, straight architecture, attached compass parts, stable orrery topology, readable glass planets, plausible splashes, coherent wet fabric, fixed facial identity, aligned eyes, natural lips, five stable fingers and consistent hairline throughout every frame. A blue-white lightning flash crosses the dome and illuminates the woman, water, brass and glass coherently, followed by physically delayed thunder. In the final close-up she catches her breath, looks into the lens, grips a small brass lever and says clearly in Russian: «Не бойся грома — смотри, как небо запоминает нас». Synchronize her lips and preserve a single natural voice. Build continuous stereo sound from rain, footsteps, brass gears, wind through cracked glass, lightning and thunder; no electronic squeal, duplicated speech or clipping. Use believable anamorphic photography, restrained halation, realistic skin, natural motion blur, coherent reflections and subtle sensor grain. No cuts, temporal resets, face morphing, crossed eyes, melting mouth, texture crawling, checkerboard grids, duplicated limbs, subtitles, logos, watermarks or black frames.",
|
| 85 |
"t2va",
|
| 86 |
+
"balanced",
|
| 87 |
"",
|
| 88 |
42,
|
| 89 |
608,
|
| 90 |
480,
|
| 91 |
124,
|
| 92 |
+
24,
|
| 93 |
"orbitquant/minimax-h3-t2va"
|
| 94 |
]
|
| 95 |
},
|
|
|
|
| 122 |
"outputs": [],
|
| 123 |
"title": "Note: Verified Profile",
|
| 124 |
"properties": {},
|
| 125 |
+
"widgets_values": ["VERIFIED 480P PROFILE\n\nwidth 608\nheight 480\nframes 124\nfps 24\nsigma points 24\ndenoiser forwards 23\ndefault profile balanced\nvisual VAE source FP32\naudio VAE source FP32\n\nH3 accepts 5–15 seconds. The runner rejects\nshorter frame counts before allocating the\ndenoiser, preventing expensive invalid jobs.\n\nScheduler checkpoints, the latent bundle,\nmetrics, and stage logs are persisted as soon\nas each artifact exists."],
|
| 126 |
"color": "#222",
|
| 127 |
"bgcolor": "#000"
|
| 128 |
}
|
comfyui_orbitquant.json
CHANGED
|
@@ -10,6 +10,7 @@
|
|
| 10 |
"width": 608,
|
| 11 |
"height": 480,
|
| 12 |
"num_frames": 124,
|
| 13 |
-
"steps":
|
|
|
|
| 14 |
}
|
| 15 |
}
|
|
|
|
| 10 |
"width": 608,
|
| 11 |
"height": 480,
|
| 12 |
"num_frames": 124,
|
| 13 |
+
"steps": 24,
|
| 14 |
+
"inference_profile": "balanced"
|
| 15 |
}
|
| 16 |
}
|
quantization_manifest.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
| 4 |
"source_revision": "73372e6cf53e414edd3ab03e357717fb0602e758",
|
| 5 |
"source_license": "minimax-h3-community-license-agreement",
|
| 6 |
"repo_id": "WaveCut/MiniMax-H3-OrbitQuant-W4A4",
|
| 7 |
-
"visibility": "
|
| 8 |
"quant_method": "orbitquant",
|
| 9 |
"recipe": "native-w4a4-text-and-denoisers-source-fp32-vaes",
|
| 10 |
"weight_bits": 4,
|
|
@@ -19,8 +19,8 @@
|
|
| 19 |
"audio_vae"
|
| 20 |
],
|
| 21 |
"calibration_data": null,
|
| 22 |
-
"orbitquant_version": "0.9.
|
| 23 |
-
"orbitquant_revision": "
|
| 24 |
"diffusers_revision": "abc5e9bf71fd38f53cd471bc3acaa84bc5ecbfdc",
|
| 25 |
"components": [
|
| 26 |
{
|
|
@@ -1554,13 +1554,21 @@
|
|
| 1554 |
"transformer_ref": "native_packed_w4a4_bf16_compute",
|
| 1555 |
"vae": "source_fp32_separate_decode",
|
| 1556 |
"audio_vae": "source_fp32_separate_decode",
|
| 1557 |
-
"num_inference_steps":
|
| 1558 |
-
"model_evaluations":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1559 |
},
|
| 1560 |
"validated_runtime_provenance": {
|
| 1561 |
-
"orbitquant_version": "0.9.
|
| 1562 |
-
"orbitquant_revision": "
|
| 1563 |
-
"orbitquant_requirement": "orbitquant[hf,kernels]>=0.9.
|
| 1564 |
"diffusers_revision": "abc5e9bf71fd38f53cd471bc3acaa84bc5ecbfdc"
|
| 1565 |
}
|
| 1566 |
}
|
|
|
|
| 4 |
"source_revision": "73372e6cf53e414edd3ab03e357717fb0602e758",
|
| 5 |
"source_license": "minimax-h3-community-license-agreement",
|
| 6 |
"repo_id": "WaveCut/MiniMax-H3-OrbitQuant-W4A4",
|
| 7 |
+
"visibility": "public",
|
| 8 |
"quant_method": "orbitquant",
|
| 9 |
"recipe": "native-w4a4-text-and-denoisers-source-fp32-vaes",
|
| 10 |
"weight_bits": 4,
|
|
|
|
| 19 |
"audio_vae"
|
| 20 |
],
|
| 21 |
"calibration_data": null,
|
| 22 |
+
"orbitquant_version": "0.9.2",
|
| 23 |
+
"orbitquant_revision": "cd58b4ecf77f22b8c4116b3d0b7d4af258e16ba3",
|
| 24 |
"diffusers_revision": "abc5e9bf71fd38f53cd471bc3acaa84bc5ecbfdc",
|
| 25 |
"components": [
|
| 26 |
{
|
|
|
|
| 1554 |
"transformer_ref": "native_packed_w4a4_bf16_compute",
|
| 1555 |
"vae": "source_fp32_separate_decode",
|
| 1556 |
"audio_vae": "source_fp32_separate_decode",
|
| 1557 |
+
"num_inference_steps": 24,
|
| 1558 |
+
"model_evaluations": 23,
|
| 1559 |
+
"default_inference_profile": "balanced",
|
| 1560 |
+
"inference_profiles": {
|
| 1561 |
+
"balanced": "streamed_leaf_group_offload_with_12_gib_allocator_cap",
|
| 1562 |
+
"speed": "resident_selected_transformer",
|
| 1563 |
+
"minimum_vram": "low_cpu_memory_streamed_leaf_group_offload_with_8_gib_allocator_cap"
|
| 1564 |
+
},
|
| 1565 |
+
"exact_int8_weight_cache": false,
|
| 1566 |
+
"attention_backend": "native_auto_torch_flash_sdpa"
|
| 1567 |
},
|
| 1568 |
"validated_runtime_provenance": {
|
| 1569 |
+
"orbitquant_version": "0.9.2",
|
| 1570 |
+
"orbitquant_revision": "cd58b4ecf77f22b8c4116b3d0b7d4af258e16ba3",
|
| 1571 |
+
"orbitquant_requirement": "orbitquant[hf,kernels]>=0.9.2,<0.10",
|
| 1572 |
"diffusers_revision": "abc5e9bf71fd38f53cd471bc3acaa84bc5ecbfdc"
|
| 1573 |
}
|
| 1574 |
}
|
runtime-requirements.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
orbitquant[hf,kernels]>=0.9.
|
| 2 |
diffusers @ git+https://github.com/huggingface/diffusers.git@abc5e9bf71fd38f53cd471bc3acaa84bc5ecbfdc
|
| 3 |
transformers>=5.13,<6
|
| 4 |
accelerate
|
|
|
|
| 1 |
+
orbitquant[hf,kernels]>=0.9.2,<0.10
|
| 2 |
diffusers @ git+https://github.com/huggingface/diffusers.git@abc5e9bf71fd38f53cd471bc3acaa84bc5ecbfdc
|
| 3 |
transformers>=5.13,<6
|
| 4 |
accelerate
|
scripts/decode_h3_latents.py
CHANGED
|
@@ -2,93 +2,169 @@
|
|
| 2 |
from __future__ import annotations
|
| 3 |
|
| 4 |
import argparse
|
|
|
|
| 5 |
import json
|
| 6 |
import resource
|
| 7 |
import time
|
| 8 |
from pathlib import Path
|
| 9 |
|
|
|
|
| 10 |
import torch
|
| 11 |
-
|
| 12 |
-
import orbitquant # noqa: F401 - register OrbitQuant Diffusers loaders
|
| 13 |
from diffusers import AutoencoderKLMiniMaxH3, AutoencoderKLMiniMaxH3Audio
|
| 14 |
-
from diffusers.modular_pipelines.minimax_h3.packing import
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
| 16 |
from diffusers.video_processor import VideoProcessor
|
| 17 |
|
| 18 |
from checkpoint_io import atomic_json_write
|
| 19 |
-
from decode_precision_policy import torch_dtype_name
|
| 20 |
from latent_io import load_latent_bundle, prepare_inference_model
|
| 21 |
from media_packaging import atomic_media_output
|
| 22 |
|
| 23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
def main() -> int:
|
| 25 |
parser = argparse.ArgumentParser()
|
| 26 |
parser.add_argument("--latents", type=Path, required=True)
|
| 27 |
parser.add_argument("--vae", type=Path, required=True)
|
| 28 |
parser.add_argument("--audio-vae", type=Path, required=True)
|
| 29 |
-
parser.add_argument("--vae-dtype", choices=("orbitquant", "fp32", "bf16"), required=True)
|
| 30 |
-
parser.add_argument(
|
| 31 |
-
"--audio-vae-dtype", choices=("orbitquant", "fp32", "bf16"), required=True
|
| 32 |
-
)
|
| 33 |
parser.add_argument("--output", type=Path, required=True)
|
|
|
|
|
|
|
| 34 |
args = parser.parse_args()
|
| 35 |
|
| 36 |
report_path = args.output.with_suffix(".decode.metrics.json")
|
| 37 |
-
report_path.parent.mkdir(parents=True, exist_ok=True)
|
| 38 |
report: dict[str, object] = {
|
| 39 |
"status": "running",
|
| 40 |
"latent_bundle": str(args.latents),
|
| 41 |
"vae": str(args.vae),
|
| 42 |
-
"vae_dtype":
|
| 43 |
"audio_vae": str(args.audio_vae),
|
| 44 |
-
"audio_vae_dtype":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
"gpu": torch.cuda.get_device_name(),
|
| 46 |
}
|
|
|
|
|
|
|
| 47 |
try:
|
| 48 |
bundle = load_latent_bundle(args.latents)
|
| 49 |
metadata = dict(bundle["metadata"])
|
| 50 |
report["metadata"] = metadata
|
| 51 |
|
| 52 |
-
|
| 53 |
-
vae_kwargs = {"low_cpu_mem_usage": True}
|
| 54 |
-
vae_dtype_name = torch_dtype_name(args.vae_dtype)
|
| 55 |
-
if vae_dtype_name is not None:
|
| 56 |
-
vae_kwargs["dtype"] = getattr(torch, vae_dtype_name)
|
| 57 |
vae = prepare_inference_model(
|
| 58 |
-
AutoencoderKLMiniMaxH3.from_pretrained(
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
|
| 70 |
torch.cuda.reset_peak_memory_stats()
|
| 71 |
-
|
| 72 |
video_latents = bundle["video_latents"].to("cuda")
|
| 73 |
with torch.inference_mode(), torch.autocast(device_type="cuda", dtype=torch.float16):
|
| 74 |
video = vae.decode(video_latents, return_dict=False)[0]
|
| 75 |
-
pixel_mean = torch.tensor(MINIMAX_H3_PIXEL_MEAN, device="cuda").view(
|
| 76 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
video = (video.float() * pixel_std + pixel_mean).clamp(0, 1)
|
| 78 |
videos = VideoProcessor(vae_scale_factor=16, do_normalize=False).postprocess_video(
|
| 79 |
-
video,
|
|
|
|
| 80 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
|
|
|
|
|
|
|
| 82 |
audio_latents = bundle["audio_latents"].to("cuda")
|
| 83 |
with torch.inference_mode():
|
| 84 |
audio = audio_vae.decode(audio_latents, return_dict=False)[0]
|
| 85 |
audio = audio.float().permute(1, 0, 2)
|
|
|
|
|
|
|
| 86 |
torch.cuda.synchronize()
|
| 87 |
-
report["
|
| 88 |
-
report["
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
-
|
| 91 |
-
with atomic_media_output(args.
|
| 92 |
encode_video(
|
| 93 |
videos[0],
|
| 94 |
fps=int(metadata["fps"]),
|
|
@@ -96,8 +172,21 @@ def main() -> int:
|
|
| 96 |
audio=audio[0],
|
| 97 |
audio_sample_rate=int(metadata["sampling_rate"]),
|
| 98 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
report["encode_seconds"] = time.perf_counter() - encode_started
|
| 100 |
-
report["video_frames"] = len(videos[0])
|
| 101 |
report["output_bytes"] = args.output.stat().st_size
|
| 102 |
report["rss_peak_bytes"] = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss * 1024
|
| 103 |
report["status"] = "pass"
|
|
|
|
| 2 |
from __future__ import annotations
|
| 3 |
|
| 4 |
import argparse
|
| 5 |
+
import gc
|
| 6 |
import json
|
| 7 |
import resource
|
| 8 |
import time
|
| 9 |
from pathlib import Path
|
| 10 |
|
| 11 |
+
import av
|
| 12 |
import torch
|
| 13 |
+
from accelerate import cpu_offload
|
|
|
|
| 14 |
from diffusers import AutoencoderKLMiniMaxH3, AutoencoderKLMiniMaxH3Audio
|
| 15 |
+
from diffusers.modular_pipelines.minimax_h3.packing import (
|
| 16 |
+
MINIMAX_H3_PIXEL_MEAN,
|
| 17 |
+
MINIMAX_H3_PIXEL_STD,
|
| 18 |
+
)
|
| 19 |
+
from diffusers.utils.export_utils import _prepare_audio_stream, _write_audio, encode_video
|
| 20 |
from diffusers.video_processor import VideoProcessor
|
| 21 |
|
| 22 |
from checkpoint_io import atomic_json_write
|
|
|
|
| 23 |
from latent_io import load_latent_bundle, prepare_inference_model
|
| 24 |
from media_packaging import atomic_media_output
|
| 25 |
|
| 26 |
|
| 27 |
+
def encode_master_crf1(
|
| 28 |
+
frames: list,
|
| 29 |
+
*,
|
| 30 |
+
fps: int,
|
| 31 |
+
output_path: Path,
|
| 32 |
+
audio: torch.Tensor,
|
| 33 |
+
audio_sample_rate: int,
|
| 34 |
+
) -> None:
|
| 35 |
+
"""Write the pre-delivery master before any HEVC recompression."""
|
| 36 |
+
container = av.open(str(output_path), mode="w", format="mp4")
|
| 37 |
+
stream = container.add_stream(
|
| 38 |
+
"libx264",
|
| 39 |
+
rate=fps,
|
| 40 |
+
options={"crf": "1", "preset": "slow"},
|
| 41 |
+
)
|
| 42 |
+
stream.width = frames[0].width
|
| 43 |
+
stream.height = frames[0].height
|
| 44 |
+
stream.pix_fmt = "yuv444p"
|
| 45 |
+
audio_stream = _prepare_audio_stream(container, audio_sample_rate)
|
| 46 |
+
try:
|
| 47 |
+
for image in frames:
|
| 48 |
+
frame = av.VideoFrame.from_image(image)
|
| 49 |
+
for packet in stream.encode(frame):
|
| 50 |
+
container.mux(packet)
|
| 51 |
+
for packet in stream.encode():
|
| 52 |
+
container.mux(packet)
|
| 53 |
+
_write_audio(container, audio_stream, audio, audio_sample_rate, av)
|
| 54 |
+
finally:
|
| 55 |
+
container.close()
|
| 56 |
+
|
| 57 |
+
|
| 58 |
def main() -> int:
|
| 59 |
parser = argparse.ArgumentParser()
|
| 60 |
parser.add_argument("--latents", type=Path, required=True)
|
| 61 |
parser.add_argument("--vae", type=Path, required=True)
|
| 62 |
parser.add_argument("--audio-vae", type=Path, required=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
parser.add_argument("--output", type=Path, required=True)
|
| 64 |
+
parser.add_argument("--preview-output", type=Path, required=True)
|
| 65 |
+
parser.add_argument("--disable-spatial-tiling", action="store_true")
|
| 66 |
args = parser.parse_args()
|
| 67 |
|
| 68 |
report_path = args.output.with_suffix(".decode.metrics.json")
|
|
|
|
| 69 |
report: dict[str, object] = {
|
| 70 |
"status": "running",
|
| 71 |
"latent_bundle": str(args.latents),
|
| 72 |
"vae": str(args.vae),
|
| 73 |
+
"vae_dtype": "fp32_source",
|
| 74 |
"audio_vae": str(args.audio_vae),
|
| 75 |
+
"audio_vae_dtype": "fp32_source",
|
| 76 |
+
"offload": {
|
| 77 |
+
"video_vae": "sequential_cpu_offload",
|
| 78 |
+
"audio_vae": "resident_cuda_during_audio_stage",
|
| 79 |
+
},
|
| 80 |
+
"video_vae_tiling": not args.disable_spatial_tiling,
|
| 81 |
+
"master_video": {
|
| 82 |
+
"codec": "libx264",
|
| 83 |
+
"crf": 1,
|
| 84 |
+
"preset": "slow",
|
| 85 |
+
"pixel_format": "yuv444p",
|
| 86 |
+
},
|
| 87 |
"gpu": torch.cuda.get_device_name(),
|
| 88 |
}
|
| 89 |
+
report_path.parent.mkdir(parents=True, exist_ok=True)
|
| 90 |
+
atomic_json_write(report, report_path)
|
| 91 |
try:
|
| 92 |
bundle = load_latent_bundle(args.latents)
|
| 93 |
metadata = dict(bundle["metadata"])
|
| 94 |
report["metadata"] = metadata
|
| 95 |
|
| 96 |
+
video_load_started = time.perf_counter()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
vae = prepare_inference_model(
|
| 98 |
+
AutoencoderKLMiniMaxH3.from_pretrained(
|
| 99 |
+
args.vae,
|
| 100 |
+
low_cpu_mem_usage=True,
|
| 101 |
+
dtype=torch.float32,
|
| 102 |
+
)
|
| 103 |
+
)
|
| 104 |
+
if args.disable_spatial_tiling:
|
| 105 |
+
vae.disable_tiling()
|
| 106 |
+
else:
|
| 107 |
+
vae.enable_tiling()
|
| 108 |
+
cpu_offload(
|
| 109 |
+
vae,
|
| 110 |
+
execution_device=torch.device("cuda"),
|
| 111 |
+
offload_buffers=True,
|
| 112 |
+
)
|
| 113 |
+
report["video_vae_load_seconds"] = time.perf_counter() - video_load_started
|
| 114 |
|
| 115 |
torch.cuda.reset_peak_memory_stats()
|
| 116 |
+
video_decode_started = time.perf_counter()
|
| 117 |
video_latents = bundle["video_latents"].to("cuda")
|
| 118 |
with torch.inference_mode(), torch.autocast(device_type="cuda", dtype=torch.float16):
|
| 119 |
video = vae.decode(video_latents, return_dict=False)[0]
|
| 120 |
+
pixel_mean = torch.tensor(MINIMAX_H3_PIXEL_MEAN, device="cuda").view(
|
| 121 |
+
1, -1, 1, 1, 1
|
| 122 |
+
)
|
| 123 |
+
pixel_std = torch.tensor(MINIMAX_H3_PIXEL_STD, device="cuda").view(
|
| 124 |
+
1, -1, 1, 1, 1
|
| 125 |
+
)
|
| 126 |
video = (video.float() * pixel_std + pixel_mean).clamp(0, 1)
|
| 127 |
videos = VideoProcessor(vae_scale_factor=16, do_normalize=False).postprocess_video(
|
| 128 |
+
video,
|
| 129 |
+
output_type="pil",
|
| 130 |
)
|
| 131 |
+
torch.cuda.synchronize()
|
| 132 |
+
report["video_decode_seconds"] = time.perf_counter() - video_decode_started
|
| 133 |
+
report["video_decode_torch_peak_bytes"] = torch.cuda.max_memory_allocated()
|
| 134 |
+
report["video_frames"] = len(videos[0])
|
| 135 |
+
|
| 136 |
+
del vae, video_latents, video, pixel_mean, pixel_std
|
| 137 |
+
gc.collect()
|
| 138 |
+
torch.cuda.empty_cache()
|
| 139 |
+
|
| 140 |
+
audio_load_started = time.perf_counter()
|
| 141 |
+
audio_vae = prepare_inference_model(
|
| 142 |
+
AutoencoderKLMiniMaxH3Audio.from_pretrained(
|
| 143 |
+
args.audio_vae,
|
| 144 |
+
low_cpu_mem_usage=True,
|
| 145 |
+
dtype=torch.float32,
|
| 146 |
+
)
|
| 147 |
+
).to("cuda")
|
| 148 |
+
report["audio_vae_offload"] = "resident_cuda_during_audio_stage"
|
| 149 |
+
report["audio_vae_load_seconds"] = time.perf_counter() - audio_load_started
|
| 150 |
|
| 151 |
+
torch.cuda.reset_peak_memory_stats()
|
| 152 |
+
audio_decode_started = time.perf_counter()
|
| 153 |
audio_latents = bundle["audio_latents"].to("cuda")
|
| 154 |
with torch.inference_mode():
|
| 155 |
audio = audio_vae.decode(audio_latents, return_dict=False)[0]
|
| 156 |
audio = audio.float().permute(1, 0, 2)
|
| 157 |
+
if not torch.isfinite(audio).all() or torch.count_nonzero(audio) == 0:
|
| 158 |
+
raise RuntimeError("source audio VAE produced invalid or silent audio")
|
| 159 |
torch.cuda.synchronize()
|
| 160 |
+
report["audio_decode_seconds"] = time.perf_counter() - audio_decode_started
|
| 161 |
+
report["audio_decode_torch_peak_bytes"] = torch.cuda.max_memory_allocated()
|
| 162 |
+
report["audio_min"] = float(audio.min())
|
| 163 |
+
report["audio_max"] = float(audio.max())
|
| 164 |
+
report["audio_std"] = float(audio.std())
|
| 165 |
|
| 166 |
+
preview_started = time.perf_counter()
|
| 167 |
+
with atomic_media_output(args.preview_output) as partial:
|
| 168 |
encode_video(
|
| 169 |
videos[0],
|
| 170 |
fps=int(metadata["fps"]),
|
|
|
|
| 172 |
audio=audio[0],
|
| 173 |
audio_sample_rate=int(metadata["sampling_rate"]),
|
| 174 |
)
|
| 175 |
+
report["preview_encode_seconds"] = time.perf_counter() - preview_started
|
| 176 |
+
report["preview_output"] = str(args.preview_output)
|
| 177 |
+
report["preview_output_bytes"] = args.preview_output.stat().st_size
|
| 178 |
+
atomic_json_write(report, report_path)
|
| 179 |
+
|
| 180 |
+
encode_started = time.perf_counter()
|
| 181 |
+
with atomic_media_output(args.output) as partial:
|
| 182 |
+
encode_master_crf1(
|
| 183 |
+
videos[0],
|
| 184 |
+
fps=int(metadata["fps"]),
|
| 185 |
+
output_path=partial,
|
| 186 |
+
audio=audio[0],
|
| 187 |
+
audio_sample_rate=int(metadata["sampling_rate"]),
|
| 188 |
+
)
|
| 189 |
report["encode_seconds"] = time.perf_counter() - encode_started
|
|
|
|
| 190 |
report["output_bytes"] = args.output.stat().st_size
|
| 191 |
report["rss_peak_bytes"] = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss * 1024
|
| 192 |
report["status"] = "pass"
|
scripts/manual_stage_offload.py
CHANGED
|
@@ -3,6 +3,8 @@ from __future__ import annotations
|
|
| 3 |
|
| 4 |
from collections.abc import Callable
|
| 5 |
|
|
|
|
|
|
|
| 6 |
|
| 7 |
class _ExecutionDeviceHint:
|
| 8 |
execution_device = "cuda"
|
|
@@ -40,6 +42,8 @@ def install_manual_h3_stage_offload(
|
|
| 40 |
text_encoder,
|
| 41 |
transformer,
|
| 42 |
empty_cuda_cache: Callable[[], None],
|
|
|
|
|
|
|
| 43 |
) -> None:
|
| 44 |
"""Run conditioning on CUDA, then free it before placing the denoiser."""
|
| 45 |
install_h3_rope_runtime_alignment(transformer)
|
|
@@ -63,13 +67,18 @@ def install_manual_h3_stage_offload(
|
|
| 63 |
|
| 64 |
def call_then_place_denoiser(step, components, state):
|
| 65 |
result = original_call(step, components, state)
|
| 66 |
-
|
| 67 |
-
|
|
|
|
| 68 |
empty_cuda_cache()
|
| 69 |
-
|
| 70 |
-
|
|
|
|
| 71 |
return result
|
| 72 |
|
| 73 |
encoder_step_cls.encode_prompt = staticmethod(encode_prompt_on_cuda)
|
| 74 |
encoder_step_cls.__call__ = call_then_place_denoiser
|
| 75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
|
| 4 |
from collections.abc import Callable
|
| 5 |
|
| 6 |
+
from accelerate import cpu_offload
|
| 7 |
+
|
| 8 |
|
| 9 |
class _ExecutionDeviceHint:
|
| 10 |
execution_device = "cuda"
|
|
|
|
| 42 |
text_encoder,
|
| 43 |
transformer,
|
| 44 |
empty_cuda_cache: Callable[[], None],
|
| 45 |
+
place_transformer: bool = True,
|
| 46 |
+
sequential_text_encoder: bool = False,
|
| 47 |
) -> None:
|
| 48 |
"""Run conditioning on CUDA, then free it before placing the denoiser."""
|
| 49 |
install_h3_rope_runtime_alignment(transformer)
|
|
|
|
| 67 |
|
| 68 |
def call_then_place_denoiser(step, components, state):
|
| 69 |
result = original_call(step, components, state)
|
| 70 |
+
if not sequential_text_encoder:
|
| 71 |
+
text_encoder.to("cpu")
|
| 72 |
+
text_encoder._hf_hook = _ExecutionDeviceHint()
|
| 73 |
empty_cuda_cache()
|
| 74 |
+
if place_transformer:
|
| 75 |
+
transformer.to("cuda")
|
| 76 |
+
move_registered_buffers(transformer, "cuda")
|
| 77 |
return result
|
| 78 |
|
| 79 |
encoder_step_cls.encode_prompt = staticmethod(encode_prompt_on_cuda)
|
| 80 |
encoder_step_cls.__call__ = call_then_place_denoiser
|
| 81 |
+
if sequential_text_encoder:
|
| 82 |
+
cpu_offload(text_encoder, execution_device="cuda", offload_buffers=True)
|
| 83 |
+
else:
|
| 84 |
+
text_encoder.to("cuda")
|
scripts/run_quantized_example.py
CHANGED
|
@@ -56,7 +56,7 @@ BF16_COMPUTE_COMPONENTS = frozenset({"transformer", "text_encoder"})
|
|
| 56 |
|
| 57 |
def component_load_request(component: str, spec: dict[str, object]) -> tuple[object, dict]:
|
| 58 |
kwargs: dict[str, object] = {"low_cpu_mem_usage": True}
|
| 59 |
-
if component in BF16_COMPUTE_COMPONENTS or spec["source"]
|
| 60 |
kwargs["dtype"] = torch.bfloat16
|
| 61 |
if spec["source"] == "bf16":
|
| 62 |
kwargs["revision"] = spec["revision"]
|
|
@@ -84,6 +84,14 @@ def main() -> int:
|
|
| 84 |
default=[],
|
| 85 |
help="Load one learned component from the pinned BF16 source for a controlled ablation.",
|
| 86 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
parser.add_argument(
|
| 88 |
"--transformer-path",
|
| 89 |
type=Path,
|
|
@@ -112,6 +120,24 @@ def main() -> int:
|
|
| 112 |
default="64GB",
|
| 113 |
help="ComponentsManager CUDA memory reserve margin, for example 12GB.",
|
| 114 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
parser.add_argument(
|
| 116 |
"--checkpoint-dir",
|
| 117 |
type=Path,
|
|
@@ -150,12 +176,38 @@ def main() -> int:
|
|
| 150 |
args = parser.parse_args()
|
| 151 |
if args.task == "ref2va" and not args.reference:
|
| 152 |
parser.error("--reference is required for ref2va")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
if args.no_cpu_offload and args.manual_stage_offload:
|
| 154 |
parser.error("--no-cpu-offload and --manual-stage-offload are mutually exclusive")
|
| 155 |
if args.stop_after_denoise_steps is not None and not (
|
| 156 |
1 <= args.stop_after_denoise_steps < args.steps
|
| 157 |
):
|
| 158 |
parser.error("--stop-after-denoise-steps must be between 1 and steps - 1")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
|
| 160 |
metrics_path = args.output.with_suffix(".metrics.json")
|
| 161 |
metrics_path.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -168,6 +220,8 @@ def main() -> int:
|
|
| 168 |
/ f"{args.output.stem}-pid-{os.getpid()}"
|
| 169 |
).resolve()
|
| 170 |
bf16_components = set(args.bf16_component)
|
|
|
|
|
|
|
| 171 |
component_paths = (
|
| 172 |
{"transformer": args.transformer_path.resolve()}
|
| 173 |
if args.transformer_path is not None
|
|
@@ -179,6 +233,15 @@ def main() -> int:
|
|
| 179 |
bf16_components=bf16_components,
|
| 180 |
component_paths=component_paths,
|
| 181 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
if args.transformer_runtime_mode == "dequant_bf16":
|
| 183 |
variant = "orbitquant_w4a4_text_w4a16_transformer"
|
| 184 |
elif not bf16_components:
|
|
@@ -204,9 +267,14 @@ def main() -> int:
|
|
| 204 |
"checkpoint_dir": str(checkpoint_dir),
|
| 205 |
"checkpoint_policy": "atomic_block_state_after_each_scheduler_step",
|
| 206 |
"gpu": torch.cuda.get_device_name(),
|
|
|
|
|
|
|
| 207 |
"pid": os.getpid(),
|
| 208 |
}
|
| 209 |
try:
|
|
|
|
|
|
|
|
|
|
| 210 |
def load_component(component: str, cls):
|
| 211 |
spec = component_plan[component]
|
| 212 |
path, kwargs = component_load_request(component, spec)
|
|
@@ -250,11 +318,49 @@ def main() -> int:
|
|
| 250 |
else 0
|
| 251 |
)
|
| 252 |
report["native_w4_preflight"] = validate_native_w4_compute_dtype(transformer)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 253 |
report["w4a4_int8_weight_cache_modules"] = (
|
| 254 |
enable_w4a4_int8_weight_cache(transformer)
|
| 255 |
if args.w4a4_int8_weight_cache
|
| 256 |
else 0
|
| 257 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 258 |
report["load_seconds"] = time.perf_counter() - load_started
|
| 259 |
|
| 260 |
move_started = time.perf_counter()
|
|
@@ -272,11 +378,35 @@ def main() -> int:
|
|
| 272 |
text_encoder=component_updates["text_encoder"],
|
| 273 |
transformer=transformer,
|
| 274 |
empty_cuda_cache=torch.cuda.empty_cache,
|
|
|
|
|
|
|
| 275 |
)
|
| 276 |
report["offload"] = {
|
| 277 |
-
"mode":
|
| 278 |
-
|
| 279 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 280 |
"vae": "cpu",
|
| 281 |
"audio_vae": "cpu",
|
| 282 |
}
|
|
@@ -285,6 +415,24 @@ def main() -> int:
|
|
| 285 |
components_manager,
|
| 286 |
memory_reserve_margin=args.offload_reserve_margin,
|
| 287 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 288 |
report["transformer_dequant_cache_disabled_modules"] = (
|
| 289 |
disable_dequantized_weight_cache(transformer, execution_device="cuda")
|
| 290 |
if args.disable_transformer_dequant_cache
|
|
|
|
| 56 |
|
| 57 |
def component_load_request(component: str, spec: dict[str, object]) -> tuple[object, dict]:
|
| 58 |
kwargs: dict[str, object] = {"low_cpu_mem_usage": True}
|
| 59 |
+
if component in BF16_COMPUTE_COMPONENTS or spec["source"] in {"bf16", "bf16_local"}:
|
| 60 |
kwargs["dtype"] = torch.bfloat16
|
| 61 |
if spec["source"] == "bf16":
|
| 62 |
kwargs["revision"] = spec["revision"]
|
|
|
|
| 84 |
default=[],
|
| 85 |
help="Load one learned component from the pinned BF16 source for a controlled ablation.",
|
| 86 |
)
|
| 87 |
+
parser.add_argument(
|
| 88 |
+
"--source-bf16-root",
|
| 89 |
+
type=Path,
|
| 90 |
+
help=(
|
| 91 |
+
"Use a completely downloaded local source-model root for BF16 "
|
| 92 |
+
"ablation components instead of fetching them from the Hub."
|
| 93 |
+
),
|
| 94 |
+
)
|
| 95 |
parser.add_argument(
|
| 96 |
"--transformer-path",
|
| 97 |
type=Path,
|
|
|
|
| 120 |
default="64GB",
|
| 121 |
help="ComponentsManager CUDA memory reserve margin, for example 12GB.",
|
| 122 |
)
|
| 123 |
+
parser.add_argument(
|
| 124 |
+
"--transformer-group-offload-blocks",
|
| 125 |
+
type=int,
|
| 126 |
+
help="Enable block-level transformer group offload with this many blocks per group.",
|
| 127 |
+
)
|
| 128 |
+
parser.add_argument(
|
| 129 |
+
"--transformer-group-offload-type",
|
| 130 |
+
choices=("block_level", "leaf_level"),
|
| 131 |
+
default="block_level",
|
| 132 |
+
)
|
| 133 |
+
parser.add_argument("--group-offload-use-stream", action="store_true")
|
| 134 |
+
parser.add_argument("--group-offload-no-record-stream", action="store_true")
|
| 135 |
+
parser.add_argument("--group-offload-low-cpu-mem-usage", action="store_true")
|
| 136 |
+
parser.add_argument("--cuda-memory-cap-gib", type=float)
|
| 137 |
+
parser.add_argument("--text-encoder-sequential-offload", action="store_true")
|
| 138 |
+
parser.add_argument("--reference-vae-sequential-offload", action="store_true")
|
| 139 |
+
parser.add_argument("--reference-vae-tile-size", type=int, default=256)
|
| 140 |
+
parser.add_argument("--attention-backend")
|
| 141 |
parser.add_argument(
|
| 142 |
"--checkpoint-dir",
|
| 143 |
type=Path,
|
|
|
|
| 176 |
args = parser.parse_args()
|
| 177 |
if args.task == "ref2va" and not args.reference:
|
| 178 |
parser.error("--reference is required for ref2va")
|
| 179 |
+
if args.reference_vae_sequential_offload and args.task != "ref2va":
|
| 180 |
+
parser.error("--reference-vae-sequential-offload requires ref2va")
|
| 181 |
+
if args.reference_vae_tile_size < 64 or args.reference_vae_tile_size % 16:
|
| 182 |
+
parser.error("--reference-vae-tile-size must be a multiple of 16 and at least 64")
|
| 183 |
if args.no_cpu_offload and args.manual_stage_offload:
|
| 184 |
parser.error("--no-cpu-offload and --manual-stage-offload are mutually exclusive")
|
| 185 |
if args.stop_after_denoise_steps is not None and not (
|
| 186 |
1 <= args.stop_after_denoise_steps < args.steps
|
| 187 |
):
|
| 188 |
parser.error("--stop-after-denoise-steps must be between 1 and steps - 1")
|
| 189 |
+
if args.transformer_group_offload_blocks is not None and args.transformer_group_offload_blocks < 1:
|
| 190 |
+
parser.error("--transformer-group-offload-blocks must be positive")
|
| 191 |
+
if args.cuda_memory_cap_gib is not None and args.cuda_memory_cap_gib <= 0:
|
| 192 |
+
parser.error("--cuda-memory-cap-gib must be positive")
|
| 193 |
+
if (
|
| 194 |
+
args.transformer_group_offload_blocks is not None
|
| 195 |
+
or args.transformer_group_offload_type == "leaf_level"
|
| 196 |
+
) and not args.manual_stage_offload:
|
| 197 |
+
parser.error("transformer group offload requires --manual-stage-offload")
|
| 198 |
+
if (
|
| 199 |
+
args.group_offload_use_stream
|
| 200 |
+
and args.transformer_group_offload_type == "block_level"
|
| 201 |
+
and args.transformer_group_offload_blocks != 1
|
| 202 |
+
):
|
| 203 |
+
parser.error("Diffusers stream group offload requires exactly one block per group")
|
| 204 |
+
|
| 205 |
+
cuda_memory_fraction = None
|
| 206 |
+
if args.cuda_memory_cap_gib is not None:
|
| 207 |
+
total_cuda_bytes = torch.cuda.get_device_properties(torch.cuda.current_device()).total_memory
|
| 208 |
+
requested_cuda_bytes = int(args.cuda_memory_cap_gib * 1024**3)
|
| 209 |
+
cuda_memory_fraction = min(1.0, requested_cuda_bytes / total_cuda_bytes)
|
| 210 |
+
torch.cuda.set_per_process_memory_fraction(cuda_memory_fraction)
|
| 211 |
|
| 212 |
metrics_path = args.output.with_suffix(".metrics.json")
|
| 213 |
metrics_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
| 220 |
/ f"{args.output.stem}-pid-{os.getpid()}"
|
| 221 |
).resolve()
|
| 222 |
bf16_components = set(args.bf16_component)
|
| 223 |
+
if args.source_bf16_root is not None and "transformer" not in bf16_components:
|
| 224 |
+
parser.error("--source-bf16-root requires --bf16-component transformer")
|
| 225 |
component_paths = (
|
| 226 |
{"transformer": args.transformer_path.resolve()}
|
| 227 |
if args.transformer_path is not None
|
|
|
|
| 233 |
bf16_components=bf16_components,
|
| 234 |
component_paths=component_paths,
|
| 235 |
)
|
| 236 |
+
if args.source_bf16_root is not None:
|
| 237 |
+
transformer_subfolder = "transformer_ref" if args.task == "ref2va" else "transformer"
|
| 238 |
+
transformer_path = args.source_bf16_root.resolve() / transformer_subfolder
|
| 239 |
+
if not transformer_path.is_dir():
|
| 240 |
+
parser.error(f"local BF16 transformer directory does not exist: {transformer_path}")
|
| 241 |
+
component_plan["transformer"] = {
|
| 242 |
+
"source": "bf16_local",
|
| 243 |
+
"path": str(transformer_path),
|
| 244 |
+
}
|
| 245 |
if args.transformer_runtime_mode == "dequant_bf16":
|
| 246 |
variant = "orbitquant_w4a4_text_w4a16_transformer"
|
| 247 |
elif not bf16_components:
|
|
|
|
| 267 |
"checkpoint_dir": str(checkpoint_dir),
|
| 268 |
"checkpoint_policy": "atomic_block_state_after_each_scheduler_step",
|
| 269 |
"gpu": torch.cuda.get_device_name(),
|
| 270 |
+
"cuda_memory_cap_gib": args.cuda_memory_cap_gib,
|
| 271 |
+
"cuda_memory_fraction": cuda_memory_fraction,
|
| 272 |
"pid": os.getpid(),
|
| 273 |
}
|
| 274 |
try:
|
| 275 |
+
if args.group_offload_use_stream:
|
| 276 |
+
report["stream_safe_orbitquant_buffer_identity"] = "package"
|
| 277 |
+
|
| 278 |
def load_component(component: str, cls):
|
| 279 |
spec = component_plan[component]
|
| 280 |
path, kwargs = component_load_request(component, spec)
|
|
|
|
| 318 |
else 0
|
| 319 |
)
|
| 320 |
report["native_w4_preflight"] = validate_native_w4_compute_dtype(transformer)
|
| 321 |
+
if args.attention_backend:
|
| 322 |
+
if args.attention_backend == "sage_hub":
|
| 323 |
+
from diffusers.models.attention_dispatch import (
|
| 324 |
+
AttentionBackendName,
|
| 325 |
+
_HUB_KERNELS_REGISTRY,
|
| 326 |
+
)
|
| 327 |
+
|
| 328 |
+
sage_config = _HUB_KERNELS_REGISTRY[AttentionBackendName.SAGE_HUB]
|
| 329 |
+
sage_config.revision = None
|
| 330 |
+
sage_config.version = 2
|
| 331 |
+
sage_config.kernel_fn = None
|
| 332 |
+
report["sage_hub_kernel_version"] = 2
|
| 333 |
+
transformer.set_attention_backend(args.attention_backend)
|
| 334 |
+
report["attention_backend"] = args.attention_backend or "native_auto"
|
| 335 |
report["w4a4_int8_weight_cache_modules"] = (
|
| 336 |
enable_w4a4_int8_weight_cache(transformer)
|
| 337 |
if args.w4a4_int8_weight_cache
|
| 338 |
else 0
|
| 339 |
)
|
| 340 |
+
group_offload_enabled = (
|
| 341 |
+
args.transformer_group_offload_blocks is not None
|
| 342 |
+
or args.transformer_group_offload_type == "leaf_level"
|
| 343 |
+
)
|
| 344 |
+
if group_offload_enabled:
|
| 345 |
+
group_offload_kwargs = {
|
| 346 |
+
"onload_device": torch.device("cuda"),
|
| 347 |
+
"offload_device": torch.device("cpu"),
|
| 348 |
+
"offload_type": args.transformer_group_offload_type,
|
| 349 |
+
"non_blocking": args.group_offload_use_stream,
|
| 350 |
+
"use_stream": args.group_offload_use_stream,
|
| 351 |
+
"record_stream": (
|
| 352 |
+
args.group_offload_use_stream
|
| 353 |
+
and not args.group_offload_no_record_stream
|
| 354 |
+
),
|
| 355 |
+
"low_cpu_mem_usage": args.group_offload_low_cpu_mem_usage,
|
| 356 |
+
}
|
| 357 |
+
if args.transformer_group_offload_type == "block_level":
|
| 358 |
+
group_offload_kwargs["num_blocks_per_group"] = (
|
| 359 |
+
args.transformer_group_offload_blocks
|
| 360 |
+
)
|
| 361 |
+
transformer.enable_group_offload(
|
| 362 |
+
**group_offload_kwargs,
|
| 363 |
+
)
|
| 364 |
report["load_seconds"] = time.perf_counter() - load_started
|
| 365 |
|
| 366 |
move_started = time.perf_counter()
|
|
|
|
| 378 |
text_encoder=component_updates["text_encoder"],
|
| 379 |
transformer=transformer,
|
| 380 |
empty_cuda_cache=torch.cuda.empty_cache,
|
| 381 |
+
place_transformer=not group_offload_enabled,
|
| 382 |
+
sequential_text_encoder=args.text_encoder_sequential_offload,
|
| 383 |
)
|
| 384 |
report["offload"] = {
|
| 385 |
+
"mode": (
|
| 386 |
+
"manual_stage_plus_transformer_group_offload"
|
| 387 |
+
if group_offload_enabled
|
| 388 |
+
else "manual_stage_offload"
|
| 389 |
+
),
|
| 390 |
+
"conditioner": (
|
| 391 |
+
"sequential_cuda_layers_then_cpu"
|
| 392 |
+
if args.text_encoder_sequential_offload
|
| 393 |
+
else "cuda_then_cpu"
|
| 394 |
+
),
|
| 395 |
+
"transformer": (
|
| 396 |
+
(
|
| 397 |
+
f"block_level_{args.transformer_group_offload_blocks}"
|
| 398 |
+
if args.transformer_group_offload_type == "block_level"
|
| 399 |
+
else "leaf_level"
|
| 400 |
+
)
|
| 401 |
+
if group_offload_enabled
|
| 402 |
+
else "cpu_then_cuda"
|
| 403 |
+
),
|
| 404 |
+
"group_offload_use_stream": args.group_offload_use_stream,
|
| 405 |
+
"group_offload_record_stream": (
|
| 406 |
+
args.group_offload_use_stream
|
| 407 |
+
and not args.group_offload_no_record_stream
|
| 408 |
+
),
|
| 409 |
+
"group_offload_low_cpu_mem_usage": args.group_offload_low_cpu_mem_usage,
|
| 410 |
"vae": "cpu",
|
| 411 |
"audio_vae": "cpu",
|
| 412 |
}
|
|
|
|
| 415 |
components_manager,
|
| 416 |
memory_reserve_margin=args.offload_reserve_margin,
|
| 417 |
)
|
| 418 |
+
if args.reference_vae_sequential_offload:
|
| 419 |
+
from accelerate import cpu_offload
|
| 420 |
+
|
| 421 |
+
reference_vae = component_updates["vae"]
|
| 422 |
+
reference_vae.enable_tiling(
|
| 423 |
+
tile_sample_min_height=args.reference_vae_tile_size,
|
| 424 |
+
tile_sample_min_width=args.reference_vae_tile_size,
|
| 425 |
+
tile_sample_min_overlap_height=args.reference_vae_tile_size // 4,
|
| 426 |
+
tile_sample_min_overlap_width=args.reference_vae_tile_size // 4,
|
| 427 |
+
)
|
| 428 |
+
cpu_offload(
|
| 429 |
+
reference_vae,
|
| 430 |
+
execution_device=torch.device("cuda"),
|
| 431 |
+
offload_buffers=True,
|
| 432 |
+
)
|
| 433 |
+
report["offload"]["vae"] = "sequential_cuda_layers_for_reference_then_cpu"
|
| 434 |
+
report["offload"]["reference_vae_tiling"] = True
|
| 435 |
+
report["offload"]["reference_vae_tile_size"] = args.reference_vae_tile_size
|
| 436 |
report["transformer_dequant_cache_disabled_modules"] = (
|
| 437 |
disable_dequantized_weight_cache(transformer, execution_device="cuda")
|
| 438 |
if args.disable_transformer_dequant_cache
|