diffsynth 2.2.0__tar.gz → 2.2.1__tar.gz

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 (324) hide show
  1. {diffsynth-2.2.0 → diffsynth-2.2.1}/PKG-INFO +7 -3
  2. {diffsynth-2.2.0 → diffsynth-2.2.1}/README.md +5 -0
  3. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/configs/model_configs.py +24 -1
  4. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/configs/vram_management_module_maps.py +22 -0
  5. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/attention/attention.py +1 -1
  6. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/quant/backends/entropack.py +2 -2
  7. diffsynth-2.2.1/diffsynth/diffusion/dmd2.py +355 -0
  8. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/diffusion/flow_match.py +16 -1
  9. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/diffusion/parsers.py +16 -18
  10. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/diffusion/runner.py +7 -4
  11. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/diffsynth_music_dit.py +4 -2
  12. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ernie_image_dit.py +0 -1
  13. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/hidream_o1_image_dit.py +1 -1
  14. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/krea2_dit.py +10 -5
  15. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/minimax_h3_controlnet.py +1 -1
  16. diffsynth-2.2.1/diffsynth/models/minimax_h3_image_dit.py +336 -0
  17. diffsynth-2.2.1/diffsynth/models/minimax_h3_image_vae.py +375 -0
  18. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/sensenova_u1_dit.py +1 -1
  19. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/yue2_mot.py +2 -2
  20. diffsynth-2.2.1/diffsynth/pipelines/minimax_h3_image.py +560 -0
  21. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/sensenova_u1_image.py +1 -1
  22. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/stable_diffusion_xl.py +7 -4
  23. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/lora/general.py +11 -3
  24. diffsynth-2.2.1/diffsynth/utils/state_dict_converters/minimax_h3_image_vae.py +16 -0
  25. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/version.py +1 -1
  26. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth.egg-info/PKG-INFO +7 -3
  27. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth.egg-info/SOURCES.txt +4 -0
  28. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth.egg-info/requires.txt +1 -2
  29. {diffsynth-2.2.0 → diffsynth-2.2.1}/pyproject.toml +1 -2
  30. diffsynth-2.2.0/diffsynth/diffusion/dmd2.py +0 -601
  31. {diffsynth-2.2.0 → diffsynth-2.2.1}/LICENSE +0 -0
  32. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/__init__.py +0 -0
  33. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/configs/__init__.py +0 -0
  34. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/__init__.py +0 -0
  35. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/attention/__init__.py +0 -0
  36. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/attention/common.py +0 -0
  37. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/attention/flash_attention.py +0 -0
  38. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/attention/flex_attention.py +0 -0
  39. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/attention/registry.py +0 -0
  40. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/attention/sage_attention.py +0 -0
  41. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/attention/torch_attention.py +0 -0
  42. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/attention/xformers_attention.py +0 -0
  43. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/data/__init__.py +0 -0
  44. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/data/operators.py +0 -0
  45. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/data/unified_dataset.py +0 -0
  46. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/device/__init__.py +0 -0
  47. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/device/npu_compatible_device.py +0 -0
  48. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/gradient/__init__.py +0 -0
  49. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/gradient/gradient_checkpoint.py +0 -0
  50. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/loader/__init__.py +0 -0
  51. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/loader/config.py +0 -0
  52. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/loader/file.py +0 -0
  53. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/loader/model.py +0 -0
  54. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/npu_patch/npu_fused_operator.py +0 -0
  55. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/offload_training/__init__.py +0 -0
  56. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/offload_training/manager.py +0 -0
  57. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/offload_training/memory_buffer.py +0 -0
  58. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/offload_training/offloader.py +0 -0
  59. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/quant/__init__.py +0 -0
  60. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/quant/backends/__init__.py +0 -0
  61. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/quant/backends/bitsandbytes.py +0 -0
  62. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/quant/backends/comfy_kitchen.py +0 -0
  63. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/quant/backends/deep_gemm.py +0 -0
  64. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/quant/backends/torchao.py +0 -0
  65. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/quant/base.py +0 -0
  66. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/quant/config.py +0 -0
  67. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/vram/__init__.py +0 -0
  68. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/vram/disk_map.py +0 -0
  69. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/vram/initialization.py +0 -0
  70. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/core/vram/layers.py +0 -0
  71. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/diffusion/__init__.py +0 -0
  72. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/diffusion/base_pipeline.py +0 -0
  73. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/diffusion/ddim_scheduler.py +0 -0
  74. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/diffusion/logger.py +0 -0
  75. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/diffusion/loss.py +0 -0
  76. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/diffusion/template.py +0 -0
  77. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/diffusion/training_module.py +0 -0
  78. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/__init__.py +0 -0
  79. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/aesthetic.py +0 -0
  80. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/base.py +0 -0
  81. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/bioclip.py +0 -0
  82. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/clip.py +0 -0
  83. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/fid.py +0 -0
  84. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/hpsv2.py +0 -0
  85. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/hpsv3.py +0 -0
  86. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/image_reward.py +0 -0
  87. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/lpips.py +0 -0
  88. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/pickscore.py +0 -0
  89. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/qwen_image_bench.py +0 -0
  90. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/unified_reward_2.py +0 -0
  91. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/metrics/unified_reward_edit.py +0 -0
  92. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ace_step_conditioner.py +0 -0
  93. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ace_step_dit.py +0 -0
  94. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ace_step_residual_fsq.py +0 -0
  95. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ace_step_text_encoder.py +0 -0
  96. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ace_step_tokenizer.py +0 -0
  97. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ace_step_vae.py +0 -0
  98. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/aesthetic.py +0 -0
  99. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/anima_dit.py +0 -0
  100. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/bioclip.py +0 -0
  101. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/boogu_image_dit.py +0 -0
  102. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/clip.py +0 -0
  103. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/demucs.py +0 -0
  104. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/dinov3_image_encoder.py +0 -0
  105. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ernie_image_text_encoder.py +0 -0
  106. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/fibo_dit.py +0 -0
  107. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/fid.py +0 -0
  108. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux2_dit.py +0 -0
  109. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux2_text_encoder.py +0 -0
  110. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux2_vae.py +0 -0
  111. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux3_dit.py +0 -0
  112. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux_controlnet.py +0 -0
  113. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux_dit.py +0 -0
  114. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux_infiniteyou.py +0 -0
  115. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux_ipadapter.py +0 -0
  116. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux_lora_encoder.py +0 -0
  117. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux_lora_patcher.py +0 -0
  118. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux_redux.py +0 -0
  119. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux_text_encoder_clip.py +0 -0
  120. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux_text_encoder_t5.py +0 -0
  121. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux_vae.py +0 -0
  122. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/flux_value_control.py +0 -0
  123. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/general_modules.py +0 -0
  124. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/hidream_common.py +0 -0
  125. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/hpsv2.py +0 -0
  126. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/hpsv3.py +0 -0
  127. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ideogram4_dit.py +0 -0
  128. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ideogram4_text_encoder.py +0 -0
  129. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ideogram4_vae.py +0 -0
  130. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/image_reward.py +0 -0
  131. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/joyai_image_dit.py +0 -0
  132. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/krea2_text_encoder.py +0 -0
  133. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/lingbot_video_dit.py +0 -0
  134. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/longcat_video_dit.py +0 -0
  135. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/lpips.py +0 -0
  136. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ltx25_diffusion_video_vae.py +0 -0
  137. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ltx25_duration_head.py +0 -0
  138. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ltx25_text_encoder.py +0 -0
  139. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ltx2_audio_vae.py +0 -0
  140. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ltx2_common.py +0 -0
  141. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ltx2_dit.py +0 -0
  142. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ltx2_text_encoder.py +0 -0
  143. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ltx2_upsampler.py +0 -0
  144. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/ltx2_video_vae.py +0 -0
  145. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/minimax_h3_audio_vae.py +0 -0
  146. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/minimax_h3_dit.py +0 -0
  147. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/minimax_h3_dit_comfy.py +0 -0
  148. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/minimax_h3_dit_vdn.py +0 -0
  149. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/minimax_h3_dit_vdn_fp8.py +0 -0
  150. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/minimax_h3_text_encoder.py +0 -0
  151. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/minimax_h3_video_vae.py +0 -0
  152. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/minimax_music3_condition_encoder.py +0 -0
  153. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/minimax_music3_dit.py +0 -0
  154. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/minimax_music3_rvq_depth_decoder.py +0 -0
  155. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/minimax_music3_text_encoder.py +0 -0
  156. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/minimax_music3_vocoder.py +0 -0
  157. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/model_loader.py +0 -0
  158. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/moss_image_dit.py +0 -0
  159. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/moss_image_text_encoder.py +0 -0
  160. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/mova_audio_dit.py +0 -0
  161. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/mova_audio_vae.py +0 -0
  162. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/mova_dual_tower_bridge.py +0 -0
  163. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/nexus_gen.py +0 -0
  164. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/nexus_gen_ar_model.py +0 -0
  165. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/nexus_gen_projector.py +0 -0
  166. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/pickscore.py +0 -0
  167. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/qwen_image_21_controlnet.py +0 -0
  168. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/qwen_image_21_dit.py +0 -0
  169. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/qwen_image_21_text_encoder.py +0 -0
  170. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/qwen_image_21_vae.py +0 -0
  171. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/qwen_image_bench.py +0 -0
  172. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/qwen_image_controlnet.py +0 -0
  173. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/qwen_image_dit.py +0 -0
  174. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/qwen_image_image2lora.py +0 -0
  175. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/qwen_image_text_encoder.py +0 -0
  176. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/qwen_image_vae.py +0 -0
  177. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/qwen_video_edit_dit.py +0 -0
  178. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/sd_text_encoder.py +0 -0
  179. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/sensenova_u1_common.py +0 -0
  180. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/siglip2_image_encoder.py +0 -0
  181. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/stable_diffusion_text_encoder.py +0 -0
  182. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/stable_diffusion_unet.py +0 -0
  183. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/stable_diffusion_vae.py +0 -0
  184. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/stable_diffusion_xl_text_encoder.py +0 -0
  185. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/stable_diffusion_xl_unet.py +0 -0
  186. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/step1x_connector.py +0 -0
  187. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/step1x_text_encoder.py +0 -0
  188. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/unified_reward_2.py +0 -0
  189. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/unified_reward_edit.py +0 -0
  190. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/wan_animate_2_dit.py +0 -0
  191. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/wan_video_animate_adapter.py +0 -0
  192. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/wan_video_camera_controller.py +0 -0
  193. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/wan_video_dit.py +0 -0
  194. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/wan_video_dit_s2v.py +0 -0
  195. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/wan_video_image_encoder.py +0 -0
  196. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/wan_video_mot.py +0 -0
  197. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/wan_video_motion_controller.py +0 -0
  198. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/wan_video_text_encoder.py +0 -0
  199. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/wan_video_vace.py +0 -0
  200. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/wan_video_vae.py +0 -0
  201. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/wantodance.py +0 -0
  202. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/wav2vec.py +0 -0
  203. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/yue2_tokenizer.py +0 -0
  204. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/yue2_vae.py +0 -0
  205. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/z_image_controlnet.py +0 -0
  206. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/z_image_dit.py +0 -0
  207. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/z_image_image2lora.py +0 -0
  208. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/models/z_image_text_encoder.py +0 -0
  209. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/ace_step.py +0 -0
  210. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/anima_image.py +0 -0
  211. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/boogu_image.py +0 -0
  212. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/diffsynth_music.py +0 -0
  213. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/ernie_image.py +0 -0
  214. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/fibo.py +0 -0
  215. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/flux2_image.py +0 -0
  216. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/flux3_image.py +0 -0
  217. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/flux_image.py +0 -0
  218. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/hidream_o1_image.py +0 -0
  219. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/ideogram4.py +0 -0
  220. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/joyai_image.py +0 -0
  221. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/krea2.py +0 -0
  222. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/lingbot_video.py +0 -0
  223. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/ltx2_audio_video.py +0 -0
  224. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/minimax_h3_audio_video.py +0 -0
  225. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/minimax_music3.py +0 -0
  226. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/moss_image.py +0 -0
  227. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/mova_audio_video.py +0 -0
  228. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/qwen_image.py +0 -0
  229. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/qwen_image_21.py +0 -0
  230. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/qwen_video_edit.py +0 -0
  231. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/stable_diffusion.py +0 -0
  232. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/wan_video.py +0 -0
  233. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/yue2.py +0 -0
  234. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/pipelines/z_image.py +0 -0
  235. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/controlnet/__init__.py +0 -0
  236. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/controlnet/annotator.py +0 -0
  237. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/controlnet/controlnet_input.py +0 -0
  238. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/data/__init__.py +0 -0
  239. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/data/audio.py +0 -0
  240. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/data/audio_video.py +0 -0
  241. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/data/media_io_ltx2.py +0 -0
  242. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/data/minimax_h3.py +0 -0
  243. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/demucs/__init__.py +0 -0
  244. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/dequantizer/__init__.py +0 -0
  245. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/lora/__init__.py +0 -0
  246. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/lora/flux.py +0 -0
  247. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/lora/flux_timestep.py +0 -0
  248. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/lora/krea2.py +0 -0
  249. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/lora/merge.py +0 -0
  250. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/lora/minimax_h3.py +0 -0
  251. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/lora/reset_rank.py +0 -0
  252. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/lora/sdxl.py +0 -0
  253. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/music_tools/__init__.py +0 -0
  254. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/music_tools/click.py +0 -0
  255. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/music_tools/prosody.py +0 -0
  256. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/quant/serialization.py +0 -0
  257. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/ses/__init__.py +0 -0
  258. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/ses/ses.py +0 -0
  259. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/__init__.py +0 -0
  260. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/ace_step_conditioner.py +0 -0
  261. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/ace_step_dit.py +0 -0
  262. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/ace_step_text_encoder.py +0 -0
  263. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/ace_step_tokenizer.py +0 -0
  264. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/anima_dit.py +0 -0
  265. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/dino_v3.py +0 -0
  266. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/ernie_image_text_encoder.py +0 -0
  267. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/flux2_text_encoder.py +0 -0
  268. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/flux3_dit.py +0 -0
  269. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/flux_controlnet.py +0 -0
  270. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/flux_dit.py +0 -0
  271. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/flux_infiniteyou.py +0 -0
  272. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/flux_ipadapter.py +0 -0
  273. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/flux_text_encoder_clip.py +0 -0
  274. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/flux_text_encoder_t5.py +0 -0
  275. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/flux_vae.py +0 -0
  276. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/ideogram4_text_encoder.py +0 -0
  277. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/image_metrics.py +0 -0
  278. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/krea2_dit.py +0 -0
  279. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/krea2_text_encoder.py +0 -0
  280. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/lingbot_video_dit.py +0 -0
  281. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/ltx25_diffusion_video_vae.py +0 -0
  282. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/ltx25_duration_head.py +0 -0
  283. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/ltx25_text_encoder.py +0 -0
  284. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/ltx2_audio_vae.py +0 -0
  285. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/ltx2_dit.py +0 -0
  286. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/ltx2_text_encoder.py +0 -0
  287. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/ltx2_video_vae.py +0 -0
  288. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/minimax_h3_audio_vae.py +0 -0
  289. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/minimax_h3_controlnet.py +0 -0
  290. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/minimax_h3_dit.py +0 -0
  291. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/minimax_h3_dit_vdn.py +0 -0
  292. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/minimax_h3_text_encoder.py +0 -0
  293. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/minimax_h3_video_vae.py +0 -0
  294. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/minimax_music3_text_encoder.py +0 -0
  295. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/moss_image_text_encoder.py +0 -0
  296. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/nexus_gen.py +0 -0
  297. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/nexus_gen_projector.py +0 -0
  298. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/qwen_image_21_text_encoder.py +0 -0
  299. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/qwen_image_text_encoder.py +0 -0
  300. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/qwen_video_edit.py +0 -0
  301. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/sdxl.py +0 -0
  302. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/sdxl_text_encoder.py +0 -0
  303. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/sdxl_text_encoder_2.py +0 -0
  304. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/sdxl_vae.py +0 -0
  305. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/stable_diffusion_text_encoder.py +0 -0
  306. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/stable_diffusion_vae.py +0 -0
  307. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/stable_diffusion_xl_text_encoder.py +0 -0
  308. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/step1x_connector.py +0 -0
  309. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/wan_video_animate_adapter.py +0 -0
  310. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/wan_video_dit.py +0 -0
  311. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/wan_video_image_encoder.py +0 -0
  312. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/wan_video_mot.py +0 -0
  313. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/wan_video_vace.py +0 -0
  314. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/wan_video_vae.py +0 -0
  315. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/wans2v_audio_encoder.py +0 -0
  316. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/z_image_dit.py +0 -0
  317. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/state_dict_converters/z_image_text_encoder.py +0 -0
  318. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/tile/__init__.py +0 -0
  319. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/tile/tile_worker.py +0 -0
  320. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/xfuser/__init__.py +0 -0
  321. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth/utils/xfuser/xdit_context_parallel.py +0 -0
  322. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth.egg-info/dependency_links.txt +0 -0
  323. {diffsynth-2.2.0 → diffsynth-2.2.1}/diffsynth.egg-info/top_level.txt +0 -0
  324. {diffsynth-2.2.0 → diffsynth-2.2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diffsynth
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Summary: Enjoy the magic of Diffusion models!
5
5
  Author: ModelScope Team
6
6
  License-Expression: Apache-2.0
@@ -20,6 +20,7 @@ Requires-Dist: ftfy
20
20
  Requires-Dist: pandas
21
21
  Requires-Dist: accelerate
22
22
  Requires-Dist: peft
23
+ Requires-Dist: entropack>=0.1.7
23
24
  Provides-Extra: audio
24
25
  Requires-Dist: av; extra == "audio"
25
26
  Requires-Dist: torchaudio; extra == "audio"
@@ -28,7 +29,6 @@ Requires-Dist: librosa; extra == "audio"
28
29
  Provides-Extra: quant
29
30
  Requires-Dist: bitsandbytes; extra == "quant"
30
31
  Requires-Dist: comfy-kitchen; extra == "quant"
31
- Requires-Dist: entropack[cuda13]; extra == "quant"
32
32
  Requires-Dist: torchao>=0.16; extra == "quant"
33
33
  Provides-Extra: training
34
34
  Requires-Dist: deepspeed; extra == "training"
@@ -63,7 +63,6 @@ Requires-Dist: torchcodec; extra == "all"
63
63
  Requires-Dist: librosa; extra == "all"
64
64
  Requires-Dist: bitsandbytes; extra == "all"
65
65
  Requires-Dist: comfy-kitchen; extra == "all"
66
- Requires-Dist: entropack[cuda13]; extra == "all"
67
66
  Requires-Dist: torchao>=0.16; extra == "all"
68
67
  Requires-Dist: deepspeed; extra == "all"
69
68
  Requires-Dist: tensorboard; extra == "all"
@@ -114,6 +113,8 @@ See also:
114
113
 
115
114
  > Currently, the development personnel of this project are limited, with most of the work handled by [Artiprocher](https://github.com/Artiprocher) and [mi804](https://github.com/mi804). Therefore, the progress of new feature development will be relatively slow, and the speed of responding to and resolving issues is limited. We apologize for this and ask developers to understand.
116
115
 
116
+ - **November 10, 2026** We now support MiniMax-H3-Image, the image model of the MiniMax-H3 family, including unified text-to-image and reference-image editing inference, low VRAM inference, and full/LoRA training. The checkpoint is distilled to six sampling steps with one transformer output head per step, and it generates about 16-megapixel images without an upscaler. See the [documentation](/docs/en/Model_Details/MiniMax-H3-Image.md) and [example code](/examples/minimax_h3_image/).
117
+
117
118
  - **October 21, 2026** We now support Fibo 2.0, including unified text-to-image and image editing inference, masked and multi-reference editing, text rendering, low VRAM inference, and full/LoRA training for both text-to-image and image editing on [Fibo-2.0-dev](https://www.modelscope.cn/models/briaai/Fibo-2.0-dev). See the [documentation](/docs/en/Model_Details/Fibo.md) and [example code](/examples/fibo/).
118
119
 
119
120
  - **October 20, 2026** We now support MOSS-Image, including inference and training for [MOSS-Image-Base](https://modelscope.cn/models/openmoss/MOSS-Image-Base) and [MOSS-Image-SFT](https://modelscope.cn/models/openmoss/MOSS-Image-SFT). In addition, we provide an [EntroPack low-bit quantized model](https://www.modelscope.cn/models/DiffSynth-Studio/MOSS-Image-EntroPack), which can run the 3.5-bit quantized model with as little as 4 GB of VRAM; and an [accelerated model](https://modelscope.cn/models/DiffSynth-Studio/MOSS-Image-SFT-TurboLoRA) distillation-accelerated via [OPD training](https://diffsynth-studio-doc.readthedocs.io/en/latest/Training/Distillation.html), supporting 8-step ultra-fast inference.
@@ -404,6 +405,7 @@ Quick start: experience popular and the latest models:
404
405
 
405
406
  | Architecture | Model ID | Inference | Low VRAM Inference | Full Training | Validation After Full Training | LoRA Training | Validation After LoRA Training |
406
407
  |-|-|-|-|-|-|-|-|
408
+ | MiniMax-H3-Image | [MiniMax/MiniMax-H3-Image](https://www.modelscope.cn/models/MiniMax/MiniMax-H3-Image) | [code](/examples/minimax_h3_image/model_inference/MiniMax-H3-Image.py) | [code](/examples/minimax_h3_image/model_inference_low_vram/MiniMax-H3-Image.py) | [code](/examples/minimax_h3_image/model_training/full/MiniMax-H3-Image.sh) | [code](/examples/minimax_h3_image/model_training/validate_full/MiniMax-H3-Image.py) | [code](/examples/minimax_h3_image/model_training/lora/MiniMax-H3-Image.sh) | [code](/examples/minimax_h3_image/model_training/validate_lora/MiniMax-H3-Image.py) |
407
409
  | Fibo 2.0 | [briaai/Fibo-2.0-dev](https://www.modelscope.cn/models/briaai/Fibo-2.0-dev) | [code](/examples/fibo/model_inference/Fibo-2.0-dev.py) | [code](/examples/fibo/model_inference_low_vram/Fibo-2.0-dev.py) | [code](/examples/fibo/model_training/full/Fibo-2.0-dev-T2I.sh) | [code](/examples/fibo/model_training/validate_full/Fibo-2.0-dev-T2I.py) | [code](/examples/fibo/model_training/lora/Fibo-2.0-dev-T2I.sh) | [code](/examples/fibo/model_training/validate_lora/Fibo-2.0-dev-T2I.py) |
408
410
  | Fibo 2.0 | [briaai/Fibo-2.0-edit-turbo](https://www.modelscope.cn/models/briaai/Fibo-2.0-edit-turbo) | [code](/examples/fibo/model_inference/Fibo-2.0-edit-turbo.py) | [code](/examples/fibo/model_inference_low_vram/Fibo-2.0-edit-turbo.py) | - | - | - | - |
409
411
  | Qwen-Image-2.1 | [Qwen/Qwen-Image-2.1](https://www.modelscope.cn/models/Qwen/Qwen-Image-2.1) | [code](/examples/qwen_image_21/model_inference/Qwen-Image-2.1.py) | [code](/examples/qwen_image_21/model_inference_low_vram/Qwen-Image-2.1.py) | [code](/examples/qwen_image_21/model_training/full/Qwen-Image-2.1.sh) | [code](/examples/qwen_image_21/model_training/validate_full/Qwen-Image-2.1.py) | [code](/examples/qwen_image_21/model_training/lora/Qwen-Image-2.1.sh) | [code](/examples/qwen_image_21/model_training/validate_lora/Qwen-Image-2.1.py) |
@@ -418,6 +420,7 @@ Quick start: experience popular and the latest models:
418
420
  Model overview:
419
421
 
420
422
  - Image generation
423
+ - MiniMax-H3-Image: [Documentation](https://diffsynth-studio-doc.readthedocs.io/en/latest/Model_Details/MiniMax-H3-Image.html), [Example code](/examples/minimax_h3_image/)
421
424
  - Fibo 2.0: [Documentation](https://diffsynth-studio-doc.readthedocs.io/en/latest/Model_Details/Fibo.html), [Example code](/examples/fibo/)
422
425
  - MOSS-Image: [Documentation](https://diffsynth-studio-doc.readthedocs.io/en/latest/Model_Details/MOSS-Image.html), [Example code](/examples/moss_image/)
423
426
  - FLUX.3: [Documentation](https://diffsynth-studio-doc.readthedocs.io/en/latest/Model_Details/FLUX.3.html), [Example code](/examples/flux3/)
@@ -707,6 +710,7 @@ https://github.com/Artiprocher/DiffSynth-Studio/assets/35051019/59fb2f7b-8de0-44
707
710
 
708
711
  | Architecture | Model ID | Inference | Low VRAM Inference | Full Training | Validation After Full Training | LoRA Training | Validation After LoRA Training |
709
712
  |-|-|-|-|-|-|-|-|
713
+ | MiniMax-H3-Image | [MiniMax/MiniMax-H3-Image](https://www.modelscope.cn/models/MiniMax/MiniMax-H3-Image) | [code](/examples/minimax_h3_image/model_inference/MiniMax-H3-Image.py) | [code](/examples/minimax_h3_image/model_inference_low_vram/MiniMax-H3-Image.py) | [code](/examples/minimax_h3_image/model_training/full/MiniMax-H3-Image.sh) | [code](/examples/minimax_h3_image/model_training/validate_full/MiniMax-H3-Image.py) | [code](/examples/minimax_h3_image/model_training/lora/MiniMax-H3-Image.sh) | [code](/examples/minimax_h3_image/model_training/validate_lora/MiniMax-H3-Image.py) |
710
714
  | Fibo 2.0 | [briaai/Fibo-2.0-dev](https://www.modelscope.cn/models/briaai/Fibo-2.0-dev) | [code](/examples/fibo/model_inference/Fibo-2.0-dev.py) | [code](/examples/fibo/model_inference_low_vram/Fibo-2.0-dev.py) | [code](/examples/fibo/model_training/full/Fibo-2.0-dev-T2I.sh) | [code](/examples/fibo/model_training/validate_full/Fibo-2.0-dev-T2I.py) | [code](/examples/fibo/model_training/lora/Fibo-2.0-dev-T2I.sh) | [code](/examples/fibo/model_training/validate_lora/Fibo-2.0-dev-T2I.py) |
711
715
  | Fibo 2.0 | [briaai/Fibo-2.0-edit-turbo](https://www.modelscope.cn/models/briaai/Fibo-2.0-edit-turbo) | [code](/examples/fibo/model_inference/Fibo-2.0-edit-turbo.py) | [code](/examples/fibo/model_inference_low_vram/Fibo-2.0-edit-turbo.py) | - | - | - | - |
712
716
  | MOSS-Image | [openmoss/MOSS-Image-Base](https://www.modelscope.cn/models/openmoss/MOSS-Image-Base) | [code](/examples/moss_image/model_inference/MOSS-Image-Base.py) | [code](/examples/moss_image/model_inference_low_vram/MOSS-Image-Base.py) | [code](/examples/moss_image/model_training/full/MOSS-Image-Base.sh) | [code](/examples/moss_image/model_training/validate_full/MOSS-Image-Base.py) | [code](/examples/moss_image/model_training/lora/MOSS-Image-Base.sh) | [code](/examples/moss_image/model_training/validate_lora/MOSS-Image-Base.py) |
@@ -41,6 +41,8 @@ See also:
41
41
 
42
42
  > Currently, the development personnel of this project are limited, with most of the work handled by [Artiprocher](https://github.com/Artiprocher) and [mi804](https://github.com/mi804). Therefore, the progress of new feature development will be relatively slow, and the speed of responding to and resolving issues is limited. We apologize for this and ask developers to understand.
43
43
 
44
+ - **November 10, 2026** We now support MiniMax-H3-Image, the image model of the MiniMax-H3 family, including unified text-to-image and reference-image editing inference, low VRAM inference, and full/LoRA training. The checkpoint is distilled to six sampling steps with one transformer output head per step, and it generates about 16-megapixel images without an upscaler. See the [documentation](/docs/en/Model_Details/MiniMax-H3-Image.md) and [example code](/examples/minimax_h3_image/).
45
+
44
46
  - **October 21, 2026** We now support Fibo 2.0, including unified text-to-image and image editing inference, masked and multi-reference editing, text rendering, low VRAM inference, and full/LoRA training for both text-to-image and image editing on [Fibo-2.0-dev](https://www.modelscope.cn/models/briaai/Fibo-2.0-dev). See the [documentation](/docs/en/Model_Details/Fibo.md) and [example code](/examples/fibo/).
45
47
 
46
48
  - **October 20, 2026** We now support MOSS-Image, including inference and training for [MOSS-Image-Base](https://modelscope.cn/models/openmoss/MOSS-Image-Base) and [MOSS-Image-SFT](https://modelscope.cn/models/openmoss/MOSS-Image-SFT). In addition, we provide an [EntroPack low-bit quantized model](https://www.modelscope.cn/models/DiffSynth-Studio/MOSS-Image-EntroPack), which can run the 3.5-bit quantized model with as little as 4 GB of VRAM; and an [accelerated model](https://modelscope.cn/models/DiffSynth-Studio/MOSS-Image-SFT-TurboLoRA) distillation-accelerated via [OPD training](https://diffsynth-studio-doc.readthedocs.io/en/latest/Training/Distillation.html), supporting 8-step ultra-fast inference.
@@ -331,6 +333,7 @@ Quick start: experience popular and the latest models:
331
333
 
332
334
  | Architecture | Model ID | Inference | Low VRAM Inference | Full Training | Validation After Full Training | LoRA Training | Validation After LoRA Training |
333
335
  |-|-|-|-|-|-|-|-|
336
+ | MiniMax-H3-Image | [MiniMax/MiniMax-H3-Image](https://www.modelscope.cn/models/MiniMax/MiniMax-H3-Image) | [code](/examples/minimax_h3_image/model_inference/MiniMax-H3-Image.py) | [code](/examples/minimax_h3_image/model_inference_low_vram/MiniMax-H3-Image.py) | [code](/examples/minimax_h3_image/model_training/full/MiniMax-H3-Image.sh) | [code](/examples/minimax_h3_image/model_training/validate_full/MiniMax-H3-Image.py) | [code](/examples/minimax_h3_image/model_training/lora/MiniMax-H3-Image.sh) | [code](/examples/minimax_h3_image/model_training/validate_lora/MiniMax-H3-Image.py) |
334
337
  | Fibo 2.0 | [briaai/Fibo-2.0-dev](https://www.modelscope.cn/models/briaai/Fibo-2.0-dev) | [code](/examples/fibo/model_inference/Fibo-2.0-dev.py) | [code](/examples/fibo/model_inference_low_vram/Fibo-2.0-dev.py) | [code](/examples/fibo/model_training/full/Fibo-2.0-dev-T2I.sh) | [code](/examples/fibo/model_training/validate_full/Fibo-2.0-dev-T2I.py) | [code](/examples/fibo/model_training/lora/Fibo-2.0-dev-T2I.sh) | [code](/examples/fibo/model_training/validate_lora/Fibo-2.0-dev-T2I.py) |
335
338
  | Fibo 2.0 | [briaai/Fibo-2.0-edit-turbo](https://www.modelscope.cn/models/briaai/Fibo-2.0-edit-turbo) | [code](/examples/fibo/model_inference/Fibo-2.0-edit-turbo.py) | [code](/examples/fibo/model_inference_low_vram/Fibo-2.0-edit-turbo.py) | - | - | - | - |
336
339
  | Qwen-Image-2.1 | [Qwen/Qwen-Image-2.1](https://www.modelscope.cn/models/Qwen/Qwen-Image-2.1) | [code](/examples/qwen_image_21/model_inference/Qwen-Image-2.1.py) | [code](/examples/qwen_image_21/model_inference_low_vram/Qwen-Image-2.1.py) | [code](/examples/qwen_image_21/model_training/full/Qwen-Image-2.1.sh) | [code](/examples/qwen_image_21/model_training/validate_full/Qwen-Image-2.1.py) | [code](/examples/qwen_image_21/model_training/lora/Qwen-Image-2.1.sh) | [code](/examples/qwen_image_21/model_training/validate_lora/Qwen-Image-2.1.py) |
@@ -345,6 +348,7 @@ Quick start: experience popular and the latest models:
345
348
  Model overview:
346
349
 
347
350
  - Image generation
351
+ - MiniMax-H3-Image: [Documentation](https://diffsynth-studio-doc.readthedocs.io/en/latest/Model_Details/MiniMax-H3-Image.html), [Example code](/examples/minimax_h3_image/)
348
352
  - Fibo 2.0: [Documentation](https://diffsynth-studio-doc.readthedocs.io/en/latest/Model_Details/Fibo.html), [Example code](/examples/fibo/)
349
353
  - MOSS-Image: [Documentation](https://diffsynth-studio-doc.readthedocs.io/en/latest/Model_Details/MOSS-Image.html), [Example code](/examples/moss_image/)
350
354
  - FLUX.3: [Documentation](https://diffsynth-studio-doc.readthedocs.io/en/latest/Model_Details/FLUX.3.html), [Example code](/examples/flux3/)
@@ -634,6 +638,7 @@ https://github.com/Artiprocher/DiffSynth-Studio/assets/35051019/59fb2f7b-8de0-44
634
638
 
635
639
  | Architecture | Model ID | Inference | Low VRAM Inference | Full Training | Validation After Full Training | LoRA Training | Validation After LoRA Training |
636
640
  |-|-|-|-|-|-|-|-|
641
+ | MiniMax-H3-Image | [MiniMax/MiniMax-H3-Image](https://www.modelscope.cn/models/MiniMax/MiniMax-H3-Image) | [code](/examples/minimax_h3_image/model_inference/MiniMax-H3-Image.py) | [code](/examples/minimax_h3_image/model_inference_low_vram/MiniMax-H3-Image.py) | [code](/examples/minimax_h3_image/model_training/full/MiniMax-H3-Image.sh) | [code](/examples/minimax_h3_image/model_training/validate_full/MiniMax-H3-Image.py) | [code](/examples/minimax_h3_image/model_training/lora/MiniMax-H3-Image.sh) | [code](/examples/minimax_h3_image/model_training/validate_lora/MiniMax-H3-Image.py) |
637
642
  | Fibo 2.0 | [briaai/Fibo-2.0-dev](https://www.modelscope.cn/models/briaai/Fibo-2.0-dev) | [code](/examples/fibo/model_inference/Fibo-2.0-dev.py) | [code](/examples/fibo/model_inference_low_vram/Fibo-2.0-dev.py) | [code](/examples/fibo/model_training/full/Fibo-2.0-dev-T2I.sh) | [code](/examples/fibo/model_training/validate_full/Fibo-2.0-dev-T2I.py) | [code](/examples/fibo/model_training/lora/Fibo-2.0-dev-T2I.sh) | [code](/examples/fibo/model_training/validate_lora/Fibo-2.0-dev-T2I.py) |
638
643
  | Fibo 2.0 | [briaai/Fibo-2.0-edit-turbo](https://www.modelscope.cn/models/briaai/Fibo-2.0-edit-turbo) | [code](/examples/fibo/model_inference/Fibo-2.0-edit-turbo.py) | [code](/examples/fibo/model_inference_low_vram/Fibo-2.0-edit-turbo.py) | - | - | - | - |
639
644
  | MOSS-Image | [openmoss/MOSS-Image-Base](https://www.modelscope.cn/models/openmoss/MOSS-Image-Base) | [code](/examples/moss_image/model_inference/MOSS-Image-Base.py) | [code](/examples/moss_image/model_inference_low_vram/MOSS-Image-Base.py) | [code](/examples/moss_image/model_training/full/MOSS-Image-Base.sh) | [code](/examples/moss_image/model_training/validate_full/MOSS-Image-Base.py) | [code](/examples/moss_image/model_training/lora/MOSS-Image-Base.sh) | [code](/examples/moss_image/model_training/validate_lora/MOSS-Image-Base.py) |
@@ -1743,6 +1743,29 @@ minimax_music3_series = [
1743
1743
  },
1744
1744
  ]
1745
1745
 
1746
+ minimax_h3_image_series = [
1747
+ {
1748
+ # Example: ModelConfig(model_id="MiniMax/MiniMax-H3-Image", origin_file_pattern="transformer/model*.safetensors")
1749
+ # Example: ModelConfig(path="./models/train/MiniMax-H3-Image-full-split/epoch-4.safetensors")
1750
+ "model_hash": "cbc654a2ff91b53b57e2556904bdbc5e",
1751
+ "model_name": "minimax_h3_image_dit",
1752
+ "model_class": "diffsynth.models.minimax_h3_image_dit.MiniMaxH3ImageDiT",
1753
+ },
1754
+ {
1755
+ # Example: ModelConfig(model_id="MiniMax/MiniMax-H3-Image", origin_file_pattern="pdd_fused_heads.safetensors")
1756
+ "model_hash": "af836167abebf4a4701ab436f291a972",
1757
+ "model_name": "minimax_h3_image_pdd_heads",
1758
+ "model_class": "diffsynth.models.minimax_h3_image_dit.MiniMaxH3ImagePDDHeads",
1759
+ },
1760
+ {
1761
+ # Example: ModelConfig(model_id="MiniMax/MiniMax-H3-Image", origin_file_pattern="vae/diffusion_pytorch_model.safetensors")
1762
+ "model_hash": "e16b57e3180a14235ffcaad014ce2772",
1763
+ "model_name": "minimax_h3_image_vae",
1764
+ "model_class": "diffsynth.models.minimax_h3_image_vae.MiniMaxH3ImageVAE",
1765
+ "state_dict_converter": "diffsynth.utils.state_dict_converters.minimax_h3_image_vae.MiniMaxH3ImageVAEStateDictConverter",
1766
+ },
1767
+ ]
1768
+
1746
1769
  sensenova_u1_series = [
1747
1770
  {
1748
1771
  # Example: ModelConfig(model_id="SenseNova/SenseNova-U1.5-8B-MoT", origin_file_pattern="model*.safetensors")
@@ -1857,5 +1880,5 @@ MODEL_CONFIGS = (
1857
1880
  stable_diffusion_xl_series + stable_diffusion_series + qwen_image_series + qwen_video_edit_series + wan_series + flux_series + flux2_series + ernie_image_series
1858
1881
  + z_image_series + ltx2_series + anima_series + mova_series + joyai_image_series + boogu_image_series + ace_step_series + hidream_o1_image_series
1859
1882
  + image_metrics_series + ideogram4_series + krea2_series + lingbot_video_series + minimax_h3_series + minimax_music3_series + sensenova_u1_series
1860
- + yue2_series + qwen_image_21_series + flux3_series + moss_image_series + fibo_series
1883
+ + yue2_series + qwen_image_21_series + flux3_series + moss_image_series + fibo_series + minimax_h3_image_series
1861
1884
  )
@@ -10,6 +10,24 @@ flux_general_vram_config = {
10
10
  }
11
11
 
12
12
  VRAM_MANAGEMENT_MODULE_MAPS = {
13
+ "diffsynth.models.minimax_h3_image_dit.MiniMaxH3ImageDiT": {
14
+ "torch.nn.Linear": "diffsynth.core.vram.layers.AutoWrappedLinear",
15
+ "torch.nn.RMSNorm": "diffsynth.core.vram.layers.AutoWrappedModule",
16
+ },
17
+ "diffsynth.models.minimax_h3_image_dit.MiniMaxH3ImagePDDHeads": {
18
+ "diffsynth.models.minimax_h3_image_dit._MiniMaxH3ImagePDDHeadParameters": "diffsynth.core.vram.layers.AutoWrappedModule",
19
+ },
20
+ "diffsynth.models.minimax_h3_image_vae.MiniMaxH3ImageVAE": {
21
+ "torch.nn.Linear": "diffsynth.core.vram.layers.AutoWrappedLinear",
22
+ "torch.nn.LayerNorm": "diffsynth.core.vram.layers.AutoWrappedModule",
23
+ "torch.nn.RMSNorm": "diffsynth.core.vram.layers.AutoWrappedModule",
24
+ "torch.nn.Conv2d": "diffsynth.core.vram.layers.AutoWrappedModule",
25
+ "torch.nn.Conv3d": "diffsynth.core.vram.layers.AutoWrappedModule",
26
+ "torch.nn.GroupNorm": "diffsynth.core.vram.layers.AutoWrappedModule",
27
+ "diffsynth.models.minimax_h3_video_vae.BaseConv3d": "diffsynth.core.vram.layers.AutoWrappedModule",
28
+ "diffsynth.models.minimax_h3_video_vae.WarpedTensor": "diffsynth.core.vram.layers.AutoWrappedModule",
29
+ "diffsynth.models.minimax_h3_video_vae.TemporalIsolatedSpatialGroupNorm": "diffsynth.core.vram.layers.AutoWrappedModule",
30
+ },
13
31
  "diffsynth.models.minimax_h3_dit.MiniMaxH3DiT": {
14
32
  "torch.nn.Linear": "diffsynth.core.vram.layers.AutoWrappedLinear",
15
33
  "torch.nn.RMSNorm": "diffsynth.core.vram.layers.AutoWrappedModule",
@@ -115,6 +133,9 @@ VRAM_MANAGEMENT_MODULE_MAPS = {
115
133
  "diffsynth.models.wan_video_animate_adapter.ConvLayer": "diffsynth.core.vram.layers.AutoWrappedModule",
116
134
  "diffsynth.models.wan_video_animate_adapter.FusedLeakyReLU": "diffsynth.core.vram.layers.AutoWrappedModule",
117
135
  "diffsynth.models.wan_video_animate_adapter.RMSNorm": "diffsynth.core.vram.layers.AutoWrappedModule",
136
+ "diffsynth.models.wan_video_animate_adapter.Blur": "diffsynth.core.vram.layers.AutoWrappedModule",
137
+ "diffsynth.models.wan_video_animate_adapter.EqualConv2d": "diffsynth.core.vram.layers.AutoWrappedModule",
138
+ "diffsynth.models.wan_video_animate_adapter.Direction": "diffsynth.core.vram.layers.AutoWrappedModule",
118
139
  "torch.nn.Linear": "diffsynth.core.vram.layers.AutoWrappedLinear",
119
140
  "torch.nn.LayerNorm": "diffsynth.core.vram.layers.AutoWrappedModule",
120
141
  "torch.nn.Conv1d": "diffsynth.core.vram.layers.AutoWrappedModule",
@@ -150,6 +171,7 @@ VRAM_MANAGEMENT_MODULE_MAPS = {
150
171
  "torch.nn.LayerNorm": "diffsynth.core.vram.layers.AutoWrappedModule",
151
172
  "diffsynth.models.wan_video_dit.RMSNorm": "diffsynth.core.vram.layers.AutoWrappedModule",
152
173
  "torch.nn.Conv2d": "diffsynth.core.vram.layers.AutoWrappedModule",
174
+ "torch.nn.MultiheadAttention": "diffsynth.core.vram.layers.AutoWrappedModule",
153
175
  },
154
176
  "diffsynth.models.wan_video_image_encoder.WanImageEncoder": {
155
177
  "diffsynth.models.wan_video_image_encoder.VisionTransformer": "diffsynth.core.vram.layers.AutoWrappedModule",
@@ -15,7 +15,7 @@ def initialize_attention_priority():
15
15
  if os.environ.get('DIFFSYNTH_ATTENTION_IMPLEMENTATION') is not None:
16
16
  return os.environ.get('DIFFSYNTH_ATTENTION_IMPLEMENTATION').strip().lower()
17
17
  else:
18
- for name in ["customized_fa_kernel", "flash_attention_4", "flash_attention_3", "flash_attention_2", "sage_attention", "xformers"]:
18
+ for name in ["customized_fa_kernel", "flash_attention_4", "flash_attention_3", "flash_attention_2", "xformers"]:
19
19
  if name in list_attention_implementations():
20
20
  return name
21
21
  return "torch"
@@ -45,13 +45,13 @@ if ENTROPACK_AVAILABLE:
45
45
  @dataclass
46
46
  class EntroPackINT8CodedConfig(BackendConfig, ep.LatticeRANSConfig):
47
47
  linear_cls = ep.CompressedINT8Linear
48
- use_convrot: bool = False
48
+ use_convrot: bool = True
49
49
  convrot_groupsize: int = 256
50
50
 
51
51
  @dataclass
52
52
  class EntroPackINT8RawConfig(BackendConfig, ep.RawConfig):
53
53
  linear_cls = ep.CompressedINT8Linear
54
- use_convrot: bool = False
54
+ use_convrot: bool = True
55
55
  convrot_groupsize: int = 256
56
56
 
57
57
 
@@ -0,0 +1,355 @@
1
+ import math, torch
2
+ import torch.nn.functional as F
3
+ from tqdm import tqdm
4
+ from accelerate.utils import broadcast, DistributedType
5
+ from diffsynth.core import load_state_dict
6
+ from .runner import exclude_quantized_params_from_ddp_sync, get_optimizer_class, save_training_args
7
+ from .training_module import DiffusionTrainingModule
8
+
9
+
10
+ class DMD2ClassifierHead(torch.nn.Module):
11
+ def __init__(self, input_channels, channels=1280):
12
+ super().__init__()
13
+ groups = math.gcd(32, channels)
14
+ if channels // groups < 2:
15
+ raise ValueError("The classifier needs at least two channels per GroupNorm group.")
16
+ layers = [torch.nn.AdaptiveAvgPool2d(32), torch.nn.Conv2d(input_channels, channels, 1)]
17
+ for stride, padding in ((2, 1), (2, 1), (2, 1), (4, 0)):
18
+ layers.extend([torch.nn.Conv2d(channels, channels, 4, stride, padding),
19
+ torch.nn.GroupNorm(groups, channels), torch.nn.SiLU()])
20
+ self.layers = torch.nn.Sequential(*layers, torch.nn.Conv2d(channels, 1, 1))
21
+
22
+ def forward(self, features):
23
+ return self.layers(features.float()).flatten(1)
24
+
25
+
26
+ class DMD2FeatureExtractor:
27
+ def __init__(self, model, module_path):
28
+ self.module = model.get_submodule(module_path)
29
+
30
+ def run(self, forward, *args, **kwargs):
31
+ features = []
32
+ handle = self.module.register_forward_hook(lambda module, inputs, output: features.append(output))
33
+ try:
34
+ forward(*args, **kwargs)
35
+ finally:
36
+ handle.remove()
37
+ if len(features) != 1:
38
+ raise ValueError("The GAN feature module must run exactly once per forward.")
39
+ return features[0]
40
+
41
+
42
+ class DMD2TrainingModule(DiffusionTrainingModule):
43
+ def switch_pipe_to_dmd2_training_mode(
44
+ self, pipe,
45
+ student_sigmas, student_timesteps, teacher_cfg=3.,
46
+ min_timestep_dmd=20, max_timestep_dmd=981,
47
+ lora_base_model=None, lora_target_modules="", lora_rank=128, lora_dtype=None, lora_checkpoint=None,
48
+ preset_lora_path=None, preset_lora_model=None,
49
+ use_gan=True, generator_gan_loss_weight=0.005, discriminator_gan_loss_weight=0.01,
50
+ classifier_channels=1280, feature_module_of_dit_for_gan=None,
51
+ trainable_models=None, noise_sampling="uniform",
52
+ ):
53
+ # Training config
54
+ self.gan = use_gan
55
+ self.teacher_cfg = teacher_cfg
56
+ self.lora_base_model = lora_base_model
57
+ self.trainable_models = trainable_models
58
+ self.generator_gan_loss_weight = generator_gan_loss_weight
59
+ self.discriminator_gan_loss_weight = discriminator_gan_loss_weight
60
+ self.min_timestep_dmd = min_timestep_dmd
61
+ self.max_timestep_dmd = max_timestep_dmd
62
+ self.noise_sampling = noise_sampling
63
+ if lora_base_model is None and trainable_models is None:
64
+ raise ValueError("DMD2 requires trainable_models or lora_base_model.")
65
+
66
+ # Freeze models
67
+ pipe.freeze_except([] if trainable_models is None else trainable_models.split(","))
68
+ if preset_lora_path is not None:
69
+ pipe.load_lora(getattr(pipe, preset_lora_model), preset_lora_path)
70
+ model = getattr(pipe, lora_base_model or trainable_models)
71
+ self.adapter_layers = []
72
+
73
+ if self.trainable_models is not None and self.lora_base_model is None:
74
+ from copy import deepcopy
75
+ self.fake_model = deepcopy(model)
76
+ self.teacher_model = deepcopy(model).eval().requires_grad_(False)
77
+
78
+ # Add LoRA
79
+ if lora_base_model is not None:
80
+ from peft.tuners.tuners_utils import BaseTunerLayer
81
+ lora_dtype = pipe.torch_dtype if lora_dtype is None else {"bf16": torch.bfloat16, "fp32": torch.float32}[lora_dtype]
82
+ model = self.add_lora_to_model(model, lora_target_modules, lora_rank, upcast_dtype=lora_dtype)
83
+ model = self.add_lora_to_model(model, lora_target_modules, lora_rank, upcast_dtype=lora_dtype, adapter_name="fake")
84
+ setattr(pipe, lora_base_model, model)
85
+
86
+ # Load student LoRA
87
+ if lora_checkpoint is not None:
88
+ if isinstance(lora_checkpoint, str):
89
+ lora = load_state_dict(lora_checkpoint)
90
+ else:
91
+ lora = lora_checkpoint
92
+ lora_loader = pipe.lora_loader(torch_dtype=pipe.torch_dtype, device=pipe.device)
93
+ lora = lora_loader.convert_state_dict(lora)
94
+ lora = self.mapping_lora_state_dict(lora)
95
+ load_result = model.load_state_dict(lora, strict=False)
96
+ print(f"LoRA checkpoint loaded. Total {len(lora)} keys")
97
+ if len(load_result[1]) > 0:
98
+ print(f"Warning, LoRA key mismatch! Unexpected keys in LoRA checkpoint: {load_result[1]}")
99
+
100
+ self.adapter_layers = [layer for layer in model.modules() if isinstance(layer, BaseTunerLayer)]
101
+ for layer in self.adapter_layers:
102
+ layer.set_adapter(["default", "fake"])
103
+
104
+ # Initialize GAN
105
+ self.classifier = self.feature_extractor = None
106
+ if self.gan:
107
+ if feature_module_of_dit_for_gan is None:
108
+ raise ValueError("GAN training requires feature_module_of_dit_for_gan.")
109
+ self.classifier = DMD2ClassifierHead(self.gan_feature_channels, classifier_channels).to(pipe.device)
110
+ self.feature_extractor = DMD2FeatureExtractor(self.fake_model if self.trainable_models is not None and self.lora_base_model is None else model, feature_module_of_dit_for_gan)
111
+
112
+ # Set student schedule
113
+ pipe.scheduler.sigmas = self.parse_float_list(student_sigmas)
114
+ pipe.scheduler.timesteps = self.parse_float_list(student_timesteps)
115
+ pipe.scheduler.training = True
116
+
117
+ def add_lora_to_model(self, model, target_modules, lora_rank, lora_alpha=None, upcast_dtype=None, adapter_name="default"):
118
+ from peft import LoraConfig, inject_adapter_in_model
119
+ if lora_alpha is None:
120
+ lora_alpha = lora_rank
121
+ target_modules = self.parse_lora_target_modules(model, target_modules)
122
+ if isinstance(target_modules, list) and len(target_modules) == 1:
123
+ target_modules = target_modules[0]
124
+ lora_config = LoraConfig(r=lora_rank, lora_alpha=lora_alpha, target_modules=target_modules)
125
+ model = inject_adapter_in_model(lora_config, model, adapter_name=adapter_name)
126
+ if upcast_dtype is not None:
127
+ for param in model.parameters():
128
+ if param.requires_grad:
129
+ param.data = param.to(upcast_dtype)
130
+ return model
131
+
132
+ def parse_float_list(self, x):
133
+ return torch.tensor(list(map(float, x.split(",")))) if isinstance(x, str) else x
134
+
135
+ def select_model(self, model_role):
136
+ if self.trainable_models is not None and self.lora_base_model is None:
137
+ return {"generator": getattr(self.pipe, self.trainable_models), "fake": self.fake_model, "teacher": self.teacher_model}[model_role]
138
+ adapter = {"generator": "default", "fake": "fake", "teacher": []}[model_role]
139
+ for layer in self.adapter_layers:
140
+ layer.set_adapter(adapter)
141
+ return getattr(self.pipe, self.lora_base_model)
142
+
143
+ def generator_parameters(self):
144
+ if self.trainable_models is not None and self.lora_base_model is None:
145
+ return list(getattr(self.pipe, self.trainable_models).parameters())
146
+ model = getattr(self.pipe, self.lora_base_model)
147
+ return [p for name, p in model.named_parameters() if ".lora_A.default." in name or ".lora_B.default." in name]
148
+
149
+ def critic_parameters(self):
150
+ if self.trainable_models is not None and self.lora_base_model is None:
151
+ parameters = list(self.fake_model.parameters())
152
+ else:
153
+ model = getattr(self.pipe, self.lora_base_model)
154
+ parameters = [p for name, p in model.named_parameters() if ".lora_A.fake." in name or ".lora_B.fake." in name]
155
+ return parameters + (list(self.classifier.parameters()) if self.gan else [])
156
+
157
+ def prepare_batch(self, data):
158
+ """Subclasses must return (inputs_shared, inputs_posi, inputs_nega) for their pipeline."""
159
+ raise NotImplementedError("Implement prepare_batch in the model's training module.")
160
+
161
+ def predict(self, x, timestep, inputs, model_role, features=False):
162
+ model = self.select_model(model_role)
163
+ inputs_shared, inputs_posi, inputs_nega = inputs
164
+ inputs_shared = dict(inputs_shared, latents=x.to(self.pipe.torch_dtype))
165
+ models = {name: getattr(self.pipe, name) for name in self.pipe.in_iteration_models}
166
+ models[self.lora_base_model or self.trainable_models] = model
167
+ if features:
168
+ output = self.feature_extractor.run(self.pipe.model_fn, **models, **inputs_shared, **inputs_posi, timestep=timestep)
169
+ output = self.reshape_gan_features(output, inputs_shared)
170
+ else:
171
+ output = self.pipe.cfg_guided_model_fn(
172
+ lambda **kwargs: self.pipe.model_fn(**kwargs).float(),
173
+ self.teacher_cfg if model_role == "teacher" else 1.,
174
+ inputs_shared, inputs_posi, inputs_nega, **models, timestep=timestep,
175
+ )
176
+ return output.float()
177
+
178
+ def rollout(self, inputs, step, track_grad=False):
179
+ x = inputs[0]["noise"].float()
180
+ for index in range(step + 1):
181
+ with torch.set_grad_enabled(track_grad and index == step):
182
+ x = x.to(self.pipe.torch_dtype).float()
183
+ timestep = self.pipe.scheduler.timesteps[index].to(x.device).reshape(1)
184
+ velocity = self.predict(x, timestep, inputs, "generator")
185
+ x = self.pipe.scheduler.step(velocity, timestep, x, to_final=index == step)
186
+ return x
187
+
188
+ def sample_noise(self, clean, distribution_matching, min_timestep_dmd=20, max_timestep_dmd=981, noise_sampling=None):
189
+ noise_sampling = self.noise_sampling if noise_sampling is None else noise_sampling
190
+ if noise_sampling == "beta":
191
+ beta = torch.distributions.Beta(torch.tensor(2.5, device=clean.device), torch.tensor(1., device=clean.device))
192
+ level = beta.sample((clean.shape[0],)).clamp((min_timestep_dmd + 1) / 1000, max_timestep_dmd / 1000)
193
+ else:
194
+ low, high = (min_timestep_dmd, max_timestep_dmd) if distribution_matching else (0, 1000)
195
+ level = (torch.randint(low, high, (clean.shape[0],), device=clean.device).float() + 1) / 1000
196
+ noise = torch.randn_like(clean)
197
+ sigma = level.reshape(-1, *([1] * (clean.ndim - 1)))
198
+ return (1 - sigma) * clean + sigma * noise, level, noise
199
+
200
+ def teacher_clean(self, noised, inputs):
201
+ noisy, level, _ = noised
202
+ velocity = self.predict(noisy, level * 1000, inputs, "teacher")
203
+ return noisy - level.reshape(-1, *([1] * (noisy.ndim - 1))) * velocity
204
+
205
+ def fake_clean(self, noised, inputs):
206
+ noisy, level, _ = noised
207
+ velocity = self.predict(noisy, level * 1000, inputs, "fake")
208
+ return noisy - level.reshape(-1, *([1] * (noisy.ndim - 1))) * velocity
209
+
210
+ def logits(self, clean, inputs):
211
+ noisy, level, _ = self.sample_noise(clean, False, noise_sampling="uniform")
212
+ features = self.predict(noisy, level * 1000, inputs, "fake", features=True)
213
+ return self.classifier(features)
214
+
215
+ def export_trainable_state_dict(self, state_dict, remove_prefix=None):
216
+ generator_param_ids = {id(param) for param in self.generator_parameters()}
217
+ trainable_param_names = {name for name, param in self.named_parameters() if id(param) in generator_param_ids}
218
+ state_dict = {name: param for name, param in state_dict.items() if name in trainable_param_names}
219
+ if remove_prefix is not None:
220
+ state_dict = {name.removeprefix(remove_prefix): param for name, param in state_dict.items()}
221
+ return state_dict
222
+
223
+ def distribution_matching_loss(self, student_sample, teacher, fake):
224
+ with torch.no_grad():
225
+ dims = tuple(range(1, student_sample.ndim))
226
+ scale = (student_sample.float() - teacher.float()).abs().mean(dim=dims, keepdim=True).clamp_min(1e-8)
227
+ direction = torch.nan_to_num((fake.float() - teacher.float()) / scale)
228
+ return 0.5 * F.mse_loss(student_sample.float(), (student_sample.float() - direction).detach())
229
+
230
+ def forward_generator(self, inputs, rollout_step, update_generator):
231
+ if update_generator:
232
+ student_sample = self.rollout(inputs, rollout_step, True)
233
+ with torch.no_grad():
234
+ noised = self.sample_noise(student_sample.detach(), True, self.min_timestep_dmd, self.max_timestep_dmd)
235
+ teacher = self.teacher_clean(noised, inputs)
236
+ fake = self.fake_clean(noised, inputs)
237
+ loss = self.distribution_matching_loss(student_sample, teacher, fake)
238
+ if self.gan:
239
+ gan_sample = student_sample.detach().requires_grad_(True)
240
+ logits = self.logits(gan_sample, inputs)
241
+ gan_loss = F.softplus(-logits).mean()
242
+ gradient = torch.autograd.grad(gan_loss, gan_sample)[0].detach()
243
+ loss = loss + self.generator_gan_loss_weight * (gan_loss.detach() + ((student_sample - student_sample.detach()) * gradient).sum())
244
+ self.select_model("generator")
245
+ else:
246
+ with torch.no_grad():
247
+ student_sample = self.rollout(inputs, rollout_step)
248
+ loss = None
249
+ return loss, student_sample.detach()
250
+
251
+ def forward_critic(self, inputs, student_sample):
252
+ inputs_shared, inputs_posi, inputs_nega = inputs
253
+ noisy, level, noise = self.sample_noise(student_sample.detach(), False, self.min_timestep_dmd, self.max_timestep_dmd)
254
+ velocity = self.predict(noisy, level * 1000, inputs, "fake")
255
+ loss = F.mse_loss(velocity.float(), noise.float() - student_sample.detach().float())
256
+ if self.gan:
257
+ real_logits = self.logits(inputs_shared['input_latents'].float(), inputs)
258
+ fake_logits = self.logits(student_sample.detach(), inputs)
259
+ loss = loss + self.discriminator_gan_loss_weight * (F.softplus(-real_logits).mean() + F.softplus(fake_logits).mean())
260
+ return loss
261
+
262
+ def forward(self, data, phase, rollout_step=None, update_generator=True, inputs=None, student_sample=None):
263
+ if phase == 'generator':
264
+ with torch.no_grad():
265
+ inputs = self.prepare_batch(data)
266
+ loss, student_sample = self.forward_generator(inputs, rollout_step, update_generator)
267
+ return loss, inputs, student_sample
268
+ elif phase == 'critic':
269
+ return self.forward_critic(inputs, student_sample)
270
+ else:
271
+ raise ValueError(f"Unknown DMD2 phase: {phase}")
272
+
273
+
274
+ def launch_dmd2_training_task(
275
+ accelerator, dataset, model, model_logger,
276
+ learning_rate=1e-4, weight_decay=0.01, num_workers=0, save_steps=None, num_epochs=1,
277
+ enable_model_cpu_offload=False, customized_optimizer=None, warm_up_steps=5,
278
+ fake_updates_per_generator=5, fake_warmup_steps=100, fake_learning_rate=None,
279
+ args=None, **kwargs,
280
+ ):
281
+ if args is not None:
282
+ learning_rate = args.learning_rate
283
+ weight_decay = args.weight_decay
284
+ num_workers = args.dataset_num_workers
285
+ save_steps = args.save_steps
286
+ num_epochs = args.num_epochs
287
+ enable_model_cpu_offload = args.enable_model_cpu_offload
288
+ customized_optimizer = args.customized_optimizer
289
+ warm_up_steps = getattr(args, "warm_up_steps", warm_up_steps)
290
+ fake_updates_per_generator = args.dmd2_fake_updates_per_generator
291
+ fake_warmup_steps = args.dmd2_fake_warmup_steps
292
+ fake_learning_rate = args.dmd2_fake_learning_rate
293
+ num_steps = len(model.pipe.scheduler.sigmas)
294
+
295
+ if accelerator.distributed_type == DistributedType.DEEPSPEED:
296
+ raise ValueError("DMD2 training does not support DeepSpeed.")
297
+ if enable_model_cpu_offload:
298
+ raise ValueError("DMD2 training does not support model CPU offload.")
299
+ if fake_updates_per_generator < 1:
300
+ raise ValueError('Update ratio must be positive.')
301
+ if fake_warmup_steps < 0:
302
+ raise ValueError('Fake warmup steps must be nonnegative.')
303
+ if accelerator.is_main_process:
304
+ save_training_args(args)
305
+
306
+ generator_params, critic_params = model.generator_parameters(), model.critic_parameters()
307
+ dataloader = torch.utils.data.DataLoader(dataset, shuffle=True, collate_fn=lambda batch: batch[0], num_workers=num_workers)
308
+ optimizer_class = get_optimizer_class(customized_optimizer)
309
+ fake_learning_rate = learning_rate if fake_learning_rate is None else fake_learning_rate
310
+ generator_optimizer = optimizer_class(generator_params, lr=learning_rate, weight_decay=weight_decay)
311
+ critic_optimizer = optimizer_class(critic_params, lr=fake_learning_rate, weight_decay=weight_decay)
312
+ generator_scheduler = torch.optim.lr_scheduler.LambdaLR(generator_optimizer, lambda s: min(1.0, (s + 1) / max(1, warm_up_steps)))
313
+ critic_scheduler = torch.optim.lr_scheduler.LambdaLR(critic_optimizer, lambda s: min(1.0, (s + 1) / max(1, warm_up_steps)))
314
+
315
+ model.to(device=accelerator.device)
316
+ exclude_quantized_params_from_ddp_sync(accelerator, model)
317
+ model, generator_optimizer, critic_optimizer, dataloader = accelerator.prepare(
318
+ model, generator_optimizer, critic_optimizer, dataloader,
319
+ )
320
+
321
+ for epoch in range(num_epochs):
322
+ for data in (progress_bar := tqdm(dataloader, disable=not accelerator.is_main_process)):
323
+ if accelerator.sync_gradients:
324
+ rollout_step = broadcast(torch.randint(num_steps, (), device=accelerator.device)).item()
325
+ step = model_logger.num_steps - fake_warmup_steps
326
+ update_generator = step >= 0 and step % fake_updates_per_generator == 0
327
+ with accelerator.accumulate(model):
328
+ with torch.set_grad_enabled(update_generator):
329
+ loss, inputs, student_sample = model(data, phase='generator', rollout_step=rollout_step, update_generator=update_generator)
330
+ if update_generator:
331
+ accelerator.backward(loss)
332
+ loss = model({}, phase='critic', inputs=inputs, student_sample=student_sample)
333
+ accelerator.backward(loss)
334
+
335
+ if accelerator.sync_gradients:
336
+ if update_generator:
337
+ accelerator.clip_grad_norm_(generator_params, 10.)
338
+ accelerator.clip_grad_norm_(critic_params, 10.)
339
+
340
+ if update_generator:
341
+ generator_optimizer.step()
342
+ if accelerator.sync_gradients and not getattr(generator_optimizer, "step_was_skipped", False):
343
+ generator_scheduler.step()
344
+ critic_optimizer.step()
345
+ if accelerator.sync_gradients and not getattr(critic_optimizer, "step_was_skipped", False):
346
+ critic_scheduler.step()
347
+ generator_optimizer.zero_grad(set_to_none=True)
348
+ critic_optimizer.zero_grad(set_to_none=True)
349
+ if accelerator.sync_gradients:
350
+ model_logger.on_step_end(accelerator, model, save_steps)
351
+ progress_bar.set_postfix(generator_updates=(max(0, model_logger.num_steps - fake_warmup_steps) + fake_updates_per_generator - 1) // fake_updates_per_generator)
352
+ if save_steps is None:
353
+ model_logger.on_epoch_end(accelerator, model, epoch)
354
+
355
+ model_logger.on_training_end(accelerator, model, save_steps)
@@ -5,7 +5,7 @@ from typing_extensions import Literal
5
5
 
6
6
  class FlowMatchScheduler():
7
7
 
8
- def __init__(self, template: Literal["FLUX.1", "Wan", "Qwen-Image", "FLUX.2", "FLUX.3", "Z-Image", "LTX-2", "Qwen-Image-Lightning", "ERNIE-Image", "MOSS-Image", "ACE-Step", "Ideogram4", "Krea-2", "Boogu", "MiniMax-H3", "MiniMax-Music3", "LingBot-Video", "SenseNova-U1", "YuE2", "Fibo"] = "FLUX.1"):
8
+ def __init__(self, template: Literal["FLUX.1", "Wan", "Qwen-Image", "FLUX.2", "FLUX.3", "Z-Image", "LTX-2", "Qwen-Image-Lightning", "ERNIE-Image", "MOSS-Image", "ACE-Step", "Ideogram4", "Krea-2", "Boogu", "MiniMax-H3", "MiniMax-H3-Image", "MiniMax-Music3", "LingBot-Video", "SenseNova-U1", "YuE2", "Fibo"] = "FLUX.1"):
9
9
  self.set_timesteps_fn = {
10
10
  "FLUX.1": FlowMatchScheduler.set_timesteps_flux,
11
11
  "Wan": FlowMatchScheduler.set_timesteps_wan,
@@ -23,6 +23,7 @@ class FlowMatchScheduler():
23
23
  "Krea-2": FlowMatchScheduler.set_timesteps_krea2,
24
24
  "Boogu": FlowMatchScheduler.set_timesteps_boogu,
25
25
  "MiniMax-H3": FlowMatchScheduler.set_timesteps_minimax_h3,
26
+ "MiniMax-H3-Image": FlowMatchScheduler.set_timesteps_minimax_h3_image,
26
27
  "MiniMax-Music3": FlowMatchScheduler.set_timesteps_minimax_music3,
27
28
  "LingBot-Video": FlowMatchScheduler.set_timesteps_lingbot_video,
28
29
  "SenseNova-U1": FlowMatchScheduler.set_timesteps_sensenova_u1,
@@ -393,6 +394,20 @@ class FlowMatchScheduler():
393
394
  timesteps = sigmas * num_train_timesteps
394
395
  return sigmas, timesteps
395
396
 
397
+ @staticmethod
398
+ def set_timesteps_minimax_h3_image(num_inference_steps=50, denoising_strength=1.0, shift=2.22, distilled=False):
399
+ if distilled:
400
+ num_train_timesteps = 1000
401
+ sample_sigmas = torch.tensor([
402
+ 1.0, 0.9675236940383911, 0.8875485062599182, 0.75, 0.5327739119529724, 0.23200887441635132, 0.0,
403
+ ], dtype=torch.float32)
404
+ timesteps = 1.0 - sample_sigmas[:-1]
405
+ sigmas = 1.0 - timesteps
406
+ timesteps = sigmas * num_train_timesteps
407
+ return sigmas, timesteps
408
+ else:
409
+ return FlowMatchScheduler.set_timesteps_minimax_h3(num_inference_steps=num_inference_steps, denoising_strength=denoising_strength, shift=shift)
410
+
396
411
  @staticmethod
397
412
  def set_timesteps_minimax_music3(num_inference_steps=30, denoising_strength=1.0):
398
413
  num_train_timesteps = 1000