comfy-diffusion 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- comfy_diffusion/__init__.py +30 -0
- comfy_diffusion/_runtime.py +26 -0
- comfy_diffusion/audio.py +168 -0
- comfy_diffusion/conditioning.py +25 -0
- comfy_diffusion/lora.py +34 -0
- comfy_diffusion/models.py +245 -0
- comfy_diffusion/runtime.py +86 -0
- comfy_diffusion/sampling.py +383 -0
- comfy_diffusion/vae.py +390 -0
- comfy_diffusion-0.1.0.dist-info/METADATA +183 -0
- comfy_diffusion-0.1.0.dist-info/RECORD +13 -0
- comfy_diffusion-0.1.0.dist-info/WHEEL +5 -0
- comfy_diffusion-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
"""Sampling helpers that wrap ComfyUI's KSampler behavior."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _get_common_ksampler() -> Any:
|
|
9
|
+
"""Resolve ComfyUI sampling entrypoint at call time."""
|
|
10
|
+
from ._runtime import ensure_comfyui_on_path
|
|
11
|
+
|
|
12
|
+
ensure_comfyui_on_path()
|
|
13
|
+
import nodes
|
|
14
|
+
|
|
15
|
+
return nodes.common_ksampler
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _get_basic_guider_type() -> Any:
|
|
19
|
+
"""Resolve ComfyUI BasicGuider implementation at call time."""
|
|
20
|
+
from ._runtime import ensure_comfyui_on_path
|
|
21
|
+
|
|
22
|
+
ensure_comfyui_on_path()
|
|
23
|
+
from comfy_extras.nodes_custom_sampler import Guider_Basic
|
|
24
|
+
|
|
25
|
+
return Guider_Basic
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _get_cfg_guider_type() -> Any:
|
|
29
|
+
"""Resolve ComfyUI CFGGuider implementation at call time."""
|
|
30
|
+
from ._runtime import ensure_comfyui_on_path
|
|
31
|
+
|
|
32
|
+
ensure_comfyui_on_path()
|
|
33
|
+
from comfy.samplers import CFGGuider
|
|
34
|
+
|
|
35
|
+
return CFGGuider
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _get_random_noise_type() -> Any:
|
|
39
|
+
"""Resolve ComfyUI RandomNoise implementation at call time."""
|
|
40
|
+
from ._runtime import ensure_comfyui_on_path
|
|
41
|
+
|
|
42
|
+
ensure_comfyui_on_path()
|
|
43
|
+
from comfy_extras.nodes_custom_sampler import RandomNoise
|
|
44
|
+
|
|
45
|
+
return RandomNoise
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _get_disable_noise_type() -> Any:
|
|
49
|
+
"""Resolve ComfyUI DisableNoise implementation at call time."""
|
|
50
|
+
from ._runtime import ensure_comfyui_on_path
|
|
51
|
+
|
|
52
|
+
ensure_comfyui_on_path()
|
|
53
|
+
from comfy_extras.nodes_custom_sampler import DisableNoise
|
|
54
|
+
|
|
55
|
+
return DisableNoise
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _get_basic_scheduler_type() -> Any:
|
|
59
|
+
"""Resolve ComfyUI BasicScheduler implementation at call time."""
|
|
60
|
+
from ._runtime import ensure_comfyui_on_path
|
|
61
|
+
|
|
62
|
+
ensure_comfyui_on_path()
|
|
63
|
+
from comfy_extras.nodes_custom_sampler import BasicScheduler
|
|
64
|
+
|
|
65
|
+
return BasicScheduler
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _get_karras_scheduler_type() -> Any:
|
|
69
|
+
"""Resolve ComfyUI KarrasScheduler implementation at call time."""
|
|
70
|
+
from ._runtime import ensure_comfyui_on_path
|
|
71
|
+
|
|
72
|
+
ensure_comfyui_on_path()
|
|
73
|
+
from comfy_extras.nodes_custom_sampler import KarrasScheduler
|
|
74
|
+
|
|
75
|
+
return KarrasScheduler
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _get_ays_scheduler_type() -> Any:
|
|
79
|
+
"""Resolve ComfyUI AlignYourStepsScheduler implementation at call time."""
|
|
80
|
+
from ._runtime import ensure_comfyui_on_path
|
|
81
|
+
|
|
82
|
+
ensure_comfyui_on_path()
|
|
83
|
+
from comfy_extras.nodes_align_your_steps import AlignYourStepsScheduler
|
|
84
|
+
|
|
85
|
+
return AlignYourStepsScheduler
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _get_flux2_scheduler_type() -> Any:
|
|
89
|
+
"""Resolve ComfyUI Flux2Scheduler implementation at call time."""
|
|
90
|
+
from ._runtime import ensure_comfyui_on_path
|
|
91
|
+
|
|
92
|
+
ensure_comfyui_on_path()
|
|
93
|
+
from comfy_extras.nodes_flux import Flux2Scheduler
|
|
94
|
+
|
|
95
|
+
return Flux2Scheduler
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _get_ltxv_scheduler_type() -> Any:
|
|
99
|
+
"""Resolve ComfyUI LTXVScheduler implementation at call time."""
|
|
100
|
+
from ._runtime import ensure_comfyui_on_path
|
|
101
|
+
|
|
102
|
+
ensure_comfyui_on_path()
|
|
103
|
+
from comfy_extras.nodes_lt import LTXVScheduler
|
|
104
|
+
|
|
105
|
+
return LTXVScheduler
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _get_sampler_custom_advanced_type() -> Any:
|
|
109
|
+
"""Resolve ComfyUI SamplerCustomAdvanced implementation at call time."""
|
|
110
|
+
from ._runtime import ensure_comfyui_on_path
|
|
111
|
+
|
|
112
|
+
ensure_comfyui_on_path()
|
|
113
|
+
from comfy_extras.nodes_custom_sampler import SamplerCustomAdvanced
|
|
114
|
+
|
|
115
|
+
return SamplerCustomAdvanced
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _get_split_sigmas_type() -> Any:
|
|
119
|
+
"""Resolve ComfyUI SplitSigmas implementation at call time."""
|
|
120
|
+
from ._runtime import ensure_comfyui_on_path
|
|
121
|
+
|
|
122
|
+
ensure_comfyui_on_path()
|
|
123
|
+
from comfy_extras.nodes_custom_sampler import SplitSigmas
|
|
124
|
+
|
|
125
|
+
return SplitSigmas
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _get_split_sigmas_denoise_type() -> Any:
|
|
129
|
+
"""Resolve ComfyUI SplitSigmasDenoise implementation at call time."""
|
|
130
|
+
from ._runtime import ensure_comfyui_on_path
|
|
131
|
+
|
|
132
|
+
ensure_comfyui_on_path()
|
|
133
|
+
from comfy_extras.nodes_custom_sampler import SplitSigmasDenoise
|
|
134
|
+
|
|
135
|
+
return SplitSigmasDenoise
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _get_ksampler_select_type() -> Any:
|
|
139
|
+
"""Resolve ComfyUI KSamplerSelect implementation at call time."""
|
|
140
|
+
from ._runtime import ensure_comfyui_on_path
|
|
141
|
+
|
|
142
|
+
ensure_comfyui_on_path()
|
|
143
|
+
from comfy_extras.nodes_custom_sampler import KSamplerSelect
|
|
144
|
+
|
|
145
|
+
return KSamplerSelect
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def _unwrap_node_output(output: Any) -> Any:
|
|
149
|
+
"""Return the first node output value from ComfyUI V3 or tuple-style APIs."""
|
|
150
|
+
result = getattr(output, "result", output)
|
|
151
|
+
return result[0]
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def basic_guider(model: Any, conditioning: Any) -> Any:
|
|
155
|
+
"""Create a BasicGuider compatible with ``sample_custom()``."""
|
|
156
|
+
guider_type = _get_basic_guider_type()
|
|
157
|
+
guider = guider_type(model)
|
|
158
|
+
guider.set_conds(conditioning)
|
|
159
|
+
return guider
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def cfg_guider(model: Any, positive: Any, negative: Any, cfg: Any) -> Any:
|
|
163
|
+
"""Create a CFGGuider compatible with ``sample_custom()``."""
|
|
164
|
+
guider_type = _get_cfg_guider_type()
|
|
165
|
+
guider = guider_type(model)
|
|
166
|
+
guider.set_conds(positive, negative)
|
|
167
|
+
guider.set_cfg(cfg)
|
|
168
|
+
return guider
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def random_noise(noise_seed: int) -> Any:
|
|
172
|
+
"""Create a RandomNoise object compatible with ``sample_custom()``."""
|
|
173
|
+
random_noise_type = _get_random_noise_type()
|
|
174
|
+
return random_noise_type(noise_seed)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def disable_noise() -> Any:
|
|
178
|
+
"""Create a DisableNoise object compatible with ``sample_custom()``."""
|
|
179
|
+
disable_noise_type = _get_disable_noise_type()
|
|
180
|
+
return disable_noise_type()
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def basic_scheduler(
|
|
184
|
+
model: Any, scheduler_name: str, steps: int, denoise: float = 1.0
|
|
185
|
+
) -> Any:
|
|
186
|
+
"""Create SIGMAS using ComfyUI BasicScheduler."""
|
|
187
|
+
basic_scheduler_type = _get_basic_scheduler_type()
|
|
188
|
+
return _unwrap_node_output(
|
|
189
|
+
basic_scheduler_type.execute(model, scheduler_name, steps, denoise)
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def karras_scheduler(
|
|
194
|
+
steps: int, sigma_max: float, sigma_min: float, rho: float = 7.0
|
|
195
|
+
) -> Any:
|
|
196
|
+
"""Create SIGMAS using ComfyUI KarrasScheduler."""
|
|
197
|
+
karras_scheduler_type = _get_karras_scheduler_type()
|
|
198
|
+
return _unwrap_node_output(
|
|
199
|
+
karras_scheduler_type.execute(steps, sigma_max, sigma_min, rho)
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def ays_scheduler(model_type: str, steps: int, denoise: float = 1.0) -> Any:
|
|
204
|
+
"""Create SIGMAS using ComfyUI AlignYourStepsScheduler."""
|
|
205
|
+
allowed_model_types = {"SD1", "SDXL", "SVD"}
|
|
206
|
+
if model_type not in allowed_model_types:
|
|
207
|
+
raise ValueError(
|
|
208
|
+
f"model_type must be one of {sorted(allowed_model_types)!r}; got {model_type!r}"
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
ays_scheduler_type = _get_ays_scheduler_type()
|
|
212
|
+
return _unwrap_node_output(ays_scheduler_type.execute(model_type, steps, denoise))
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def flux2_scheduler(steps: int, width: int, height: int) -> Any:
|
|
216
|
+
"""Create SIGMAS using ComfyUI Flux2Scheduler."""
|
|
217
|
+
flux2_scheduler_type = _get_flux2_scheduler_type()
|
|
218
|
+
return _unwrap_node_output(flux2_scheduler_type.execute(steps, width, height))
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def ltxv_scheduler(
|
|
222
|
+
steps: int,
|
|
223
|
+
max_shift: float,
|
|
224
|
+
base_shift: float,
|
|
225
|
+
*,
|
|
226
|
+
stretch: bool = True,
|
|
227
|
+
terminal: float = 0.1,
|
|
228
|
+
latent: Any = None,
|
|
229
|
+
) -> Any:
|
|
230
|
+
"""Create SIGMAS using ComfyUI LTXVScheduler."""
|
|
231
|
+
ltxv_scheduler_type = _get_ltxv_scheduler_type()
|
|
232
|
+
return _unwrap_node_output(
|
|
233
|
+
ltxv_scheduler_type.execute(
|
|
234
|
+
steps,
|
|
235
|
+
max_shift,
|
|
236
|
+
base_shift,
|
|
237
|
+
stretch,
|
|
238
|
+
terminal,
|
|
239
|
+
latent,
|
|
240
|
+
)
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def split_sigmas(sigmas: Any, step: int) -> tuple[Any, Any]:
|
|
245
|
+
"""Split SIGMAS by step index using ComfyUI SplitSigmas."""
|
|
246
|
+
split_sigmas_type = _get_split_sigmas_type()
|
|
247
|
+
output = split_sigmas_type.execute(sigmas, step)
|
|
248
|
+
result = getattr(output, "result", output)
|
|
249
|
+
return result[0], result[1]
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def split_sigmas_denoise(sigmas: Any, denoise: float) -> tuple[Any, Any]:
|
|
253
|
+
"""Split SIGMAS by denoise percent using ComfyUI SplitSigmasDenoise."""
|
|
254
|
+
split_sigmas_denoise_type = _get_split_sigmas_denoise_type()
|
|
255
|
+
output = split_sigmas_denoise_type.execute(sigmas, denoise)
|
|
256
|
+
result = getattr(output, "result", output)
|
|
257
|
+
return result[0], result[1]
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def get_sampler(sampler_name: str) -> Any:
|
|
261
|
+
"""Build a SAMPLER object using ComfyUI KSamplerSelect."""
|
|
262
|
+
ksampler_select_type = _get_ksampler_select_type()
|
|
263
|
+
return _unwrap_node_output(ksampler_select_type.execute(sampler_name))
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def sample(
|
|
267
|
+
model: Any,
|
|
268
|
+
positive: Any,
|
|
269
|
+
negative: Any,
|
|
270
|
+
latent: Any,
|
|
271
|
+
steps: Any,
|
|
272
|
+
cfg: Any,
|
|
273
|
+
sampler_name: str,
|
|
274
|
+
scheduler: str,
|
|
275
|
+
seed: int,
|
|
276
|
+
*,
|
|
277
|
+
denoise: float = 1.0,
|
|
278
|
+
) -> Any:
|
|
279
|
+
"""Run denoising through ComfyUI and return the denoised LATENT object.
|
|
280
|
+
|
|
281
|
+
The `latent` input follows ComfyUI's `common_ksampler` contract: a LATENT dict
|
|
282
|
+
containing `"samples"` and optional metadata keys.
|
|
283
|
+
"""
|
|
284
|
+
common_ksampler = _get_common_ksampler()
|
|
285
|
+
|
|
286
|
+
return common_ksampler(
|
|
287
|
+
model,
|
|
288
|
+
seed,
|
|
289
|
+
steps,
|
|
290
|
+
cfg,
|
|
291
|
+
sampler_name,
|
|
292
|
+
scheduler,
|
|
293
|
+
positive,
|
|
294
|
+
negative,
|
|
295
|
+
latent,
|
|
296
|
+
denoise=denoise,
|
|
297
|
+
)[0]
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def sample_advanced(
|
|
301
|
+
model: Any,
|
|
302
|
+
positive: Any,
|
|
303
|
+
negative: Any,
|
|
304
|
+
latent: Any,
|
|
305
|
+
steps: Any,
|
|
306
|
+
cfg: Any,
|
|
307
|
+
sampler_name: str,
|
|
308
|
+
scheduler: str,
|
|
309
|
+
noise_seed: int,
|
|
310
|
+
*,
|
|
311
|
+
add_noise: bool = True,
|
|
312
|
+
return_with_leftover_noise: bool = False,
|
|
313
|
+
denoise: float = 1.0,
|
|
314
|
+
start_at_step: int = 0,
|
|
315
|
+
end_at_step: int = 10000,
|
|
316
|
+
) -> Any:
|
|
317
|
+
"""Run advanced denoising with explicit noise and final-step control.
|
|
318
|
+
|
|
319
|
+
Mirrors ComfyUI `KSamplerAdvanced` semantics by mapping:
|
|
320
|
+
- `add_noise=False` -> `disable_noise=True`
|
|
321
|
+
- `return_with_leftover_noise=True` -> `force_full_denoise=False`
|
|
322
|
+
"""
|
|
323
|
+
common_ksampler = _get_common_ksampler()
|
|
324
|
+
|
|
325
|
+
return common_ksampler(
|
|
326
|
+
model,
|
|
327
|
+
noise_seed,
|
|
328
|
+
steps,
|
|
329
|
+
cfg,
|
|
330
|
+
sampler_name,
|
|
331
|
+
scheduler,
|
|
332
|
+
positive,
|
|
333
|
+
negative,
|
|
334
|
+
latent,
|
|
335
|
+
denoise=denoise,
|
|
336
|
+
disable_noise=not add_noise,
|
|
337
|
+
start_step=start_at_step,
|
|
338
|
+
last_step=end_at_step,
|
|
339
|
+
force_full_denoise=not return_with_leftover_noise,
|
|
340
|
+
)[0]
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def sample_custom(
|
|
344
|
+
noise: Any,
|
|
345
|
+
guider: Any,
|
|
346
|
+
sampler: Any,
|
|
347
|
+
sigmas: Any,
|
|
348
|
+
latent_image: Any,
|
|
349
|
+
) -> tuple[Any, Any]:
|
|
350
|
+
"""Run custom sampling with explicit noise/guider/sampler/sigmas inputs.
|
|
351
|
+
|
|
352
|
+
The `model` is not a direct argument here: it is already embedded in the
|
|
353
|
+
provided `guider` object (for example from `basic_guider()` or `cfg_guider()`).
|
|
354
|
+
"""
|
|
355
|
+
sampler_custom_advanced_type = _get_sampler_custom_advanced_type()
|
|
356
|
+
output = sampler_custom_advanced_type.execute(
|
|
357
|
+
noise,
|
|
358
|
+
guider,
|
|
359
|
+
sampler,
|
|
360
|
+
sigmas,
|
|
361
|
+
latent_image,
|
|
362
|
+
)
|
|
363
|
+
result = getattr(output, "result", output)
|
|
364
|
+
return result[0], result[1]
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
__all__ = [
|
|
368
|
+
"sample",
|
|
369
|
+
"sample_advanced",
|
|
370
|
+
"sample_custom",
|
|
371
|
+
"basic_guider",
|
|
372
|
+
"cfg_guider",
|
|
373
|
+
"random_noise",
|
|
374
|
+
"disable_noise",
|
|
375
|
+
"basic_scheduler",
|
|
376
|
+
"karras_scheduler",
|
|
377
|
+
"ays_scheduler",
|
|
378
|
+
"flux2_scheduler",
|
|
379
|
+
"ltxv_scheduler",
|
|
380
|
+
"split_sigmas",
|
|
381
|
+
"split_sigmas_denoise",
|
|
382
|
+
"get_sampler",
|
|
383
|
+
]
|