Skip to content

Commit 715b6e5

Browse files
authored
feat: support for z-image-turbo (#815)
* [FEAT] support for z-image * fix wrong doc string * patch scale key * add pytest case for z-image-turbo * fix test case * add test case for `skip_refiners` model * update example * update * update docs * update docs * update docs * update * runnable * rename the test * skip the fp4_r256 test * update the dependencies * update image link
1 parent b0544d9 commit 715b6e5

20 files changed

Lines changed: 590 additions & 34 deletions

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Check out `DeepCompressor <github_deepcompressor_>`_ for the quantization librar
2828
usage/fbcache.rst
2929
usage/pulid.rst
3030
usage/ip_adapter.rst
31+
usage/zimage.rst
3132

3233
.. toctree::
3334
:maxdepth: 1

docs/source/python_api/nunchaku.models.attention_processors.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ nunchaku.models.attention_processors
66

77
nunchaku.models.attention_processors.flux
88
nunchaku.models.attention_processors.qwenimage
9+
nunchaku.models.attention_processors.zimage
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
nunchaku.models.attention_processors.zimage
2+
===========================================
3+
4+
.. automodule:: nunchaku.models.attention_processors.zimage
5+
:members:
6+
:undoc-members:
7+
:show-inheritance:

docs/source/python_api/nunchaku.models.transformers.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ nunchaku.models.transformers
77
nunchaku.models.transformers.transformer_flux
88
nunchaku.models.transformers.transformer_flux_v2
99
nunchaku.models.transformers.transformer_qwenimage
10+
nunchaku.models.transformers.transformer_zimage
1011
nunchaku.models.transformers.transformer_sana
1112
nunchaku.models.transformers.utils
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
nunchaku.models.transformers.transformer\_zimage
2+
================================================
3+
4+
.. automodule:: nunchaku.models.transformers.transformer_zimage
5+
:members:
6+
:undoc-members:
7+
:show-inheritance:

docs/source/usage/zimage.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Z-Image
2+
=======
3+
4+
The following is the example of running Nunchaku version of Z-Image text-to-image pipeline.
5+
6+
.. tabs::
7+
8+
.. tab:: Z-Image-Turbo
9+
10+
.. literalinclude:: ../../../examples/v1/z-image-turbo.py
11+
:language: python
12+
:caption: Running Z-Image-Turbo (`examples/v1/z-image-turbo.py <https://github.com/nunchaku-tech/nunchaku/blob/main/examples/v1/z-image-turbo.py>`__)
13+
:linenos:
14+
15+
16+
For more details, see :class:`~nunchaku.models.transformers.transformer_zimage.NunchakuZImageTransformer2DModel`.

examples/v1/z-image-turbo.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import torch
2+
from diffusers.pipelines.z_image.pipeline_z_image import ZImagePipeline
3+
4+
from nunchaku import NunchakuZImageTransformer2DModel
5+
from nunchaku.utils import get_precision
6+
7+
if __name__ == "__main__":
8+
precision = get_precision() # auto-detect your precision is 'int4' or 'fp4' based on your GPU
9+
rank = 128 # Use 32 for faster sampling; 256 (INT4 only) for best quality
10+
transformer = NunchakuZImageTransformer2DModel.from_pretrained(
11+
f"nunchaku-tech/nunchaku-z-image-turbo/svdq-{precision}_r{rank}-z-image-turbo.safetensors"
12+
)
13+
14+
pipe = ZImagePipeline.from_pretrained(
15+
"Tongyi-MAI/Z-Image-Turbo", transformer=transformer, torch_dtype=torch.bfloat16, low_cpu_mem_usage=False
16+
).to("cuda")
17+
18+
prompt = "a young military male cooking in the kitchen for therapy"
19+
20+
image = pipe(
21+
prompt=prompt,
22+
height=1024,
23+
width=1024,
24+
num_inference_steps=8, # This actually results in 8 DiT forwards
25+
guidance_scale=0.0, # Guidance should be 0 for the Turbo models
26+
generator=torch.Generator().manual_seed(12345),
27+
).images[0]
28+
29+
image.save(f"z-image-turbo-{precision}_r{rank}.png")

nunchaku/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
NunchakuQwenImageTransformer2DModel,
55
NunchakuSanaTransformer2DModel,
66
NunchakuT5EncoderModel,
7+
NunchakuZImageTransformer2DModel,
78
)
89

910
__all__ = [
@@ -12,4 +13,5 @@
1213
"NunchakuT5EncoderModel",
1314
"NunchakuFluxTransformer2DModelV2",
1415
"NunchakuQwenImageTransformer2DModel",
16+
"NunchakuZImageTransformer2DModel",
1517
]

nunchaku/merge_safetensors.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535

3636
def merge_safetensors(
37-
pretrained_model_name_or_path: str | os.PathLike[str], **kwargs
37+
pretrained_model_name_or_path: str | os.PathLike[str], model_class: str, **kwargs
3838
) -> tuple[dict[str, torch.Tensor], dict[str, str]]:
3939
"""
4040
Merge split safetensors model files into a single state dict and metadata.
@@ -47,6 +47,8 @@ def merge_safetensors(
4747
----------
4848
pretrained_model_name_or_path : str or os.PathLike
4949
Path to the model directory or HuggingFace repo.
50+
model_class : str
51+
Specify model class. E.g. NunchakuFluxTransformer2dModel or NunchakuZImageTransformer2DModel
5052
**kwargs
5153
Additional keyword arguments for subfolder, comfy_config_path, and HuggingFace download options.
5254
@@ -108,6 +110,9 @@ def merge_safetensors(
108110
state_dict.update(transformer_block_sd)
109111

110112
rank = next((v.shape[1] for k, v in transformer_block_sd.items() if ".lora_down" in k), 32)
113+
if "ZImage" in model_class:
114+
rank = next((v.shape[1] for k, v in transformer_block_sd.items() if ".proj_down" in k), 32)
115+
skip_refiners = not any(("refiner" in k and "attention.to_qkv" in k) for k in transformer_block_sd.keys())
111116

112117
precision = "int4"
113118
for v in state_dict.values():
@@ -134,10 +139,12 @@ def merge_safetensors(
134139
},
135140
"rank": rank,
136141
}
142+
if "ZImage" in model_class:
143+
quantization_config["skip_refiners"] = skip_refiners
137144
return state_dict, {
138145
"config": Path(config_path).read_text(),
139146
"comfy_config": Path(comfy_config_path).read_text(),
140-
"model_class": "NunchakuFluxTransformer2dModel",
147+
"model_class": model_class,
141148
"quantization_config": json.dumps(quantization_config),
142149
}
143150

@@ -151,10 +158,20 @@ def merge_safetensors(
151158
required=True,
152159
help="Path to model directory. It can also be a huggingface repo.",
153160
)
161+
parser.add_argument(
162+
"-m",
163+
"--model-class",
164+
type=str,
165+
required=True,
166+
help="Specify model class. E.g. NunchakuFluxTransformer2dModel or NunchakuZImageTransformer2DModel",
167+
)
154168
parser.add_argument("-o", "--output-path", type=Path, required=True, help="Path to output path")
155169
args = parser.parse_args()
156-
state_dict, metadata = merge_safetensors(args.input_path)
170+
state_dict, metadata = merge_safetensors(args.input_path, args.model_class)
157171
output_path = Path(args.output_path)
172+
print(f" --input-path: {args.input_path}")
173+
print(f" --model-class: {args.model_class}")
174+
print(f" --output-path: {args.output_path}")
158175
dirpath = output_path.parent
159176
dirpath.mkdir(parents=True, exist_ok=True)
160177
save_file(state_dict, output_path, metadata=metadata)

nunchaku/models/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
NunchakuFluxTransformer2DModelV2,
55
NunchakuQwenImageTransformer2DModel,
66
NunchakuSanaTransformer2DModel,
7+
NunchakuZImageTransformer2DModel,
78
)
89

910
__all__ = [
@@ -12,4 +13,5 @@
1213
"NunchakuT5EncoderModel",
1314
"NunchakuFluxTransformer2DModelV2",
1415
"NunchakuQwenImageTransformer2DModel",
16+
"NunchakuZImageTransformer2DModel",
1517
]

0 commit comments

Comments
 (0)