File size: 10,350 Bytes
3a804c0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4a14bfd
 
 
 
3a804c0
 
 
4a14bfd
3a804c0
 
 
4a14bfd
 
3a804c0
 
 
 
 
4a14bfd
 
3a804c0
 
 
 
4a14bfd
 
 
 
 
 
 
3a804c0
 
 
 
 
 
 
 
 
 
4a14bfd
 
 
 
3a804c0
7315dc5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4a14bfd
 
3a804c0
4a14bfd
3a804c0
4a14bfd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3a804c0
4a14bfd
 
3a804c0
 
 
4a14bfd
 
3a804c0
 
 
7315dc5
 
4a14bfd
3a804c0
7315dc5
 
 
 
 
 
 
 
 
 
3a804c0
 
 
4a14bfd
 
 
3a804c0
4a14bfd
 
 
 
 
 
 
 
1c9a468
 
3a804c0
4a14bfd
3a804c0
 
 
 
4a14bfd
 
 
 
 
 
 
 
3a804c0
 
 
 
 
4a14bfd
 
3a804c0
4a14bfd
3a804c0
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
---
license: other
license_name: minimax-h3-image-community-license
license_link: LICENSE
base_model: MiniMaxAI/MiniMax-H3-Image
pipeline_tag: text-to-image
library_name: diffusers
tags:
  - minimax-h3-image
  - text-to-image
  - image-editing
  - pruned
---

# MiniMax-H3-Image-Pruned

[MiniMax-H3-Image](https://huggingface.co/MiniMaxAI/MiniMax-H3-Image) without the weights its inference never needs:
135.3 GB → 95.1 GB on disk (transformer, text encoder and VAE). The stock Diffusers and Transformers classes load
it like the original, with no custom code and no `trust_remote_code`. Text-to-image results are bit-identical to the
original on the same GPU; edit results differ by a small margin (PSNR 43.3 dB on the test edit). Every kept tensor is a byte copy of the original;
nothing is quantized or retrained.

![Generation time, GPU memory and checkpoint size](assets/speed_memory_size.png)

![Samples: two text-to-image results, bit-identical to the original, and an edit](assets/samples.jpg)

| | Original | Pruned |
|---|---|---|
| Transformer | 66.3 GB, 33.1B parameters | 40.2 GB, 20.1B parameters |
| Text encoder (Qwen3-VL-32B) | 66.7 GB, 64 decoder layers | 52.5 GB, 51 decoder layers |
| VAE | 2.3 GB | 2.3 GB (unchanged) |

## Usage

```bash
pip install "diffusers @ git+https://github.com/huggingface/diffusers@875373ac7f5856071e345a3e394c74efccc6b9e6" \
  "transformers>=5.22" accelerate torchvision
```

```python
import torch
from diffusers import ComponentsManager, ModularPipeline

manager = ComponentsManager()
manager.enable_auto_cpu_offload(device="cuda")  # or skip this and call pipe.to("cuda") on a GPU with 96 GB or more

pipe = ModularPipeline.from_pretrained("WaveCut/MiniMax-H3-Image-Pruned", components_manager=manager)
pipe.load_components(dtype=torch.bfloat16)

image = pipe(
    prompt="The image is a top-down photograph of ...",
    height=3552,
    width=4736,
    generator=torch.Generator().manual_seed(42),
    output="images",
)[0]
```

This is the code of the [original card](https://huggingface.co/MiniMaxAI/MiniMax-H3-Image) with another repository
name. Editing: pass `image=reference` (or a list) and refer to the images as `<Picture 1>`, `<Picture 2>`, ... in the
prompt. The prompting guidance of the original card applies unchanged: long, complete English descriptions;
recommended sizes from 4096×4096 (1:1) to 6272×2688 (21:9).

### Memory modes

`enable_auto_cpu_offload` moves a model off the GPU only when the next one does not fit. On a 96 GB card the pruned
models fit together, so after the first image nothing moves and the run is as fast as with everything on the GPU
(peak 92.7 GiB). For the lowest peak, keep one model on the GPU at a time; set the strategy after loading, because
adding the components resets it to the default:

```python
pipe.load_components(dtype=torch.bfloat16)
manager.set_offload_strategy(lambda hooks, **kwargs: hooks)  # move every other model off the GPU first
```

The peak is then 50-52 GiB, set by the text encoder (48.9 GiB of weights), and each image moves both models over
PCIe: about 72 s at 2048×2048 instead of 5.6 s (see Profiles).

The components also load alone with the stock classes: `MiniMaxH3ImageTransformer2DModel.from_pretrained(repo,
subfolder="transformer")` and `Qwen3VLForConditionalGeneration.from_pretrained(repo, subfolder="text_encoder")`.

## What was removed

- **AdaLN projection inputs (13.0B parameters).** Every block projects the timestep embedding to its modulation
  vectors, and the checkpoint samples on a fixed grid: six steps (one output head per step), plus t = 0.999 for the
  reference images of an edit. Seven timesteps need seven input columns, so `adaln_proj.linear` and `norm_out.linear`
  keep 8 of their 2688 input columns (`time_embed_dim: 8` in the config). The new `time_embedder` (16 hidden units)
  turns each grid timestep into a one-hot code, and column k holds the original projection's output for timestep k.
  The stock forward pass then returns the original modulation values exactly; the
  [GitHub repository](https://github.com/iamwavecut/MiniMax-H3-Image-Pruned) explains the construction.
- **Text encoder layers 51-63 and `lm_head`.** The transformer is conditioned on `hidden_states[50]` of the Qwen3-VL
  text encoder, the output of decoder layer 49. Layer 50 stays because the pipeline requires more than 50 layers; with
  51 layers, `hidden_states[50]` is still the output of layer 49. `lm_head` is tied to the input embedding, so loading
  allocates nothing for it.

## Text-to-image and edit

The original model computes the modulation for a step with one timestep row in text-to-image and with two rows (step
and reference) in an edit, and the matrix products round slightly differently in the two cases. The pruned
checkpoint stores one value per timestep: the text-to-image value for the six steps and the edit value for the
reference timestep.

- Text-to-image: bit-identical to the original.
- Edit: not bit-identical. 59,279 of the 29.1 million modulation values of the six step rows (0.20 %) differ from the original's two-row result by rounding steps. Through the 50 blocks this changes each edit step's transformer output by 2.1-2.5 % (relative L2), and the 2048×2048 test edit by PSNR 43.3 dB: mean absolute difference 0.63 of 255, 261 of 4.2 million pixels off by more than 64. In the worst region the differences follow edges; the two images look the same.

## Profiles

Measured on one RTX PRO 6000 Blackwell Server Edition (96 GB, 600 W power limit), bfloat16, one image after a
warm-up image. Time includes prompt encoding, six steps and VAE decoding.

| Run | 2048×2048 | Edit, 2048×2048 | 4736×3552 | GPU memory peak, 4736×3552 |
|---|---|---|---|---|
| Original, model offload (code of the original card) | 97.6 s | 101.6 s | 120.8 s | 68.2 GiB |
| Pruned, one model on the GPU at a time | 72.2 s | 76.0 s | 92.8 s | 50.4 GiB (edit: 51.7 GiB) |
| Pruned, all on the GPU (`pipe.to("cuda")`) | 5.6 s | 9.3 s | 26.7 s | 92.7 GiB |

The original does not fit a 96 GB card (124 GiB of transformer and text encoder), so the offload manager moves the
transformer and the text encoder for every image. With one model on the GPU at a time the pruned checkpoint does the
same, with 30 % less data to move. With everything on the GPU nothing moves; the stock auto offload (the code above)
measured the same on this card, 5.6 s / 9.4 s / 26.4 s with a 92.7 GiB peak. The sampling steps themselves cost the
same in all rows. GPUs with 80 GB or with 141 GB or more were not measured.

All rows ran on the same machine. With every model on the GPU (auto offload on this card included), the edit took
14-22 s instead of 9.3 s in three of five runs: the text encoder's pass over the reference image took 5-9 s instead of
under 1 s. The cause is not identified; the table shows the fast runs.
With one model on the GPU at a time the images are bit-identical to the all-on-GPU ones.

## Verification

`scripts/verify.py` in the GitHub repository ran the official Modular Diffusers pipeline and this checkpoint, both
with the stock classes, on the same prompts and seeds: two text-to-image prompts and one edit at 2048×2048, and one
text-to-image prompt at 4736×3552.

- Text-to-image images: bit-identical in every run (0 differing pixels), with model offload and with everything on
  the GPU.
- Text conditioning (`hidden_states[50]`, 36 to 1757 tokens, the edit included): bit-identical.
- Transformer: the 18 recorded calls of the original pipeline, replayed through the pruned transformer. The 12
  text-to-image calls give bit-identical outputs; the 6 edit calls differ by 2.1-2.5 % (relative L2).
- Edit image: PSNR 43.3 dB against the original, mean absolute difference 0.63 of 255.
- Build checks: every grid timestep gives an exact one-hot code with float32, TF32 and bfloat16 matmuls; every
  stored column times 32 reproduces the original projection output.
- The published repository, loaded from the Hub into an empty cache with only Diffusers and Transformers installed
  (the code above), reproduced the text-to-image test image bit for bit and the edit with the same PSNR 43.3 dB.

Software: torch 2.11.0+cu128, diffusers at `875373ac`, transformers 5.22.2, NVIDIA driver 615.71.09; source checkpoint
`MiniMaxAI/MiniMax-H3-Image@492fd8c4`.

## Limits

- Only the release's sampling grid. A timestep off the grid gives no valid code, and the stock transformer does not
  check for it: the result is wrong without an error. The original has one output head per step of this grid and
  cannot change it either.
- The stored values were computed on an RTX PRO 6000 Blackwell. On another GPU type the original model can round its
  own AdaLN outputs differently by single bfloat16 steps, while this checkpoint keeps the values of the build GPU, so
  the two can differ there by about as much as the original differs between two GPU types (not measured).
  `minimax-h3-image-prune --skip text_encoder copies` from the GitHub repository rebuilds the transformer on your GPU.
- SGLang and ComfyUI were not tested with this checkpoint.

## Files

| Path | Content |
|---|---|
| `transformer/` | Transformer with 8-column AdaLN projections and the one-hot `time_embedder`; `build_report.json` |
| `text_encoder/` | Qwen3-VL conditioner, decoder layers 0-50, with its tokenizer files |
| `vae/`, `tokenizer/`, `processor/`, `scheduler/` | Original files |
| `modular_model_index.json` | Modular Diffusers index, original component classes |
| `LICENSE`, `NOTICE` | MiniMax-H3-Image Community License and the required notice |
| `assets/` | Card images |

## License

MiniMax-H3-Image is licensed under the MiniMax-H3-Image Community License Agreement, Copyright © 2026 MiniMax. All
Rights Reserved. This is a modified version by WaveCut; the modified files carry a notice of the change (`_notice` in
configs, `notice` in safetensors metadata). The license applies to this repository unchanged: use, reproduction and
distribution are licensed only within the Applicable Territory, which excludes the European Union, the United Kingdom,
the Republic of Korea and the United States of America, and they are subject to the Acceptable Use Policy (Exhibit A).
A Hosted Service, or annual revenue above 1 million USD, needs MiniMax's prior written authorization. See `LICENSE`.