This repository demonstrates Quantization-aware Training (QAT) of Stable Diffusion Unet model wich is the most time-consuming element of the whole pipeline. The quantized model is exported to the OpenVINO IR.
The expected speedup from quantization is ~1.7x (for CPUs w/ Intel DL Boost) and can very depeding on the HW.
Knowledge distillation and EMA techniques can be used to improve the model accuracy.
pipinstall-rrequirements.txtInstall NNCF from source:
pipinstallgit+https://github.com/openvinotoolkit/nncf.gitfromoptimum.intel.openvinoimportOVStableDiffusionPipelinepipe=OVStableDiffusionPipeline.from_pretrained("OpenVINO/stable-diffusion-1-5-quantized", compile=False)
pipe.reshape(batch_size=1, height=512, width=512, num_images_per_prompt=1)
pipe.compile()
prompt="Super cute fluffy cat warrior in armor, photorealistic, 4K, ultra detailed, vray rendering, unreal engine"output=pipe(prompt, num_inference_steps=50, output_type="pil")
output.images[0].save("result.png")The minimal HW setup for the run is GPU with 24GB of memory.
NOTE: Potentially you can set the number of training steps to 0 and it will lead to Post-Training Quantization. CPU should be enough in this case but you may need to modify the scipt.
pythonquantize.py--use_kd--center_crop--random_flip--dataset_name="lambdalabs/pokemon-blip-captions"--max_train_steps=0--model_id="runwayml/stable-diffusion-v1-5"On a part of "laion/laion2B-en" dateset:
pythonquantize.py--use_kd--center_crop--random_flip--dataset_name="laion/laion2B-en"--model_id="stabilityai/stable-diffusion-2-1"--max_train_samples=800--opt_init_steps=800--dataloader_num_workers=6NOTE: You may need to paly with seed or do one more try to get good results. The results can be better if to use the same dataset that was used to train the original model.
- The best results are achieved with Knowledge Distillation and EMA techniques when tuning on a laion dataset:
CUDA_VISIBLE_DEVICES=2pythonquantize.py--ema_device="cpu"--use_kd--center_crop--random_flip--dataset_name="laion/laion2B-en"--max_train_steps=4096--model_id="runwayml/stable-diffusion-v1-5"--max_train_samples=10000--dataloader_num_workers=8--gradient_checkpointing--output_dir=sd-1-5-quantied-laion- Tune model parameters on a target dataset with QAT:
pythonquantize.py--use_kd--ema_device="cpu"--model_id="runwayml/stable-diffusion-v1-5"--center_crop--random_flip--gradient_checkpointing--dataloader_num_workers=8--dataset_name="lambdalabs/pokemon-blip-captions"--max_train_steps=15000--ema_device="cpu" and --gradient_checkpointing are used to save GPU mememory.
- Tune only quantization parameters for a short time. You can use smaller training steps and any relevant dataset:
pythonquantize.py--use_kd--model_id="runwayml/stable-diffusion-v1-5"--center_crop--random_flip--gradient_checkpointing--dataloader_num_workers=8--dataset_name="laion/laion2B-en"--tune_quantizers_only--max_train_steps=256--max_train_samples=10000--opt_init_steps=800--opt_init_type="min_max"