hcpdiff 2.2__tar.gz → 2.3__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 (139) hide show
  1. {hcpdiff-2.2 → hcpdiff-2.3}/PKG-INFO +8 -4
  2. {hcpdiff-2.2 → hcpdiff-2.3}/README.md +6 -2
  3. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/ckpt_manager/__init__.py +1 -1
  4. hcpdiff-2.3/hcpdiff/ckpt_manager/ckpt.py +28 -0
  5. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/ckpt_manager/format/diffusers.py +4 -4
  6. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/ckpt_manager/format/sd_single.py +3 -3
  7. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/ckpt_manager/loader.py +11 -4
  8. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/diffusion/noise/__init__.py +0 -1
  9. hcpdiff-2.3/hcpdiff/diffusion/sampler/VP.py +27 -0
  10. hcpdiff-2.3/hcpdiff/diffusion/sampler/__init__.py +4 -0
  11. hcpdiff-2.3/hcpdiff/diffusion/sampler/base.py +134 -0
  12. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/diffusion/sampler/diffusers.py +11 -17
  13. hcpdiff-2.3/hcpdiff/diffusion/sampler/sigma_scheduler/__init__.py +5 -0
  14. hcpdiff-2.3/hcpdiff/diffusion/sampler/sigma_scheduler/base.py +89 -0
  15. hcpdiff-2.3/hcpdiff/diffusion/sampler/sigma_scheduler/ddpm.py +341 -0
  16. hcpdiff-2.3/hcpdiff/diffusion/sampler/sigma_scheduler/edm.py +125 -0
  17. hcpdiff-2.3/hcpdiff/diffusion/sampler/sigma_scheduler/flow.py +74 -0
  18. hcpdiff-2.3/hcpdiff/diffusion/sampler/sigma_scheduler/zero_terminal.py +22 -0
  19. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/easy/cfg/sd15_train.py +35 -24
  20. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/easy/cfg/sdxl_train.py +34 -25
  21. hcpdiff-2.3/hcpdiff/evaluate/__init__.py +3 -0
  22. hcpdiff-2.2/hcpdiff/evaluate/previewer.py → hcpdiff-2.3/hcpdiff/evaluate/evaluator.py +20 -4
  23. hcpdiff-2.3/hcpdiff/evaluate/metrics/__init__.py +1 -0
  24. hcpdiff-2.3/hcpdiff/evaluate/metrics/clip_score.py +23 -0
  25. hcpdiff-2.3/hcpdiff/evaluate/previewer.py +77 -0
  26. hcpdiff-2.3/hcpdiff/loss/base.py +24 -0
  27. hcpdiff-2.3/hcpdiff/loss/weighting.py +84 -0
  28. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/lora_base_patch.py +26 -0
  29. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/text_emb_ex.py +4 -0
  30. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/wrapper/sd.py +17 -19
  31. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/trainer_ac.py +7 -12
  32. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/trainer_ac_single.py +1 -6
  33. hcpdiff-2.3/hcpdiff/trainer_deepspeed.py +47 -0
  34. hcpdiff-2.3/hcpdiff/utils/__init__.py +3 -0
  35. hcpdiff-2.3/hcpdiff/utils/torch_utils.py +25 -0
  36. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/workflow/__init__.py +1 -1
  37. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/workflow/diffusion.py +27 -7
  38. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/workflow/io.py +20 -3
  39. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/workflow/text.py +6 -1
  40. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff.egg-info/PKG-INFO +8 -4
  41. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff.egg-info/SOURCES.txt +8 -4
  42. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff.egg-info/entry_points.txt +1 -0
  43. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff.egg-info/requires.txt +1 -1
  44. {hcpdiff-2.2 → hcpdiff-2.3}/setup.py +2 -1
  45. hcpdiff-2.2/hcpdiff/ckpt_manager/ckpt.py +0 -24
  46. hcpdiff-2.2/hcpdiff/diffusion/noise/zero_terminal.py +0 -39
  47. hcpdiff-2.2/hcpdiff/diffusion/sampler/__init__.py +0 -5
  48. hcpdiff-2.2/hcpdiff/diffusion/sampler/base.py +0 -72
  49. hcpdiff-2.2/hcpdiff/diffusion/sampler/ddpm.py +0 -20
  50. hcpdiff-2.2/hcpdiff/diffusion/sampler/edm.py +0 -22
  51. hcpdiff-2.2/hcpdiff/diffusion/sampler/sigma_scheduler/__init__.py +0 -3
  52. hcpdiff-2.2/hcpdiff/diffusion/sampler/sigma_scheduler/base.py +0 -14
  53. hcpdiff-2.2/hcpdiff/diffusion/sampler/sigma_scheduler/ddpm.py +0 -197
  54. hcpdiff-2.2/hcpdiff/diffusion/sampler/sigma_scheduler/edm.py +0 -48
  55. hcpdiff-2.2/hcpdiff/evaluate/__init__.py +0 -1
  56. hcpdiff-2.2/hcpdiff/loss/base.py +0 -41
  57. hcpdiff-2.2/hcpdiff/loss/weighting.py +0 -66
  58. hcpdiff-2.2/hcpdiff/train_deepspeed.py +0 -69
  59. hcpdiff-2.2/hcpdiff/utils/__init__.py +0 -2
  60. {hcpdiff-2.2 → hcpdiff-2.3}/LICENSE +0 -0
  61. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/__init__.py +0 -0
  62. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/ckpt_manager/format/__init__.py +0 -0
  63. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/ckpt_manager/format/emb.py +0 -0
  64. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/ckpt_manager/format/lora_webui.py +0 -0
  65. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/data/__init__.py +0 -0
  66. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/data/cache/__init__.py +0 -0
  67. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/data/cache/vae.py +0 -0
  68. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/data/dataset.py +0 -0
  69. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/data/handler/__init__.py +0 -0
  70. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/data/handler/controlnet.py +0 -0
  71. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/data/handler/diffusion.py +0 -0
  72. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/data/handler/text.py +0 -0
  73. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/data/source/__init__.py +0 -0
  74. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/data/source/folder_class.py +0 -0
  75. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/data/source/text.py +0 -0
  76. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/data/source/text2img.py +0 -0
  77. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/data/source/text2img_cond.py +0 -0
  78. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/diffusion/__init__.py +0 -0
  79. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/diffusion/noise/pyramid_noise.py +0 -0
  80. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/easy/__init__.py +0 -0
  81. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/easy/cfg/__init__.py +0 -0
  82. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/easy/cfg/t2i.py +0 -0
  83. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/easy/model/__init__.py +0 -0
  84. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/easy/model/cnet.py +0 -0
  85. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/easy/model/loader.py +0 -0
  86. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/easy/sampler.py +0 -0
  87. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/loss/__init__.py +0 -0
  88. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/loss/gw.py +0 -0
  89. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/loss/ssim.py +0 -0
  90. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/loss/vlb.py +0 -0
  91. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/__init__.py +0 -0
  92. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/cfg_context.py +0 -0
  93. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/compose/__init__.py +0 -0
  94. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/compose/compose_hook.py +0 -0
  95. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/compose/compose_textencoder.py +0 -0
  96. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/compose/compose_tokenizer.py +0 -0
  97. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/compose/sdxl_composer.py +0 -0
  98. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/container.py +0 -0
  99. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/controlnet.py +0 -0
  100. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/lora_base.py +0 -0
  101. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/lora_layers.py +0 -0
  102. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/lora_layers_patch.py +0 -0
  103. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/textencoder_ex.py +0 -0
  104. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/tokenizer_ex.py +0 -0
  105. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/wrapper/__init__.py +0 -0
  106. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/wrapper/pixart.py +0 -0
  107. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/models/wrapper/utils.py +0 -0
  108. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/parser/__init__.py +0 -0
  109. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/parser/embpt.py +0 -0
  110. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/tools/__init__.py +0 -0
  111. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/tools/convert_caption_txt2json.py +0 -0
  112. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/tools/convert_old_lora.py +0 -0
  113. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/tools/create_embedding.py +0 -0
  114. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/tools/dataset_generator.py +0 -0
  115. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/tools/diffusers2sd.py +0 -0
  116. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/tools/download_hf_model.py +0 -0
  117. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/tools/embedding_convert.py +0 -0
  118. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/tools/gen_from_ptlist.py +0 -0
  119. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/tools/init_proj.py +0 -0
  120. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/tools/lora_convert.py +0 -0
  121. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/tools/save_model.py +0 -0
  122. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/tools/sd2diffusers.py +0 -0
  123. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/train_colo.py +0 -0
  124. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/utils/colo_utils.py +0 -0
  125. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/utils/inpaint_pipe.py +0 -0
  126. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/utils/net_utils.py +0 -0
  127. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/utils/pipe_hook.py +0 -0
  128. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/utils/utils.py +0 -0
  129. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/workflow/daam/__init__.py +0 -0
  130. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/workflow/daam/act.py +0 -0
  131. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/workflow/daam/hook.py +0 -0
  132. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/workflow/fast.py +0 -0
  133. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/workflow/flow.py +0 -0
  134. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/workflow/model.py +0 -0
  135. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/workflow/utils.py +0 -0
  136. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff/workflow/vae.py +0 -0
  137. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff.egg-info/dependency_links.txt +0 -0
  138. {hcpdiff-2.2 → hcpdiff-2.3}/hcpdiff.egg-info/top_level.txt +0 -0
  139. {hcpdiff-2.2 → hcpdiff-2.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hcpdiff
3
- Version: 2.2
3
+ Version: 2.3
4
4
  Summary: A universal Diffusion toolbox
5
5
  Home-page: https://github.com/IrisRainbowNeko/HCP-Diffusion
6
6
  Author: Ziyi Dong
@@ -17,7 +17,7 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
17
  Requires-Python: >=3.8
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
- Requires-Dist: rainbowneko
20
+ Requires-Dist: rainbowneko>=1.9
21
21
  Requires-Dist: diffusers
22
22
  Requires-Dist: matplotlib
23
23
  Requires-Dist: pyarrow
@@ -262,9 +262,13 @@ hcp_run --cfg cfgs/workflow/text2img_cli.py \
262
262
  seed=42
263
263
  ```
264
264
 
265
- ### Tutorials
265
+ ### 📚 Tutorials
266
266
 
267
- 🚧 In Development
267
+ + 🧠 [Model Training Guide](https://hcpdiff.readthedocs.io/en/latest/user_guides/train.html)
268
+ + 🔧 [LoRA Training Tutorial](https://hcpdiff.readthedocs.io/enlatest/tutorial/lora.html)
269
+ + 🎨 [Image Generation Guide](https://hcpdiff.readthedocs.io/en/latest/user_guides/workflow.html)
270
+ + ⚙️ [Configuration File Explanation](https://hcpdiff.readthedocs.io/en/latest/user_guides/cfg.html)
271
+ + 🧩 [Model Format Explanation](https://hcpdiff.readthedocs.io/en/latest/user_guides/model_format.html)
268
272
 
269
273
  ---
270
274
 
@@ -225,9 +225,13 @@ hcp_run --cfg cfgs/workflow/text2img_cli.py \
225
225
  seed=42
226
226
  ```
227
227
 
228
- ### Tutorials
228
+ ### 📚 Tutorials
229
229
 
230
- 🚧 In Development
230
+ + 🧠 [Model Training Guide](https://hcpdiff.readthedocs.io/en/latest/user_guides/train.html)
231
+ + 🔧 [LoRA Training Tutorial](https://hcpdiff.readthedocs.io/enlatest/tutorial/lora.html)
232
+ + 🎨 [Image Generation Guide](https://hcpdiff.readthedocs.io/en/latest/user_guides/workflow.html)
233
+ + ⚙️ [Configuration File Explanation](https://hcpdiff.readthedocs.io/en/latest/user_guides/cfg.html)
234
+ + 🧩 [Model Format Explanation](https://hcpdiff.readthedocs.io/en/latest/user_guides/model_format.html)
231
235
 
232
236
  ---
233
237
 
@@ -1,4 +1,4 @@
1
1
  from .format import EmbFormat, DiffusersSD15Format, DiffusersModelFormat, DiffusersSDXLFormat, DiffusersPixArtFormat, OfficialSDXLFormat, \
2
2
  OfficialSD15Format, LoraWebuiFormat
3
- from .ckpt import EmbSaver, easy_emb_saver
3
+ from .ckpt import EmbSaver
4
4
  from .loader import HCPLoraLoader
@@ -0,0 +1,28 @@
1
+ from rainbowneko.ckpt_manager import NekoSaver, CkptFormat, LocalCkptSource, PKLFormat, LAYERS_ALL, LAYERS_TRAINABLE
2
+ from torch import Tensor
3
+ from typing import Dict, Any
4
+
5
+ class EmbSaver(NekoSaver):
6
+ def __init__(self, format: CkptFormat=None, source: LocalCkptSource=None, layers='all', key_map=None, prefix=None):
7
+ if format is None:
8
+ format = PKLFormat()
9
+ if source is None:
10
+ source = LocalCkptSource()
11
+ key_map = key_map or ('name -> name', 'embs -> embs', 'name_template -> name_template')
12
+ super().__init__(format, source, layers=layers, key_map=key_map)
13
+ self.prefix = prefix
14
+
15
+ def _save_to(self, name, embs: Dict[str, Tensor], name_template=None):
16
+ for pt_name, pt in embs.items():
17
+ if self.layers == LAYERS_ALL:
18
+ pass
19
+ elif self.layers == LAYERS_TRAINABLE:
20
+ if not pt.requires_grad:
21
+ continue
22
+ elif pt_name not in self.layers:
23
+ continue
24
+
25
+ self.save((pt_name, pt), pt_name, prefix=self.prefix)
26
+ if name_template is not None:
27
+ pt_name = name_template.format(pt_name)
28
+ self.save((pt_name, pt), pt_name, prefix=self.prefix)
@@ -3,7 +3,7 @@ from diffusers import ModelMixin, AutoencoderKL, UNet2DConditionModel, PixArtTra
3
3
  from rainbowneko.ckpt_manager.format import CkptFormat
4
4
  from transformers import CLIPTextModel, AutoTokenizer, T5EncoderModel
5
5
 
6
- from hcpdiff.diffusion.sampler import DDPMSampler, DDPMDiscreteSigmaScheduler
6
+ from hcpdiff.diffusion.sampler import VPSampler, DDPMDiscreteSigmaScheduler
7
7
  from hcpdiff.models.compose import SDXLTokenizer, SDXLTextEncoder
8
8
 
9
9
  class DiffusersModelFormat(CkptFormat):
@@ -23,7 +23,7 @@ class DiffusersSD15Format(CkptFormat):
23
23
  pretrained_model, subfolder="unet", revision=revision, torch_dtype=dtype
24
24
  )
25
25
  vae = vae or AutoencoderKL.from_pretrained(pretrained_model, subfolder="vae", revision=revision, torch_dtype=dtype)
26
- noise_sampler = noise_sampler or DDPMSampler(DDPMDiscreteSigmaScheduler())
26
+ noise_sampler = noise_sampler or VPSampler(DDPMDiscreteSigmaScheduler())
27
27
 
28
28
  TE = TE or CLIPTextModel.from_pretrained(pretrained_model, subfolder="text_encoder", revision=revision, torch_dtype=dtype)
29
29
  tokenizer = tokenizer or AutoTokenizer.from_pretrained(pretrained_model, subfolder="tokenizer", revision=revision, use_fast=False)
@@ -37,7 +37,7 @@ class DiffusersSDXLFormat(CkptFormat):
37
37
  pretrained_model, subfolder="unet", revision=revision, torch_dtype=dtype
38
38
  )
39
39
  vae = vae or AutoencoderKL.from_pretrained(pretrained_model, subfolder="vae", revision=revision, torch_dtype=dtype)
40
- noise_sampler = noise_sampler or DDPMSampler(DDPMDiscreteSigmaScheduler())
40
+ noise_sampler = noise_sampler or VPSampler(DDPMDiscreteSigmaScheduler())
41
41
 
42
42
  TE = TE or SDXLTextEncoder.from_pretrained(pretrained_model, subfolder="text_encoder", revision=revision, torch_dtype=dtype)
43
43
  tokenizer = tokenizer or SDXLTokenizer.from_pretrained(pretrained_model, subfolder="tokenizer", revision=revision, use_fast=False)
@@ -51,7 +51,7 @@ class DiffusersPixArtFormat(CkptFormat):
51
51
  pretrained_model, subfolder="transformer", revision=revision, torch_dtype=dtype
52
52
  )
53
53
  vae = vae or AutoencoderKL.from_pretrained(pretrained_model, subfolder="vae", revision=revision, torch_dtype=dtype)
54
- noise_sampler = noise_sampler or DDPMSampler(DDPMDiscreteSigmaScheduler())
54
+ noise_sampler = noise_sampler or VPSampler(DDPMDiscreteSigmaScheduler())
55
55
 
56
56
  TE = TE or T5EncoderModel.from_pretrained(pretrained_model, subfolder="text_encoder", revision=revision, torch_dtype=dtype)
57
57
  tokenizer = tokenizer or AutoTokenizer.from_pretrained(pretrained_model, subfolder="tokenizer", revision=revision, use_fast=False)
@@ -2,7 +2,7 @@ import torch
2
2
  from diffusers import AutoencoderKL, StableDiffusionPipeline, StableDiffusionXLPipeline
3
3
  from rainbowneko.ckpt_manager.format import CkptFormat
4
4
 
5
- from hcpdiff.diffusion.sampler import DDPMSampler, DDPMDiscreteSigmaScheduler
5
+ from hcpdiff.diffusion.sampler import VPSampler, DDPMDiscreteSigmaScheduler
6
6
  from hcpdiff.models.compose import SDXLTextEncoder, SDXLTokenizer
7
7
 
8
8
  class OfficialSD15Format(CkptFormat):
@@ -14,7 +14,7 @@ class OfficialSD15Format(CkptFormat):
14
14
  pipe = StableDiffusionPipeline.from_single_file(
15
15
  pretrained_model, revision=revision, torch_dtype=dtype, **pipe_args
16
16
  )
17
- noise_sampler = noise_sampler or DDPMSampler(DDPMDiscreteSigmaScheduler())
17
+ noise_sampler = noise_sampler or VPSampler(DDPMDiscreteSigmaScheduler())
18
18
  return dict(denoiser=pipe.unet, TE=pipe.text_encoder, vae=pipe.vae, noise_sampler=noise_sampler, tokenizer=pipe.tokenizer)
19
19
 
20
20
  class OfficialSDXLFormat(CkptFormat):
@@ -34,7 +34,7 @@ class OfficialSDXLFormat(CkptFormat):
34
34
  pretrained_model, revision=revision, torch_dtype=dtype, **pipe_args
35
35
  )
36
36
 
37
- noise_sampler = noise_sampler or DDPMSampler(DDPMDiscreteSigmaScheduler())
37
+ noise_sampler = noise_sampler or VPSampler(DDPMDiscreteSigmaScheduler())
38
38
  TE = SDXLTextEncoder([('clip_L', pipe.text_encoder), ('clip_bigG', pipe.text_encoder_2)])
39
39
  tokenizer = SDXLTokenizer([('clip_L', pipe.tokenizer), ('clip_bigG', pipe.tokenizer_2)])
40
40
 
@@ -14,17 +14,24 @@ def get_lora_rank_and_cls(lora_state):
14
14
 
15
15
  class HCPLoraLoader(NekoPluginLoader):
16
16
  def __init__(self, format: CkptFormat=None, source: LocalCkptSource=None, path: str = None, layers='all', target_plugin=None,
17
- state_prefix=None, base_model_alpha=0.0, load_ema=False, module_to_load='', **plugin_kwargs):
17
+ state_prefix=None, base_model_alpha=0.0, load_ema=False, module_to_load='', key_map=None, **plugin_kwargs):
18
+ key_map = key_map or ('name -> name', 'model -> model')
18
19
  super().__init__(format, source, path=path, layers=layers, target_plugin=target_plugin, state_prefix=state_prefix,
19
- base_model_alpha=base_model_alpha, load_ema=load_ema, **plugin_kwargs)
20
+ base_model_alpha=base_model_alpha, load_ema=load_ema, key_map=key_map, **plugin_kwargs)
20
21
  self.module_to_load = module_to_load
21
22
 
22
- def load_to(self, name, model):
23
+ def _load_to(self, name, model):
23
24
  # get model to load plugin and its named_modules
24
25
  model = model if self.module_to_load == '' else eval(f"model.{self.module_to_load}")
25
26
 
26
27
  named_modules = {k:v for k, v in model.named_modules()}
27
- plugin_state = self.load(self.path, map_location='cpu')['base_ema' if self.load_ema else 'base']
28
+ state_dict = self.load(self.path, map_location='cpu')
29
+ if 'base' in state_dict or 'base_ema' in state_dict:
30
+ plugin_state = state_dict['base_ema' if self.load_ema else 'base']
31
+ elif 'plugin' in state_dict or 'plugin_ema' in state_dict:
32
+ plugin_state = state_dict['plugin_ema' if self.load_ema else 'plugin']
33
+ else:
34
+ plugin_state = state_dict
28
35
 
29
36
  # filter layers to load
30
37
  if self.layers != 'all':
@@ -1,2 +1 @@
1
1
  from .pyramid_noise import PyramidNoiseSampler
2
- from .zero_terminal import ZeroTerminalSampler
@@ -0,0 +1,27 @@
1
+ from .base import Sampler
2
+
3
+ class VPSampler(Sampler):
4
+ # closed-form: \alpha(t)^2 + \sigma(t)^2 = 1
5
+ def velocity_to_eps(self, v_pred, x_t, t):
6
+ alpha = self.sigma_scheduler.alpha(t)
7
+ sigma = self.sigma_scheduler.sigma(t)
8
+ return alpha*v_pred+sigma*x_t
9
+
10
+ def eps_to_velocity(self, eps, x_t, t, x_0=None):
11
+ alpha = self.sigma_scheduler.alpha(t)
12
+ sigma = self.sigma_scheduler.sigma(t)
13
+ if x_0 is None:
14
+ x_0 = self.eps_to_x0(eps, x_t, t)
15
+ return alpha*eps-sigma*x_0
16
+
17
+ def velocity_to_x0(self, v_pred, x_t, t):
18
+ alpha = self.sigma_scheduler.alpha(t)
19
+ sigma = self.sigma_scheduler.sigma(t)
20
+ return alpha*x_t-sigma*v_pred
21
+
22
+ def x0_to_velocity(self, x_0, x_t, t, eps=None):
23
+ alpha = self.sigma_scheduler.alpha(t)
24
+ sigma = self.sigma_scheduler.sigma(t)
25
+ if eps is None:
26
+ eps = self.x0_to_eps(x_0, x_t, t)
27
+ return alpha*eps-sigma*x_0
@@ -0,0 +1,4 @@
1
+ from .sigma_scheduler import *
2
+ from .base import BaseSampler, Sampler
3
+ from .VP import VPSampler
4
+ from .diffusers import DiffusersSampler
@@ -0,0 +1,134 @@
1
+ from typing import Tuple
2
+
3
+ import torch
4
+
5
+ from .sigma_scheduler import SigmaScheduler
6
+
7
+ try:
8
+ from diffusers.utils import randn_tensor
9
+ except:
10
+ # new version of diffusers
11
+ from diffusers.utils.torch_utils import randn_tensor
12
+
13
+ class BaseSampler:
14
+ def __init__(self, sigma_scheduler: SigmaScheduler, pred_type='eps', target_type='eps', generator: torch.Generator = None):
15
+ '''
16
+ Some losses can only be calculated in a specific space. Such as SSIM in x0 space.
17
+ The model pred need convert to target space.
18
+
19
+ :param pred_type: ['x0', 'eps', 'velocity', ..., None] The output space of the model
20
+ :param target_type: ['x0', 'eps', 'velocity', ..., None] The space to calculate the loss
21
+ '''
22
+
23
+ self.sigma_scheduler = sigma_scheduler
24
+ self.generator = generator
25
+ self.pred_type = pred_type
26
+ self.target_type = target_type
27
+
28
+ def get_timesteps(self, N_steps, device='cuda'):
29
+ times = torch.linspace(0., 1., N_steps, device=device)
30
+ return self.sigma_scheduler.scale_t(times)
31
+
32
+ def make_nosie(self, shape, device='cuda', dtype=torch.float32):
33
+ return randn_tensor(shape, generator=self.generator, device=device, dtype=dtype)
34
+
35
+ def init_noise(self, shape, device='cuda', dtype=torch.float32):
36
+ sigma = self.sigma_scheduler.sigma_end
37
+ return self.make_nosie(shape, device, dtype)*sigma
38
+
39
+ def add_noise(self, x, t) -> Tuple[torch.Tensor, torch.Tensor]:
40
+ noise = self.make_nosie(x.shape, device=x.device)
41
+ alpha = self.sigma_scheduler.alpha(t).view(-1, 1, 1, 1).to(x.device)
42
+ sigma = self.sigma_scheduler.sigma(t).view(-1, 1, 1, 1).to(x.device)
43
+ noisy_x = alpha*x+sigma*noise
44
+ return noisy_x.to(dtype=x.dtype), noise.to(dtype=x.dtype)
45
+
46
+ def add_noise_rand_t(self, x):
47
+ bs = x.shape[0]
48
+ # timesteps: [0, 1]
49
+ timesteps = self.sigma_scheduler.sample(shape=(bs,))
50
+ timesteps = timesteps.to(x.device)
51
+ noisy_x, noise = self.add_noise(x, timesteps)
52
+
53
+ # Sample a random timestep for each image
54
+ return noisy_x, noise, timesteps
55
+
56
+ def denoise(self, x, sigma, eps=None, generator=None):
57
+ raise NotImplementedError
58
+
59
+ def get_target(self, x0, x_t, t, eps=None, target_type=None):
60
+ raise x0
61
+
62
+ def pred_for_target(self, pred, x_t, t, eps=None, target_type=None):
63
+ return self.sigma_scheduler.c_skip(t)*x_t+self.sigma_scheduler.c_out(t)*pred
64
+
65
+ class Sampler(BaseSampler):
66
+ '''
67
+ Some losses can only be calculated in a specific space. Such as SSIM in x0 space.
68
+ The model pred need convert to target space.
69
+
70
+ :param pred_type: ['x0', 'eps', 'velocity', ..., None] The output space of the model
71
+ :param target_type: ['x0', 'eps', 'velocity', ..., None] The space to calculate the loss
72
+ '''
73
+
74
+ def get_target(self, x_0, x_t, t, eps=None, target_type=None):
75
+ '''
76
+ target_type can be specified by the loss. If not specified use self.target_type as default.
77
+ '''
78
+ target_type = target_type or self.target_type
79
+ if target_type == 'x0':
80
+ raise x_0
81
+ elif target_type == 'eps':
82
+ return eps if eps is not None else self.x0_to_eps(eps, x_t, t)
83
+ elif target_type == 'velocity':
84
+ return self.x0_to_velocity(x_0, x_t, t, eps)
85
+ else:
86
+ return (x_0-self.sigma_scheduler.c_skip(t)*x_t)/self.sigma_scheduler.c_out(t)
87
+
88
+ def pred_for_target(self, pred, x_t, t, eps=None, target_type=None):
89
+ '''
90
+ target_type can be specified by the loss. If not specified use self.target_type as default.
91
+ '''
92
+ target_type = target_type or self.target_type
93
+ if self.pred_type == target_type:
94
+ return pred
95
+ else:
96
+ cvt_func = getattr(self, f'{self.pred_type}_to_{target_type}', None)
97
+ if cvt_func is None:
98
+ if target_type == 'x0':
99
+ return self.sigma_scheduler.c_skip(t)*x_t+self.sigma_scheduler.c_out(t)*pred
100
+ else:
101
+ raise ValueError(f'pred_type "{self.pred_type}" can not be convert for target_type "{target_type}"')
102
+ else:
103
+ return cvt_func(pred, x_t, t)
104
+
105
+ # convert targets
106
+ def x0_to_eps(self, x_0, x_t, t):
107
+ return (x_t-self.sigma_scheduler.alpha(t)*x_0)/self.sigma_scheduler.sigma(t)
108
+
109
+ def x0_to_velocity(self, x_0, x_t, t, eps=None):
110
+ d_alpha, d_sigma = self.sigma_scheduler.velocity(t)
111
+ if eps is None:
112
+ eps = self.x0_to_eps(x_0, x_t, t)
113
+ return d_alpha*x_0+d_sigma*eps
114
+
115
+ def eps_to_x0(self, eps, x_t, t):
116
+ return (x_t-self.sigma_scheduler.sigma(t)*eps)/self.sigma_scheduler.alpha(t)
117
+
118
+ def eps_to_velocity(self, eps, x_t, t, x_0=None):
119
+ d_alpha, d_sigma = self.sigma_scheduler.velocity(t)
120
+ if x_0 is None:
121
+ x_0 = self.eps_to_x0(eps, x_t, t)
122
+ return d_alpha*x_0+d_sigma*eps
123
+
124
+ def velocity_to_eps(self, v_pred, x_t, t):
125
+ alpha = self.sigma_scheduler.alpha(t)
126
+ sigma = self.sigma_scheduler.sigma(t)
127
+ d_alpha, d_sigma = self.sigma_scheduler.velocity(t)
128
+ return (alpha*v_pred-d_alpha*x_t)/(d_sigma*alpha-d_alpha*sigma)
129
+
130
+ def velocity_to_x0(self, v_pred, x_t, t):
131
+ alpha = self.sigma_scheduler.alpha(t)
132
+ sigma = self.sigma_scheduler.sigma(t)
133
+ d_alpha, d_sigma = self.sigma_scheduler.velocity(t)
134
+ return (sigma*v_pred-d_sigma*x_t)/(d_alpha*sigma-d_sigma*alpha)
@@ -18,31 +18,24 @@ class DiffusersSampler(BaseSampler):
18
18
  self.scheduler = scheduler
19
19
  self.eta = eta
20
20
 
21
- def c_in(self, sigma):
22
- one = torch.ones_like(sigma)
21
+ self.sigma_scheduler.c_in = self.c_in
22
+
23
+ def c_in(self, t):
24
+ one = torch.ones_like(t)
23
25
  if hasattr(self.scheduler, '_step_index'):
24
26
  self.scheduler._step_index = None
25
- return self.scheduler.scale_model_input(one, sigma)
26
-
27
- def c_out(self, sigma):
28
- return -sigma
29
-
30
- def c_skip(self, sigma):
31
- if self.c_in(sigma) == 1.: # DDPM model
32
- return (sigma**2+1).sqrt() # 1/sqrt(alpha_)
33
- else: # EDM model
34
- return 1.
27
+ return self.scheduler.scale_model_input(one, t)
35
28
 
36
29
  def get_timesteps(self, N_steps, device='cuda'):
37
30
  self.scheduler.set_timesteps(N_steps, device=device)
38
- return self.scheduler.timesteps
31
+ return self.scheduler.timesteps / self.sigma_scheduler.num_timesteps # Normalize timesteps to [0, 1]
39
32
 
40
33
  def init_noise(self, shape, device='cuda', dtype=torch.float32):
41
34
  return randn_tensor(shape, generator=self.generator, device=device, dtype=dtype)*self.scheduler.init_noise_sigma
42
35
 
43
- def add_noise(self, x, sigma):
36
+ def add_noise(self, x, t):
44
37
  noise = randn_tensor(x.shape, generator=self.generator, device=x.device, dtype=x.dtype)
45
- return self.scheduler.add_noise(x, noise, sigma), noise
38
+ return self.scheduler.add_noise(x, noise, t), noise
46
39
 
47
40
  def prepare_extra_step_kwargs(self, scheduler, generator, eta):
48
41
  # prepare extra kwargs for the scheduler step, since not all schedulers have the same signature
@@ -61,6 +54,7 @@ class DiffusersSampler(BaseSampler):
61
54
  extra_step_kwargs["generator"] = generator
62
55
  return extra_step_kwargs
63
56
 
64
- def denoise(self, x_t, sigma, eps=None, generator=None):
57
+ def denoise(self, x_t, t, eps=None, generator=None):
58
+ t_in = self.sigma_scheduler.c_noise(t)
65
59
  extra_step_kwargs = self.prepare_extra_step_kwargs(self.scheduler, generator, self.eta)
66
- return self.scheduler.step(eps, sigma, x_t, **extra_step_kwargs).prev_sample
60
+ return self.scheduler.step(eps, t_in, x_t, **extra_step_kwargs).prev_sample
@@ -0,0 +1,5 @@
1
+ from .base import SigmaScheduler
2
+ from .ddpm import DDPMDiscreteSigmaScheduler, DDPMContinuousSigmaScheduler, TimeSigmaScheduler
3
+ from .edm import EDMSigmaScheduler, EDMTimeRescaleScheduler
4
+ from .flow import FlowSigmaScheduler
5
+ from .zero_terminal import ZeroTerminalScheduler
@@ -0,0 +1,89 @@
1
+ from typing import Union, Tuple
2
+
3
+ import torch
4
+
5
+ class SigmaScheduler:
6
+ def scale_t(self, t):
7
+ return t
8
+
9
+ def sigma(self, t: Union[float, torch.Tensor]) -> torch.Tensor:
10
+ '''
11
+ x(t) = \alpha(t)*x(0) + \sigma(t)*eps
12
+ :param t: 0-1, rate of time step
13
+ '''
14
+ raise NotImplementedError
15
+
16
+ def alpha(self, t: Union[float, torch.Tensor]) -> torch.Tensor:
17
+ '''
18
+ x(t) = \alpha(t)*x(0) + \sigma(t)*eps
19
+ :param t: 0-1, rate of time step
20
+ '''
21
+ raise NotImplementedError
22
+
23
+ def velocity(self, t: Union[float, torch.Tensor], dt=1e-8, normlize=True) -> Tuple[torch.Tensor, torch.Tensor]:
24
+ '''
25
+ v(t) = dx(t)/dt = d\alpha(t)/dt * x(0) + d\sigma(t)/dt *eps
26
+ :param t: 0-1, rate of time step
27
+ :return: d\alpha(t)/dt, d\sigma(t)/dt
28
+ '''
29
+ d_alpha = (self.alpha(t+dt)-self.alpha(t))/dt
30
+ d_sigma = (self.sigma(t+dt)-self.sigma(t))/dt
31
+ if normlize:
32
+ norm = torch.sqrt(d_alpha**2+d_sigma**2)
33
+ return d_alpha/norm, d_sigma/norm
34
+ else:
35
+ return d_alpha, d_sigma
36
+
37
+ @property
38
+ def sigma_start(self):
39
+ return self.sigma(0)
40
+
41
+ @property
42
+ def sigma_end(self):
43
+ return self.sigma(1)
44
+
45
+ @property
46
+ def alpha_start(self):
47
+ return self.alpha(0)
48
+
49
+ @property
50
+ def alpha_end(self):
51
+ return self.alpha(1)
52
+
53
+ def alpha_to_sigma(self, alpha):
54
+ raise NotImplementedError
55
+
56
+ def sigma_to_alpha(self, sigma):
57
+ raise NotImplementedError
58
+
59
+ def c_in(self, t: Union[float, torch.Tensor]):
60
+ if isinstance(t, float):
61
+ return 1.
62
+ else:
63
+ return torch.ones_like(t, dtype=torch.float32)
64
+
65
+ def c_skip(self, t: Union[float, torch.Tensor]):
66
+ '''
67
+ \hat{x}(0) = c_skip*x(t) + c_out*f(x(t))
68
+ :param t: 0-1, rate of time step
69
+ '''
70
+ return 1./self.alpha(t)
71
+
72
+ def c_out(self, t: Union[float, torch.Tensor]):
73
+ '''
74
+ \hat{x}(0) = c_skip*x(t) + c_out*f(x(t))
75
+ :param t: 0-1, rate of time step
76
+ '''
77
+ return -self.sigma(t)/self.alpha(t)
78
+
79
+ def c_noise(self, t: Union[float, torch.Tensor]):
80
+ return t
81
+
82
+ def sample(self, min_t=0.0, max_t=1.0, shape=(1,)) -> torch.Tensor:
83
+ if isinstance(min_t, float):
84
+ min_t = torch.full(shape, min_t)
85
+ if isinstance(max_t, float):
86
+ max_t = torch.full(shape, max_t)
87
+
88
+ t = torch.lerp(min_t, max_t, torch.rand_like(min_t))
89
+ return t