diffusers 0.32.2__py3-none-any.whl → 0.33.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- diffusers/__init__.py +186 -3
- diffusers/configuration_utils.py +40 -12
- diffusers/dependency_versions_table.py +9 -2
- diffusers/hooks/__init__.py +9 -0
- diffusers/hooks/faster_cache.py +653 -0
- diffusers/hooks/group_offloading.py +793 -0
- diffusers/hooks/hooks.py +236 -0
- diffusers/hooks/layerwise_casting.py +245 -0
- diffusers/hooks/pyramid_attention_broadcast.py +311 -0
- diffusers/loaders/__init__.py +6 -0
- diffusers/loaders/ip_adapter.py +38 -30
- diffusers/loaders/lora_base.py +121 -86
- diffusers/loaders/lora_conversion_utils.py +504 -44
- diffusers/loaders/lora_pipeline.py +1769 -181
- diffusers/loaders/peft.py +167 -57
- diffusers/loaders/single_file.py +17 -2
- diffusers/loaders/single_file_model.py +53 -5
- diffusers/loaders/single_file_utils.py +646 -72
- diffusers/loaders/textual_inversion.py +9 -9
- diffusers/loaders/transformer_flux.py +8 -9
- diffusers/loaders/transformer_sd3.py +120 -39
- diffusers/loaders/unet.py +20 -7
- diffusers/models/__init__.py +22 -0
- diffusers/models/activations.py +9 -9
- diffusers/models/attention.py +0 -1
- diffusers/models/attention_processor.py +163 -25
- diffusers/models/auto_model.py +169 -0
- diffusers/models/autoencoders/__init__.py +2 -0
- diffusers/models/autoencoders/autoencoder_asym_kl.py +2 -0
- diffusers/models/autoencoders/autoencoder_dc.py +106 -4
- diffusers/models/autoencoders/autoencoder_kl.py +0 -4
- diffusers/models/autoencoders/autoencoder_kl_allegro.py +5 -23
- diffusers/models/autoencoders/autoencoder_kl_cogvideox.py +17 -55
- diffusers/models/autoencoders/autoencoder_kl_hunyuan_video.py +17 -97
- diffusers/models/autoencoders/autoencoder_kl_ltx.py +326 -107
- diffusers/models/autoencoders/autoencoder_kl_magvit.py +1094 -0
- diffusers/models/autoencoders/autoencoder_kl_mochi.py +21 -56
- diffusers/models/autoencoders/autoencoder_kl_temporal_decoder.py +11 -42
- diffusers/models/autoencoders/autoencoder_kl_wan.py +855 -0
- diffusers/models/autoencoders/autoencoder_oobleck.py +1 -0
- diffusers/models/autoencoders/autoencoder_tiny.py +0 -4
- diffusers/models/autoencoders/consistency_decoder_vae.py +3 -1
- diffusers/models/autoencoders/vae.py +31 -141
- diffusers/models/autoencoders/vq_model.py +3 -0
- diffusers/models/cache_utils.py +108 -0
- diffusers/models/controlnets/__init__.py +1 -0
- diffusers/models/controlnets/controlnet.py +3 -8
- diffusers/models/controlnets/controlnet_flux.py +14 -42
- diffusers/models/controlnets/controlnet_sd3.py +58 -34
- diffusers/models/controlnets/controlnet_sparsectrl.py +4 -7
- diffusers/models/controlnets/controlnet_union.py +27 -18
- diffusers/models/controlnets/controlnet_xs.py +7 -46
- diffusers/models/controlnets/multicontrolnet_union.py +196 -0
- diffusers/models/embeddings.py +18 -7
- diffusers/models/model_loading_utils.py +122 -80
- diffusers/models/modeling_flax_pytorch_utils.py +1 -1
- diffusers/models/modeling_flax_utils.py +1 -1
- diffusers/models/modeling_pytorch_flax_utils.py +1 -1
- diffusers/models/modeling_utils.py +617 -272
- diffusers/models/normalization.py +67 -14
- diffusers/models/resnet.py +1 -1
- diffusers/models/transformers/__init__.py +6 -0
- diffusers/models/transformers/auraflow_transformer_2d.py +9 -35
- diffusers/models/transformers/cogvideox_transformer_3d.py +13 -24
- diffusers/models/transformers/consisid_transformer_3d.py +789 -0
- diffusers/models/transformers/dit_transformer_2d.py +5 -19
- diffusers/models/transformers/hunyuan_transformer_2d.py +4 -3
- diffusers/models/transformers/latte_transformer_3d.py +20 -15
- diffusers/models/transformers/lumina_nextdit2d.py +3 -1
- diffusers/models/transformers/pixart_transformer_2d.py +4 -19
- diffusers/models/transformers/prior_transformer.py +5 -1
- diffusers/models/transformers/sana_transformer.py +144 -40
- diffusers/models/transformers/stable_audio_transformer.py +5 -20
- diffusers/models/transformers/transformer_2d.py +7 -22
- diffusers/models/transformers/transformer_allegro.py +9 -17
- diffusers/models/transformers/transformer_cogview3plus.py +6 -17
- diffusers/models/transformers/transformer_cogview4.py +462 -0
- diffusers/models/transformers/transformer_easyanimate.py +527 -0
- diffusers/models/transformers/transformer_flux.py +68 -110
- diffusers/models/transformers/transformer_hunyuan_video.py +404 -46
- diffusers/models/transformers/transformer_ltx.py +53 -35
- diffusers/models/transformers/transformer_lumina2.py +548 -0
- diffusers/models/transformers/transformer_mochi.py +6 -17
- diffusers/models/transformers/transformer_omnigen.py +469 -0
- diffusers/models/transformers/transformer_sd3.py +56 -86
- diffusers/models/transformers/transformer_temporal.py +5 -11
- diffusers/models/transformers/transformer_wan.py +469 -0
- diffusers/models/unets/unet_1d.py +3 -1
- diffusers/models/unets/unet_2d.py +21 -20
- diffusers/models/unets/unet_2d_blocks.py +19 -243
- diffusers/models/unets/unet_2d_condition.py +4 -6
- diffusers/models/unets/unet_3d_blocks.py +14 -127
- diffusers/models/unets/unet_3d_condition.py +8 -12
- diffusers/models/unets/unet_i2vgen_xl.py +5 -13
- diffusers/models/unets/unet_kandinsky3.py +0 -4
- diffusers/models/unets/unet_motion_model.py +20 -114
- diffusers/models/unets/unet_spatio_temporal_condition.py +7 -8
- diffusers/models/unets/unet_stable_cascade.py +8 -35
- diffusers/models/unets/uvit_2d.py +1 -4
- diffusers/optimization.py +2 -2
- diffusers/pipelines/__init__.py +57 -8
- diffusers/pipelines/allegro/pipeline_allegro.py +22 -2
- diffusers/pipelines/amused/pipeline_amused.py +15 -2
- diffusers/pipelines/amused/pipeline_amused_img2img.py +15 -2
- diffusers/pipelines/amused/pipeline_amused_inpaint.py +15 -2
- diffusers/pipelines/animatediff/pipeline_animatediff.py +15 -2
- diffusers/pipelines/animatediff/pipeline_animatediff_controlnet.py +15 -3
- diffusers/pipelines/animatediff/pipeline_animatediff_sdxl.py +24 -4
- diffusers/pipelines/animatediff/pipeline_animatediff_sparsectrl.py +15 -2
- diffusers/pipelines/animatediff/pipeline_animatediff_video2video.py +16 -4
- diffusers/pipelines/animatediff/pipeline_animatediff_video2video_controlnet.py +16 -4
- diffusers/pipelines/audioldm/pipeline_audioldm.py +13 -2
- diffusers/pipelines/audioldm2/modeling_audioldm2.py +13 -68
- diffusers/pipelines/audioldm2/pipeline_audioldm2.py +39 -9
- diffusers/pipelines/aura_flow/pipeline_aura_flow.py +63 -7
- diffusers/pipelines/auto_pipeline.py +35 -14
- diffusers/pipelines/blip_diffusion/blip_image_processing.py +1 -1
- diffusers/pipelines/blip_diffusion/modeling_blip2.py +5 -8
- diffusers/pipelines/blip_diffusion/pipeline_blip_diffusion.py +12 -0
- diffusers/pipelines/cogvideo/pipeline_cogvideox.py +22 -6
- diffusers/pipelines/cogvideo/pipeline_cogvideox_fun_control.py +22 -6
- diffusers/pipelines/cogvideo/pipeline_cogvideox_image2video.py +22 -5
- diffusers/pipelines/cogvideo/pipeline_cogvideox_video2video.py +22 -6
- diffusers/pipelines/cogview3/pipeline_cogview3plus.py +12 -4
- diffusers/pipelines/cogview4/__init__.py +49 -0
- diffusers/pipelines/cogview4/pipeline_cogview4.py +684 -0
- diffusers/pipelines/cogview4/pipeline_cogview4_control.py +732 -0
- diffusers/pipelines/cogview4/pipeline_output.py +21 -0
- diffusers/pipelines/consisid/__init__.py +49 -0
- diffusers/pipelines/consisid/consisid_utils.py +357 -0
- diffusers/pipelines/consisid/pipeline_consisid.py +974 -0
- diffusers/pipelines/consisid/pipeline_output.py +20 -0
- diffusers/pipelines/consistency_models/pipeline_consistency_models.py +11 -0
- diffusers/pipelines/controlnet/pipeline_controlnet.py +6 -5
- diffusers/pipelines/controlnet/pipeline_controlnet_blip_diffusion.py +13 -0
- diffusers/pipelines/controlnet/pipeline_controlnet_img2img.py +17 -5
- diffusers/pipelines/controlnet/pipeline_controlnet_inpaint.py +31 -12
- diffusers/pipelines/controlnet/pipeline_controlnet_inpaint_sd_xl.py +26 -7
- diffusers/pipelines/controlnet/pipeline_controlnet_sd_xl.py +20 -3
- diffusers/pipelines/controlnet/pipeline_controlnet_sd_xl_img2img.py +22 -3
- diffusers/pipelines/controlnet/pipeline_controlnet_union_inpaint_sd_xl.py +26 -25
- diffusers/pipelines/controlnet/pipeline_controlnet_union_sd_xl.py +224 -109
- diffusers/pipelines/controlnet/pipeline_controlnet_union_sd_xl_img2img.py +25 -29
- diffusers/pipelines/controlnet/pipeline_flax_controlnet.py +7 -4
- diffusers/pipelines/controlnet_hunyuandit/pipeline_hunyuandit_controlnet.py +3 -5
- diffusers/pipelines/controlnet_sd3/pipeline_stable_diffusion_3_controlnet.py +121 -10
- diffusers/pipelines/controlnet_sd3/pipeline_stable_diffusion_3_controlnet_inpainting.py +122 -11
- diffusers/pipelines/controlnet_xs/pipeline_controlnet_xs.py +12 -1
- diffusers/pipelines/controlnet_xs/pipeline_controlnet_xs_sd_xl.py +20 -3
- diffusers/pipelines/dance_diffusion/pipeline_dance_diffusion.py +14 -2
- diffusers/pipelines/ddim/pipeline_ddim.py +14 -1
- diffusers/pipelines/ddpm/pipeline_ddpm.py +15 -1
- diffusers/pipelines/deepfloyd_if/pipeline_if.py +12 -0
- diffusers/pipelines/deepfloyd_if/pipeline_if_img2img.py +12 -0
- diffusers/pipelines/deepfloyd_if/pipeline_if_img2img_superresolution.py +14 -1
- diffusers/pipelines/deepfloyd_if/pipeline_if_inpainting.py +12 -0
- diffusers/pipelines/deepfloyd_if/pipeline_if_inpainting_superresolution.py +14 -1
- diffusers/pipelines/deepfloyd_if/pipeline_if_superresolution.py +14 -1
- diffusers/pipelines/deprecated/alt_diffusion/pipeline_alt_diffusion.py +11 -7
- diffusers/pipelines/deprecated/alt_diffusion/pipeline_alt_diffusion_img2img.py +11 -7
- diffusers/pipelines/deprecated/repaint/pipeline_repaint.py +1 -1
- diffusers/pipelines/deprecated/stable_diffusion_variants/pipeline_cycle_diffusion.py +10 -6
- diffusers/pipelines/deprecated/stable_diffusion_variants/pipeline_onnx_stable_diffusion_inpaint_legacy.py +2 -2
- diffusers/pipelines/deprecated/stable_diffusion_variants/pipeline_stable_diffusion_inpaint_legacy.py +11 -7
- diffusers/pipelines/deprecated/stable_diffusion_variants/pipeline_stable_diffusion_model_editing.py +1 -1
- diffusers/pipelines/deprecated/stable_diffusion_variants/pipeline_stable_diffusion_paradigms.py +1 -1
- diffusers/pipelines/deprecated/stable_diffusion_variants/pipeline_stable_diffusion_pix2pix_zero.py +1 -1
- diffusers/pipelines/deprecated/versatile_diffusion/modeling_text_unet.py +10 -105
- diffusers/pipelines/deprecated/versatile_diffusion/pipeline_versatile_diffusion.py +1 -1
- diffusers/pipelines/deprecated/versatile_diffusion/pipeline_versatile_diffusion_dual_guided.py +1 -1
- diffusers/pipelines/deprecated/versatile_diffusion/pipeline_versatile_diffusion_image_variation.py +1 -1
- diffusers/pipelines/deprecated/versatile_diffusion/pipeline_versatile_diffusion_text_to_image.py +1 -1
- diffusers/pipelines/dit/pipeline_dit.py +15 -2
- diffusers/pipelines/easyanimate/__init__.py +52 -0
- diffusers/pipelines/easyanimate/pipeline_easyanimate.py +770 -0
- diffusers/pipelines/easyanimate/pipeline_easyanimate_control.py +994 -0
- diffusers/pipelines/easyanimate/pipeline_easyanimate_inpaint.py +1234 -0
- diffusers/pipelines/easyanimate/pipeline_output.py +20 -0
- diffusers/pipelines/flux/pipeline_flux.py +53 -21
- diffusers/pipelines/flux/pipeline_flux_control.py +9 -12
- diffusers/pipelines/flux/pipeline_flux_control_img2img.py +6 -10
- diffusers/pipelines/flux/pipeline_flux_control_inpaint.py +8 -10
- diffusers/pipelines/flux/pipeline_flux_controlnet.py +185 -13
- diffusers/pipelines/flux/pipeline_flux_controlnet_image_to_image.py +8 -10
- diffusers/pipelines/flux/pipeline_flux_controlnet_inpainting.py +16 -16
- diffusers/pipelines/flux/pipeline_flux_fill.py +107 -39
- diffusers/pipelines/flux/pipeline_flux_img2img.py +193 -15
- diffusers/pipelines/flux/pipeline_flux_inpaint.py +199 -19
- diffusers/pipelines/free_noise_utils.py +3 -3
- diffusers/pipelines/hunyuan_video/__init__.py +4 -0
- diffusers/pipelines/hunyuan_video/pipeline_hunyuan_skyreels_image2video.py +804 -0
- diffusers/pipelines/hunyuan_video/pipeline_hunyuan_video.py +90 -23
- diffusers/pipelines/hunyuan_video/pipeline_hunyuan_video_image2video.py +924 -0
- diffusers/pipelines/hunyuandit/pipeline_hunyuandit.py +3 -5
- diffusers/pipelines/i2vgen_xl/pipeline_i2vgen_xl.py +13 -1
- diffusers/pipelines/kandinsky/pipeline_kandinsky.py +12 -0
- diffusers/pipelines/kandinsky/pipeline_kandinsky_combined.py +1 -1
- diffusers/pipelines/kandinsky/pipeline_kandinsky_img2img.py +12 -0
- diffusers/pipelines/kandinsky/pipeline_kandinsky_inpaint.py +13 -1
- diffusers/pipelines/kandinsky/pipeline_kandinsky_prior.py +12 -0
- diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2.py +12 -1
- diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2_controlnet.py +13 -0
- diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2_controlnet_img2img.py +12 -0
- diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2_img2img.py +12 -1
- diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2_inpainting.py +12 -1
- diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2_prior.py +12 -0
- diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2_prior_emb2emb.py +12 -0
- diffusers/pipelines/kandinsky3/pipeline_kandinsky3.py +12 -0
- diffusers/pipelines/kandinsky3/pipeline_kandinsky3_img2img.py +12 -0
- diffusers/pipelines/kolors/pipeline_kolors.py +10 -8
- diffusers/pipelines/kolors/pipeline_kolors_img2img.py +6 -4
- diffusers/pipelines/kolors/text_encoder.py +7 -34
- diffusers/pipelines/latent_consistency_models/pipeline_latent_consistency_img2img.py +12 -1
- diffusers/pipelines/latent_consistency_models/pipeline_latent_consistency_text2img.py +13 -1
- diffusers/pipelines/latent_diffusion/pipeline_latent_diffusion.py +14 -13
- diffusers/pipelines/latent_diffusion/pipeline_latent_diffusion_superresolution.py +12 -1
- diffusers/pipelines/latte/pipeline_latte.py +36 -7
- diffusers/pipelines/ledits_pp/pipeline_leditspp_stable_diffusion.py +67 -13
- diffusers/pipelines/ledits_pp/pipeline_leditspp_stable_diffusion_xl.py +60 -15
- diffusers/pipelines/ltx/__init__.py +2 -0
- diffusers/pipelines/ltx/pipeline_ltx.py +25 -13
- diffusers/pipelines/ltx/pipeline_ltx_condition.py +1194 -0
- diffusers/pipelines/ltx/pipeline_ltx_image2video.py +31 -17
- diffusers/pipelines/lumina/__init__.py +2 -2
- diffusers/pipelines/lumina/pipeline_lumina.py +83 -20
- diffusers/pipelines/lumina2/__init__.py +48 -0
- diffusers/pipelines/lumina2/pipeline_lumina2.py +790 -0
- diffusers/pipelines/marigold/__init__.py +2 -0
- diffusers/pipelines/marigold/marigold_image_processing.py +127 -14
- diffusers/pipelines/marigold/pipeline_marigold_depth.py +31 -16
- diffusers/pipelines/marigold/pipeline_marigold_intrinsics.py +721 -0
- diffusers/pipelines/marigold/pipeline_marigold_normals.py +31 -16
- diffusers/pipelines/mochi/pipeline_mochi.py +14 -18
- diffusers/pipelines/musicldm/pipeline_musicldm.py +16 -1
- diffusers/pipelines/omnigen/__init__.py +50 -0
- diffusers/pipelines/omnigen/pipeline_omnigen.py +512 -0
- diffusers/pipelines/omnigen/processor_omnigen.py +327 -0
- diffusers/pipelines/onnx_utils.py +5 -3
- diffusers/pipelines/pag/pag_utils.py +1 -1
- diffusers/pipelines/pag/pipeline_pag_controlnet_sd.py +12 -1
- diffusers/pipelines/pag/pipeline_pag_controlnet_sd_inpaint.py +15 -4
- diffusers/pipelines/pag/pipeline_pag_controlnet_sd_xl.py +20 -3
- diffusers/pipelines/pag/pipeline_pag_controlnet_sd_xl_img2img.py +20 -3
- diffusers/pipelines/pag/pipeline_pag_hunyuandit.py +1 -3
- diffusers/pipelines/pag/pipeline_pag_kolors.py +6 -4
- diffusers/pipelines/pag/pipeline_pag_pixart_sigma.py +16 -3
- diffusers/pipelines/pag/pipeline_pag_sana.py +65 -8
- diffusers/pipelines/pag/pipeline_pag_sd.py +23 -7
- diffusers/pipelines/pag/pipeline_pag_sd_3.py +3 -5
- diffusers/pipelines/pag/pipeline_pag_sd_3_img2img.py +3 -5
- diffusers/pipelines/pag/pipeline_pag_sd_animatediff.py +13 -1
- diffusers/pipelines/pag/pipeline_pag_sd_img2img.py +23 -7
- diffusers/pipelines/pag/pipeline_pag_sd_inpaint.py +26 -10
- diffusers/pipelines/pag/pipeline_pag_sd_xl.py +12 -4
- diffusers/pipelines/pag/pipeline_pag_sd_xl_img2img.py +7 -3
- diffusers/pipelines/pag/pipeline_pag_sd_xl_inpaint.py +10 -6
- diffusers/pipelines/paint_by_example/pipeline_paint_by_example.py +13 -3
- diffusers/pipelines/pia/pipeline_pia.py +13 -1
- diffusers/pipelines/pipeline_flax_utils.py +7 -7
- diffusers/pipelines/pipeline_loading_utils.py +193 -83
- diffusers/pipelines/pipeline_utils.py +221 -106
- diffusers/pipelines/pixart_alpha/pipeline_pixart_alpha.py +17 -5
- diffusers/pipelines/pixart_alpha/pipeline_pixart_sigma.py +17 -4
- diffusers/pipelines/sana/__init__.py +2 -0
- diffusers/pipelines/sana/pipeline_sana.py +183 -58
- diffusers/pipelines/sana/pipeline_sana_sprint.py +889 -0
- diffusers/pipelines/semantic_stable_diffusion/pipeline_semantic_stable_diffusion.py +12 -2
- diffusers/pipelines/shap_e/pipeline_shap_e.py +12 -0
- diffusers/pipelines/shap_e/pipeline_shap_e_img2img.py +12 -0
- diffusers/pipelines/shap_e/renderer.py +6 -6
- diffusers/pipelines/stable_audio/pipeline_stable_audio.py +1 -1
- diffusers/pipelines/stable_cascade/pipeline_stable_cascade.py +15 -4
- diffusers/pipelines/stable_cascade/pipeline_stable_cascade_combined.py +12 -8
- diffusers/pipelines/stable_cascade/pipeline_stable_cascade_prior.py +12 -1
- diffusers/pipelines/stable_diffusion/convert_from_ckpt.py +3 -2
- diffusers/pipelines/stable_diffusion/pipeline_flax_stable_diffusion.py +14 -10
- diffusers/pipelines/stable_diffusion/pipeline_flax_stable_diffusion_img2img.py +3 -3
- diffusers/pipelines/stable_diffusion/pipeline_flax_stable_diffusion_inpaint.py +14 -10
- diffusers/pipelines/stable_diffusion/pipeline_onnx_stable_diffusion.py +2 -2
- diffusers/pipelines/stable_diffusion/pipeline_onnx_stable_diffusion_img2img.py +4 -3
- diffusers/pipelines/stable_diffusion/pipeline_onnx_stable_diffusion_inpaint.py +5 -4
- diffusers/pipelines/stable_diffusion/pipeline_onnx_stable_diffusion_upscale.py +2 -2
- diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py +18 -13
- diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_depth2img.py +30 -8
- diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_image_variation.py +24 -10
- diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_img2img.py +28 -12
- diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_inpaint.py +39 -18
- diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_instruct_pix2pix.py +17 -6
- diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_latent_upscale.py +13 -3
- diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_upscale.py +20 -3
- diffusers/pipelines/stable_diffusion/pipeline_stable_unclip.py +14 -2
- diffusers/pipelines/stable_diffusion/pipeline_stable_unclip_img2img.py +13 -1
- diffusers/pipelines/stable_diffusion_3/pipeline_stable_diffusion_3.py +16 -17
- diffusers/pipelines/stable_diffusion_3/pipeline_stable_diffusion_3_img2img.py +136 -18
- diffusers/pipelines/stable_diffusion_3/pipeline_stable_diffusion_3_inpaint.py +150 -21
- diffusers/pipelines/stable_diffusion_attend_and_excite/pipeline_stable_diffusion_attend_and_excite.py +15 -3
- diffusers/pipelines/stable_diffusion_diffedit/pipeline_stable_diffusion_diffedit.py +26 -11
- diffusers/pipelines/stable_diffusion_gligen/pipeline_stable_diffusion_gligen.py +15 -3
- diffusers/pipelines/stable_diffusion_gligen/pipeline_stable_diffusion_gligen_text_image.py +22 -4
- diffusers/pipelines/stable_diffusion_k_diffusion/pipeline_stable_diffusion_k_diffusion.py +30 -13
- diffusers/pipelines/stable_diffusion_k_diffusion/pipeline_stable_diffusion_xl_k_diffusion.py +12 -4
- diffusers/pipelines/stable_diffusion_ldm3d/pipeline_stable_diffusion_ldm3d.py +15 -3
- diffusers/pipelines/stable_diffusion_panorama/pipeline_stable_diffusion_panorama.py +15 -3
- diffusers/pipelines/stable_diffusion_safe/pipeline_stable_diffusion_safe.py +26 -12
- diffusers/pipelines/stable_diffusion_sag/pipeline_stable_diffusion_sag.py +16 -4
- diffusers/pipelines/stable_diffusion_xl/pipeline_flax_stable_diffusion_xl.py +1 -1
- diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl.py +12 -4
- diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl_img2img.py +7 -3
- diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl_inpaint.py +10 -6
- diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl_instruct_pix2pix.py +11 -4
- diffusers/pipelines/stable_video_diffusion/pipeline_stable_video_diffusion.py +13 -2
- diffusers/pipelines/t2i_adapter/pipeline_stable_diffusion_adapter.py +18 -4
- diffusers/pipelines/t2i_adapter/pipeline_stable_diffusion_xl_adapter.py +26 -5
- diffusers/pipelines/text_to_video_synthesis/pipeline_text_to_video_synth.py +13 -1
- diffusers/pipelines/text_to_video_synthesis/pipeline_text_to_video_synth_img2img.py +13 -1
- diffusers/pipelines/text_to_video_synthesis/pipeline_text_to_video_zero.py +28 -6
- diffusers/pipelines/text_to_video_synthesis/pipeline_text_to_video_zero_sdxl.py +26 -4
- diffusers/pipelines/transformers_loading_utils.py +121 -0
- diffusers/pipelines/unclip/pipeline_unclip.py +11 -1
- diffusers/pipelines/unclip/pipeline_unclip_image_variation.py +11 -1
- diffusers/pipelines/unidiffuser/pipeline_unidiffuser.py +19 -2
- diffusers/pipelines/wan/__init__.py +51 -0
- diffusers/pipelines/wan/pipeline_output.py +20 -0
- diffusers/pipelines/wan/pipeline_wan.py +593 -0
- diffusers/pipelines/wan/pipeline_wan_i2v.py +722 -0
- diffusers/pipelines/wan/pipeline_wan_video2video.py +725 -0
- diffusers/pipelines/wuerstchen/modeling_wuerstchen_prior.py +7 -31
- diffusers/pipelines/wuerstchen/pipeline_wuerstchen.py +12 -1
- diffusers/pipelines/wuerstchen/pipeline_wuerstchen_prior.py +12 -1
- diffusers/quantizers/auto.py +5 -1
- diffusers/quantizers/base.py +5 -9
- diffusers/quantizers/bitsandbytes/bnb_quantizer.py +41 -29
- diffusers/quantizers/bitsandbytes/utils.py +30 -20
- diffusers/quantizers/gguf/gguf_quantizer.py +1 -0
- diffusers/quantizers/gguf/utils.py +4 -2
- diffusers/quantizers/quantization_config.py +59 -4
- diffusers/quantizers/quanto/__init__.py +1 -0
- diffusers/quantizers/quanto/quanto_quantizer.py +177 -0
- diffusers/quantizers/quanto/utils.py +60 -0
- diffusers/quantizers/torchao/__init__.py +1 -1
- diffusers/quantizers/torchao/torchao_quantizer.py +47 -2
- diffusers/schedulers/__init__.py +2 -1
- diffusers/schedulers/scheduling_consistency_models.py +1 -2
- diffusers/schedulers/scheduling_ddim_inverse.py +1 -1
- diffusers/schedulers/scheduling_ddpm.py +2 -3
- diffusers/schedulers/scheduling_ddpm_parallel.py +1 -2
- diffusers/schedulers/scheduling_dpmsolver_multistep.py +12 -4
- diffusers/schedulers/scheduling_edm_euler.py +45 -10
- diffusers/schedulers/scheduling_flow_match_euler_discrete.py +116 -28
- diffusers/schedulers/scheduling_flow_match_heun_discrete.py +7 -6
- diffusers/schedulers/scheduling_heun_discrete.py +1 -1
- diffusers/schedulers/scheduling_lcm.py +1 -2
- diffusers/schedulers/scheduling_lms_discrete.py +1 -1
- diffusers/schedulers/scheduling_repaint.py +5 -1
- diffusers/schedulers/scheduling_scm.py +265 -0
- diffusers/schedulers/scheduling_tcd.py +1 -2
- diffusers/schedulers/scheduling_utils.py +2 -1
- diffusers/training_utils.py +14 -7
- diffusers/utils/__init__.py +9 -1
- diffusers/utils/constants.py +13 -1
- diffusers/utils/deprecation_utils.py +1 -1
- diffusers/utils/dummy_bitsandbytes_objects.py +17 -0
- diffusers/utils/dummy_gguf_objects.py +17 -0
- diffusers/utils/dummy_optimum_quanto_objects.py +17 -0
- diffusers/utils/dummy_pt_objects.py +233 -0
- diffusers/utils/dummy_torch_and_transformers_and_opencv_objects.py +17 -0
- diffusers/utils/dummy_torch_and_transformers_objects.py +270 -0
- diffusers/utils/dummy_torchao_objects.py +17 -0
- diffusers/utils/dynamic_modules_utils.py +1 -1
- diffusers/utils/export_utils.py +28 -3
- diffusers/utils/hub_utils.py +52 -102
- diffusers/utils/import_utils.py +121 -221
- diffusers/utils/loading_utils.py +2 -1
- diffusers/utils/logging.py +1 -2
- diffusers/utils/peft_utils.py +6 -14
- diffusers/utils/remote_utils.py +425 -0
- diffusers/utils/source_code_parsing_utils.py +52 -0
- diffusers/utils/state_dict_utils.py +15 -1
- diffusers/utils/testing_utils.py +243 -13
- diffusers/utils/torch_utils.py +10 -0
- diffusers/utils/typing_utils.py +91 -0
- diffusers/video_processor.py +1 -1
- {diffusers-0.32.2.dist-info → diffusers-0.33.0.dist-info}/METADATA +76 -44
- diffusers-0.33.0.dist-info/RECORD +608 -0
- {diffusers-0.32.2.dist-info → diffusers-0.33.0.dist-info}/WHEEL +1 -1
- diffusers-0.32.2.dist-info/RECORD +0 -550
- {diffusers-0.32.2.dist-info → diffusers-0.33.0.dist-info}/LICENSE +0 -0
- {diffusers-0.32.2.dist-info → diffusers-0.33.0.dist-info}/entry_points.txt +0 -0
- {diffusers-0.32.2.dist-info → diffusers-0.33.0.dist-info}/top_level.txt +0 -0
diffusers/loaders/peft.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# coding=utf-8
|
2
|
-
# Copyright
|
2
|
+
# Copyright 2025 The HuggingFace Inc. team.
|
3
3
|
#
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
5
|
# you may not use this file except in compliance with the License.
|
@@ -16,7 +16,7 @@ import inspect
|
|
16
16
|
import os
|
17
17
|
from functools import partial
|
18
18
|
from pathlib import Path
|
19
|
-
from typing import Dict, List, Optional, Union
|
19
|
+
from typing import Dict, List, Literal, Optional, Union
|
20
20
|
|
21
21
|
import safetensors
|
22
22
|
import torch
|
@@ -47,27 +47,22 @@ _SET_ADAPTER_SCALE_FN_MAPPING = {
|
|
47
47
|
"SD3Transformer2DModel": lambda model_cls, weights: weights,
|
48
48
|
"FluxTransformer2DModel": lambda model_cls, weights: weights,
|
49
49
|
"CogVideoXTransformer3DModel": lambda model_cls, weights: weights,
|
50
|
+
"ConsisIDTransformer3DModel": lambda model_cls, weights: weights,
|
50
51
|
"MochiTransformer3DModel": lambda model_cls, weights: weights,
|
51
52
|
"HunyuanVideoTransformer3DModel": lambda model_cls, weights: weights,
|
52
53
|
"LTXVideoTransformer3DModel": lambda model_cls, weights: weights,
|
53
54
|
"SanaTransformer2DModel": lambda model_cls, weights: weights,
|
55
|
+
"Lumina2Transformer2DModel": lambda model_cls, weights: weights,
|
56
|
+
"WanTransformer3DModel": lambda model_cls, weights: weights,
|
57
|
+
"CogView4Transformer2DModel": lambda model_cls, weights: weights,
|
54
58
|
}
|
55
59
|
|
56
60
|
|
57
|
-
def
|
58
|
-
"""
|
59
|
-
We may run into some ambiguous configuration values when a model has module names, sharing a common prefix
|
60
|
-
(`proj_out.weight` and `blocks.transformer.proj_out.weight`, for example) and they have different LoRA ranks. This
|
61
|
-
method removes the ambiguity by following what is described here:
|
62
|
-
https://github.com/huggingface/diffusers/pull/9985#issuecomment-2493840028.
|
63
|
-
"""
|
61
|
+
def _maybe_raise_error_for_ambiguity(config):
|
64
62
|
rank_pattern = config["rank_pattern"].copy()
|
65
63
|
target_modules = config["target_modules"]
|
66
|
-
original_r = config["r"]
|
67
64
|
|
68
65
|
for key in list(rank_pattern.keys()):
|
69
|
-
key_rank = rank_pattern[key]
|
70
|
-
|
71
66
|
# try to detect ambiguity
|
72
67
|
# `target_modules` can also be a str, in which case this loop would loop
|
73
68
|
# over the chars of the str. The technically correct way to match LoRA keys
|
@@ -75,34 +70,12 @@ def _maybe_adjust_config(config):
|
|
75
70
|
# But this cuts it for now.
|
76
71
|
exact_matches = [mod for mod in target_modules if mod == key]
|
77
72
|
substring_matches = [mod for mod in target_modules if key in mod and mod != key]
|
78
|
-
ambiguous_key = key
|
79
73
|
|
80
74
|
if exact_matches and substring_matches:
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
for mod in substring_matches:
|
86
|
-
# avoid overwriting if the module already has a specific rank
|
87
|
-
if mod not in config["rank_pattern"]:
|
88
|
-
config["rank_pattern"][mod] = original_r
|
89
|
-
|
90
|
-
# update the rest of the keys with the `original_r`
|
91
|
-
for mod in target_modules:
|
92
|
-
if mod != ambiguous_key and mod not in config["rank_pattern"]:
|
93
|
-
config["rank_pattern"][mod] = original_r
|
94
|
-
|
95
|
-
# handle alphas to deal with cases like
|
96
|
-
# https://github.com/huggingface/diffusers/pull/9999#issuecomment-2516180777
|
97
|
-
has_different_ranks = len(config["rank_pattern"]) > 1 and list(config["rank_pattern"])[0] != config["r"]
|
98
|
-
if has_different_ranks:
|
99
|
-
config["lora_alpha"] = config["r"]
|
100
|
-
alpha_pattern = {}
|
101
|
-
for module_name, rank in config["rank_pattern"].items():
|
102
|
-
alpha_pattern[module_name] = rank
|
103
|
-
config["alpha_pattern"] = alpha_pattern
|
104
|
-
|
105
|
-
return config
|
75
|
+
if is_peft_version("<", "0.14.1"):
|
76
|
+
raise ValueError(
|
77
|
+
"There are ambiguous keys present in this LoRA. To load it, please update your `peft` installation - `pip install -U peft`."
|
78
|
+
)
|
106
79
|
|
107
80
|
|
108
81
|
class PeftAdapterMixin:
|
@@ -120,6 +93,8 @@ class PeftAdapterMixin:
|
|
120
93
|
"""
|
121
94
|
|
122
95
|
_hf_peft_config_loaded = False
|
96
|
+
# kwargs for prepare_model_for_compiled_hotswap, if required
|
97
|
+
_prepare_lora_hotswap_kwargs: Optional[dict] = None
|
123
98
|
|
124
99
|
@classmethod
|
125
100
|
# Copied from diffusers.loaders.lora_base.LoraBaseMixin._optionally_disable_offloading
|
@@ -137,7 +112,9 @@ class PeftAdapterMixin:
|
|
137
112
|
"""
|
138
113
|
return _func_optionally_disable_offloading(_pipeline=_pipeline)
|
139
114
|
|
140
|
-
def load_lora_adapter(
|
115
|
+
def load_lora_adapter(
|
116
|
+
self, pretrained_model_name_or_path_or_dict, prefix="transformer", hotswap: bool = False, **kwargs
|
117
|
+
):
|
141
118
|
r"""
|
142
119
|
Loads a LoRA adapter into the underlying model.
|
143
120
|
|
@@ -181,6 +158,29 @@ class PeftAdapterMixin:
|
|
181
158
|
low_cpu_mem_usage (`bool`, *optional*):
|
182
159
|
Speed up model loading by only loading the pretrained LoRA weights and not initializing the random
|
183
160
|
weights.
|
161
|
+
hotswap : (`bool`, *optional*)
|
162
|
+
Defaults to `False`. Whether to substitute an existing (LoRA) adapter with the newly loaded adapter
|
163
|
+
in-place. This means that, instead of loading an additional adapter, this will take the existing
|
164
|
+
adapter weights and replace them with the weights of the new adapter. This can be faster and more
|
165
|
+
memory efficient. However, the main advantage of hotswapping is that when the model is compiled with
|
166
|
+
torch.compile, loading the new adapter does not require recompilation of the model. When using
|
167
|
+
hotswapping, the passed `adapter_name` should be the name of an already loaded adapter.
|
168
|
+
|
169
|
+
If the new adapter and the old adapter have different ranks and/or LoRA alphas (i.e. scaling), you need
|
170
|
+
to call an additional method before loading the adapter:
|
171
|
+
|
172
|
+
```py
|
173
|
+
pipeline = ... # load diffusers pipeline
|
174
|
+
max_rank = ... # the highest rank among all LoRAs that you want to load
|
175
|
+
# call *before* compiling and loading the LoRA adapter
|
176
|
+
pipeline.enable_lora_hotswap(target_rank=max_rank)
|
177
|
+
pipeline.load_lora_weights(file_name)
|
178
|
+
# optionally compile the model now
|
179
|
+
```
|
180
|
+
|
181
|
+
Note that hotswapping adapters of the text encoder is not yet supported. There are some further
|
182
|
+
limitations to this technique, which are documented here:
|
183
|
+
https://huggingface.co/docs/peft/main/en/package_reference/hotswap
|
184
184
|
"""
|
185
185
|
from peft import LoraConfig, inject_adapter_in_model, set_peft_model_state_dict
|
186
186
|
from peft.tuners.tuners_utils import BaseTunerLayer
|
@@ -228,16 +228,18 @@ class PeftAdapterMixin:
|
|
228
228
|
raise ValueError("`network_alphas` cannot be None when `prefix` is None.")
|
229
229
|
|
230
230
|
if prefix is not None:
|
231
|
-
|
232
|
-
model_keys = [k for k in keys if k.startswith(f"{prefix}.")]
|
233
|
-
if len(model_keys) > 0:
|
234
|
-
state_dict = {k.replace(f"{prefix}.", ""): v for k, v in state_dict.items() if k in model_keys}
|
231
|
+
state_dict = {k[len(f"{prefix}.") :]: v for k, v in state_dict.items() if k.startswith(f"{prefix}.")}
|
235
232
|
|
236
233
|
if len(state_dict) > 0:
|
237
|
-
if adapter_name in getattr(self, "peft_config", {}):
|
234
|
+
if adapter_name in getattr(self, "peft_config", {}) and not hotswap:
|
238
235
|
raise ValueError(
|
239
236
|
f"Adapter name {adapter_name} already in use in the model - please select a new adapter name."
|
240
237
|
)
|
238
|
+
elif adapter_name not in getattr(self, "peft_config", {}) and hotswap:
|
239
|
+
raise ValueError(
|
240
|
+
f"Trying to hotswap LoRA adapter '{adapter_name}' but there is no existing adapter by that name. "
|
241
|
+
"Please choose an existing adapter name or set `hotswap=False` to prevent hotswapping."
|
242
|
+
)
|
241
243
|
|
242
244
|
# check with first key if is not in peft format
|
243
245
|
first_key = next(iter(state_dict.keys()))
|
@@ -249,14 +251,18 @@ class PeftAdapterMixin:
|
|
249
251
|
# Cannot figure out rank from lora layers that don't have atleast 2 dimensions.
|
250
252
|
# Bias layers in LoRA only have a single dimension
|
251
253
|
if "lora_B" in key and val.ndim > 1:
|
252
|
-
|
254
|
+
# Check out https://github.com/huggingface/peft/pull/2419 for the `^` symbol.
|
255
|
+
# We may run into some ambiguous configuration values when a model has module
|
256
|
+
# names, sharing a common prefix (`proj_out.weight` and `blocks.transformer.proj_out.weight`,
|
257
|
+
# for example) and they have different LoRA ranks.
|
258
|
+
rank[f"^{key}"] = val.shape[1]
|
253
259
|
|
254
260
|
if network_alphas is not None and len(network_alphas) >= 1:
|
255
261
|
alpha_keys = [k for k in network_alphas.keys() if k.startswith(f"{prefix}.")]
|
256
262
|
network_alphas = {k.replace(f"{prefix}.", ""): v for k, v in network_alphas.items() if k in alpha_keys}
|
257
263
|
|
258
264
|
lora_config_kwargs = get_peft_kwargs(rank, network_alpha_dict=network_alphas, peft_state_dict=state_dict)
|
259
|
-
|
265
|
+
_maybe_raise_error_for_ambiguity(lora_config_kwargs)
|
260
266
|
|
261
267
|
if "use_dora" in lora_config_kwargs:
|
262
268
|
if lora_config_kwargs["use_dora"]:
|
@@ -295,20 +301,82 @@ class PeftAdapterMixin:
|
|
295
301
|
if is_peft_version(">=", "0.13.1"):
|
296
302
|
peft_kwargs["low_cpu_mem_usage"] = low_cpu_mem_usage
|
297
303
|
|
304
|
+
if hotswap or (self._prepare_lora_hotswap_kwargs is not None):
|
305
|
+
if is_peft_version(">", "0.14.0"):
|
306
|
+
from peft.utils.hotswap import (
|
307
|
+
check_hotswap_configs_compatible,
|
308
|
+
hotswap_adapter_from_state_dict,
|
309
|
+
prepare_model_for_compiled_hotswap,
|
310
|
+
)
|
311
|
+
else:
|
312
|
+
msg = (
|
313
|
+
"Hotswapping requires PEFT > v0.14. Please upgrade PEFT to a higher version or install it "
|
314
|
+
"from source."
|
315
|
+
)
|
316
|
+
raise ImportError(msg)
|
317
|
+
|
318
|
+
if hotswap:
|
319
|
+
|
320
|
+
def map_state_dict_for_hotswap(sd):
|
321
|
+
# For hotswapping, we need the adapter name to be present in the state dict keys
|
322
|
+
new_sd = {}
|
323
|
+
for k, v in sd.items():
|
324
|
+
if k.endswith("lora_A.weight") or key.endswith("lora_B.weight"):
|
325
|
+
k = k[: -len(".weight")] + f".{adapter_name}.weight"
|
326
|
+
elif k.endswith("lora_B.bias"): # lora_bias=True option
|
327
|
+
k = k[: -len(".bias")] + f".{adapter_name}.bias"
|
328
|
+
new_sd[k] = v
|
329
|
+
return new_sd
|
330
|
+
|
298
331
|
# To handle scenarios where we cannot successfully set state dict. If it's unsucessful,
|
299
332
|
# we should also delete the `peft_config` associated to the `adapter_name`.
|
300
333
|
try:
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
334
|
+
if hotswap:
|
335
|
+
state_dict = map_state_dict_for_hotswap(state_dict)
|
336
|
+
check_hotswap_configs_compatible(self.peft_config[adapter_name], lora_config)
|
337
|
+
try:
|
338
|
+
hotswap_adapter_from_state_dict(
|
339
|
+
model=self,
|
340
|
+
state_dict=state_dict,
|
341
|
+
adapter_name=adapter_name,
|
342
|
+
config=lora_config,
|
343
|
+
)
|
344
|
+
except Exception as e:
|
345
|
+
logger.error(f"Hotswapping {adapter_name} was unsucessful with the following error: \n{e}")
|
346
|
+
raise
|
347
|
+
# the hotswap function raises if there are incompatible keys, so if we reach this point we can set
|
348
|
+
# it to None
|
349
|
+
incompatible_keys = None
|
350
|
+
else:
|
351
|
+
inject_adapter_in_model(lora_config, self, adapter_name=adapter_name, **peft_kwargs)
|
352
|
+
incompatible_keys = set_peft_model_state_dict(self, state_dict, adapter_name, **peft_kwargs)
|
353
|
+
|
354
|
+
if self._prepare_lora_hotswap_kwargs is not None:
|
355
|
+
# For hotswapping of compiled models or adapters with different ranks.
|
356
|
+
# If the user called enable_lora_hotswap, we need to ensure it is called:
|
357
|
+
# - after the first adapter was loaded
|
358
|
+
# - before the model is compiled and the 2nd adapter is being hotswapped in
|
359
|
+
# Therefore, it needs to be called here
|
360
|
+
prepare_model_for_compiled_hotswap(
|
361
|
+
self, config=lora_config, **self._prepare_lora_hotswap_kwargs
|
362
|
+
)
|
363
|
+
# We only want to call prepare_model_for_compiled_hotswap once
|
364
|
+
self._prepare_lora_hotswap_kwargs = None
|
365
|
+
|
366
|
+
# Set peft config loaded flag to True if module has been successfully injected and incompatible keys retrieved
|
367
|
+
if not self._hf_peft_config_loaded:
|
368
|
+
self._hf_peft_config_loaded = True
|
369
|
+
except Exception as e:
|
370
|
+
# In case `inject_adapter_in_model()` was unsuccessful even before injecting the `peft_config`.
|
371
|
+
if hasattr(self, "peft_config"):
|
372
|
+
for module in self.modules():
|
373
|
+
if isinstance(module, BaseTunerLayer):
|
374
|
+
active_adapters = module.active_adapters
|
375
|
+
for active_adapter in active_adapters:
|
376
|
+
if adapter_name in active_adapter:
|
377
|
+
module.delete_adapter(adapter_name)
|
378
|
+
|
379
|
+
self.peft_config.pop(adapter_name)
|
312
380
|
logger.error(f"Loading {adapter_name} was unsucessful with the following error: \n{e}")
|
313
381
|
raise
|
314
382
|
|
@@ -344,6 +412,15 @@ class PeftAdapterMixin:
|
|
344
412
|
_pipeline.enable_sequential_cpu_offload()
|
345
413
|
# Unsafe code />
|
346
414
|
|
415
|
+
if prefix is not None and not state_dict:
|
416
|
+
logger.warning(
|
417
|
+
f"No LoRA keys associated to {self.__class__.__name__} found with the {prefix=}. "
|
418
|
+
"This is safe to ignore if LoRA state dict didn't originally have any "
|
419
|
+
f"{self.__class__.__name__} related params. You can also try specifying `prefix=None` "
|
420
|
+
"to resolve the warning. Otherwise, open an issue if you think it's unexpected: "
|
421
|
+
"https://github.com/huggingface/diffusers/issues/new"
|
422
|
+
)
|
423
|
+
|
347
424
|
def save_lora_adapter(
|
348
425
|
self,
|
349
426
|
save_directory,
|
@@ -748,3 +825,36 @@ class PeftAdapterMixin:
|
|
748
825
|
# Pop also the corresponding adapter from the config
|
749
826
|
if hasattr(self, "peft_config"):
|
750
827
|
self.peft_config.pop(adapter_name, None)
|
828
|
+
|
829
|
+
def enable_lora_hotswap(
|
830
|
+
self, target_rank: int = 128, check_compiled: Literal["error", "warn", "ignore"] = "error"
|
831
|
+
) -> None:
|
832
|
+
"""Enables the possibility to hotswap LoRA adapters.
|
833
|
+
|
834
|
+
Calling this method is only required when hotswapping adapters and if the model is compiled or if the ranks of
|
835
|
+
the loaded adapters differ.
|
836
|
+
|
837
|
+
Args:
|
838
|
+
target_rank (`int`, *optional*, defaults to `128`):
|
839
|
+
The highest rank among all the adapters that will be loaded.
|
840
|
+
|
841
|
+
check_compiled (`str`, *optional*, defaults to `"error"`):
|
842
|
+
How to handle the case when the model is already compiled, which should generally be avoided. The
|
843
|
+
options are:
|
844
|
+
- "error" (default): raise an error
|
845
|
+
- "warn": issue a warning
|
846
|
+
- "ignore": do nothing
|
847
|
+
"""
|
848
|
+
if getattr(self, "peft_config", {}):
|
849
|
+
if check_compiled == "error":
|
850
|
+
raise RuntimeError("Call `enable_lora_hotswap` before loading the first adapter.")
|
851
|
+
elif check_compiled == "warn":
|
852
|
+
logger.warning(
|
853
|
+
"It is recommended to call `enable_lora_hotswap` before loading the first adapter to avoid recompilation."
|
854
|
+
)
|
855
|
+
elif check_compiled != "ignore":
|
856
|
+
raise ValueError(
|
857
|
+
f"check_compiles should be one of 'error', 'warn', or 'ignore', got '{check_compiled}' instead."
|
858
|
+
)
|
859
|
+
|
860
|
+
self._prepare_lora_hotswap_kwargs = {"target_rank": target_rank, "check_compiled": check_compiled}
|
diffusers/loaders/single_file.py
CHANGED
@@ -19,6 +19,7 @@ import torch
|
|
19
19
|
from huggingface_hub import snapshot_download
|
20
20
|
from huggingface_hub.utils import LocalEntryNotFoundError, validate_hf_hub_args
|
21
21
|
from packaging import version
|
22
|
+
from typing_extensions import Self
|
22
23
|
|
23
24
|
from ..utils import deprecate, is_transformers_available, logging
|
24
25
|
from .single_file_utils import (
|
@@ -60,6 +61,7 @@ def load_single_file_sub_model(
|
|
60
61
|
local_files_only=False,
|
61
62
|
torch_dtype=None,
|
62
63
|
is_legacy_loading=False,
|
64
|
+
disable_mmap=False,
|
63
65
|
**kwargs,
|
64
66
|
):
|
65
67
|
if is_pipeline_module:
|
@@ -106,6 +108,7 @@ def load_single_file_sub_model(
|
|
106
108
|
subfolder=name,
|
107
109
|
torch_dtype=torch_dtype,
|
108
110
|
local_files_only=local_files_only,
|
111
|
+
disable_mmap=disable_mmap,
|
109
112
|
**kwargs,
|
110
113
|
)
|
111
114
|
|
@@ -267,7 +270,7 @@ class FromSingleFileMixin:
|
|
267
270
|
|
268
271
|
@classmethod
|
269
272
|
@validate_hf_hub_args
|
270
|
-
def from_single_file(cls, pretrained_model_link_or_path, **kwargs):
|
273
|
+
def from_single_file(cls, pretrained_model_link_or_path, **kwargs) -> Self:
|
271
274
|
r"""
|
272
275
|
Instantiate a [`DiffusionPipeline`] from pretrained pipeline weights saved in the `.ckpt` or `.safetensors`
|
273
276
|
format. The pipeline is set in evaluation mode (`model.eval()`) by default.
|
@@ -308,6 +311,9 @@ class FromSingleFileMixin:
|
|
308
311
|
hosted on the Hub.
|
309
312
|
- A path to a *directory* (for example `./my_pipeline_directory/`) containing the pipeline
|
310
313
|
component configs in Diffusers format.
|
314
|
+
disable_mmap ('bool', *optional*, defaults to 'False'):
|
315
|
+
Whether to disable mmap when loading a Safetensors model. This option can perform better when the model
|
316
|
+
is on a network mount or hard drive.
|
311
317
|
kwargs (remaining dictionary of keyword arguments, *optional*):
|
312
318
|
Can be used to overwrite load and saveable variables (the pipeline components of the specific pipeline
|
313
319
|
class). The overwritten components are passed directly to the pipelines `__init__` method. See example
|
@@ -329,7 +335,7 @@ class FromSingleFileMixin:
|
|
329
335
|
|
330
336
|
>>> # Enable float16 and move to GPU
|
331
337
|
>>> pipeline = StableDiffusionPipeline.from_single_file(
|
332
|
-
... "https://huggingface.co/
|
338
|
+
... "https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5/blob/main/v1-5-pruned-emaonly.ckpt",
|
333
339
|
... torch_dtype=torch.float16,
|
334
340
|
... )
|
335
341
|
>>> pipeline.to("cuda")
|
@@ -355,9 +361,16 @@ class FromSingleFileMixin:
|
|
355
361
|
local_files_only = kwargs.pop("local_files_only", False)
|
356
362
|
revision = kwargs.pop("revision", None)
|
357
363
|
torch_dtype = kwargs.pop("torch_dtype", None)
|
364
|
+
disable_mmap = kwargs.pop("disable_mmap", False)
|
358
365
|
|
359
366
|
is_legacy_loading = False
|
360
367
|
|
368
|
+
if torch_dtype is not None and not isinstance(torch_dtype, torch.dtype):
|
369
|
+
torch_dtype = torch.float32
|
370
|
+
logger.warning(
|
371
|
+
f"Passed `torch_dtype` {torch_dtype} is not a `torch.dtype`. Defaulting to `torch.float32`."
|
372
|
+
)
|
373
|
+
|
361
374
|
# We shouldn't allow configuring individual models components through a Pipeline creation method
|
362
375
|
# These model kwargs should be deprecated
|
363
376
|
scaling_factor = kwargs.get("scaling_factor", None)
|
@@ -383,6 +396,7 @@ class FromSingleFileMixin:
|
|
383
396
|
cache_dir=cache_dir,
|
384
397
|
local_files_only=local_files_only,
|
385
398
|
revision=revision,
|
399
|
+
disable_mmap=disable_mmap,
|
386
400
|
)
|
387
401
|
|
388
402
|
if config is None:
|
@@ -504,6 +518,7 @@ class FromSingleFileMixin:
|
|
504
518
|
original_config=original_config,
|
505
519
|
local_files_only=local_files_only,
|
506
520
|
is_legacy_loading=is_legacy_loading,
|
521
|
+
disable_mmap=disable_mmap,
|
507
522
|
**kwargs,
|
508
523
|
)
|
509
524
|
except SingleFileComponentError as e:
|
@@ -19,12 +19,14 @@ from typing import Optional
|
|
19
19
|
|
20
20
|
import torch
|
21
21
|
from huggingface_hub.utils import validate_hf_hub_args
|
22
|
+
from typing_extensions import Self
|
22
23
|
|
23
24
|
from ..quantizers import DiffusersAutoQuantizer
|
24
25
|
from ..utils import deprecate, is_accelerate_available, logging
|
25
26
|
from .single_file_utils import (
|
26
27
|
SingleFileComponentError,
|
27
28
|
convert_animatediff_checkpoint_to_diffusers,
|
29
|
+
convert_auraflow_transformer_checkpoint_to_diffusers,
|
28
30
|
convert_autoencoder_dc_checkpoint_to_diffusers,
|
29
31
|
convert_controlnet_checkpoint,
|
30
32
|
convert_flux_transformer_checkpoint_to_diffusers,
|
@@ -33,9 +35,13 @@ from .single_file_utils import (
|
|
33
35
|
convert_ldm_vae_checkpoint,
|
34
36
|
convert_ltx_transformer_checkpoint_to_diffusers,
|
35
37
|
convert_ltx_vae_checkpoint_to_diffusers,
|
38
|
+
convert_lumina2_to_diffusers,
|
36
39
|
convert_mochi_transformer_checkpoint_to_diffusers,
|
40
|
+
convert_sana_transformer_to_diffusers,
|
37
41
|
convert_sd3_transformer_checkpoint_to_diffusers,
|
38
42
|
convert_stable_cascade_unet_single_file_to_diffusers,
|
43
|
+
convert_wan_transformer_to_diffusers,
|
44
|
+
convert_wan_vae_to_diffusers,
|
39
45
|
create_controlnet_diffusers_config_from_ldm,
|
40
46
|
create_unet_diffusers_config_from_ldm,
|
41
47
|
create_vae_diffusers_config_from_ldm,
|
@@ -49,7 +55,7 @@ logger = logging.get_logger(__name__)
|
|
49
55
|
|
50
56
|
|
51
57
|
if is_accelerate_available():
|
52
|
-
from accelerate import init_empty_weights
|
58
|
+
from accelerate import dispatch_model, init_empty_weights
|
53
59
|
|
54
60
|
from ..models.modeling_utils import load_model_dict_into_meta
|
55
61
|
|
@@ -106,6 +112,26 @@ SINGLE_FILE_LOADABLE_CLASSES = {
|
|
106
112
|
"checkpoint_mapping_fn": convert_hunyuan_video_transformer_to_diffusers,
|
107
113
|
"default_subfolder": "transformer",
|
108
114
|
},
|
115
|
+
"AuraFlowTransformer2DModel": {
|
116
|
+
"checkpoint_mapping_fn": convert_auraflow_transformer_checkpoint_to_diffusers,
|
117
|
+
"default_subfolder": "transformer",
|
118
|
+
},
|
119
|
+
"Lumina2Transformer2DModel": {
|
120
|
+
"checkpoint_mapping_fn": convert_lumina2_to_diffusers,
|
121
|
+
"default_subfolder": "transformer",
|
122
|
+
},
|
123
|
+
"SanaTransformer2DModel": {
|
124
|
+
"checkpoint_mapping_fn": convert_sana_transformer_to_diffusers,
|
125
|
+
"default_subfolder": "transformer",
|
126
|
+
},
|
127
|
+
"WanTransformer3DModel": {
|
128
|
+
"checkpoint_mapping_fn": convert_wan_transformer_to_diffusers,
|
129
|
+
"default_subfolder": "transformer",
|
130
|
+
},
|
131
|
+
"AutoencoderKLWan": {
|
132
|
+
"checkpoint_mapping_fn": convert_wan_vae_to_diffusers,
|
133
|
+
"default_subfolder": "vae",
|
134
|
+
},
|
109
135
|
}
|
110
136
|
|
111
137
|
|
@@ -138,7 +164,7 @@ class FromOriginalModelMixin:
|
|
138
164
|
|
139
165
|
@classmethod
|
140
166
|
@validate_hf_hub_args
|
141
|
-
def from_single_file(cls, pretrained_model_link_or_path_or_dict: Optional[str] = None, **kwargs):
|
167
|
+
def from_single_file(cls, pretrained_model_link_or_path_or_dict: Optional[str] = None, **kwargs) -> Self:
|
142
168
|
r"""
|
143
169
|
Instantiate a model from pretrained weights saved in the original `.ckpt` or `.safetensors` format. The model
|
144
170
|
is set in evaluation mode (`model.eval()`) by default.
|
@@ -182,6 +208,9 @@ class FromOriginalModelMixin:
|
|
182
208
|
revision (`str`, *optional*, defaults to `"main"`):
|
183
209
|
The specific model version to use. It can be a branch name, a tag name, a commit id, or any identifier
|
184
210
|
allowed by Git.
|
211
|
+
disable_mmap ('bool', *optional*, defaults to 'False'):
|
212
|
+
Whether to disable mmap when loading a Safetensors model. This option can perform better when the model
|
213
|
+
is on a network mount or hard drive, which may not handle the seeky-ness of mmap very well.
|
185
214
|
kwargs (remaining dictionary of keyword arguments, *optional*):
|
186
215
|
Can be used to overwrite load and saveable variables (for example the pipeline components of the
|
187
216
|
specific pipeline class). The overwritten components are directly passed to the pipelines `__init__`
|
@@ -229,6 +258,13 @@ class FromOriginalModelMixin:
|
|
229
258
|
torch_dtype = kwargs.pop("torch_dtype", None)
|
230
259
|
quantization_config = kwargs.pop("quantization_config", None)
|
231
260
|
device = kwargs.pop("device", None)
|
261
|
+
disable_mmap = kwargs.pop("disable_mmap", False)
|
262
|
+
|
263
|
+
if torch_dtype is not None and not isinstance(torch_dtype, torch.dtype):
|
264
|
+
torch_dtype = torch.float32
|
265
|
+
logger.warning(
|
266
|
+
f"Passed `torch_dtype` {torch_dtype} is not a `torch.dtype`. Defaulting to `torch.float32`."
|
267
|
+
)
|
232
268
|
|
233
269
|
if isinstance(pretrained_model_link_or_path_or_dict, dict):
|
234
270
|
checkpoint = pretrained_model_link_or_path_or_dict
|
@@ -241,10 +277,12 @@ class FromOriginalModelMixin:
|
|
241
277
|
cache_dir=cache_dir,
|
242
278
|
local_files_only=local_files_only,
|
243
279
|
revision=revision,
|
280
|
+
disable_mmap=disable_mmap,
|
244
281
|
)
|
245
282
|
if quantization_config is not None:
|
246
283
|
hf_quantizer = DiffusersAutoQuantizer.from_config(quantization_config)
|
247
284
|
hf_quantizer.validate_environment()
|
285
|
+
torch_dtype = hf_quantizer.update_torch_dtype(torch_dtype)
|
248
286
|
|
249
287
|
else:
|
250
288
|
hf_quantizer = None
|
@@ -350,17 +388,23 @@ class FromOriginalModelMixin:
|
|
350
388
|
keep_in_fp32_modules=keep_in_fp32_modules,
|
351
389
|
)
|
352
390
|
|
391
|
+
device_map = None
|
353
392
|
if is_accelerate_available():
|
354
393
|
param_device = torch.device(device) if device else torch.device("cpu")
|
355
|
-
|
394
|
+
empty_state_dict = model.state_dict()
|
395
|
+
unexpected_keys = [
|
396
|
+
param_name for param_name in diffusers_format_checkpoint if param_name not in empty_state_dict
|
397
|
+
]
|
398
|
+
device_map = {"": param_device}
|
399
|
+
load_model_dict_into_meta(
|
356
400
|
model,
|
357
401
|
diffusers_format_checkpoint,
|
358
402
|
dtype=torch_dtype,
|
359
|
-
|
403
|
+
device_map=device_map,
|
360
404
|
hf_quantizer=hf_quantizer,
|
361
405
|
keep_in_fp32_modules=keep_in_fp32_modules,
|
406
|
+
unexpected_keys=unexpected_keys,
|
362
407
|
)
|
363
|
-
|
364
408
|
else:
|
365
409
|
_, unexpected_keys = model.load_state_dict(diffusers_format_checkpoint, strict=False)
|
366
410
|
|
@@ -382,4 +426,8 @@ class FromOriginalModelMixin:
|
|
382
426
|
|
383
427
|
model.eval()
|
384
428
|
|
429
|
+
if device_map is not None:
|
430
|
+
device_map_kwargs = {"device_map": device_map}
|
431
|
+
dispatch_model(model, **device_map_kwargs)
|
432
|
+
|
385
433
|
return model
|