File size: 1,664 Bytes
140017c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
---
base_model: Qwen/Qwen-Image
library_name: diffusers
license: apache-2.0
pipeline_tag: text-to-image
tags:
- qwen-image
- text-to-image
- quantized
- fp8
- e4m3
- diffusers
base_model_relation: quantized
---
# Qwen-Image-e4m3

FP8 (e4m3) dynamically-quantized [Qwen-Image](https://huggingface.co/Qwen/Qwen-Image),
saved as a complete `QwenImagePipeline`.

## What was changed

All 60 blocks of the `QwenImageTransformer2DModel` are quantized to
`e4m3_e4m3_dynamic` — `float8_e4m3fn` weights with dynamically scaled
`float8_e4m3fn` activations. The Qwen2.5-VL text encoder, the VAE and the
transformer's non-block tensors are untouched and stay in bf16. The transformer
drops from ~40.9 GB to ~20.5 GB.

Quantization was done with WaveSpeed's `xelerate.ao.quantize`. Weights are
stored as pickled `.bin` shards, so loading requires `use_safetensors=False`.

FP8 matmul needs Hopper (H100/H200) or newer to be faster than bf16; on older
GPUs the weights are dequantized on the fly and you only get the memory saving.

One caveat worth repeating from our own testing: on Qwen-Image, running fp8
*weight-and-activation* matmul under a fully fused fast path produces visible
quality loss. The configuration published here — dynamic per-tensor activation
scaling with bf16 accumulation — is the one that holds up.

## Usage

```python
import torch
from diffusers import QwenImagePipeline

pipe = QwenImagePipeline.from_pretrained(
    "wavespeed/Qwen-Image-e4m3",
    torch_dtype=torch.bfloat16,
    use_safetensors=False,
).to("cuda")

image = pipe("a chalkboard menu written in neat cursive").images[0]
```

## License

Apache-2.0, inherited from Qwen-Image.