diffusers 0.32.1__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 +198 -28
- diffusers/loaders/lora_conversion_utils.py +679 -44
- diffusers/loaders/lora_pipeline.py +1963 -801
- diffusers/loaders/peft.py +169 -84
- diffusers/loaders/single_file.py +17 -2
- diffusers/loaders/single_file_model.py +53 -5
- diffusers/loaders/single_file_utils.py +653 -75
- 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 +22 -32
- 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 +409 -49
- 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 +10 -2
- 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 +14 -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.1.dist-info → diffusers-0.33.0.dist-info}/METADATA +76 -44
- diffusers-0.33.0.dist-info/RECORD +608 -0
- {diffusers-0.32.1.dist-info → diffusers-0.33.0.dist-info}/WHEEL +1 -1
- diffusers-0.32.1.dist-info/RECORD +0 -550
- {diffusers-0.32.1.dist-info → diffusers-0.33.0.dist-info}/LICENSE +0 -0
- {diffusers-0.32.1.dist-info → diffusers-0.33.0.dist-info}/entry_points.txt +0 -0
- {diffusers-0.32.1.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,11 +16,10 @@ 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
|
23
|
-
import torch.nn as nn
|
24
23
|
|
25
24
|
from ..utils import (
|
26
25
|
MIN_PEFT_VERSION,
|
@@ -30,20 +29,16 @@ from ..utils import (
|
|
30
29
|
delete_adapter_layers,
|
31
30
|
get_adapter_name,
|
32
31
|
get_peft_kwargs,
|
33
|
-
is_accelerate_available,
|
34
32
|
is_peft_available,
|
35
33
|
is_peft_version,
|
36
34
|
logging,
|
37
35
|
set_adapter_layers,
|
38
36
|
set_weights_and_activate_adapters,
|
39
37
|
)
|
40
|
-
from .lora_base import _fetch_state_dict
|
38
|
+
from .lora_base import _fetch_state_dict, _func_optionally_disable_offloading
|
41
39
|
from .unet_loader_utils import _maybe_expand_lora_scales
|
42
40
|
|
43
41
|
|
44
|
-
if is_accelerate_available():
|
45
|
-
from accelerate.hooks import AlignDevicesHook, CpuOffload, remove_hook_from_module
|
46
|
-
|
47
42
|
logger = logging.get_logger(__name__)
|
48
43
|
|
49
44
|
_SET_ADAPTER_SCALE_FN_MAPPING = {
|
@@ -52,27 +47,22 @@ _SET_ADAPTER_SCALE_FN_MAPPING = {
|
|
52
47
|
"SD3Transformer2DModel": lambda model_cls, weights: weights,
|
53
48
|
"FluxTransformer2DModel": lambda model_cls, weights: weights,
|
54
49
|
"CogVideoXTransformer3DModel": lambda model_cls, weights: weights,
|
50
|
+
"ConsisIDTransformer3DModel": lambda model_cls, weights: weights,
|
55
51
|
"MochiTransformer3DModel": lambda model_cls, weights: weights,
|
56
52
|
"HunyuanVideoTransformer3DModel": lambda model_cls, weights: weights,
|
57
53
|
"LTXVideoTransformer3DModel": lambda model_cls, weights: weights,
|
58
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,
|
59
58
|
}
|
60
59
|
|
61
60
|
|
62
|
-
def
|
63
|
-
"""
|
64
|
-
We may run into some ambiguous configuration values when a model has module names, sharing a common prefix
|
65
|
-
(`proj_out.weight` and `blocks.transformer.proj_out.weight`, for example) and they have different LoRA ranks. This
|
66
|
-
method removes the ambiguity by following what is described here:
|
67
|
-
https://github.com/huggingface/diffusers/pull/9985#issuecomment-2493840028.
|
68
|
-
"""
|
61
|
+
def _maybe_raise_error_for_ambiguity(config):
|
69
62
|
rank_pattern = config["rank_pattern"].copy()
|
70
63
|
target_modules = config["target_modules"]
|
71
|
-
original_r = config["r"]
|
72
64
|
|
73
65
|
for key in list(rank_pattern.keys()):
|
74
|
-
key_rank = rank_pattern[key]
|
75
|
-
|
76
66
|
# try to detect ambiguity
|
77
67
|
# `target_modules` can also be a str, in which case this loop would loop
|
78
68
|
# over the chars of the str. The technically correct way to match LoRA keys
|
@@ -80,34 +70,12 @@ def _maybe_adjust_config(config):
|
|
80
70
|
# But this cuts it for now.
|
81
71
|
exact_matches = [mod for mod in target_modules if mod == key]
|
82
72
|
substring_matches = [mod for mod in target_modules if key in mod and mod != key]
|
83
|
-
ambiguous_key = key
|
84
73
|
|
85
74
|
if exact_matches and substring_matches:
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
for mod in substring_matches:
|
91
|
-
# avoid overwriting if the module already has a specific rank
|
92
|
-
if mod not in config["rank_pattern"]:
|
93
|
-
config["rank_pattern"][mod] = original_r
|
94
|
-
|
95
|
-
# update the rest of the keys with the `original_r`
|
96
|
-
for mod in target_modules:
|
97
|
-
if mod != ambiguous_key and mod not in config["rank_pattern"]:
|
98
|
-
config["rank_pattern"][mod] = original_r
|
99
|
-
|
100
|
-
# handle alphas to deal with cases like
|
101
|
-
# https://github.com/huggingface/diffusers/pull/9999#issuecomment-2516180777
|
102
|
-
has_different_ranks = len(config["rank_pattern"]) > 1 and list(config["rank_pattern"])[0] != config["r"]
|
103
|
-
if has_different_ranks:
|
104
|
-
config["lora_alpha"] = config["r"]
|
105
|
-
alpha_pattern = {}
|
106
|
-
for module_name, rank in config["rank_pattern"].items():
|
107
|
-
alpha_pattern[module_name] = rank
|
108
|
-
config["alpha_pattern"] = alpha_pattern
|
109
|
-
|
110
|
-
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
|
+
)
|
111
79
|
|
112
80
|
|
113
81
|
class PeftAdapterMixin:
|
@@ -125,6 +93,8 @@ class PeftAdapterMixin:
|
|
125
93
|
"""
|
126
94
|
|
127
95
|
_hf_peft_config_loaded = False
|
96
|
+
# kwargs for prepare_model_for_compiled_hotswap, if required
|
97
|
+
_prepare_lora_hotswap_kwargs: Optional[dict] = None
|
128
98
|
|
129
99
|
@classmethod
|
130
100
|
# Copied from diffusers.loaders.lora_base.LoraBaseMixin._optionally_disable_offloading
|
@@ -140,29 +110,11 @@ class PeftAdapterMixin:
|
|
140
110
|
tuple:
|
141
111
|
A tuple indicating if `is_model_cpu_offload` or `is_sequential_cpu_offload` is True.
|
142
112
|
"""
|
143
|
-
|
144
|
-
is_sequential_cpu_offload = False
|
145
|
-
|
146
|
-
if _pipeline is not None and _pipeline.hf_device_map is None:
|
147
|
-
for _, component in _pipeline.components.items():
|
148
|
-
if isinstance(component, nn.Module) and hasattr(component, "_hf_hook"):
|
149
|
-
if not is_model_cpu_offload:
|
150
|
-
is_model_cpu_offload = isinstance(component._hf_hook, CpuOffload)
|
151
|
-
if not is_sequential_cpu_offload:
|
152
|
-
is_sequential_cpu_offload = (
|
153
|
-
isinstance(component._hf_hook, AlignDevicesHook)
|
154
|
-
or hasattr(component._hf_hook, "hooks")
|
155
|
-
and isinstance(component._hf_hook.hooks[0], AlignDevicesHook)
|
156
|
-
)
|
157
|
-
|
158
|
-
logger.info(
|
159
|
-
"Accelerate hooks detected. Since you have called `load_lora_weights()`, the previous hooks will be first removed. Then the LoRA parameters will be loaded and the hooks will be applied again."
|
160
|
-
)
|
161
|
-
remove_hook_from_module(component, recurse=is_sequential_cpu_offload)
|
113
|
+
return _func_optionally_disable_offloading(_pipeline=_pipeline)
|
162
114
|
|
163
|
-
|
164
|
-
|
165
|
-
|
115
|
+
def load_lora_adapter(
|
116
|
+
self, pretrained_model_name_or_path_or_dict, prefix="transformer", hotswap: bool = False, **kwargs
|
117
|
+
):
|
166
118
|
r"""
|
167
119
|
Loads a LoRA adapter into the underlying model.
|
168
120
|
|
@@ -206,6 +158,29 @@ class PeftAdapterMixin:
|
|
206
158
|
low_cpu_mem_usage (`bool`, *optional*):
|
207
159
|
Speed up model loading by only loading the pretrained LoRA weights and not initializing the random
|
208
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
|
209
184
|
"""
|
210
185
|
from peft import LoraConfig, inject_adapter_in_model, set_peft_model_state_dict
|
211
186
|
from peft.tuners.tuners_utils import BaseTunerLayer
|
@@ -253,16 +228,18 @@ class PeftAdapterMixin:
|
|
253
228
|
raise ValueError("`network_alphas` cannot be None when `prefix` is None.")
|
254
229
|
|
255
230
|
if prefix is not None:
|
256
|
-
|
257
|
-
model_keys = [k for k in keys if k.startswith(f"{prefix}.")]
|
258
|
-
if len(model_keys) > 0:
|
259
|
-
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}.")}
|
260
232
|
|
261
233
|
if len(state_dict) > 0:
|
262
|
-
if adapter_name in getattr(self, "peft_config", {}):
|
234
|
+
if adapter_name in getattr(self, "peft_config", {}) and not hotswap:
|
263
235
|
raise ValueError(
|
264
236
|
f"Adapter name {adapter_name} already in use in the model - please select a new adapter name."
|
265
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
|
+
)
|
266
243
|
|
267
244
|
# check with first key if is not in peft format
|
268
245
|
first_key = next(iter(state_dict.keys()))
|
@@ -274,14 +251,18 @@ class PeftAdapterMixin:
|
|
274
251
|
# Cannot figure out rank from lora layers that don't have atleast 2 dimensions.
|
275
252
|
# Bias layers in LoRA only have a single dimension
|
276
253
|
if "lora_B" in key and val.ndim > 1:
|
277
|
-
|
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]
|
278
259
|
|
279
260
|
if network_alphas is not None and len(network_alphas) >= 1:
|
280
261
|
alpha_keys = [k for k in network_alphas.keys() if k.startswith(f"{prefix}.")]
|
281
262
|
network_alphas = {k.replace(f"{prefix}.", ""): v for k, v in network_alphas.items() if k in alpha_keys}
|
282
263
|
|
283
264
|
lora_config_kwargs = get_peft_kwargs(rank, network_alpha_dict=network_alphas, peft_state_dict=state_dict)
|
284
|
-
|
265
|
+
_maybe_raise_error_for_ambiguity(lora_config_kwargs)
|
285
266
|
|
286
267
|
if "use_dora" in lora_config_kwargs:
|
287
268
|
if lora_config_kwargs["use_dora"]:
|
@@ -320,20 +301,82 @@ class PeftAdapterMixin:
|
|
320
301
|
if is_peft_version(">=", "0.13.1"):
|
321
302
|
peft_kwargs["low_cpu_mem_usage"] = low_cpu_mem_usage
|
322
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
|
+
|
323
331
|
# To handle scenarios where we cannot successfully set state dict. If it's unsucessful,
|
324
332
|
# we should also delete the `peft_config` associated to the `adapter_name`.
|
325
333
|
try:
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
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)
|
337
380
|
logger.error(f"Loading {adapter_name} was unsucessful with the following error: \n{e}")
|
338
381
|
raise
|
339
382
|
|
@@ -369,6 +412,15 @@ class PeftAdapterMixin:
|
|
369
412
|
_pipeline.enable_sequential_cpu_offload()
|
370
413
|
# Unsafe code />
|
371
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
|
+
|
372
424
|
def save_lora_adapter(
|
373
425
|
self,
|
374
426
|
save_directory,
|
@@ -773,3 +825,36 @@ class PeftAdapterMixin:
|
|
773
825
|
# Pop also the corresponding adapter from the config
|
774
826
|
if hasattr(self, "peft_config"):
|
775
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
|