6.2 KiB
6.2 KiB
GGUF Quantization
Goals
- Reuse vLLM quantization configs and weight loaders as much as possible.
- Add native GGUF support to diffusion transformers without changing model definitions.
- Keep user-facing knobs minimal and consistent across offline and online flows.
Scope
- Models: Z-Image, Flux2-klein, and Qwen-Image family.
- Components: diffusion transformer weights, loader paths, and quantization configs.
- Modes: native GGUF (transformer-only weights).
Architecture Overview
OmniDiffusionConfigacceptsquantizationorquantization_config.- Diffusion quantization wrapper (
DiffusionGGUFConfig) produces vLLMQuantizationConfigobjects for linear layers. DiffusersPipelineLoaderbranches on quantization method and loads either HF weights or GGUF weights for the transformer.- GGUF transformer loading is routed through model-specific adapters (e.g., Flux2Klein).
- vLLM GGUF path uses
GGUFConfigandGGUFLinearMethodfor matmul.
Call Chain (Offline)
CLI (examples/offline_inference/text_to_image/text_to_image.py)
|
v
Omni (vllm_omni/entrypoints/__init__.py)
|
v
AsyncOmniEngine
|
v
Orchestrator
|
v
StageDiffusionClient
|
v
DiffusionWorker
|
v
DiffusionModelRunner
|
v
DiffusersPipelineLoader
|
v
Pipeline.forward (Flux2/Qwen/Z-Image)
|
v
DiffusionEngine
|
v
OmniRequestOutput
|
v
Client (saved PNG)
Call Chain (Online)
Client
|
| POST /v1/images/generations
v
APIServer (vllm_omni/entrypoints/openai/api_server.py)
|
v
_generate_with_async_omni
|
v
AsyncOmni
|
v
AsyncOmniEngine
|
v
Orchestrator
|
v
StageDiffusionClient
|
v
OmniRequestOutput
|
v
encode_image_base64
|
v
ImageGenerationResponse
|
v
Client
Call Chain (GGUF Operator Path)
Pipeline.forward (Flux2/Qwen/Z-Image)
|
v
Transformer blocks
|
v
QKVParallelLinear / ColumnParallelLinear / RowParallelLinear
|
v
LinearBase.forward
|
v
QuantMethod.apply (GGUFLinearMethod.apply)
|
v
fused_mul_mat_gguf
|
v
_fused_mul_mat_gguf (custom op)
|
v
ops.ggml_dequantize
|
v
x @ weight.T
GGUF Weight Loading Path (Transformer-Only)
DiffusersPipelineLoader.load_modeldetectsquantization_config.method == "gguf".gguf_modelis resolved as one of: local file,repo/file.gguf, orrepo:quant_type.- GGUF weights are routed through adapters in
vllm_omni/diffusion/model_loader/gguf_adapters/. - Name mapping is applied per-architecture (Z-Image, Flux2Klein, Qwen-Image).
- GGUF weights are loaded into transformer modules, remaining non-transformer weights come from the HF checkpoint.
GGUF Adapter Design
GGUFAdapteris an abstract base class for model-specific adapters.Flux2KleinGGUFAdapterimplements Flux2-Klein remapping + qkv split + adaLN swap.ZImageGGUFAdapterimplements Z-Image qkv + ffn shard handling and linear qweight routing.QwenImageGGUFAdapterimplements Qwen-Image fused attention projection remapping.get_gguf_adapter(...)strictly selects by model class/config; unsupported models raise an error (no fallback adapter).
Adapter paths:
- Base:
vllm_omni/diffusion/model_loader/gguf_adapters/base.py - Z-Image:
vllm_omni/diffusion/model_loader/gguf_adapters/z_image.py - Flux2-Klein:
vllm_omni/diffusion/model_loader/gguf_adapters/flux2_klein.py - Qwen-Image:
vllm_omni/diffusion/model_loader/gguf_adapters/qwen_image.py
User Usage (Offline)
Baseline BF16
python examples/offline_inference/text_to_image/text_to_image.py \
--model /workspace/models/black-forest-labs/FLUX.2-klein-4B \
--prompt "a photo of a forest with mist swirling around the tree trunks. The word 'FLUX.2' is painted over it in big, red brush strokes with visible texture" \
--height 768 \
--width 1360 \
--seed 42 \
--cfg-scale 4.0 \
--num-images-per-prompt 1 \
--num-inference-steps 4 \
--output outputs/flux2_klein_4b.png
Native GGUF (Transformer Only)
python examples/offline_inference/text_to_image/text_to_image.py \
--model /workspace/models/black-forest-labs/FLUX.2-klein-4B \
--gguf-model "/workspace/models/unsloth/FLUX.2-klein-4B-GGUF/flux-2-klein-4b-Q8_0.gguf" \
--quantization gguf \
--prompt "a photo of a forest with mist swirling around the tree trunks. The word 'FLUX.2' is painted over it in big, red brush strokes with visible texture" \
--height 768 \
--width 1360 \
--seed 42 \
--cfg-scale 4.0 \
--num-images-per-prompt 1 \
--num-inference-steps 4 \
--output outputs/flux2_klein_4b_gguf.png
Notes for GGUF:
- Many GGUF repos do not ship
model_index.jsonand configs. Use the base repo for--modeland only pass the GGUF file via--gguf-model. gguf_modelsupports local path,repo/file.gguf, orrepo:quant_type.
User Usage (Online)
Start Server (Native GGUF via CLI)
vllm serve /workspace/models/black-forest-labs/FLUX.2-klein-4B \
--omni \
--port 8000 \
--quantization-config '{"method":"gguf","gguf_model":"/workspace/models/unsloth/FLUX.2-klein-4B-GGUF/flux-2-klein-4b-Q8_0.gguf"}'
Online Request (Images API)
curl -X POST http://localhost:8000/v1/images/generations \
-H "Content-Type: application/json" \
-d '{
"prompt": "a dragon laying over the spine of the Green Mountains of Vermont",
"size": "1024x1024",
"seed": 42,
"num_inference_steps": 4
}'
Qwen-Image Example
Offline
python examples/offline_inference/text_to_image/text_to_image.py \
--model Qwen/Qwen-Image \
--gguf-model QuantStack/Qwen-Image-GGUF/Qwen_Image-Q4_K_M.gguf \
--quantization gguf \
--prompt "a red paper kite hanging from a pine tree in a winter courtyard" \
--height 1024 \
--width 1024 \
--seed 42 \
--num_inference_steps 20 \
--output outputs/qwen_image_q4km.png
Online
vllm serve Qwen/Qwen-Image \
--omni \
--port 8000 \
--quantization-config '{"method":"gguf","gguf_model":"QuantStack/Qwen-Image-GGUF/Qwen_Image-Q4_K_M.gguf"}'
Notes:
- The GGUF repo provides transformer weights only; the base model repo still provides tokenizer, text encoder, scheduler, and VAE.
- The same adapter path covers
QwenImagePipeline,QwenImageEditPipeline,QwenImageEditPlusPipeline, andQwenImageLayeredPipeline.