Skip to content

Commit f6e40fb

Browse files
Add GemLite quantization backend support for pre-quantized checkpoints
1 parent 4d89a88 commit f6e40fb

18 files changed

Lines changed: 1377 additions & 4 deletions

File tree

.github/workflows/nightly_tests.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,9 @@ jobs:
348348
- backend: "gguf"
349349
test_location: "gguf"
350350
additional_deps: ["peft", "kernels"]
351+
- backend: "gemlite"
352+
test_location: "gemlite"
353+
additional_deps: []
351354
- backend: "torchao"
352355
test_location: "torchao"
353356
additional_deps: []

docs/source/en/_toctree.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@
174174
title: bitsandbytes
175175
- local: quantization/gguf
176176
title: gguf
177+
- local: quantization/gemlite
178+
title: GemLite
177179
- local: quantization/nunchaku
178180
title: Nunchaku Lite
179181
- local: quantization/torchao

docs/source/en/api/quantization.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ Quantization techniques reduce memory and computational costs by representing we
3030

3131
[[autodoc]] quantizers.quantization_config.GGUFQuantizationConfig
3232

33+
## GemLiteConfig
34+
35+
[[autodoc]] quantizers.quantization_config.GemLiteConfig
36+
3337
## NunchakuLiteQuantizationConfig
3438

3539
[[autodoc]] quantizers.quantization_config.NunchakuLiteQuantizationConfig
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<!--Copyright 2026 The HuggingFace Team. All rights reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
4+
the License. You may obtain a copy of the License at
5+
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
8+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
9+
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
10+
specific language governing permissions and limitations under the License.
11+
12+
-->
13+
14+
# GemLite
15+
16+
[GemLite](https://github.com/mobiusml/gemlite) is a quantization backend for loading prequantized checkpoints in
17+
Diffusers. It replaces supported `torch.nn.Linear` layers with GemLite layers, which run packed low-bit weights
18+
directly with GemLite kernels.
19+
20+
## Install GemLite
21+
22+
GemLite requires version 0.6.0 or later.
23+
24+
```bash
25+
pip install -U "gemlite>=0.6.0"
26+
```
27+
28+
## Load a quantized pipeline
29+
30+
GemLite only supports loading prequantized checkpoints. The quantization configuration is stored in the checkpoint's
31+
`config.json` and read automatically by [`~DiffusionPipeline.from_pretrained`].
32+
33+
```python
34+
import torch
35+
from diffusers import DiffusionPipeline
36+
37+
model_id = "gabe-engineers/bonsai-image-ternary-4B-gemlite-2bit-unpacked-encoder"
38+
39+
pipe = DiffusionPipeline.from_pretrained(
40+
model_id,
41+
dtype=torch.float16,
42+
device_map="cuda",
43+
)
44+
45+
image = pipe(
46+
prompt="A bonsai tree in a quiet ceramic studio, soft morning light",
47+
height=1024,
48+
width=1024,
49+
num_inference_steps=4,
50+
guidance_scale=1.0,
51+
).images[0]
52+
image.save("bonsai-gemlite.png")
53+
```
54+
55+
> [!TIP]
56+
> `dtype` must match the `compute_dtype` in the checkpoint's GemLite quantization configuration. This
57+
> checkpoint uses `torch.float16`.

docs/source/en/quantization/overview.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ The following backends support loading prequantized checkpoints out of the box.
145145
|---|---|
146146
| [bitsandbytes](./bitsandbytes) | Config is saved in `config.json`; no extra arguments needed. |
147147
| [GGUF](./gguf) | Uses `from_single_file` with Model classes; pipeline-level loading is not supported. |
148+
| [GemLite](./gemlite) | Loads prequantized checkpoints; requires the `gemlite` library. |
148149
| [AutoRound](./autoround) | Only loading is supported; quantize first with the AutoRound CLI or Python API. |
149150
| [Nunchaku Lite](./nunchaku) | Config is saved in `config.json`; requires the `kernels` package. |
150151
| [ModelOpt](./modelopt) | Supports both quantizing on the fly and loading prequantized models. |

src/diffusers/__init__.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
is_accelerate_available,
1010
is_auto_round_available,
1111
is_bitsandbytes_available,
12+
is_gemlite_available,
1213
is_gguf_available,
1314
is_librosa_available,
1415
is_note_seq_available,
@@ -46,6 +47,7 @@
4647
"schedulers": [],
4748
"utils": [
4849
"OptionalDependencyNotAvailable",
50+
"is_gemlite_available",
4951
"is_inflect_available",
5052
"is_invisible_watermark_available",
5153
"is_librosa_available",
@@ -85,6 +87,18 @@
8587
else:
8688
_import_structure["quantizers.quantization_config"].append("GGUFQuantizationConfig")
8789

90+
try:
91+
if not is_torch_available() and not is_accelerate_available() and not is_gemlite_available():
92+
raise OptionalDependencyNotAvailable()
93+
except OptionalDependencyNotAvailable:
94+
from .utils import dummy_gemlite_objects
95+
96+
_import_structure["utils.dummy_gemlite_objects"] = [
97+
name for name in dir(dummy_gemlite_objects) if not name.startswith("_")
98+
]
99+
else:
100+
_import_structure["quantizers.quantization_config"].append("GemLiteConfig")
101+
88102
try:
89103
if not is_torch_available() and not is_accelerate_available() and not is_torchao_available():
90104
raise OptionalDependencyNotAvailable()
@@ -947,6 +961,14 @@
947961
else:
948962
from .quantizers.quantization_config import GGUFQuantizationConfig
949963

964+
try:
965+
if not is_gemlite_available():
966+
raise OptionalDependencyNotAvailable()
967+
except OptionalDependencyNotAvailable:
968+
from .utils.dummy_gemlite_objects import *
969+
else:
970+
from .quantizers.quantization_config import GemLiteConfig
971+
950972
try:
951973
if not is_torchao_available():
952974
raise OptionalDependencyNotAvailable()

src/diffusers/models/modeling_utils.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,11 @@ def from_pretrained(cls, pretrained_model_name_or_path: str | os.PathLike | None
14111411
"error_msgs": error_msgs,
14121412
}
14131413

1414+
# Quantizers may need to finalize module state before dispatch reads `model.state_dict()`.
1415+
if hf_quantizer is not None:
1416+
hf_quantizer.postprocess_model(model)
1417+
model.hf_quantizer = hf_quantizer
1418+
14141419
# Dispatch model with hooks on all devices if necessary
14151420
if device_map is not None:
14161421
device_map_kwargs = {
@@ -1420,10 +1425,6 @@ def from_pretrained(cls, pretrained_model_name_or_path: str | os.PathLike | None
14201425
}
14211426
dispatch_model(model, **device_map_kwargs)
14221427

1423-
if hf_quantizer is not None:
1424-
hf_quantizer.postprocess_model(model)
1425-
model.hf_quantizer = hf_quantizer
1426-
14271428
if (
14281429
torch_dtype is not None
14291430
and torch_dtype == getattr(torch, "float8_e4m3fn", None)

src/diffusers/quantizers/auto.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020

2121
from .autoround import AutoRoundQuantizer
2222
from .bitsandbytes import BnB4BitDiffusersQuantizer, BnB8BitDiffusersQuantizer
23+
from .gemlite import GemLiteQuantizer
2324
from .gguf import GGUFQuantizer
2425
from .modelopt import NVIDIAModelOptQuantizer
2526
from .nunchaku import NunchakuLiteQuantizer
2627
from .quantization_config import (
2728
AutoRoundConfig,
2829
BitsAndBytesConfig,
30+
GemLiteConfig,
2931
GGUFQuantizationConfig,
3032
NunchakuLiteQuantizationConfig,
3133
NVIDIAModelOptConfig,
@@ -41,6 +43,7 @@
4143
AUTO_QUANTIZER_MAPPING = {
4244
"bitsandbytes_4bit": BnB4BitDiffusersQuantizer,
4345
"bitsandbytes_8bit": BnB8BitDiffusersQuantizer,
46+
"gemlite": GemLiteQuantizer,
4447
"gguf": GGUFQuantizer,
4548
"quanto": QuantoQuantizer,
4649
"torchao": TorchAoHfQuantizer,
@@ -52,6 +55,7 @@
5255
AUTO_QUANTIZATION_CONFIG_MAPPING = {
5356
"bitsandbytes_4bit": BitsAndBytesConfig,
5457
"bitsandbytes_8bit": BitsAndBytesConfig,
58+
"gemlite": GemLiteConfig,
5559
"gguf": GGUFQuantizationConfig,
5660
"quanto": QuantoConfig,
5761
"torchao": TorchAoConfig,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .gemlite_quantizer import GemLiteQuantizer

0 commit comments

Comments
 (0)