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.
Files changed (389) hide show
  1. diffusers/__init__.py +186 -3
  2. diffusers/configuration_utils.py +40 -12
  3. diffusers/dependency_versions_table.py +9 -2
  4. diffusers/hooks/__init__.py +9 -0
  5. diffusers/hooks/faster_cache.py +653 -0
  6. diffusers/hooks/group_offloading.py +793 -0
  7. diffusers/hooks/hooks.py +236 -0
  8. diffusers/hooks/layerwise_casting.py +245 -0
  9. diffusers/hooks/pyramid_attention_broadcast.py +311 -0
  10. diffusers/loaders/__init__.py +6 -0
  11. diffusers/loaders/ip_adapter.py +38 -30
  12. diffusers/loaders/lora_base.py +198 -28
  13. diffusers/loaders/lora_conversion_utils.py +679 -44
  14. diffusers/loaders/lora_pipeline.py +1963 -801
  15. diffusers/loaders/peft.py +169 -84
  16. diffusers/loaders/single_file.py +17 -2
  17. diffusers/loaders/single_file_model.py +53 -5
  18. diffusers/loaders/single_file_utils.py +653 -75
  19. diffusers/loaders/textual_inversion.py +9 -9
  20. diffusers/loaders/transformer_flux.py +8 -9
  21. diffusers/loaders/transformer_sd3.py +120 -39
  22. diffusers/loaders/unet.py +22 -32
  23. diffusers/models/__init__.py +22 -0
  24. diffusers/models/activations.py +9 -9
  25. diffusers/models/attention.py +0 -1
  26. diffusers/models/attention_processor.py +163 -25
  27. diffusers/models/auto_model.py +169 -0
  28. diffusers/models/autoencoders/__init__.py +2 -0
  29. diffusers/models/autoencoders/autoencoder_asym_kl.py +2 -0
  30. diffusers/models/autoencoders/autoencoder_dc.py +106 -4
  31. diffusers/models/autoencoders/autoencoder_kl.py +0 -4
  32. diffusers/models/autoencoders/autoencoder_kl_allegro.py +5 -23
  33. diffusers/models/autoencoders/autoencoder_kl_cogvideox.py +17 -55
  34. diffusers/models/autoencoders/autoencoder_kl_hunyuan_video.py +17 -97
  35. diffusers/models/autoencoders/autoencoder_kl_ltx.py +326 -107
  36. diffusers/models/autoencoders/autoencoder_kl_magvit.py +1094 -0
  37. diffusers/models/autoencoders/autoencoder_kl_mochi.py +21 -56
  38. diffusers/models/autoencoders/autoencoder_kl_temporal_decoder.py +11 -42
  39. diffusers/models/autoencoders/autoencoder_kl_wan.py +855 -0
  40. diffusers/models/autoencoders/autoencoder_oobleck.py +1 -0
  41. diffusers/models/autoencoders/autoencoder_tiny.py +0 -4
  42. diffusers/models/autoencoders/consistency_decoder_vae.py +3 -1
  43. diffusers/models/autoencoders/vae.py +31 -141
  44. diffusers/models/autoencoders/vq_model.py +3 -0
  45. diffusers/models/cache_utils.py +108 -0
  46. diffusers/models/controlnets/__init__.py +1 -0
  47. diffusers/models/controlnets/controlnet.py +3 -8
  48. diffusers/models/controlnets/controlnet_flux.py +14 -42
  49. diffusers/models/controlnets/controlnet_sd3.py +58 -34
  50. diffusers/models/controlnets/controlnet_sparsectrl.py +4 -7
  51. diffusers/models/controlnets/controlnet_union.py +27 -18
  52. diffusers/models/controlnets/controlnet_xs.py +7 -46
  53. diffusers/models/controlnets/multicontrolnet_union.py +196 -0
  54. diffusers/models/embeddings.py +18 -7
  55. diffusers/models/model_loading_utils.py +122 -80
  56. diffusers/models/modeling_flax_pytorch_utils.py +1 -1
  57. diffusers/models/modeling_flax_utils.py +1 -1
  58. diffusers/models/modeling_pytorch_flax_utils.py +1 -1
  59. diffusers/models/modeling_utils.py +617 -272
  60. diffusers/models/normalization.py +67 -14
  61. diffusers/models/resnet.py +1 -1
  62. diffusers/models/transformers/__init__.py +6 -0
  63. diffusers/models/transformers/auraflow_transformer_2d.py +9 -35
  64. diffusers/models/transformers/cogvideox_transformer_3d.py +13 -24
  65. diffusers/models/transformers/consisid_transformer_3d.py +789 -0
  66. diffusers/models/transformers/dit_transformer_2d.py +5 -19
  67. diffusers/models/transformers/hunyuan_transformer_2d.py +4 -3
  68. diffusers/models/transformers/latte_transformer_3d.py +20 -15
  69. diffusers/models/transformers/lumina_nextdit2d.py +3 -1
  70. diffusers/models/transformers/pixart_transformer_2d.py +4 -19
  71. diffusers/models/transformers/prior_transformer.py +5 -1
  72. diffusers/models/transformers/sana_transformer.py +144 -40
  73. diffusers/models/transformers/stable_audio_transformer.py +5 -20
  74. diffusers/models/transformers/transformer_2d.py +7 -22
  75. diffusers/models/transformers/transformer_allegro.py +9 -17
  76. diffusers/models/transformers/transformer_cogview3plus.py +6 -17
  77. diffusers/models/transformers/transformer_cogview4.py +462 -0
  78. diffusers/models/transformers/transformer_easyanimate.py +527 -0
  79. diffusers/models/transformers/transformer_flux.py +68 -110
  80. diffusers/models/transformers/transformer_hunyuan_video.py +409 -49
  81. diffusers/models/transformers/transformer_ltx.py +53 -35
  82. diffusers/models/transformers/transformer_lumina2.py +548 -0
  83. diffusers/models/transformers/transformer_mochi.py +6 -17
  84. diffusers/models/transformers/transformer_omnigen.py +469 -0
  85. diffusers/models/transformers/transformer_sd3.py +56 -86
  86. diffusers/models/transformers/transformer_temporal.py +5 -11
  87. diffusers/models/transformers/transformer_wan.py +469 -0
  88. diffusers/models/unets/unet_1d.py +3 -1
  89. diffusers/models/unets/unet_2d.py +21 -20
  90. diffusers/models/unets/unet_2d_blocks.py +19 -243
  91. diffusers/models/unets/unet_2d_condition.py +4 -6
  92. diffusers/models/unets/unet_3d_blocks.py +14 -127
  93. diffusers/models/unets/unet_3d_condition.py +8 -12
  94. diffusers/models/unets/unet_i2vgen_xl.py +5 -13
  95. diffusers/models/unets/unet_kandinsky3.py +0 -4
  96. diffusers/models/unets/unet_motion_model.py +20 -114
  97. diffusers/models/unets/unet_spatio_temporal_condition.py +7 -8
  98. diffusers/models/unets/unet_stable_cascade.py +8 -35
  99. diffusers/models/unets/uvit_2d.py +1 -4
  100. diffusers/optimization.py +2 -2
  101. diffusers/pipelines/__init__.py +57 -8
  102. diffusers/pipelines/allegro/pipeline_allegro.py +22 -2
  103. diffusers/pipelines/amused/pipeline_amused.py +15 -2
  104. diffusers/pipelines/amused/pipeline_amused_img2img.py +15 -2
  105. diffusers/pipelines/amused/pipeline_amused_inpaint.py +15 -2
  106. diffusers/pipelines/animatediff/pipeline_animatediff.py +15 -2
  107. diffusers/pipelines/animatediff/pipeline_animatediff_controlnet.py +15 -3
  108. diffusers/pipelines/animatediff/pipeline_animatediff_sdxl.py +24 -4
  109. diffusers/pipelines/animatediff/pipeline_animatediff_sparsectrl.py +15 -2
  110. diffusers/pipelines/animatediff/pipeline_animatediff_video2video.py +16 -4
  111. diffusers/pipelines/animatediff/pipeline_animatediff_video2video_controlnet.py +16 -4
  112. diffusers/pipelines/audioldm/pipeline_audioldm.py +13 -2
  113. diffusers/pipelines/audioldm2/modeling_audioldm2.py +13 -68
  114. diffusers/pipelines/audioldm2/pipeline_audioldm2.py +39 -9
  115. diffusers/pipelines/aura_flow/pipeline_aura_flow.py +63 -7
  116. diffusers/pipelines/auto_pipeline.py +35 -14
  117. diffusers/pipelines/blip_diffusion/blip_image_processing.py +1 -1
  118. diffusers/pipelines/blip_diffusion/modeling_blip2.py +5 -8
  119. diffusers/pipelines/blip_diffusion/pipeline_blip_diffusion.py +12 -0
  120. diffusers/pipelines/cogvideo/pipeline_cogvideox.py +22 -6
  121. diffusers/pipelines/cogvideo/pipeline_cogvideox_fun_control.py +22 -6
  122. diffusers/pipelines/cogvideo/pipeline_cogvideox_image2video.py +22 -5
  123. diffusers/pipelines/cogvideo/pipeline_cogvideox_video2video.py +22 -6
  124. diffusers/pipelines/cogview3/pipeline_cogview3plus.py +12 -4
  125. diffusers/pipelines/cogview4/__init__.py +49 -0
  126. diffusers/pipelines/cogview4/pipeline_cogview4.py +684 -0
  127. diffusers/pipelines/cogview4/pipeline_cogview4_control.py +732 -0
  128. diffusers/pipelines/cogview4/pipeline_output.py +21 -0
  129. diffusers/pipelines/consisid/__init__.py +49 -0
  130. diffusers/pipelines/consisid/consisid_utils.py +357 -0
  131. diffusers/pipelines/consisid/pipeline_consisid.py +974 -0
  132. diffusers/pipelines/consisid/pipeline_output.py +20 -0
  133. diffusers/pipelines/consistency_models/pipeline_consistency_models.py +11 -0
  134. diffusers/pipelines/controlnet/pipeline_controlnet.py +6 -5
  135. diffusers/pipelines/controlnet/pipeline_controlnet_blip_diffusion.py +13 -0
  136. diffusers/pipelines/controlnet/pipeline_controlnet_img2img.py +17 -5
  137. diffusers/pipelines/controlnet/pipeline_controlnet_inpaint.py +31 -12
  138. diffusers/pipelines/controlnet/pipeline_controlnet_inpaint_sd_xl.py +26 -7
  139. diffusers/pipelines/controlnet/pipeline_controlnet_sd_xl.py +20 -3
  140. diffusers/pipelines/controlnet/pipeline_controlnet_sd_xl_img2img.py +22 -3
  141. diffusers/pipelines/controlnet/pipeline_controlnet_union_inpaint_sd_xl.py +26 -25
  142. diffusers/pipelines/controlnet/pipeline_controlnet_union_sd_xl.py +224 -109
  143. diffusers/pipelines/controlnet/pipeline_controlnet_union_sd_xl_img2img.py +25 -29
  144. diffusers/pipelines/controlnet/pipeline_flax_controlnet.py +7 -4
  145. diffusers/pipelines/controlnet_hunyuandit/pipeline_hunyuandit_controlnet.py +3 -5
  146. diffusers/pipelines/controlnet_sd3/pipeline_stable_diffusion_3_controlnet.py +121 -10
  147. diffusers/pipelines/controlnet_sd3/pipeline_stable_diffusion_3_controlnet_inpainting.py +122 -11
  148. diffusers/pipelines/controlnet_xs/pipeline_controlnet_xs.py +12 -1
  149. diffusers/pipelines/controlnet_xs/pipeline_controlnet_xs_sd_xl.py +20 -3
  150. diffusers/pipelines/dance_diffusion/pipeline_dance_diffusion.py +14 -2
  151. diffusers/pipelines/ddim/pipeline_ddim.py +14 -1
  152. diffusers/pipelines/ddpm/pipeline_ddpm.py +15 -1
  153. diffusers/pipelines/deepfloyd_if/pipeline_if.py +12 -0
  154. diffusers/pipelines/deepfloyd_if/pipeline_if_img2img.py +12 -0
  155. diffusers/pipelines/deepfloyd_if/pipeline_if_img2img_superresolution.py +14 -1
  156. diffusers/pipelines/deepfloyd_if/pipeline_if_inpainting.py +12 -0
  157. diffusers/pipelines/deepfloyd_if/pipeline_if_inpainting_superresolution.py +14 -1
  158. diffusers/pipelines/deepfloyd_if/pipeline_if_superresolution.py +14 -1
  159. diffusers/pipelines/deprecated/alt_diffusion/pipeline_alt_diffusion.py +11 -7
  160. diffusers/pipelines/deprecated/alt_diffusion/pipeline_alt_diffusion_img2img.py +11 -7
  161. diffusers/pipelines/deprecated/repaint/pipeline_repaint.py +1 -1
  162. diffusers/pipelines/deprecated/stable_diffusion_variants/pipeline_cycle_diffusion.py +10 -6
  163. diffusers/pipelines/deprecated/stable_diffusion_variants/pipeline_onnx_stable_diffusion_inpaint_legacy.py +2 -2
  164. diffusers/pipelines/deprecated/stable_diffusion_variants/pipeline_stable_diffusion_inpaint_legacy.py +11 -7
  165. diffusers/pipelines/deprecated/stable_diffusion_variants/pipeline_stable_diffusion_model_editing.py +1 -1
  166. diffusers/pipelines/deprecated/stable_diffusion_variants/pipeline_stable_diffusion_paradigms.py +1 -1
  167. diffusers/pipelines/deprecated/stable_diffusion_variants/pipeline_stable_diffusion_pix2pix_zero.py +1 -1
  168. diffusers/pipelines/deprecated/versatile_diffusion/modeling_text_unet.py +10 -105
  169. diffusers/pipelines/deprecated/versatile_diffusion/pipeline_versatile_diffusion.py +1 -1
  170. diffusers/pipelines/deprecated/versatile_diffusion/pipeline_versatile_diffusion_dual_guided.py +1 -1
  171. diffusers/pipelines/deprecated/versatile_diffusion/pipeline_versatile_diffusion_image_variation.py +1 -1
  172. diffusers/pipelines/deprecated/versatile_diffusion/pipeline_versatile_diffusion_text_to_image.py +1 -1
  173. diffusers/pipelines/dit/pipeline_dit.py +15 -2
  174. diffusers/pipelines/easyanimate/__init__.py +52 -0
  175. diffusers/pipelines/easyanimate/pipeline_easyanimate.py +770 -0
  176. diffusers/pipelines/easyanimate/pipeline_easyanimate_control.py +994 -0
  177. diffusers/pipelines/easyanimate/pipeline_easyanimate_inpaint.py +1234 -0
  178. diffusers/pipelines/easyanimate/pipeline_output.py +20 -0
  179. diffusers/pipelines/flux/pipeline_flux.py +53 -21
  180. diffusers/pipelines/flux/pipeline_flux_control.py +9 -12
  181. diffusers/pipelines/flux/pipeline_flux_control_img2img.py +6 -10
  182. diffusers/pipelines/flux/pipeline_flux_control_inpaint.py +8 -10
  183. diffusers/pipelines/flux/pipeline_flux_controlnet.py +185 -13
  184. diffusers/pipelines/flux/pipeline_flux_controlnet_image_to_image.py +8 -10
  185. diffusers/pipelines/flux/pipeline_flux_controlnet_inpainting.py +16 -16
  186. diffusers/pipelines/flux/pipeline_flux_fill.py +107 -39
  187. diffusers/pipelines/flux/pipeline_flux_img2img.py +193 -15
  188. diffusers/pipelines/flux/pipeline_flux_inpaint.py +199 -19
  189. diffusers/pipelines/free_noise_utils.py +3 -3
  190. diffusers/pipelines/hunyuan_video/__init__.py +4 -0
  191. diffusers/pipelines/hunyuan_video/pipeline_hunyuan_skyreels_image2video.py +804 -0
  192. diffusers/pipelines/hunyuan_video/pipeline_hunyuan_video.py +90 -23
  193. diffusers/pipelines/hunyuan_video/pipeline_hunyuan_video_image2video.py +924 -0
  194. diffusers/pipelines/hunyuandit/pipeline_hunyuandit.py +3 -5
  195. diffusers/pipelines/i2vgen_xl/pipeline_i2vgen_xl.py +13 -1
  196. diffusers/pipelines/kandinsky/pipeline_kandinsky.py +12 -0
  197. diffusers/pipelines/kandinsky/pipeline_kandinsky_combined.py +1 -1
  198. diffusers/pipelines/kandinsky/pipeline_kandinsky_img2img.py +12 -0
  199. diffusers/pipelines/kandinsky/pipeline_kandinsky_inpaint.py +13 -1
  200. diffusers/pipelines/kandinsky/pipeline_kandinsky_prior.py +12 -0
  201. diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2.py +12 -1
  202. diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2_controlnet.py +13 -0
  203. diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2_controlnet_img2img.py +12 -0
  204. diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2_img2img.py +12 -1
  205. diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2_inpainting.py +12 -1
  206. diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2_prior.py +12 -0
  207. diffusers/pipelines/kandinsky2_2/pipeline_kandinsky2_2_prior_emb2emb.py +12 -0
  208. diffusers/pipelines/kandinsky3/pipeline_kandinsky3.py +12 -0
  209. diffusers/pipelines/kandinsky3/pipeline_kandinsky3_img2img.py +12 -0
  210. diffusers/pipelines/kolors/pipeline_kolors.py +10 -8
  211. diffusers/pipelines/kolors/pipeline_kolors_img2img.py +6 -4
  212. diffusers/pipelines/kolors/text_encoder.py +7 -34
  213. diffusers/pipelines/latent_consistency_models/pipeline_latent_consistency_img2img.py +12 -1
  214. diffusers/pipelines/latent_consistency_models/pipeline_latent_consistency_text2img.py +13 -1
  215. diffusers/pipelines/latent_diffusion/pipeline_latent_diffusion.py +14 -13
  216. diffusers/pipelines/latent_diffusion/pipeline_latent_diffusion_superresolution.py +12 -1
  217. diffusers/pipelines/latte/pipeline_latte.py +36 -7
  218. diffusers/pipelines/ledits_pp/pipeline_leditspp_stable_diffusion.py +67 -13
  219. diffusers/pipelines/ledits_pp/pipeline_leditspp_stable_diffusion_xl.py +60 -15
  220. diffusers/pipelines/ltx/__init__.py +2 -0
  221. diffusers/pipelines/ltx/pipeline_ltx.py +25 -13
  222. diffusers/pipelines/ltx/pipeline_ltx_condition.py +1194 -0
  223. diffusers/pipelines/ltx/pipeline_ltx_image2video.py +31 -17
  224. diffusers/pipelines/lumina/__init__.py +2 -2
  225. diffusers/pipelines/lumina/pipeline_lumina.py +83 -20
  226. diffusers/pipelines/lumina2/__init__.py +48 -0
  227. diffusers/pipelines/lumina2/pipeline_lumina2.py +790 -0
  228. diffusers/pipelines/marigold/__init__.py +2 -0
  229. diffusers/pipelines/marigold/marigold_image_processing.py +127 -14
  230. diffusers/pipelines/marigold/pipeline_marigold_depth.py +31 -16
  231. diffusers/pipelines/marigold/pipeline_marigold_intrinsics.py +721 -0
  232. diffusers/pipelines/marigold/pipeline_marigold_normals.py +31 -16
  233. diffusers/pipelines/mochi/pipeline_mochi.py +14 -18
  234. diffusers/pipelines/musicldm/pipeline_musicldm.py +16 -1
  235. diffusers/pipelines/omnigen/__init__.py +50 -0
  236. diffusers/pipelines/omnigen/pipeline_omnigen.py +512 -0
  237. diffusers/pipelines/omnigen/processor_omnigen.py +327 -0
  238. diffusers/pipelines/onnx_utils.py +5 -3
  239. diffusers/pipelines/pag/pag_utils.py +1 -1
  240. diffusers/pipelines/pag/pipeline_pag_controlnet_sd.py +12 -1
  241. diffusers/pipelines/pag/pipeline_pag_controlnet_sd_inpaint.py +15 -4
  242. diffusers/pipelines/pag/pipeline_pag_controlnet_sd_xl.py +20 -3
  243. diffusers/pipelines/pag/pipeline_pag_controlnet_sd_xl_img2img.py +20 -3
  244. diffusers/pipelines/pag/pipeline_pag_hunyuandit.py +1 -3
  245. diffusers/pipelines/pag/pipeline_pag_kolors.py +6 -4
  246. diffusers/pipelines/pag/pipeline_pag_pixart_sigma.py +16 -3
  247. diffusers/pipelines/pag/pipeline_pag_sana.py +65 -8
  248. diffusers/pipelines/pag/pipeline_pag_sd.py +23 -7
  249. diffusers/pipelines/pag/pipeline_pag_sd_3.py +3 -5
  250. diffusers/pipelines/pag/pipeline_pag_sd_3_img2img.py +3 -5
  251. diffusers/pipelines/pag/pipeline_pag_sd_animatediff.py +13 -1
  252. diffusers/pipelines/pag/pipeline_pag_sd_img2img.py +23 -7
  253. diffusers/pipelines/pag/pipeline_pag_sd_inpaint.py +26 -10
  254. diffusers/pipelines/pag/pipeline_pag_sd_xl.py +12 -4
  255. diffusers/pipelines/pag/pipeline_pag_sd_xl_img2img.py +7 -3
  256. diffusers/pipelines/pag/pipeline_pag_sd_xl_inpaint.py +10 -6
  257. diffusers/pipelines/paint_by_example/pipeline_paint_by_example.py +13 -3
  258. diffusers/pipelines/pia/pipeline_pia.py +13 -1
  259. diffusers/pipelines/pipeline_flax_utils.py +7 -7
  260. diffusers/pipelines/pipeline_loading_utils.py +193 -83
  261. diffusers/pipelines/pipeline_utils.py +221 -106
  262. diffusers/pipelines/pixart_alpha/pipeline_pixart_alpha.py +17 -5
  263. diffusers/pipelines/pixart_alpha/pipeline_pixart_sigma.py +17 -4
  264. diffusers/pipelines/sana/__init__.py +2 -0
  265. diffusers/pipelines/sana/pipeline_sana.py +183 -58
  266. diffusers/pipelines/sana/pipeline_sana_sprint.py +889 -0
  267. diffusers/pipelines/semantic_stable_diffusion/pipeline_semantic_stable_diffusion.py +12 -2
  268. diffusers/pipelines/shap_e/pipeline_shap_e.py +12 -0
  269. diffusers/pipelines/shap_e/pipeline_shap_e_img2img.py +12 -0
  270. diffusers/pipelines/shap_e/renderer.py +6 -6
  271. diffusers/pipelines/stable_audio/pipeline_stable_audio.py +1 -1
  272. diffusers/pipelines/stable_cascade/pipeline_stable_cascade.py +15 -4
  273. diffusers/pipelines/stable_cascade/pipeline_stable_cascade_combined.py +12 -8
  274. diffusers/pipelines/stable_cascade/pipeline_stable_cascade_prior.py +12 -1
  275. diffusers/pipelines/stable_diffusion/convert_from_ckpt.py +3 -2
  276. diffusers/pipelines/stable_diffusion/pipeline_flax_stable_diffusion.py +14 -10
  277. diffusers/pipelines/stable_diffusion/pipeline_flax_stable_diffusion_img2img.py +3 -3
  278. diffusers/pipelines/stable_diffusion/pipeline_flax_stable_diffusion_inpaint.py +14 -10
  279. diffusers/pipelines/stable_diffusion/pipeline_onnx_stable_diffusion.py +2 -2
  280. diffusers/pipelines/stable_diffusion/pipeline_onnx_stable_diffusion_img2img.py +4 -3
  281. diffusers/pipelines/stable_diffusion/pipeline_onnx_stable_diffusion_inpaint.py +5 -4
  282. diffusers/pipelines/stable_diffusion/pipeline_onnx_stable_diffusion_upscale.py +2 -2
  283. diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py +18 -13
  284. diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_depth2img.py +30 -8
  285. diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_image_variation.py +24 -10
  286. diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_img2img.py +28 -12
  287. diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_inpaint.py +39 -18
  288. diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_instruct_pix2pix.py +17 -6
  289. diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_latent_upscale.py +13 -3
  290. diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_upscale.py +20 -3
  291. diffusers/pipelines/stable_diffusion/pipeline_stable_unclip.py +14 -2
  292. diffusers/pipelines/stable_diffusion/pipeline_stable_unclip_img2img.py +13 -1
  293. diffusers/pipelines/stable_diffusion_3/pipeline_stable_diffusion_3.py +16 -17
  294. diffusers/pipelines/stable_diffusion_3/pipeline_stable_diffusion_3_img2img.py +136 -18
  295. diffusers/pipelines/stable_diffusion_3/pipeline_stable_diffusion_3_inpaint.py +150 -21
  296. diffusers/pipelines/stable_diffusion_attend_and_excite/pipeline_stable_diffusion_attend_and_excite.py +15 -3
  297. diffusers/pipelines/stable_diffusion_diffedit/pipeline_stable_diffusion_diffedit.py +26 -11
  298. diffusers/pipelines/stable_diffusion_gligen/pipeline_stable_diffusion_gligen.py +15 -3
  299. diffusers/pipelines/stable_diffusion_gligen/pipeline_stable_diffusion_gligen_text_image.py +22 -4
  300. diffusers/pipelines/stable_diffusion_k_diffusion/pipeline_stable_diffusion_k_diffusion.py +30 -13
  301. diffusers/pipelines/stable_diffusion_k_diffusion/pipeline_stable_diffusion_xl_k_diffusion.py +12 -4
  302. diffusers/pipelines/stable_diffusion_ldm3d/pipeline_stable_diffusion_ldm3d.py +15 -3
  303. diffusers/pipelines/stable_diffusion_panorama/pipeline_stable_diffusion_panorama.py +15 -3
  304. diffusers/pipelines/stable_diffusion_safe/pipeline_stable_diffusion_safe.py +26 -12
  305. diffusers/pipelines/stable_diffusion_sag/pipeline_stable_diffusion_sag.py +16 -4
  306. diffusers/pipelines/stable_diffusion_xl/pipeline_flax_stable_diffusion_xl.py +1 -1
  307. diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl.py +12 -4
  308. diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl_img2img.py +7 -3
  309. diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl_inpaint.py +10 -6
  310. diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl_instruct_pix2pix.py +11 -4
  311. diffusers/pipelines/stable_video_diffusion/pipeline_stable_video_diffusion.py +13 -2
  312. diffusers/pipelines/t2i_adapter/pipeline_stable_diffusion_adapter.py +18 -4
  313. diffusers/pipelines/t2i_adapter/pipeline_stable_diffusion_xl_adapter.py +26 -5
  314. diffusers/pipelines/text_to_video_synthesis/pipeline_text_to_video_synth.py +13 -1
  315. diffusers/pipelines/text_to_video_synthesis/pipeline_text_to_video_synth_img2img.py +13 -1
  316. diffusers/pipelines/text_to_video_synthesis/pipeline_text_to_video_zero.py +28 -6
  317. diffusers/pipelines/text_to_video_synthesis/pipeline_text_to_video_zero_sdxl.py +26 -4
  318. diffusers/pipelines/transformers_loading_utils.py +121 -0
  319. diffusers/pipelines/unclip/pipeline_unclip.py +11 -1
  320. diffusers/pipelines/unclip/pipeline_unclip_image_variation.py +11 -1
  321. diffusers/pipelines/unidiffuser/pipeline_unidiffuser.py +19 -2
  322. diffusers/pipelines/wan/__init__.py +51 -0
  323. diffusers/pipelines/wan/pipeline_output.py +20 -0
  324. diffusers/pipelines/wan/pipeline_wan.py +593 -0
  325. diffusers/pipelines/wan/pipeline_wan_i2v.py +722 -0
  326. diffusers/pipelines/wan/pipeline_wan_video2video.py +725 -0
  327. diffusers/pipelines/wuerstchen/modeling_wuerstchen_prior.py +7 -31
  328. diffusers/pipelines/wuerstchen/pipeline_wuerstchen.py +12 -1
  329. diffusers/pipelines/wuerstchen/pipeline_wuerstchen_prior.py +12 -1
  330. diffusers/quantizers/auto.py +5 -1
  331. diffusers/quantizers/base.py +5 -9
  332. diffusers/quantizers/bitsandbytes/bnb_quantizer.py +41 -29
  333. diffusers/quantizers/bitsandbytes/utils.py +30 -20
  334. diffusers/quantizers/gguf/gguf_quantizer.py +1 -0
  335. diffusers/quantizers/gguf/utils.py +4 -2
  336. diffusers/quantizers/quantization_config.py +59 -4
  337. diffusers/quantizers/quanto/__init__.py +1 -0
  338. diffusers/quantizers/quanto/quanto_quantizer.py +177 -0
  339. diffusers/quantizers/quanto/utils.py +60 -0
  340. diffusers/quantizers/torchao/__init__.py +1 -1
  341. diffusers/quantizers/torchao/torchao_quantizer.py +47 -2
  342. diffusers/schedulers/__init__.py +2 -1
  343. diffusers/schedulers/scheduling_consistency_models.py +1 -2
  344. diffusers/schedulers/scheduling_ddim_inverse.py +1 -1
  345. diffusers/schedulers/scheduling_ddpm.py +2 -3
  346. diffusers/schedulers/scheduling_ddpm_parallel.py +1 -2
  347. diffusers/schedulers/scheduling_dpmsolver_multistep.py +12 -4
  348. diffusers/schedulers/scheduling_edm_euler.py +45 -10
  349. diffusers/schedulers/scheduling_flow_match_euler_discrete.py +116 -28
  350. diffusers/schedulers/scheduling_flow_match_heun_discrete.py +7 -6
  351. diffusers/schedulers/scheduling_heun_discrete.py +1 -1
  352. diffusers/schedulers/scheduling_lcm.py +1 -2
  353. diffusers/schedulers/scheduling_lms_discrete.py +1 -1
  354. diffusers/schedulers/scheduling_repaint.py +5 -1
  355. diffusers/schedulers/scheduling_scm.py +265 -0
  356. diffusers/schedulers/scheduling_tcd.py +1 -2
  357. diffusers/schedulers/scheduling_utils.py +2 -1
  358. diffusers/training_utils.py +14 -7
  359. diffusers/utils/__init__.py +10 -2
  360. diffusers/utils/constants.py +13 -1
  361. diffusers/utils/deprecation_utils.py +1 -1
  362. diffusers/utils/dummy_bitsandbytes_objects.py +17 -0
  363. diffusers/utils/dummy_gguf_objects.py +17 -0
  364. diffusers/utils/dummy_optimum_quanto_objects.py +17 -0
  365. diffusers/utils/dummy_pt_objects.py +233 -0
  366. diffusers/utils/dummy_torch_and_transformers_and_opencv_objects.py +17 -0
  367. diffusers/utils/dummy_torch_and_transformers_objects.py +270 -0
  368. diffusers/utils/dummy_torchao_objects.py +17 -0
  369. diffusers/utils/dynamic_modules_utils.py +1 -1
  370. diffusers/utils/export_utils.py +28 -3
  371. diffusers/utils/hub_utils.py +52 -102
  372. diffusers/utils/import_utils.py +121 -221
  373. diffusers/utils/loading_utils.py +14 -1
  374. diffusers/utils/logging.py +1 -2
  375. diffusers/utils/peft_utils.py +6 -14
  376. diffusers/utils/remote_utils.py +425 -0
  377. diffusers/utils/source_code_parsing_utils.py +52 -0
  378. diffusers/utils/state_dict_utils.py +15 -1
  379. diffusers/utils/testing_utils.py +243 -13
  380. diffusers/utils/torch_utils.py +10 -0
  381. diffusers/utils/typing_utils.py +91 -0
  382. diffusers/video_processor.py +1 -1
  383. {diffusers-0.32.1.dist-info → diffusers-0.33.0.dist-info}/METADATA +76 -44
  384. diffusers-0.33.0.dist-info/RECORD +608 -0
  385. {diffusers-0.32.1.dist-info → diffusers-0.33.0.dist-info}/WHEEL +1 -1
  386. diffusers-0.32.1.dist-info/RECORD +0 -550
  387. {diffusers-0.32.1.dist-info → diffusers-0.33.0.dist-info}/LICENSE +0 -0
  388. {diffusers-0.32.1.dist-info → diffusers-0.33.0.dist-info}/entry_points.txt +0 -0
  389. {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 2024 The HuggingFace Inc. team.
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 _maybe_adjust_config(config):
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
- # if ambiguous we update the rank associated with the ambiguous key (`proj_out`, for example)
87
- config["r"] = key_rank
88
- # remove the ambiguous key from `rank_pattern` and update its rank to `r`, instead
89
- del config["rank_pattern"][key]
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
- is_model_cpu_offload = False
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
- return (is_model_cpu_offload, is_sequential_cpu_offload)
164
-
165
- def load_lora_adapter(self, pretrained_model_name_or_path_or_dict, prefix="transformer", **kwargs):
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
- keys = list(state_dict.keys())
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
- rank[key] = val.shape[1]
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
- lora_config_kwargs = _maybe_adjust_config(lora_config_kwargs)
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
- inject_adapter_in_model(lora_config, self, adapter_name=adapter_name, **peft_kwargs)
327
- incompatible_keys = set_peft_model_state_dict(self, state_dict, adapter_name, **peft_kwargs)
328
- except RuntimeError as e:
329
- for module in self.modules():
330
- if isinstance(module, BaseTunerLayer):
331
- active_adapters = module.active_adapters
332
- for active_adapter in active_adapters:
333
- if adapter_name in active_adapter:
334
- module.delete_adapter(adapter_name)
335
-
336
- self.peft_config.pop(adapter_name)
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}
@@ -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/runwayml/stable-diffusion-v1-5/blob/main/v1-5-pruned-emaonly.ckpt",
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
- unexpected_keys = load_model_dict_into_meta(
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
- device=param_device,
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