Upload 3 files
Browse files- sd_agga_schedulers.py +67 -0
- sd_samplers_pseudo_hires.py +1518 -0
- sd_samplers_pseudo_hires_loader.py +81 -0
sd_agga_schedulers.py
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import modules.sd_schedulers as sd_schedulers
|
| 2 |
+
import modules.shared as shared
|
| 3 |
+
from modules.sd_samplers_pseudo_hires import (
|
| 4 |
+
get_sigmas_agga_dmd,
|
| 5 |
+
get_sigmas_log_linear,
|
| 6 |
+
get_sigmas_dynamic_rho,
|
| 7 |
+
get_sigmas_pseudo_native,
|
| 8 |
+
get_sigmas_agga_smart,
|
| 9 |
+
get_sigmas_style_anchor,
|
| 10 |
+
get_sigmas_ultra_anchor,
|
| 11 |
+
get_sigmas_agga_ays_anchor,
|
| 12 |
+
get_sigmas_agga_double_anchor,
|
| 13 |
+
get_sigmas_agga_pixel_staircase,
|
| 14 |
+
get_sigmas_agga_pixel_staircase_v2,
|
| 15 |
+
get_sigmas_agga_lora_universal_bridge,
|
| 16 |
+
)
|
| 17 |
+
|
| 18 |
+
def register():
|
| 19 |
+
|
| 20 |
+
new_data = [
|
| 21 |
+
('agga_dmd_p', 'AGGA DMD Power',
|
| 22 |
+
lambda n, sigma_min, sigma_max, device, **k: get_sigmas_agga_dmd(n, sigma_min, sigma_max, device), 7.0),
|
| 23 |
+
|
| 24 |
+
('agga_log', 'AGGA Log-Linear',
|
| 25 |
+
lambda n, sigma_min, sigma_max, device, **k: get_sigmas_log_linear(n, sigma_min, sigma_max, device), -1),
|
| 26 |
+
|
| 27 |
+
('agga_dyn_rho', 'AGGA Dynamic Rho',
|
| 28 |
+
lambda n, sigma_min, sigma_max, device, **k: get_sigmas_dynamic_rho(n, sigma_min, sigma_max, device), -1),
|
| 29 |
+
|
| 30 |
+
('agga_pseudo', 'AGGA Pseudo-Native',
|
| 31 |
+
lambda n, sigma_min, sigma_max, device, **k: get_sigmas_pseudo_native(n, sigma_min, sigma_max, device), -1),
|
| 32 |
+
|
| 33 |
+
('agga_smart', 'AGGA Smart-Automatic',
|
| 34 |
+
lambda n, sigma_min, sigma_max, device, **k: get_sigmas_agga_smart(n, sigma_min, sigma_max, device), -1),
|
| 35 |
+
|
| 36 |
+
('agga_ays_anchor', 'AGGA AYS-Anchor',
|
| 37 |
+
lambda n, sigma_min, sigma_max, device, **k: get_sigmas_agga_ays_anchor(n, sigma_min, sigma_max, device), -1),
|
| 38 |
+
|
| 39 |
+
('agga_style_anchor', 'AGGA Style-Anchor',
|
| 40 |
+
lambda n, sigma_min, sigma_max, device, **k: get_sigmas_style_anchor(n, sigma_min, sigma_max, device), -1),
|
| 41 |
+
|
| 42 |
+
('agga_style_Ultra', 'AGGA Style-Ultra',
|
| 43 |
+
lambda n, sigma_min, sigma_max, device, **k: get_sigmas_ultra_anchor(n, sigma_min, sigma_max, device), -1),
|
| 44 |
+
|
| 45 |
+
('agga_double_anchor', 'AGGA Double-Anchor',
|
| 46 |
+
lambda n, sigma_min, sigma_max, device, **k: get_sigmas_agga_double_anchor(n, sigma_min, sigma_max, device), -1),
|
| 47 |
+
|
| 48 |
+
('agga_LUB', 'AGGA UNIVERSAL BRIDGE',
|
| 49 |
+
lambda n, sigma_min, sigma_max, device, **k: get_sigmas_agga_lora_universal_bridge(n, sigma_min, sigma_max, device), -1),
|
| 50 |
+
|
| 51 |
+
('agga_pixel', 'AGGA Pixel Staircase',
|
| 52 |
+
lambda n, sigma_min, sigma_max, device, **k: get_sigmas_agga_pixel_staircase(n, sigma_min, sigma_max, device), -1),
|
| 53 |
+
|
| 54 |
+
('agga_pixel_v2', 'AGGA Pixel Staircase V2',
|
| 55 |
+
lambda n, sigma_min, sigma_max, device, **k: get_sigmas_agga_pixel_staircase_v2(n, sigma_min, sigma_max, device), -1),
|
| 56 |
+
]
|
| 57 |
+
|
| 58 |
+
for name, label, func, rho in new_data:
|
| 59 |
+
if any(x.name == name for x in sd_schedulers.schedulers): continue
|
| 60 |
+
|
| 61 |
+
sched = sd_schedulers.Scheduler(name, label, func, default_rho=rho)
|
| 62 |
+
sd_schedulers.schedulers.append(sched)
|
| 63 |
+
sd_schedulers.schedulers_map.update({sched.name: sched, sched.label: sched})
|
| 64 |
+
|
| 65 |
+
print(f"[AGGA Module] {len(new_data)} Schedulers registered successfully.")
|
| 66 |
+
|
| 67 |
+
register()
|
sd_samplers_pseudo_hires.py
ADDED
|
@@ -0,0 +1,1518 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
from modules import shared
|
| 3 |
+
import torch.nn.functional as F
|
| 4 |
+
import inspect
|
| 5 |
+
|
| 6 |
+
# =====================================================
|
| 7 |
+
# SIGMAS BASE (COMPARTIDOS)
|
| 8 |
+
# =====================================================
|
| 9 |
+
|
| 10 |
+
def pseudo_hires_sigmas(n, sigma_min, sigma_max, device):
|
| 11 |
+
ramp = torch.linspace(0, 1, n, device=device)
|
| 12 |
+
|
| 13 |
+
sigmas = sigma_max * torch.exp(-ramp * 4.5)
|
| 14 |
+
|
| 15 |
+
p0 = int(n * 0.45)
|
| 16 |
+
p1 = int(n * 0.80)
|
| 17 |
+
|
| 18 |
+
sigmas[p0:p1] = sigmas[p0]
|
| 19 |
+
sigmas[p1:] = torch.linspace(sigmas[p1], sigma_min, n - p1, device=device)
|
| 20 |
+
|
| 21 |
+
sigmas[-2] = sigmas[-1]
|
| 22 |
+
return sigmas
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
# =====================================================
|
| 26 |
+
# PSEUDO-HIRES SOFT
|
| 27 |
+
# =====================================================
|
| 28 |
+
|
| 29 |
+
@torch.no_grad()
|
| 30 |
+
def sample_pseudo_hires_soft(
|
| 31 |
+
model,
|
| 32 |
+
x,
|
| 33 |
+
sigmas,
|
| 34 |
+
extra_args=None,
|
| 35 |
+
callback=None,
|
| 36 |
+
**kwargs
|
| 37 |
+
):
|
| 38 |
+
extra_args = {} if extra_args is None else extra_args
|
| 39 |
+
s_in = x.new_ones([x.shape[0]])
|
| 40 |
+
|
| 41 |
+
total_steps = len(sigmas) - 1
|
| 42 |
+
shared.state.sampling_steps = total_steps
|
| 43 |
+
|
| 44 |
+
shared.state.job_count = 1
|
| 45 |
+
shared.state.job_no = 0
|
| 46 |
+
|
| 47 |
+
for i in range(total_steps):
|
| 48 |
+
shared.state.sampling_step = i + 1
|
| 49 |
+
|
| 50 |
+
sigma = sigmas[i]
|
| 51 |
+
sigma_next = sigmas[i + 1]
|
| 52 |
+
dt = sigma_next - sigma
|
| 53 |
+
|
| 54 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 55 |
+
d = (x - denoised) / sigma
|
| 56 |
+
|
| 57 |
+
x = x + d * dt
|
| 58 |
+
|
| 59 |
+
if callback is not None:
|
| 60 |
+
callback({
|
| 61 |
+
"x": x,
|
| 62 |
+
"i": i,
|
| 63 |
+
"sigma": sigma,
|
| 64 |
+
"sampling_step": i + 1,
|
| 65 |
+
"sampling_steps": total_steps
|
| 66 |
+
})
|
| 67 |
+
|
| 68 |
+
return x
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
# =====================================================
|
| 72 |
+
# PSEUDO-HIRES SHARP
|
| 73 |
+
# =====================================================
|
| 74 |
+
|
| 75 |
+
@torch.no_grad()
|
| 76 |
+
def sample_pseudo_hires_sharp(
|
| 77 |
+
model,
|
| 78 |
+
x,
|
| 79 |
+
sigmas,
|
| 80 |
+
extra_args=None,
|
| 81 |
+
callback=None,
|
| 82 |
+
**kwargs
|
| 83 |
+
):
|
| 84 |
+
extra_args = {} if extra_args is None else extra_args
|
| 85 |
+
s_in = x.new_ones([x.shape[0]])
|
| 86 |
+
|
| 87 |
+
total_steps = len(sigmas) - 1
|
| 88 |
+
shared.state.sampling_steps = total_steps
|
| 89 |
+
|
| 90 |
+
shared.state.job_count = 1
|
| 91 |
+
shared.state.job_no = 0
|
| 92 |
+
|
| 93 |
+
for i in range(total_steps):
|
| 94 |
+
shared.state.sampling_step = i + 1
|
| 95 |
+
|
| 96 |
+
sigma = sigmas[i]
|
| 97 |
+
sigma_next = sigmas[i + 1]
|
| 98 |
+
dt = sigma_next - sigma
|
| 99 |
+
|
| 100 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 101 |
+
d = (x - denoised) / sigma
|
| 102 |
+
|
| 103 |
+
if i > total_steps * 0.65:
|
| 104 |
+
x = x + d * dt * 1.12
|
| 105 |
+
else:
|
| 106 |
+
x = x + d * dt
|
| 107 |
+
|
| 108 |
+
if callback is not None:
|
| 109 |
+
callback({
|
| 110 |
+
"x": x,
|
| 111 |
+
"i": i,
|
| 112 |
+
"sigma": sigma,
|
| 113 |
+
"sampling_step": i + 1,
|
| 114 |
+
"sampling_steps": total_steps
|
| 115 |
+
})
|
| 116 |
+
|
| 117 |
+
return x
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
# =====================================================
|
| 121 |
+
# PSEUDO-HIRES ULTRA
|
| 122 |
+
# =====================================================
|
| 123 |
+
|
| 124 |
+
@torch.no_grad()
|
| 125 |
+
def sample_pseudo_hires_ultra(
|
| 126 |
+
model,
|
| 127 |
+
x,
|
| 128 |
+
sigmas,
|
| 129 |
+
extra_args=None,
|
| 130 |
+
callback=None,
|
| 131 |
+
**kwargs
|
| 132 |
+
):
|
| 133 |
+
extra_args = {} if extra_args is None else extra_args
|
| 134 |
+
s_in = x.new_ones([x.shape[0]])
|
| 135 |
+
|
| 136 |
+
total_steps = len(sigmas) - 1
|
| 137 |
+
shared.state.sampling_steps = total_steps
|
| 138 |
+
|
| 139 |
+
shared.state.job_count = 1
|
| 140 |
+
shared.state.job_no = 0
|
| 141 |
+
|
| 142 |
+
for i in range(total_steps):
|
| 143 |
+
shared.state.sampling_step = i + 1
|
| 144 |
+
|
| 145 |
+
sigma = sigmas[i]
|
| 146 |
+
sigma_next = sigmas[i + 1]
|
| 147 |
+
dt = sigma_next - sigma
|
| 148 |
+
|
| 149 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 150 |
+
d = (x - denoised) / sigma
|
| 151 |
+
|
| 152 |
+
# ULTRA: refuerzo progresivo
|
| 153 |
+
if i > total_steps * 0.55:
|
| 154 |
+
boost = 1.18 + (i / total_steps) * 0.10
|
| 155 |
+
x = x + d * dt * boost
|
| 156 |
+
else:
|
| 157 |
+
x = x + d * dt
|
| 158 |
+
|
| 159 |
+
if callback is not None:
|
| 160 |
+
callback({
|
| 161 |
+
"x": x,
|
| 162 |
+
"i": i,
|
| 163 |
+
"sigma": sigma,
|
| 164 |
+
"sampling_step": i + 1,
|
| 165 |
+
"sampling_steps": total_steps
|
| 166 |
+
})
|
| 167 |
+
|
| 168 |
+
return x
|
| 169 |
+
|
| 170 |
+
# =====================================================
|
| 171 |
+
# DPM++ 2M PSEUDO-HIRES
|
| 172 |
+
# =====================================================
|
| 173 |
+
|
| 174 |
+
@torch.no_grad()
|
| 175 |
+
def sample_dpmpp_2m_pseudo_hires(
|
| 176 |
+
model,
|
| 177 |
+
x,
|
| 178 |
+
sigmas,
|
| 179 |
+
extra_args=None,
|
| 180 |
+
callback=None,
|
| 181 |
+
**kwargs
|
| 182 |
+
):
|
| 183 |
+
extra_args = {} if extra_args is None else extra_args
|
| 184 |
+
s_in = x.new_ones([x.shape[0]])
|
| 185 |
+
|
| 186 |
+
total_steps = len(sigmas) - 1
|
| 187 |
+
shared.state.sampling_steps = total_steps
|
| 188 |
+
|
| 189 |
+
shared.state.job_count = 1
|
| 190 |
+
shared.state.job_no = 0
|
| 191 |
+
|
| 192 |
+
old_denoised = None
|
| 193 |
+
|
| 194 |
+
for i in range(total_steps):
|
| 195 |
+
shared.state.sampling_step = i + 1
|
| 196 |
+
|
| 197 |
+
sigma = sigmas[i]
|
| 198 |
+
sigma_next = sigmas[i + 1]
|
| 199 |
+
dt = sigma_next - sigma
|
| 200 |
+
|
| 201 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 202 |
+
|
| 203 |
+
if old_denoised is None:
|
| 204 |
+
d = (x - denoised) / sigma
|
| 205 |
+
x = x + d * dt
|
| 206 |
+
else:
|
| 207 |
+
d = (x - denoised) / sigma
|
| 208 |
+
d_old = (x - old_denoised) / sigmas[max(i-1, 0)] if old_denoised is not None else d
|
| 209 |
+
|
| 210 |
+
correction = 0.5 * (d + d_old) * dt
|
| 211 |
+
x = x + correction * 1.0 # puedes ajustar el factor
|
| 212 |
+
|
| 213 |
+
# Boost progresivo (similar a Ultra, pero más suave para feeling DPM)
|
| 214 |
+
if i > total_steps * 0.60:
|
| 215 |
+
boost = 1.12 + (i / total_steps) * 0.08 # más conservador que Ultra
|
| 216 |
+
x = x + d * dt * boost
|
| 217 |
+
|
| 218 |
+
old_denoised = denoised
|
| 219 |
+
|
| 220 |
+
if callback is not None:
|
| 221 |
+
callback({
|
| 222 |
+
"x": x,
|
| 223 |
+
"i": i,
|
| 224 |
+
"sigma": sigma,
|
| 225 |
+
"sampling_step": i + 1,
|
| 226 |
+
"sampling_steps": total_steps
|
| 227 |
+
})
|
| 228 |
+
|
| 229 |
+
return x
|
| 230 |
+
|
| 231 |
+
# =====================================================
|
| 232 |
+
# AGGA SMART-COMBO V9 (Universal Fusion)
|
| 233 |
+
# =====================================================
|
| 234 |
+
@torch.no_grad()
|
| 235 |
+
def sample_agga_smart_combo(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 236 |
+
extra_args = extra_args or {}
|
| 237 |
+
s_in = x.new_ones([x.shape[0]])
|
| 238 |
+
|
| 239 |
+
total_steps = len(sigmas) - 1
|
| 240 |
+
shared.state.sampling_steps = total_steps
|
| 241 |
+
|
| 242 |
+
# ---------------------------------------------------------
|
| 243 |
+
# 1. Prompt Reader
|
| 244 |
+
# ---------------------------------------------------------
|
| 245 |
+
prompt_tags = ""
|
| 246 |
+
try:
|
| 247 |
+
# Buscamos en la pila de ejecución el objeto 'p' de A1111
|
| 248 |
+
for frame_info in inspect.stack():
|
| 249 |
+
if 'p' in frame_info.frame.f_locals:
|
| 250 |
+
p_obj = frame_info.frame.f_locals['p']
|
| 251 |
+
if hasattr(p_obj, 'prompt'):
|
| 252 |
+
prompt_tags = (str(p_obj.prompt) + " " + str(p_obj.all_prompts)).lower()
|
| 253 |
+
break
|
| 254 |
+
except:
|
| 255 |
+
pass
|
| 256 |
+
|
| 257 |
+
# ---------------------------------------------------------
|
| 258 |
+
# 2. CONFIGURACIÓN DE ESTRATEGIA
|
| 259 |
+
# ---------------------------------------------------------
|
| 260 |
+
|
| 261 |
+
# Valores por defecto
|
| 262 |
+
strategy = "AUTO"
|
| 263 |
+
engine_1 = "NONE"
|
| 264 |
+
engine_2 = "NONE"
|
| 265 |
+
split_ratio = 0.5 # 50% por defecto
|
| 266 |
+
|
| 267 |
+
# A) DETECCIÓN DE MODO FUSIÓN (Prioridad Alta)
|
| 268 |
+
if "fsn_" in prompt_tags:
|
| 269 |
+
strategy = "FUSION"
|
| 270 |
+
|
| 271 |
+
# Detectar combinaciones
|
| 272 |
+
if "euler_dpm" in prompt_tags:
|
| 273 |
+
engine_1, engine_2 = "EULER_A", "DPM2"
|
| 274 |
+
desc = "Euler A >> DPM++ 2M"
|
| 275 |
+
elif "native_flash" in prompt_tags:
|
| 276 |
+
engine_1, engine_2 = "NATIVE", "FLASH"
|
| 277 |
+
desc = "Native >> Flash V2"
|
| 278 |
+
elif "dpm_euler" in prompt_tags:
|
| 279 |
+
engine_1, engine_2 = "DPM2", "EULER_A"
|
| 280 |
+
desc = "DPM++ 2M >> Euler A"
|
| 281 |
+
elif "native_dpm" in prompt_tags:
|
| 282 |
+
engine_1, engine_2 = "NATIVE", "DPM2"
|
| 283 |
+
desc = "Native >> DPM++ 2M"
|
| 284 |
+
else:
|
| 285 |
+
# Fusión por defecto si solo pone 'fsn_'
|
| 286 |
+
engine_1, engine_2 = "EULER_A", "DPM2"
|
| 287 |
+
desc = "Standard Fusion"
|
| 288 |
+
|
| 289 |
+
# Detectar punto de corte personalizado (ej: split_70)
|
| 290 |
+
# Busca palabras como 'split_30', 'split_80'
|
| 291 |
+
import re
|
| 292 |
+
match = re.search(r'split_(\d+)', prompt_tags)
|
| 293 |
+
if match:
|
| 294 |
+
split_val = int(match.group(1))
|
| 295 |
+
split_ratio = split_val / 100.0
|
| 296 |
+
|
| 297 |
+
shared.state.textinfo = f"AGGA FUSION: [{desc}] @ {int(split_ratio*100)}%"
|
| 298 |
+
|
| 299 |
+
# B) MODO AUTOMÁTICO (Si no hay fusión)
|
| 300 |
+
else:
|
| 301 |
+
if total_steps > 15:
|
| 302 |
+
strategy = "HIGH_RES"
|
| 303 |
+
engine_1 = "FLASH" # Solo usa un motor
|
| 304 |
+
shared.state.textinfo = "AGGA High-Res: [Flash V2]"
|
| 305 |
+
else:
|
| 306 |
+
strategy = "SMART_LOW"
|
| 307 |
+
engine_1 = "SMART" # El motor se decide en el paso 0
|
| 308 |
+
shared.state.textinfo = "AGGA Smart: Analyzing..."
|
| 309 |
+
|
| 310 |
+
# ---------------------------------------------------------
|
| 311 |
+
# 3. BUCLE DE GENERACIÓN
|
| 312 |
+
# ---------------------------------------------------------
|
| 313 |
+
|
| 314 |
+
# Estados internos
|
| 315 |
+
old_denoised = None
|
| 316 |
+
h_last = None
|
| 317 |
+
current_engine = engine_1
|
| 318 |
+
|
| 319 |
+
# Helper para DPM
|
| 320 |
+
def t_fn(sigma): return -sigma.log()
|
| 321 |
+
|
| 322 |
+
for i in range(total_steps):
|
| 323 |
+
shared.state.sampling_step = i + 1
|
| 324 |
+
sigma = sigmas[i]
|
| 325 |
+
sigma_next = sigmas[i + 1]
|
| 326 |
+
|
| 327 |
+
# --- Predicción ---
|
| 328 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 329 |
+
|
| 330 |
+
# --- LÓGICA DE CAMBIO DE MOTOR (Fusión) ---
|
| 331 |
+
if strategy == "FUSION":
|
| 332 |
+
switch_step = int(total_steps * split_ratio)
|
| 333 |
+
|
| 334 |
+
if i < switch_step:
|
| 335 |
+
new_engine = engine_1
|
| 336 |
+
else:
|
| 337 |
+
new_engine = engine_2
|
| 338 |
+
|
| 339 |
+
# Si cambiamos de motor, limpiamos la memoria del sampler anterior
|
| 340 |
+
if new_engine != current_engine:
|
| 341 |
+
old_denoised = None # Reset vital para DPM
|
| 342 |
+
current_engine = new_engine
|
| 343 |
+
|
| 344 |
+
# --- LÓGICA SMART (Análisis en paso 0) ---
|
| 345 |
+
if strategy == "SMART_LOW" and i == 0:
|
| 346 |
+
energy = denoised.std()
|
| 347 |
+
if energy < 0.88:
|
| 348 |
+
current_engine = "EULER_A"
|
| 349 |
+
tag = "Rescue: Euler A"
|
| 350 |
+
elif energy > 1.25:
|
| 351 |
+
current_engine = "DPM2"
|
| 352 |
+
tag = "Rescue: DPM++ 2M"
|
| 353 |
+
else:
|
| 354 |
+
current_engine = "NATIVE"
|
| 355 |
+
tag = "Native Optimized"
|
| 356 |
+
shared.state.textinfo = f"AGGA Smart: [{tag}]"
|
| 357 |
+
|
| 358 |
+
# -----------------------------------------------------
|
| 359 |
+
# EJECUCIÓN DE MOTORES
|
| 360 |
+
# -----------------------------------------------------
|
| 361 |
+
|
| 362 |
+
# === MOTOR: DPM++ 2M (Exacto) ===
|
| 363 |
+
if current_engine == "DPM2":
|
| 364 |
+
t, t_next = t_fn(sigma), t_fn(sigma_next)
|
| 365 |
+
h = t_next - t
|
| 366 |
+
|
| 367 |
+
if old_denoised is None or sigma_next == 0:
|
| 368 |
+
x = (sigma_next / sigma) * x - (-h).expm1() * denoised
|
| 369 |
+
else:
|
| 370 |
+
h_last = -sigmas[i-1].log() + sigmas[i].log()
|
| 371 |
+
r = h / h_last
|
| 372 |
+
denoised_d = (1 + 1 / (2 * r)) * denoised - (1 / (2 * r)) * old_denoised
|
| 373 |
+
x = (sigma_next / sigma) * x - (-h).expm1() * denoised_d
|
| 374 |
+
|
| 375 |
+
# === MOTOR: EULER ANCESTRAL (Exacto) ===
|
| 376 |
+
elif current_engine == "EULER_A":
|
| 377 |
+
sigma_up = (sigma_next ** 2 * (sigma ** 2 - sigma_next ** 2) / sigma ** 2) ** 0.5
|
| 378 |
+
sigma_down = (sigma_next ** 2 - sigma_up ** 2) ** 0.5
|
| 379 |
+
d = (x - denoised) / sigma
|
| 380 |
+
|
| 381 |
+
x = x + d * (sigma_down - sigma)
|
| 382 |
+
if sigma_next > 0:
|
| 383 |
+
x = x + torch.randn_like(x) * sigma_up
|
| 384 |
+
|
| 385 |
+
# === MOTOR: NATIVE (Turbo Stable) ===
|
| 386 |
+
elif current_engine == "NATIVE":
|
| 387 |
+
if i < total_steps - 1:
|
| 388 |
+
x = denoised + (x - denoised) * (sigma_next / sigma)
|
| 389 |
+
else:
|
| 390 |
+
x = denoised
|
| 391 |
+
|
| 392 |
+
# === MOTOR: FLASH V2 (Texturizado) ===
|
| 393 |
+
elif current_engine == "FLASH":
|
| 394 |
+
dt = sigma_next - sigma
|
| 395 |
+
if old_denoised is None:
|
| 396 |
+
d = (x - denoised) / sigma
|
| 397 |
+
x = x + d * dt * 1.05
|
| 398 |
+
else:
|
| 399 |
+
d = (x - denoised) / sigma
|
| 400 |
+
d_old = (x - old_denoised) / sigmas[max(i-1, 0)]
|
| 401 |
+
x = x + (0.6 * d + 0.4 * d_old) * dt
|
| 402 |
+
|
| 403 |
+
# Boost Lógico de Flash
|
| 404 |
+
if i > total_steps * 0.50:
|
| 405 |
+
progress = (i - total_steps * 0.50) / (total_steps * 0.50)
|
| 406 |
+
boost = 1.08 + progress * 0.18
|
| 407 |
+
x = x + d * dt * boost
|
| 408 |
+
if i == total_steps - 1:
|
| 409 |
+
x = x + (denoised - x) * 0.15
|
| 410 |
+
|
| 411 |
+
old_denoised = denoised
|
| 412 |
+
if callback: callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i, "sampling_steps": total_steps})
|
| 413 |
+
if shared.state.interrupted: break
|
| 414 |
+
|
| 415 |
+
return torch.clamp(x, -5.0, 5.0)
|
| 416 |
+
|
| 417 |
+
# =====================================================
|
| 418 |
+
# AGGA PSEUDO-HIRES DETAIL
|
| 419 |
+
# =====================================================
|
| 420 |
+
|
| 421 |
+
@torch.no_grad()
|
| 422 |
+
def sample_pseudo_hires_detail(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 423 |
+
extra_args = extra_args or {}
|
| 424 |
+
s_in = x.new_ones([x.shape[0]])
|
| 425 |
+
total_steps = len(sigmas) - 1
|
| 426 |
+
shared.state.sampling_steps = total_steps
|
| 427 |
+
|
| 428 |
+
prev_x = x.clone()
|
| 429 |
+
|
| 430 |
+
def get_detail_mask(latent):
|
| 431 |
+
# Calculamos gradientes de forma más eficiente
|
| 432 |
+
dy = torch.abs(latent[:, :, 1:, :] - latent[:, :, :-1, :])
|
| 433 |
+
dx = torch.abs(latent[:, :, :, 1:] - latent[:, :, :, :-1])
|
| 434 |
+
|
| 435 |
+
# Padding para recuperar el tamaño original (B, C, H, W)
|
| 436 |
+
dy = F.pad(dy, (0, 0, 0, 1), mode='replicate')
|
| 437 |
+
dx = F.pad(dx, (0, 1, 0, 0), mode='replicate')
|
| 438 |
+
|
| 439 |
+
grad = torch.sqrt(dx**2 + dy**2).mean(dim=1, keepdim=True)
|
| 440 |
+
# Normalización robusta: No usamos .max() para evitar amplificar ruido en zonas planas
|
| 441 |
+
grad = torch.clamp(grad * 2.0, 0.0, 1.0)
|
| 442 |
+
return grad
|
| 443 |
+
|
| 444 |
+
for i in range(total_steps):
|
| 445 |
+
sigma = sigmas[i]
|
| 446 |
+
sigma_next = sigmas[i + 1]
|
| 447 |
+
dt = sigma_next - sigma
|
| 448 |
+
|
| 449 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 450 |
+
d = (x - denoised) / sigma # Dirección del gradiente
|
| 451 |
+
|
| 452 |
+
progress = i / total_steps
|
| 453 |
+
|
| 454 |
+
if progress < 0.4:
|
| 455 |
+
multiplier = 1.05
|
| 456 |
+
elif progress < 0.7:
|
| 457 |
+
multiplier = 1.10 + (progress * 0.10)
|
| 458 |
+
else:
|
| 459 |
+
multiplier = 1.0
|
| 460 |
+
|
| 461 |
+
x_next = x + d * dt * multiplier
|
| 462 |
+
|
| 463 |
+
if progress >= 0.7:
|
| 464 |
+
detail_mask = get_detail_mask(x)
|
| 465 |
+
|
| 466 |
+
refine_strength = 0.05 * (1.0 - progress)
|
| 467 |
+
x_next = x_next + (denoised - x_next) * refine_strength * detail_mask
|
| 468 |
+
|
| 469 |
+
sharpen_strength = 0.03 * detail_mask
|
| 470 |
+
x_next = x_next + (x_next - x) * sharpen_strength
|
| 471 |
+
|
| 472 |
+
x = x_next
|
| 473 |
+
|
| 474 |
+
if callback is not None:
|
| 475 |
+
callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i + 1, "sampling_steps": total_steps})
|
| 476 |
+
|
| 477 |
+
return torch.clamp(x, -5.0, 5.0)
|
| 478 |
+
|
| 479 |
+
# =====================================================
|
| 480 |
+
# AGGA DMD-TURBO LANDING - Optimizado para guías LCM/DMD2 (pocos pasos)
|
| 481 |
+
# =====================================================
|
| 482 |
+
|
| 483 |
+
@torch.no_grad()
|
| 484 |
+
def sample_agga_dmd_turbo(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 485 |
+
extra_args = extra_args or {}
|
| 486 |
+
s_in = x.new_ones([x.shape[0]])
|
| 487 |
+
total_steps = len(sigmas) - 1
|
| 488 |
+
shared.state.sampling_steps = total_steps
|
| 489 |
+
|
| 490 |
+
for i in range(total_steps):
|
| 491 |
+
sigma = sigmas[i]
|
| 492 |
+
sigma_next = sigmas[i + 1]
|
| 493 |
+
dt = sigma_next - sigma
|
| 494 |
+
|
| 495 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 496 |
+
d = (x - denoised) / sigma
|
| 497 |
+
|
| 498 |
+
if i < total_steps - 1:
|
| 499 |
+
x = x + d * dt
|
| 500 |
+
|
| 501 |
+
else:
|
| 502 |
+
x = x + (denoised - x) * 0.85
|
| 503 |
+
|
| 504 |
+
blurred_x = F.avg_pool2d(x, kernel_size=3, stride=1, padding=1)
|
| 505 |
+
sharpen_map = x - blurred_x
|
| 506 |
+
|
| 507 |
+
x = x + sharpen_map * 0.15
|
| 508 |
+
|
| 509 |
+
if callback is not None:
|
| 510 |
+
callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i + 1, "sampling_steps": total_steps})
|
| 511 |
+
|
| 512 |
+
return torch.clamp(x, -5.0, 5.0)
|
| 513 |
+
|
| 514 |
+
# =====================================================
|
| 515 |
+
# AGGA Herrscher-Native
|
| 516 |
+
# =====================================================
|
| 517 |
+
@torch.no_grad()
|
| 518 |
+
def sample_agga_herrscher_native(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 519 |
+
extra_args = extra_args or {}
|
| 520 |
+
s_in = x.new_ones([x.shape[0]])
|
| 521 |
+
total_steps = len(sigmas) - 1
|
| 522 |
+
shared.state.sampling_steps = total_steps
|
| 523 |
+
|
| 524 |
+
# Reducimos momentum para que sea más ágil en pocos pasos (8 steps)
|
| 525 |
+
momentum_beta = 0.50
|
| 526 |
+
momentum = None
|
| 527 |
+
|
| 528 |
+
for i in range(total_steps):
|
| 529 |
+
sigma = sigmas[i]
|
| 530 |
+
sigma_next = sigmas[i+1]
|
| 531 |
+
dt = sigma_next - sigma
|
| 532 |
+
|
| 533 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 534 |
+
d = (x - denoised) / sigma
|
| 535 |
+
|
| 536 |
+
if momentum is None:
|
| 537 |
+
momentum = d
|
| 538 |
+
else:
|
| 539 |
+
momentum = momentum_beta * momentum + (1 - momentum_beta) * d
|
| 540 |
+
|
| 541 |
+
x_next = x + momentum * dt
|
| 542 |
+
|
| 543 |
+
progress = i / total_steps
|
| 544 |
+
if 0.2 < progress < 0.9:
|
| 545 |
+
mag = x_next.std()
|
| 546 |
+
if mag < 1.0:
|
| 547 |
+
scale_factor = (1.0 / (mag + 1e-6)) * 0.05
|
| 548 |
+
x_next = x_next * (1.0 + scale_factor)
|
| 549 |
+
|
| 550 |
+
x_next = x_next - (x_next.mean() * 0.02)
|
| 551 |
+
|
| 552 |
+
x = x_next
|
| 553 |
+
|
| 554 |
+
if callback is not None:
|
| 555 |
+
callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i + 1, "sampling_steps": total_steps})
|
| 556 |
+
|
| 557 |
+
return torch.clamp(x, -5.0, 5.0)
|
| 558 |
+
|
| 559 |
+
# =====================================================
|
| 560 |
+
# AGGA-Detail-Native
|
| 561 |
+
# =====================================================
|
| 562 |
+
@torch.no_grad()
|
| 563 |
+
def sample_agga_detail_native(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 564 |
+
extra_args = extra_args or {}
|
| 565 |
+
s_in = x.new_ones([x.shape[0]])
|
| 566 |
+
total_steps = len(sigmas) - 1
|
| 567 |
+
shared.state.sampling_steps = total_steps
|
| 568 |
+
shared.state.textinfo = "LCM Detail V4: Hires-Refiner Mode"
|
| 569 |
+
|
| 570 |
+
for i in range(total_steps):
|
| 571 |
+
shared.state.sampling_step = i
|
| 572 |
+
sigma, sigma_next = sigmas[i], sigmas[i + 1]
|
| 573 |
+
progress = i / total_steps
|
| 574 |
+
|
| 575 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 576 |
+
|
| 577 |
+
if i > 0:
|
| 578 |
+
|
| 579 |
+
dy = torch.abs(denoised[:, :, 1:, :] - denoised[:, :, :-1, :])
|
| 580 |
+
dx = torch.abs(denoised[:, :, :, 1:] - denoised[:, :, :, :-1])
|
| 581 |
+
dy = F.pad(dy, (0, 0, 0, 1), mode='replicate')
|
| 582 |
+
dx = F.pad(dx, (0, 1, 0, 0), mode='replicate')
|
| 583 |
+
detail_mask = torch.clamp((dx + dy).mean(dim=1, keepdim=True) * 2.5, 0.0, 1.0)
|
| 584 |
+
|
| 585 |
+
if progress > 0.60:
|
| 586 |
+
|
| 587 |
+
sigma_refine = sigma * 0.95
|
| 588 |
+
refine_denoised = model(x, sigma_refine * s_in, **extra_args)
|
| 589 |
+
|
| 590 |
+
denoised = denoised + (refine_denoised - denoised) * (0.4 * detail_mask)
|
| 591 |
+
else:
|
| 592 |
+
|
| 593 |
+
blurred = F.avg_pool2d(denoised, 3, 1, 1)
|
| 594 |
+
denoised = denoised + (denoised - blurred) * (0.12 * detail_mask)
|
| 595 |
+
|
| 596 |
+
if i < total_steps - 1:
|
| 597 |
+
x = denoised + (x - denoised) * (sigma_next / sigma)
|
| 598 |
+
else:
|
| 599 |
+
x = denoised
|
| 600 |
+
|
| 601 |
+
if callback:
|
| 602 |
+
callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i, "sampling_steps": total_steps})
|
| 603 |
+
if shared.state.interrupted: break
|
| 604 |
+
|
| 605 |
+
return torch.clamp(x, -5.0, 5.0)
|
| 606 |
+
|
| 607 |
+
# =====================================================
|
| 608 |
+
# AGGA Hyper-Detail Hybrid
|
| 609 |
+
# =====================================================
|
| 610 |
+
@torch.no_grad()
|
| 611 |
+
def sample_agga_hyper_detail_hybrid(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 612 |
+
extra_args = extra_args or {}
|
| 613 |
+
s_in = x.new_ones([x.shape[0]])
|
| 614 |
+
total_steps = len(sigmas) - 1
|
| 615 |
+
shared.state.sampling_steps = total_steps
|
| 616 |
+
|
| 617 |
+
split_step = int(total_steps * 0.66)
|
| 618 |
+
|
| 619 |
+
for i in range(total_steps):
|
| 620 |
+
shared.state.sampling_step = i
|
| 621 |
+
sigma, sigma_next = sigmas[i], sigmas[i + 1]
|
| 622 |
+
|
| 623 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 624 |
+
|
| 625 |
+
dy = torch.abs(denoised[:, :, 1:, :] - denoised[:, :, :-1, :])
|
| 626 |
+
dx = torch.abs(denoised[:, :, :, 1:] - denoised[:, :, :, :-1])
|
| 627 |
+
dy = F.pad(dy, (0, 0, 0, 1), mode='replicate')
|
| 628 |
+
dx = F.pad(dx, (0, 1, 0, 0), mode='replicate')
|
| 629 |
+
detail_mask = torch.clamp((dx + dy).mean(dim=1, keepdim=True) * 2.5, 0.0, 1.0)
|
| 630 |
+
|
| 631 |
+
if i >= split_step:
|
| 632 |
+
shared.state.textinfo = f"Phase 2: Power Detail (Step {i+1})"
|
| 633 |
+
sigma_refine = sigma * 0.95
|
| 634 |
+
refine_denoised = model(x, sigma_refine * s_in, **extra_args)
|
| 635 |
+
denoised = denoised + (refine_denoised - denoised) * (0.45 * detail_mask)
|
| 636 |
+
|
| 637 |
+
else:
|
| 638 |
+
shared.state.textinfo = f"Phase 1: V2 Structure (Step {i+1})"
|
| 639 |
+
blurred = F.avg_pool2d(denoised, 3, 1, 1)
|
| 640 |
+
denoised = denoised + (denoised - blurred) * (0.12 * detail_mask)
|
| 641 |
+
|
| 642 |
+
if i < total_steps - 1:
|
| 643 |
+
x = denoised + (x - denoised) * (sigma_next / sigma)
|
| 644 |
+
|
| 645 |
+
x_std = x.std()
|
| 646 |
+
if x_std < 1.0:
|
| 647 |
+
x = x * (1.0 + (1.0 - x_std) * 0.05)
|
| 648 |
+
else:
|
| 649 |
+
|
| 650 |
+
x = denoised
|
| 651 |
+
|
| 652 |
+
if callback:
|
| 653 |
+
callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i, "sampling_steps": total_steps})
|
| 654 |
+
if shared.state.interrupted: break
|
| 655 |
+
|
| 656 |
+
return torch.clamp(x, -5.0, 5.0)
|
| 657 |
+
|
| 658 |
+
# =====================================================
|
| 659 |
+
# AGGA Style Repair
|
| 660 |
+
# =====================================================
|
| 661 |
+
@torch.no_grad()
|
| 662 |
+
def sample_agga_style_repair_pro(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 663 |
+
extra_args = extra_args or {}
|
| 664 |
+
s_in = x.new_ones([x.shape[0]])
|
| 665 |
+
total_steps = len(sigmas) - 1
|
| 666 |
+
shared.state.sampling_steps = total_steps
|
| 667 |
+
|
| 668 |
+
BOCETADO_STEPS = int(total_steps * 0.40)
|
| 669 |
+
prev_x = x.clone()
|
| 670 |
+
|
| 671 |
+
for i in range(total_steps):
|
| 672 |
+
shared.state.sampling_step = i
|
| 673 |
+
sigma, sigma_next = sigmas[i], sigmas[i + 1]
|
| 674 |
+
progress = i / total_steps
|
| 675 |
+
|
| 676 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 677 |
+
|
| 678 |
+
dy = torch.abs(denoised[:, :, 1:, :] - denoised[:, :, :-1, :])
|
| 679 |
+
dx = torch.abs(denoised[:, :, :, 1:] - denoised[:, :, :, :-1])
|
| 680 |
+
dy = F.pad(dy, (0, 0, 0, 1), mode='replicate')
|
| 681 |
+
dx = F.pad(dx, (0, 1, 0, 0), mode='replicate')
|
| 682 |
+
style_mask = torch.clamp(torch.sqrt(dx**2 + dy**2).mean(dim=1, keepdim=True) * 2.8, 0.0, 1.0)
|
| 683 |
+
|
| 684 |
+
if i < BOCETADO_STEPS:
|
| 685 |
+
shared.state.textinfo = f"Phase 1: Creative Sketching (Step {i+1})"
|
| 686 |
+
|
| 687 |
+
boost = 1.20 + (i / BOCETADO_STEPS) * 0.25
|
| 688 |
+
d = (x - denoised) / sigma
|
| 689 |
+
x = x + d * (sigma_next - sigma) * boost
|
| 690 |
+
|
| 691 |
+
else:
|
| 692 |
+
shared.state.textinfo = f"Phase 2: Style Repair (Step {i+1})"
|
| 693 |
+
|
| 694 |
+
strength = 0.05 + progress * 0.15
|
| 695 |
+
x = x + (denoised - x) * strength * style_mask
|
| 696 |
+
|
| 697 |
+
if i % 3 == 0 and i < total_steps - 1:
|
| 698 |
+
|
| 699 |
+
sigma_style = sigma * (1.12 + 0.05 * (progress - 0.4))
|
| 700 |
+
denoised_style = model(x, sigma_style * s_in, **extra_args)
|
| 701 |
+
|
| 702 |
+
style_delta = (denoised_style - denoised) * 0.04 * style_mask
|
| 703 |
+
x = x + style_delta
|
| 704 |
+
|
| 705 |
+
x = x + (x - prev_x) * 0.035 * style_mask
|
| 706 |
+
|
| 707 |
+
if i < total_steps - 1 and i >= BOCETADO_STEPS:
|
| 708 |
+
|
| 709 |
+
x = denoised + (x - denoised) * (sigma_next / sigma)
|
| 710 |
+
|
| 711 |
+
x_std = x.std()
|
| 712 |
+
if x_std < 1.08:
|
| 713 |
+
x = x * (1.08 / (x_std + 1e-6))
|
| 714 |
+
elif i == total_steps - 1:
|
| 715 |
+
|
| 716 |
+
x = denoised + (x - denoised) * 0.07
|
| 717 |
+
|
| 718 |
+
prev_x = x.clone()
|
| 719 |
+
if callback:
|
| 720 |
+
callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i, "sampling_steps": total_steps})
|
| 721 |
+
if shared.state.interrupted: break
|
| 722 |
+
|
| 723 |
+
return torch.clamp(x, -5.0, 5.0)
|
| 724 |
+
|
| 725 |
+
# =====================================================
|
| 726 |
+
# AGGA Style Repair Ultra
|
| 727 |
+
# =====================================================
|
| 728 |
+
@torch.no_grad()
|
| 729 |
+
def sample_agga_style_repair_ultra(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 730 |
+
extra_args = extra_args or {}
|
| 731 |
+
s_in = x.new_ones([x.shape[0]])
|
| 732 |
+
total_steps = len(sigmas) - 1
|
| 733 |
+
shared.state.sampling_steps = total_steps
|
| 734 |
+
|
| 735 |
+
BOCETADO_STEPS = int(total_steps * 0.45)
|
| 736 |
+
prev_x = x.clone()
|
| 737 |
+
|
| 738 |
+
for i in range(total_steps):
|
| 739 |
+
shared.state.sampling_step = i
|
| 740 |
+
sigma, sigma_next = sigmas[i], sigmas[i + 1]
|
| 741 |
+
dt = sigma_next - sigma
|
| 742 |
+
progress = i / total_steps
|
| 743 |
+
|
| 744 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 745 |
+
d = (x - denoised) / sigma
|
| 746 |
+
|
| 747 |
+
dy = torch.abs(denoised[:, :, 1:, :] - denoised[:, :, :-1, :])
|
| 748 |
+
dx = torch.abs(denoised[:, :, :, 1:] - denoised[:, :, :, :-1])
|
| 749 |
+
dy = F.pad(dy, (0, 0, 0, 1), mode='replicate')
|
| 750 |
+
dx = F.pad(dx, (0, 1, 0, 0), mode='replicate')
|
| 751 |
+
|
| 752 |
+
style_mask = torch.clamp(torch.sqrt(dx**2 + dy**2).mean(dim=1, keepdim=True) * 2.8, 0.0, 1.0)
|
| 753 |
+
|
| 754 |
+
if i < BOCETADO_STEPS:
|
| 755 |
+
x = x + d * dt
|
| 756 |
+
|
| 757 |
+
else:
|
| 758 |
+
|
| 759 |
+
speed_factor = torch.exp(-torch.abs(dt) * 2.5).item()
|
| 760 |
+
u_boost = 1.18 + progress * 0.12
|
| 761 |
+
|
| 762 |
+
if i % 2 == 0 or speed_factor > 0.6:
|
| 763 |
+
|
| 764 |
+
sigma_style = sigma * (1.15 + 0.05 * (progress - 0.4))
|
| 765 |
+
denoised_style = model(x, sigma_style * s_in, **extra_args)
|
| 766 |
+
|
| 767 |
+
atm_mask = torch.clamp(style_mask + 0.20, 0.0, 1.0)
|
| 768 |
+
|
| 769 |
+
style_delta = (denoised_style - denoised) * 0.05 * atm_mask * (1.0 + speed_factor)
|
| 770 |
+
x = x + style_delta * u_boost
|
| 771 |
+
|
| 772 |
+
x = x + d * dt * u_boost
|
| 773 |
+
|
| 774 |
+
sharpen = 0.038 + (speed_factor * 0.015)
|
| 775 |
+
x = x + (x - prev_x) * sharpen * style_mask
|
| 776 |
+
|
| 777 |
+
if i == total_steps - 1:
|
| 778 |
+
x = denoised + (x - denoised) * 0.08
|
| 779 |
+
|
| 780 |
+
prev_x = x.clone()
|
| 781 |
+
if callback: callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i, "sampling_steps": total_steps})
|
| 782 |
+
if shared.state.interrupted: break
|
| 783 |
+
|
| 784 |
+
return torch.clamp(x, -5.5, 5.5)
|
| 785 |
+
|
| 786 |
+
# =====================================================
|
| 787 |
+
# AGGA STRUCTURAL-DETAIL (Hybrid V5)
|
| 788 |
+
# =====================================================
|
| 789 |
+
@torch.no_grad()
|
| 790 |
+
def sample_agga_structural_detail(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 791 |
+
extra_args = extra_args or {}
|
| 792 |
+
s_in = x.new_ones([x.shape[0]])
|
| 793 |
+
total_steps = len(sigmas) - 1
|
| 794 |
+
shared.state.sampling_steps = total_steps
|
| 795 |
+
|
| 796 |
+
old_d = None
|
| 797 |
+
|
| 798 |
+
split_idx = int(total_steps * 0.45)
|
| 799 |
+
|
| 800 |
+
for i in range(total_steps):
|
| 801 |
+
shared.state.sampling_step = i + 1
|
| 802 |
+
sigma = sigmas[i]
|
| 803 |
+
sigma_next = sigmas[i + 1]
|
| 804 |
+
dt = sigma_next - sigma
|
| 805 |
+
|
| 806 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 807 |
+
d = (x - denoised) / sigma
|
| 808 |
+
|
| 809 |
+
if i < split_idx:
|
| 810 |
+
|
| 811 |
+
if old_d is None:
|
| 812 |
+
|
| 813 |
+
x = x + d * dt
|
| 814 |
+
else:
|
| 815 |
+
|
| 816 |
+
x = x + 0.5 * (d + old_d) * dt
|
| 817 |
+
|
| 818 |
+
else:
|
| 819 |
+
|
| 820 |
+
dy = torch.abs(denoised[:, :, 1:, :] - denoised[:, :, :-1, :])
|
| 821 |
+
dx = torch.abs(denoised[:, :, :, 1:] - denoised[:, :, :, :-1])
|
| 822 |
+
dy = F.pad(dy, (0, 0, 0, 1), mode='replicate')
|
| 823 |
+
dx = F.pad(dx, (0, 1, 0, 0), mode='replicate')
|
| 824 |
+
|
| 825 |
+
detail_mask = torch.clamp((dx + dy).mean(dim=1, keepdim=True) * 2.2, 0.0, 1.0)
|
| 826 |
+
|
| 827 |
+
progress_phase2 = (i - split_idx) / (total_steps - split_idx)
|
| 828 |
+
boost_amount = 1.0 + (progress_phase2 * 0.15)
|
| 829 |
+
|
| 830 |
+
final_dt = dt * (1.0 + (boost_amount - 1.0) * detail_mask)
|
| 831 |
+
|
| 832 |
+
x = x + d * final_dt
|
| 833 |
+
|
| 834 |
+
if progress_phase2 > 0.6:
|
| 835 |
+
x = x + (x - x.clone()) * 0.04 * detail_mask
|
| 836 |
+
|
| 837 |
+
old_d = d
|
| 838 |
+
|
| 839 |
+
if callback is not None:
|
| 840 |
+
callback({
|
| 841 |
+
"x": x,
|
| 842 |
+
"i": i,
|
| 843 |
+
"sigma": sigma,
|
| 844 |
+
"sampling_step": i + 1,
|
| 845 |
+
"sampling_steps": total_steps
|
| 846 |
+
})
|
| 847 |
+
|
| 848 |
+
return torch.clamp(x, -5.0, 5.0)
|
| 849 |
+
|
| 850 |
+
# =====================================================
|
| 851 |
+
# AGGA STYLE-REPAIR (Prompt-Aware Edition)
|
| 852 |
+
# =====================================================
|
| 853 |
+
@torch.no_grad()
|
| 854 |
+
def sample_agga_style_repair_prompt_aware(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 855 |
+
|
| 856 |
+
if hasattr(model, 'need_last_noise_uncond'):
|
| 857 |
+
model.need_last_noise_uncond = True
|
| 858 |
+
|
| 859 |
+
extra_args = extra_args or {}
|
| 860 |
+
s_in = x.new_ones([x.shape[0]])
|
| 861 |
+
total_steps = len(sigmas) - 1
|
| 862 |
+
shared.state.sampling_steps = total_steps
|
| 863 |
+
|
| 864 |
+
BOCETADO_STEPS = int(total_steps * 0.40)
|
| 865 |
+
prev_x = x.clone()
|
| 866 |
+
|
| 867 |
+
for i in range(total_steps):
|
| 868 |
+
shared.state.sampling_step = i
|
| 869 |
+
sigma = sigmas[i]
|
| 870 |
+
sigma_next = sigmas[i + 1]
|
| 871 |
+
dt = sigma_next - sigma
|
| 872 |
+
progress = i / total_steps
|
| 873 |
+
|
| 874 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 875 |
+
|
| 876 |
+
style_force_vector = None
|
| 877 |
+
|
| 878 |
+
last_noise_uncond = getattr(model, 'last_noise_uncond', None)
|
| 879 |
+
|
| 880 |
+
if last_noise_uncond is not None and i > BOCETADO_STEPS:
|
| 881 |
+
# Reconstruimos la imagen "Incondicional" (x0_uncond) desde el ruido
|
| 882 |
+
# x0 = x - sigma * noise
|
| 883 |
+
uncond_denoised = x - sigma * last_noise_uncond
|
| 884 |
+
|
| 885 |
+
style_force_vector = denoised - uncond_denoised
|
| 886 |
+
|
| 887 |
+
dy = torch.abs(denoised[:, :, 1:, :] - denoised[:, :, :-1, :])
|
| 888 |
+
dx = torch.abs(denoised[:, :, :, 1:] - denoised[:, :, :, :-1])
|
| 889 |
+
dy = F.pad(dy, (0, 0, 0, 1), mode='replicate')
|
| 890 |
+
dx = F.pad(dx, (0, 1, 0, 0), mode='replicate')
|
| 891 |
+
style_mask = torch.clamp(torch.sqrt(dx**2 + dy**2).mean(dim=1, keepdim=True) * 2.8, 0.0, 1.0)
|
| 892 |
+
|
| 893 |
+
# --- FASE 1: BOCETADO ---
|
| 894 |
+
if i < BOCETADO_STEPS:
|
| 895 |
+
|
| 896 |
+
boost = 1.20 + (i / BOCETADO_STEPS) * 0.20
|
| 897 |
+
d = (x - denoised) / sigma
|
| 898 |
+
x = x + d * dt * boost
|
| 899 |
+
|
| 900 |
+
# --- FASE 2: RECUPERACIÓN DE ESTILO DIRIGIDA ---
|
| 901 |
+
else:
|
| 902 |
+
|
| 903 |
+
if style_force_vector is not None:
|
| 904 |
+
|
| 905 |
+
prompt_guidance = style_force_vector * style_mask * 0.25
|
| 906 |
+
|
| 907 |
+
x = x + prompt_guidance * torch.abs(dt)
|
| 908 |
+
|
| 909 |
+
x = x + (x - prev_x) * 0.035 * style_mask
|
| 910 |
+
|
| 911 |
+
d = (x - denoised) / sigma
|
| 912 |
+
x = x + d * dt
|
| 913 |
+
|
| 914 |
+
if i >= BOCETADO_STEPS:
|
| 915 |
+
x_std = x.std()
|
| 916 |
+
if x_std > 1.15: # Límite de seguridad
|
| 917 |
+
x = x * (1.15 / x_std)
|
| 918 |
+
|
| 919 |
+
prev_x = x.clone()
|
| 920 |
+
|
| 921 |
+
if callback:
|
| 922 |
+
callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i, "sampling_steps": total_steps})
|
| 923 |
+
|
| 924 |
+
return torch.clamp(x, -5.0, 5.0)
|
| 925 |
+
|
| 926 |
+
# =====================================================
|
| 927 |
+
# AGGA PIXEL-MASTER V10 (Spatial-Only)
|
| 928 |
+
# =====================================================
|
| 929 |
+
@torch.no_grad()
|
| 930 |
+
def sample_agga_pixel_master(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 931 |
+
extra_args = extra_args or {}
|
| 932 |
+
s_in = x.new_ones([x.shape[0]])
|
| 933 |
+
total_steps = len(sigmas) - 1
|
| 934 |
+
shared.state.sampling_steps = total_steps
|
| 935 |
+
|
| 936 |
+
# AJUSTES V10
|
| 937 |
+
# Factor de reducción.
|
| 938 |
+
# 2.0 = Bloques visibles (SNES)
|
| 939 |
+
# 3.0 - 4.0 = Bloques muy grandes (Atari/NES)
|
| 940 |
+
# Si con 2.0 se ve borroso, SUBE a 3.0 o 4.0.
|
| 941 |
+
block_size = 1.88
|
| 942 |
+
|
| 943 |
+
for i in range(total_steps):
|
| 944 |
+
shared.state.sampling_step = i
|
| 945 |
+
sigma = sigmas[i]
|
| 946 |
+
sigma_next = sigmas[i + 1]
|
| 947 |
+
dt = sigma_next - sigma
|
| 948 |
+
|
| 949 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 950 |
+
|
| 951 |
+
d = (x - denoised) / sigma
|
| 952 |
+
x = x + d * dt
|
| 953 |
+
|
| 954 |
+
if i == total_steps - 1:
|
| 955 |
+
|
| 956 |
+
latents = denoised
|
| 957 |
+
|
| 958 |
+
h, w = latents.shape[-2:]
|
| 959 |
+
small_h, small_w = int(h / block_size), int(w / block_size)
|
| 960 |
+
|
| 961 |
+
latents_pixelated = F.interpolate(latents, size=(small_h, small_w), mode='area')
|
| 962 |
+
|
| 963 |
+
latents_pixelated = F.interpolate(latents_pixelated, size=(h, w), mode='nearest')
|
| 964 |
+
|
| 965 |
+
x = latents_pixelated
|
| 966 |
+
|
| 967 |
+
if callback:
|
| 968 |
+
callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i, "sampling_steps": total_steps})
|
| 969 |
+
|
| 970 |
+
return x
|
| 971 |
+
|
| 972 |
+
|
| 973 |
+
# =====================================================
|
| 974 |
+
# LORA BRIDGE (PDXL TO VELVETTE_V4/ NoobAI)
|
| 975 |
+
# =====================================================
|
| 976 |
+
|
| 977 |
+
@torch.no_grad()
|
| 978 |
+
def sample_agga_lora_bridge(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 979 |
+
extra_args = extra_args or {}
|
| 980 |
+
s_in = x.new_ones([x.shape[0]])
|
| 981 |
+
total_steps = len(sigmas) - 1
|
| 982 |
+
|
| 983 |
+
# ADN de Pony V6 (Valores reales extraídos)
|
| 984 |
+
PONY_STD_TARGET = 0.016593
|
| 985 |
+
DELTA_MEAN = -0.0104
|
| 986 |
+
|
| 987 |
+
for i in range(total_steps):
|
| 988 |
+
sigma, sigma_next = sigmas[i], sigmas[i + 1]
|
| 989 |
+
dt = sigma_next - sigma
|
| 990 |
+
progress = i / total_steps
|
| 991 |
+
|
| 992 |
+
# 1. Predicción y Limpieza Anti-NaNs
|
| 993 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 994 |
+
denoised = torch.nan_to_num(denoised, nan=0.0, posinf=4.0, neginf=-4.0)
|
| 995 |
+
|
| 996 |
+
# 2. Monitor de Salud del Tensor
|
| 997 |
+
mag = denoised.std()
|
| 998 |
+
|
| 999 |
+
# --- EL SUELO DE ENERGÍA AGGA ---
|
| 1000 |
+
# Si la energía cae demasiado (gris), forzamos recuperación
|
| 1001 |
+
if mag < 0.90:
|
| 1002 |
+
denoised = denoised * (0.95 / (mag + 1e-6))
|
| 1003 |
+
|
| 1004 |
+
# 3. Inyección de ADN con Factor 1.3 (Blindada)
|
| 1005 |
+
influence = 1.0 - (2.0 * progress - 1.0)**4
|
| 1006 |
+
# El ratio de escala se calcula con precisión de seguridad
|
| 1007 |
+
scale_ratio = torch.clamp(torch.tensor(PONY_STD_TARGET / (mag + 1e-6)), 0.8, 1.25)
|
| 1008 |
+
|
| 1009 |
+
# Aplicamos la fórmula de ADN:
|
| 1010 |
+
# $$denoised = denoised \cdot (1 + (ratio - 1) \cdot influence \cdot 1.3) + (\Delta\mu \cdot influence)$$
|
| 1011 |
+
denoised = denoised * (1.0 + (scale_ratio - 1.0) * influence * 1.3)
|
| 1012 |
+
denoised = denoised + (DELTA_MEAN * influence * 0.7) # Reducido un 30% para evitar el colapso
|
| 1013 |
+
|
| 1014 |
+
# 4. Salto de Consistencia con Suelo de Precisión
|
| 1015 |
+
safe_sigma = max(sigma.item(), 1e-4)
|
| 1016 |
+
d = (x - denoised) / safe_sigma
|
| 1017 |
+
x = x + d * dt
|
| 1018 |
+
|
| 1019 |
+
if callback:
|
| 1020 |
+
callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i, "sampling_steps": total_steps})
|
| 1021 |
+
|
| 1022 |
+
return torch.clamp(x, -6.0, 6.0)
|
| 1023 |
+
|
| 1024 |
+
@torch.no_grad()
|
| 1025 |
+
def sample_agga_lora_bridge_stable(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 1026 |
+
|
| 1027 |
+
extra_args = extra_args or {}
|
| 1028 |
+
s_in = x.new_ones([x.shape[0]])
|
| 1029 |
+
total_steps = len(sigmas) - 1
|
| 1030 |
+
|
| 1031 |
+
# ADN de Pony V6 (Valores reales extraídos)
|
| 1032 |
+
PONY_STD_TARGET = 0.016593
|
| 1033 |
+
DELTA_MEAN = -0.0104
|
| 1034 |
+
|
| 1035 |
+
for i in range(total_steps):
|
| 1036 |
+
sigma, sigma_next = sigmas[i], sigmas[i + 1]
|
| 1037 |
+
dt = sigma_next - sigma
|
| 1038 |
+
progress = i / total_steps
|
| 1039 |
+
|
| 1040 |
+
# 1. Predicción y Sanitización Instantánea (FP16 Safe)
|
| 1041 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 1042 |
+
denoised = torch.nan_to_num(denoised, nan=0.0, posinf=4.0, neginf=-4.0)
|
| 1043 |
+
|
| 1044 |
+
# 2. Monitor de Salud y Suelo de Energía
|
| 1045 |
+
mag = denoised.std()
|
| 1046 |
+
|
| 1047 |
+
# Si la energía cae por debajo de 0.90 (zona de peligro gris), inyectamos soporte.
|
| 1048 |
+
# Esto es lo que salvó tu imagen en el paso 08.
|
| 1049 |
+
if mag < 0.90:
|
| 1050 |
+
denoised = denoised * (0.95 / (mag + 1e-6))
|
| 1051 |
+
|
| 1052 |
+
# 3. Inyección de ADN Pony
|
| 1053 |
+
# Curva de influencia tipo campana
|
| 1054 |
+
influence = 1.0 - (2.0 * progress - 1.0)**4
|
| 1055 |
+
|
| 1056 |
+
# Cálculo del ratio con límites estrictos (basado en tus logs)
|
| 1057 |
+
scale_ratio = torch.clamp(torch.tensor(PONY_STD_TARGET / (mag + 1e-6)), 0.8, 1.25)
|
| 1058 |
+
|
| 1059 |
+
# Aplicamos el ADN con tu factor agresivo de 1.3, ahora que es seguro
|
| 1060 |
+
denoised = denoised * (1.0 + (scale_ratio - 1.0) * influence * 1.3)
|
| 1061 |
+
denoised = denoised + (DELTA_MEAN * influence * 0.7)
|
| 1062 |
+
|
| 1063 |
+
# 4. Salto de Consistencia Blindado
|
| 1064 |
+
# Evita la división por cero al final que causa la "niebla"
|
| 1065 |
+
safe_sigma = max(sigma.item(), 1e-4)
|
| 1066 |
+
d = (x - denoised) / safe_sigma
|
| 1067 |
+
x = x + d * dt
|
| 1068 |
+
|
| 1069 |
+
if callback:
|
| 1070 |
+
callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i, "sampling_steps": total_steps})
|
| 1071 |
+
|
| 1072 |
+
return torch.clamp(x, -6.0, 6.0)
|
| 1073 |
+
|
| 1074 |
+
@torch.no_grad()
|
| 1075 |
+
def sample_agga_lora_bridge_sharp(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 1076 |
+
|
| 1077 |
+
extra_args = extra_args or {}
|
| 1078 |
+
s_in = x.new_ones([x.shape[0]])
|
| 1079 |
+
total_steps = len(sigmas) - 1
|
| 1080 |
+
|
| 1081 |
+
PONY_STD_TARGET = 0.016593
|
| 1082 |
+
DELTA_MEAN = -0.0104
|
| 1083 |
+
|
| 1084 |
+
for i in range(total_steps):
|
| 1085 |
+
sigma, sigma_next = sigmas[i], sigmas[i + 1]
|
| 1086 |
+
dt = sigma_next - sigma
|
| 1087 |
+
progress = i / total_steps
|
| 1088 |
+
|
| 1089 |
+
# 1. Predicción y Sanitización
|
| 1090 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 1091 |
+
denoised = torch.nan_to_num(denoised, nan=0.0, posinf=4.0, neginf=-4.0)
|
| 1092 |
+
|
| 1093 |
+
# 2. Monitor de Salud
|
| 1094 |
+
mag = denoised.std()
|
| 1095 |
+
|
| 1096 |
+
# --- INYECTOR DE NITIDEZ INTELIGENTE ---
|
| 1097 |
+
# Condición doble:
|
| 1098 |
+
# a) Solo en fase de textura (30% al 85%)
|
| 1099 |
+
# b) SOLO si el tensor está "✅ ESTABLE" (mag >= 0.90)
|
| 1100 |
+
if 0.3 < progress < 0.85 and mag >= 0.90:
|
| 1101 |
+
# Aislamiento de altas frecuencias (bordes, pestañas, texturas finas)
|
| 1102 |
+
blurred = F.avg_pool2d(denoised, kernel_size=3, stride=1, padding=1)
|
| 1103 |
+
high_freq = denoised - blurred
|
| 1104 |
+
# Inyectamos un 15% extra de nitidez
|
| 1105 |
+
denoised = denoised + (high_freq * 0.15)
|
| 1106 |
+
|
| 1107 |
+
# --- SUELO DE ENERGÍA ---
|
| 1108 |
+
# Si no está estable, aplicamos el rescate normal
|
| 1109 |
+
if mag < 0.90:
|
| 1110 |
+
denoised = denoised * (0.95 / (mag + 1e-6))
|
| 1111 |
+
|
| 1112 |
+
# 3. Inyección de ADN Pony (Igual que la estable)
|
| 1113 |
+
influence = 1.0 - (2.0 * progress - 1.0)**4
|
| 1114 |
+
scale_ratio = torch.clamp(torch.tensor(PONY_STD_TARGET / (mag + 1e-6)), 0.8, 1.25)
|
| 1115 |
+
denoised = denoised * (1.0 + (scale_ratio - 1.0) * influence * 1.3)
|
| 1116 |
+
denoised = denoised + (DELTA_MEAN * influence * 0.7)
|
| 1117 |
+
|
| 1118 |
+
# 4. Salto de Consistencia Blindado
|
| 1119 |
+
safe_sigma = max(sigma.item(), 1e-4)
|
| 1120 |
+
d = (x - denoised) / safe_sigma
|
| 1121 |
+
x = x + d * dt
|
| 1122 |
+
|
| 1123 |
+
if callback:
|
| 1124 |
+
callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i, "sampling_steps": total_steps})
|
| 1125 |
+
|
| 1126 |
+
return torch.clamp(x, -6.0, 6.0)
|
| 1127 |
+
|
| 1128 |
+
|
| 1129 |
+
@torch.no_grad()
|
| 1130 |
+
def sample_agga_lora_bridge_ultra_sharp(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 1131 |
+
extra_args = extra_args or {}
|
| 1132 |
+
s_in = x.new_ones([x.shape[0]])
|
| 1133 |
+
total_steps = len(sigmas) - 1
|
| 1134 |
+
|
| 1135 |
+
# Valores de ADN
|
| 1136 |
+
PONY_STD_TARGET = 0.016593
|
| 1137 |
+
DELTA_MEAN = -0.0104
|
| 1138 |
+
# NUEVO: Factor de "Temperatura" o Vibrancia (1.15 = 15% extra de pop)
|
| 1139 |
+
VIBRANCY_FACTOR = 1.15
|
| 1140 |
+
|
| 1141 |
+
for i in range(total_steps):
|
| 1142 |
+
sigma, sigma_next = sigmas[i], sigmas[i + 1]
|
| 1143 |
+
dt = sigma_next - sigma
|
| 1144 |
+
progress = i / total_steps
|
| 1145 |
+
|
| 1146 |
+
# 1. Predicción y Sanitización
|
| 1147 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 1148 |
+
denoised = torch.nan_to_num(denoised, nan=0.0, posinf=4.5, neginf=-4.5)
|
| 1149 |
+
|
| 1150 |
+
# 2. Monitor de Salud
|
| 1151 |
+
mag = denoised.std()
|
| 1152 |
+
|
| 1153 |
+
# --- FASE DE INYECCIÓN ACTIVA (30% al 85%) ---
|
| 1154 |
+
if 0.3 < progress < 0.85 and mag >= 0.88:
|
| 1155 |
+
# A) INYECTOR DE NITIDEZ (Bordes)
|
| 1156 |
+
blurred = F.avg_pool2d(denoised, kernel_size=3, stride=1, padding=1)
|
| 1157 |
+
high_freq = denoised - blurred
|
| 1158 |
+
denoised = denoised + (high_freq * 0.18) # Ligeramente más agresivo (18%)
|
| 1159 |
+
|
| 1160 |
+
# B) NUEVO: INYECTOR DE VIBRANCIA (Temperatura/Color)
|
| 1161 |
+
# Calculamos la media actual del tensor
|
| 1162 |
+
current_mean = denoised.mean(dim=(1, 2, 3), keepdim=True)
|
| 1163 |
+
# Centramos el color alrededor de la media
|
| 1164 |
+
centered_color = denoised - current_mean
|
| 1165 |
+
# Estiramos la saturación (boost de vibrancia) sin mover el brillo medio
|
| 1166 |
+
boosted_color = centered_color * VIBRANCY_FACTOR
|
| 1167 |
+
# Restauramos la media
|
| 1168 |
+
denoised = boosted_color + current_mean
|
| 1169 |
+
|
| 1170 |
+
# --- SUELO DE ENERGÍA (Anti-Gris) ---
|
| 1171 |
+
if mag < 0.88:
|
| 1172 |
+
denoised = denoised * (0.95 / (mag + 1e-6))
|
| 1173 |
+
|
| 1174 |
+
# 3. Inyección de ADN Pony (Estructural)
|
| 1175 |
+
influence = 1.0 - (2.0 * progress - 1.0)**4
|
| 1176 |
+
scale_ratio = torch.clamp(torch.tensor(PONY_STD_TARGET / (mag + 1e-6)), 0.8, 1.3)
|
| 1177 |
+
|
| 1178 |
+
# Aplicamos el ADN con tu factor 1.3
|
| 1179 |
+
denoised = denoised * (1.0 + (scale_ratio - 1.0) * influence * 1.3)
|
| 1180 |
+
# Aplicamos el desplazamiento de negros
|
| 1181 |
+
denoised = denoised + (DELTA_MEAN * influence * 0.7)
|
| 1182 |
+
|
| 1183 |
+
# 4. Salto de Consistencia Blindado
|
| 1184 |
+
safe_sigma = max(sigma.item(), 1e-4)
|
| 1185 |
+
d = (x - denoised) / safe_sigma
|
| 1186 |
+
x = x + d * dt
|
| 1187 |
+
|
| 1188 |
+
if callback:
|
| 1189 |
+
callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i, "sampling_steps": total_steps})
|
| 1190 |
+
|
| 1191 |
+
return torch.clamp(x, -6.0, 6.0)
|
| 1192 |
+
|
| 1193 |
+
# =====================================================
|
| 1194 |
+
# AGGA UNIVERSAL BRIDGE
|
| 1195 |
+
# =====================================================
|
| 1196 |
+
DNA_LIBRARY = {
|
| 1197 |
+
"PONY": {"std": 0.016593, "mean": -0.000042},
|
| 1198 |
+
"NOOBAI": {"std": 0.019757, "mean": 0.010395},
|
| 1199 |
+
"ILLUSTRIOUS_V1": {"std": 0.021907, "mean": 0.012189},
|
| 1200 |
+
"ILLUSTRIOUS_V2": {"std": 0.022665, "mean": 0.011841},
|
| 1201 |
+
"VELVETTE": {"std": 0.019734, "mean": 0.010366},
|
| 1202 |
+
"ONEOBSESSION": {"std": 0.019625, "mean": 0.010283},
|
| 1203 |
+
"SDXL": {"std": 0.017260, "mean": 0.000001},
|
| 1204 |
+
"ANIMAGINE": {"std": 0.017165, "mean": 0.000001},
|
| 1205 |
+
}
|
| 1206 |
+
|
| 1207 |
+
@torch.no_grad()
|
| 1208 |
+
def sample_agga_universal_bridge(model, x, sigmas, extra_args=None, callback=None, **kwargs):
|
| 1209 |
+
extra_args = extra_args or {}
|
| 1210 |
+
s_in = x.new_ones([x.shape[0]])
|
| 1211 |
+
total_steps = len(sigmas) - 1
|
| 1212 |
+
shared.state.sampling_steps = total_steps
|
| 1213 |
+
|
| 1214 |
+
source_dna, target_dna = None, None
|
| 1215 |
+
p_scale, p_mean = 1.15, 0.85
|
| 1216 |
+
|
| 1217 |
+
for i in range(total_steps):
|
| 1218 |
+
shared.state.sampling_step = i + 1
|
| 1219 |
+
sigma, sigma_next = sigmas[i], sigmas[i + 1]
|
| 1220 |
+
dt = sigma_next - sigma
|
| 1221 |
+
progress = i / total_steps
|
| 1222 |
+
|
| 1223 |
+
denoised = model(x, sigma * s_in, **extra_args)
|
| 1224 |
+
denoised = torch.nan_to_num(denoised, nan=0.0, posinf=4.0, neginf=-4.0)
|
| 1225 |
+
mag = denoised.std()
|
| 1226 |
+
|
| 1227 |
+
if i == 0:
|
| 1228 |
+
# 1. AUTO-DETECCIÓN DE BASE
|
| 1229 |
+
source_key = min(DNA_LIBRARY, key=lambda k: abs(DNA_LIBRARY[k]["std"] - mag.item()))
|
| 1230 |
+
source_dna = DNA_LIBRARY[source_key]
|
| 1231 |
+
target_dna = source_dna
|
| 1232 |
+
|
| 1233 |
+
# 2. HACK DE DETECCIÓN DE PROMPT (Fix A1111/Reforge)
|
| 1234 |
+
prompt = ""
|
| 1235 |
+
for frame_info in inspect.stack():
|
| 1236 |
+
if 'p' in frame_info.frame.f_locals:
|
| 1237 |
+
p_obj = frame_info.frame.f_locals['p']
|
| 1238 |
+
if hasattr(p_obj, 'prompt'):
|
| 1239 |
+
prompt = str(p_obj.prompt).lower()
|
| 1240 |
+
break
|
| 1241 |
+
|
| 1242 |
+
# 3. MATRIZ DE COMANDOS
|
| 1243 |
+
detected_hacia = "Nativo (Auto)"
|
| 1244 |
+
detected_desde = "Auto-Detectado"
|
| 1245 |
+
for key in DNA_LIBRARY.keys():
|
| 1246 |
+
k_low = key.lower()
|
| 1247 |
+
if f"hacia_{k_low}" in prompt:
|
| 1248 |
+
target_dna = DNA_LIBRARY[key]
|
| 1249 |
+
detected_hacia = key
|
| 1250 |
+
if f"desde_{k_low}" in prompt:
|
| 1251 |
+
source_dna = DNA_LIBRARY[key]
|
| 1252 |
+
source_key = key
|
| 1253 |
+
detected_desde = "Forzado (Manual)"
|
| 1254 |
+
|
| 1255 |
+
# 4. SELECTOR DE POTENCIA
|
| 1256 |
+
modo_desc = "Estándar"
|
| 1257 |
+
if "modo_fuerte" in prompt:
|
| 1258 |
+
p_scale, p_mean = 1.35, 0.75
|
| 1259 |
+
modo_desc = "Fuerte (Contraste AGGA)"
|
| 1260 |
+
elif "modo_safe" in prompt:
|
| 1261 |
+
p_scale, p_mean = 1.0, 1.0
|
| 1262 |
+
modo_desc = "Safe (Sincronización 1:1)"
|
| 1263 |
+
elif "modo_ultra" in prompt:
|
| 1264 |
+
p_scale, p_mean = 1.50, 0.60
|
| 1265 |
+
modo_desc = "Ultra (Fuerza Bruta)"
|
| 1266 |
+
elif "modo_neutral" in prompt:
|
| 1267 |
+
p_scale, p_mean = 0.0, 0.0
|
| 1268 |
+
modo_desc = "Neutral (Solo Post-Proceso)"
|
| 1269 |
+
|
| 1270 |
+
# --- PANEL DE CONTROL AGGA: MOSTRANDO EL PODER ---
|
| 1271 |
+
print(f"\n" + "═"*60)
|
| 1272 |
+
print(f" 🚀 AGGA UNIVERSAL BRIDGE V10 - MOTOR ACTIVO")
|
| 1273 |
+
print(f" " + "─"*58)
|
| 1274 |
+
print(f" 📡 BASE: {source_key} [{detected_desde}]")
|
| 1275 |
+
print(f" 🎯 LORA: {detected_hacia} (Hacia)")
|
| 1276 |
+
print(f" ⚡ MODO: {modo_desc}")
|
| 1277 |
+
print(f" 📈 PARÁMETROS: Scale {p_scale} | Mean Shift {p_mean}")
|
| 1278 |
+
|
| 1279 |
+
# Extraemos solo tus comandos del prompt para mostrarlos
|
| 1280 |
+
comandos = [w for w in prompt.split() if any(x in w for x in ["hacia_", "desde_", "modo_"])]
|
| 1281 |
+
if comandos: print(f" 📝 COMANDOS DETECTADOS: {', '.join(comandos)}")
|
| 1282 |
+
|
| 1283 |
+
print(f" 🛠️ MÉTODO: Traducción Matricial de ADN (Campana de Gauss)")
|
| 1284 |
+
print(f"═"*60 + "\n")
|
| 1285 |
+
|
| 1286 |
+
# 5. INYECTOR DE NITIDEZ (Tus 0.16 clásicos)
|
| 1287 |
+
if 0.35 < progress < 0.85 and mag >= 0.90:
|
| 1288 |
+
blurred = F.avg_pool2d(denoised, kernel_size=3, stride=1, padding=1)
|
| 1289 |
+
denoised = denoised + ((denoised - blurred) * 0.16)
|
| 1290 |
+
|
| 1291 |
+
# 6. TRADUCCIÓN DE ADN MATRICIAL (Campana de Gauss)
|
| 1292 |
+
influence = 1.0 - (2.0 * progress - 1.0)**4
|
| 1293 |
+
scale_ratio = torch.clamp(torch.tensor(target_dna["std"] / (mag + 1e-6)), 0.6, 1.4)
|
| 1294 |
+
|
| 1295 |
+
denoised = denoised * (1.0 + (scale_ratio - 1.0) * influence * p_scale)
|
| 1296 |
+
denoised = denoised + ((target_dna["mean"] - source_dna["mean"]) * influence * p_mean)
|
| 1297 |
+
|
| 1298 |
+
# 7. SUELO DE ENERGÍA Y SALTO
|
| 1299 |
+
if mag < 0.88: denoised = denoised * (0.95 / (mag + 1e-6))
|
| 1300 |
+
x = x + ((x - denoised) / max(sigma.item(), 1e-4)) * dt
|
| 1301 |
+
|
| 1302 |
+
if callback:
|
| 1303 |
+
callback({"x": x, "i": i, "sigma": sigma, "sampling_step": i + 1, "sampling_steps": total_steps})
|
| 1304 |
+
|
| 1305 |
+
return torch.clamp(x, -6.0, 6.0)
|
| 1306 |
+
|
| 1307 |
+
# =====================================================
|
| 1308 |
+
# AGGA AUTO-INTELLIGENT SCHEDULER V2
|
| 1309 |
+
# =====================================================
|
| 1310 |
+
|
| 1311 |
+
def get_sigmas_agga_smart(n, sigma_min, sigma_max, device):
|
| 1312 |
+
|
| 1313 |
+
# 1. ESCÁNER DE PROMPT (Para overrides manuales)
|
| 1314 |
+
prompt_tags = ""
|
| 1315 |
+
try:
|
| 1316 |
+
for frame_info in inspect.stack():
|
| 1317 |
+
if 'p' in frame_info.frame.f_locals:
|
| 1318 |
+
p_obj = frame_info.frame.f_locals['p']
|
| 1319 |
+
if hasattr(p_obj, 'prompt'):
|
| 1320 |
+
prompt_tags = (str(p_obj.prompt) + " " + str(p_obj.all_prompts)).lower()
|
| 1321 |
+
break
|
| 1322 |
+
except:
|
| 1323 |
+
pass
|
| 1324 |
+
|
| 1325 |
+
# 2. SELECTOR MANUAL (Prioridad Absoluta)
|
| 1326 |
+
if "sched_ays" in prompt_tags:
|
| 1327 |
+
print(" AGGA SCHEDULER: Forzado a [AYS Anchor]")
|
| 1328 |
+
return get_sigmas_agga_ays_anchor(n, sigma_min, sigma_max, device)
|
| 1329 |
+
|
| 1330 |
+
if "sched_turbo" in prompt_tags:
|
| 1331 |
+
print(" AGGA SCHEDULER: Forzado a [DMD Turbo]")
|
| 1332 |
+
return get_sigmas_agga_dmd(n, sigma_min, sigma_max, device)
|
| 1333 |
+
|
| 1334 |
+
if "sched_repair" in prompt_tags:
|
| 1335 |
+
print(" AGGA SCHEDULER: Forzado a [Double Anchor]")
|
| 1336 |
+
return get_sigmas_agga_double_anchor(n, sigma_min, sigma_max, device)
|
| 1337 |
+
|
| 1338 |
+
# 3. LÓGICA AUTOMÁTICA POR ZONAS (La magia)
|
| 1339 |
+
|
| 1340 |
+
# ZONA 1: LIGHTNING (1-4 Pasos)
|
| 1341 |
+
# Aquí necesitamos Rho explosivo para que la imagen aparezca de golpe.
|
| 1342 |
+
if n <= 4:
|
| 1343 |
+
# Usamos DMD pero con una curva logarítmica simulada para convergencia instantánea
|
| 1344 |
+
return get_sigmas_agga_dmd(n, sigma_min, sigma_max, device)
|
| 1345 |
+
|
| 1346 |
+
# ZONA 2: TURBO (5-8 Pasos) -> Tu favorito para Flash V2
|
| 1347 |
+
# La curva DMD (Rho 7) es perfecta aquí porque mantiene el ruido alto al principio
|
| 1348 |
+
# y cae en picada al final, ideal para samplers agresivos.
|
| 1349 |
+
elif n <= 8:
|
| 1350 |
+
return get_sigmas_agga_dmd(n, sigma_min, sigma_max, device)
|
| 1351 |
+
|
| 1352 |
+
# ZONA 3: HYBRID SWEET-SPOT (9-19 Pasos) -> La zona de FUSIÓN
|
| 1353 |
+
# Aquí es donde AYS (Align Your Steps) brilla. Es una curva optimizada por NVIDIA
|
| 1354 |
+
# que distribuye los pasos "donde más importan". Ideal para 'fsn_euler_dpm'.
|
| 1355 |
+
elif n < 20:
|
| 1356 |
+
return get_sigmas_agga_ays_anchor(n, sigma_min, sigma_max, device)
|
| 1357 |
+
|
| 1358 |
+
# ZONA 4: HIGH FIDELITY (20-49 Pasos)
|
| 1359 |
+
# Dynamic Rho empieza suave y se vuelve preciso.
|
| 1360 |
+
# Da el mejor acabado de piel y texturas para 'sample_pseudo_hires_flash_v2'.
|
| 1361 |
+
elif n < 50:
|
| 1362 |
+
return get_sigmas_dynamic_rho(n, sigma_min, sigma_max, device)
|
| 1363 |
+
|
| 1364 |
+
# ZONA 5: DEEP REPAIR / WALLPAPER (50+ Pasos)
|
| 1365 |
+
# Si pones tantos pasos, es porque quieres arreglar algo roto o hacer upscaling.
|
| 1366 |
+
# Usamos Double Anchor para fijar la estructura.
|
| 1367 |
+
else:
|
| 1368 |
+
return get_sigmas_agga_double_anchor(n, sigma_min, sigma_max, device)
|
| 1369 |
+
|
| 1370 |
+
# =====================================================
|
| 1371 |
+
# AGGA Schedule
|
| 1372 |
+
# =====================================================
|
| 1373 |
+
|
| 1374 |
+
def get_sigmas_agga_dmd(n, sigma_min, sigma_max, device):
|
| 1375 |
+
|
| 1376 |
+
rho = 7.0
|
| 1377 |
+
ramp = torch.linspace(0, 1, n, device=device)
|
| 1378 |
+
min_inv_rho = sigma_min ** (1 / rho)
|
| 1379 |
+
max_inv_rho = sigma_max ** (1 / rho)
|
| 1380 |
+
sigmas = (max_inv_rho + ramp * (min_inv_rho - max_inv_rho)) ** rho
|
| 1381 |
+
|
| 1382 |
+
return torch.cat([sigmas, sigmas.new_zeros([1])])
|
| 1383 |
+
|
| 1384 |
+
def get_sigmas_log_linear(n, sigma_min, sigma_max, device):
|
| 1385 |
+
"""Ideal para AGGA Detail: Distribución logarítmica perfecta."""
|
| 1386 |
+
steps = torch.linspace(0, 1, n, device=device)
|
| 1387 |
+
sigmas = torch.exp(torch.log(torch.tensor(sigma_max)) * (1 - steps) + torch.log(torch.tensor(sigma_min)) * steps)
|
| 1388 |
+
return torch.cat([sigmas, sigmas.new_zeros([1])])
|
| 1389 |
+
|
| 1390 |
+
def get_sigmas_dynamic_rho(n, sigma_min, sigma_max, device, rho_start=5.0, rho_end=9.0):
|
| 1391 |
+
"""Curva de potencia variable para máxima estabilidad."""
|
| 1392 |
+
ramp = torch.linspace(0, 1, n, device=device)
|
| 1393 |
+
|
| 1394 |
+
v_rho = rho_start + (rho_end - rho_start) * ramp
|
| 1395 |
+
|
| 1396 |
+
sigmas = []
|
| 1397 |
+
for i in range(n):
|
| 1398 |
+
r = v_rho[i]
|
| 1399 |
+
m_inv_r = sigma_min ** (1 / r)
|
| 1400 |
+
M_inv_r = sigma_max ** (1 / r)
|
| 1401 |
+
sig = (M_inv_r + ramp[i] * (m_inv_r - M_inv_r)) ** r
|
| 1402 |
+
sigmas.append(sig)
|
| 1403 |
+
|
| 1404 |
+
sigmas = torch.stack(sigmas)
|
| 1405 |
+
return torch.cat([sigmas, sigmas.new_zeros([1])])
|
| 1406 |
+
|
| 1407 |
+
def get_sigmas_pseudo_native(n, sigma_min, sigma_max, device):
|
| 1408 |
+
"""Tu lógica original de rampas Soft/Sharp ahora como Scheduler universal."""
|
| 1409 |
+
return pseudo_hires_sigmas(n, sigma_min, sigma_max, device)
|
| 1410 |
+
|
| 1411 |
+
def get_sigmas_style_anchor(n, sigma_min, sigma_max, device):
|
| 1412 |
+
|
| 1413 |
+
ramp = torch.linspace(0, 1, n, device=device)
|
| 1414 |
+
|
| 1415 |
+
ramp_anchored = ramp + 0.15 * torch.sin(ramp * 3.1415)
|
| 1416 |
+
|
| 1417 |
+
sigmas = sigma_max * ((sigma_min / sigma_max) ** ramp_anchored)
|
| 1418 |
+
|
| 1419 |
+
sigmas[-2] = sigmas[-2] * 0.9
|
| 1420 |
+
|
| 1421 |
+
return torch.cat([sigmas, sigmas.new_zeros([1])])
|
| 1422 |
+
|
| 1423 |
+
def get_sigmas_ultra_anchor(n, sigma_min, sigma_max, device):
|
| 1424 |
+
|
| 1425 |
+
ramp = torch.linspace(0, 1, n, device=device)
|
| 1426 |
+
|
| 1427 |
+
ramp_hybrid = ramp + 0.32 * torch.sin(ramp * torch.pi)
|
| 1428 |
+
|
| 1429 |
+
sigmas = sigma_max * ((sigma_min / sigma_max) ** ramp_hybrid)
|
| 1430 |
+
|
| 1431 |
+
sigmas[-3:] = torch.linspace(sigmas[-3].item(), sigma_min, 3, device=device)
|
| 1432 |
+
|
| 1433 |
+
return torch.cat([sigmas, sigmas.new_zeros([1])])
|
| 1434 |
+
|
| 1435 |
+
def get_sigmas_agga_double_anchor(n, sigma_min, sigma_max, device):
|
| 1436 |
+
|
| 1437 |
+
t = torch.linspace(0, 1, n, device=device)
|
| 1438 |
+
|
| 1439 |
+
style_warp = 0.35 * torch.sin(t * torch.pi)
|
| 1440 |
+
|
| 1441 |
+
eye_sniper = 0.15 * torch.exp(-180 * (t - 0.82)**2)
|
| 1442 |
+
|
| 1443 |
+
dmd_tail = 0.10 * (t**4)
|
| 1444 |
+
|
| 1445 |
+
t_warped = t + style_warp + eye_sniper + dmd_tail
|
| 1446 |
+
t_warped = t_warped / t_warped[-1] # Normalización de la línea de tiempo
|
| 1447 |
+
|
| 1448 |
+
sigmas = sigma_max * ((sigma_min / sigma_max) ** (t_warped**1.1))
|
| 1449 |
+
|
| 1450 |
+
s_start = torch.log10(sigmas[-4])
|
| 1451 |
+
s_end = torch.log10(torch.as_tensor(sigma_min, device=device))
|
| 1452 |
+
|
| 1453 |
+
sigmas[-4:] = torch.logspace(s_start, s_end, 4, device=device)
|
| 1454 |
+
|
| 1455 |
+
return torch.cat([sigmas, sigmas.new_zeros([1])])
|
| 1456 |
+
|
| 1457 |
+
|
| 1458 |
+
def get_sigmas_agga_pixel_staircase(n, sigma_min, sigma_max, device):
|
| 1459 |
+
|
| 1460 |
+
t = torch.linspace(0, 1, n, device=device)
|
| 1461 |
+
sigmas = torch.exp(torch.log(torch.tensor(sigma_max)) * (1 - t) + torch.log(torch.tensor(sigma_min)) * t)
|
| 1462 |
+
|
| 1463 |
+
for i in range(len(sigmas)):
|
| 1464 |
+
if i % 3 != 0 and i > 0:
|
| 1465 |
+
# Bajada minúscula para evitar dt=0 (que rompe el sampler)
|
| 1466 |
+
sigmas[i] = sigmas[i-1] * 0.98
|
| 1467 |
+
|
| 1468 |
+
return torch.cat([sigmas, sigmas.new_zeros([1])])
|
| 1469 |
+
|
| 1470 |
+
def get_sigmas_agga_pixel_staircase_v2(
|
| 1471 |
+
n,
|
| 1472 |
+
sigma_min,
|
| 1473 |
+
sigma_max,
|
| 1474 |
+
device,
|
| 1475 |
+
hold_steps=3,
|
| 1476 |
+
decay=0.985
|
| 1477 |
+
):
|
| 1478 |
+
t = torch.linspace(0, 1, n, device=device)
|
| 1479 |
+
s_max = torch.as_tensor(sigma_max, device=device)
|
| 1480 |
+
s_min = torch.as_tensor(sigma_min, device=device)
|
| 1481 |
+
|
| 1482 |
+
sigmas = torch.exp(
|
| 1483 |
+
torch.log(s_max) * (1 - t) +
|
| 1484 |
+
torch.log(s_min) * t
|
| 1485 |
+
)
|
| 1486 |
+
|
| 1487 |
+
for i in range(1, len(sigmas)):
|
| 1488 |
+
if i % hold_steps != 0:
|
| 1489 |
+
|
| 1490 |
+
sigmas[i] = sigmas[i - 1] * decay
|
| 1491 |
+
|
| 1492 |
+
return torch.cat([sigmas, sigmas.new_zeros([1])])
|
| 1493 |
+
|
| 1494 |
+
def get_sigmas_agga_lora_universal_bridge(n, sigma_min, sigma_max, device):
|
| 1495 |
+
t = torch.linspace(0, 1, n, device=device)
|
| 1496 |
+
|
| 1497 |
+
t_warped = t + 0.28 * torch.sin(t * torch.pi)
|
| 1498 |
+
|
| 1499 |
+
sigmas = sigma_max * ((sigma_min / sigma_max) ** (t_warped**1.15))
|
| 1500 |
+
|
| 1501 |
+
sigmas[-2] = sigmas[-2] * 0.90
|
| 1502 |
+
|
| 1503 |
+
return torch.cat([sigmas, sigmas.new_zeros([1])])
|
| 1504 |
+
|
| 1505 |
+
def get_sigmas_agga_ays_anchor(n, sigma_min, sigma_max, device):
|
| 1506 |
+
ays_base = [14.615, 6.315, 3.771, 2.181, 1.342, 0.862, 0.555, 0.380, 0.234, 0.113, 0.029]
|
| 1507 |
+
t = torch.linspace(0, 1, n, device=device)
|
| 1508 |
+
t_warped = t + 0.15 * torch.sin(t * torch.pi)
|
| 1509 |
+
sigmas_base = torch.tensor(ays_base, device=device).log()
|
| 1510 |
+
indices = t_warped * (len(ays_base) - 1)
|
| 1511 |
+
idx_floor = indices.long().clamp(0, len(ays_base)-2)
|
| 1512 |
+
idx_ceil = (idx_floor + 1).clamp(0, len(ays_base)-1)
|
| 1513 |
+
alpha = indices - idx_floor
|
| 1514 |
+
|
| 1515 |
+
log_sigmas = sigmas_base[idx_floor] * (1 - alpha) + sigmas_base[idx_ceil] * alpha
|
| 1516 |
+
sigmas = torch.exp(log_sigmas)
|
| 1517 |
+
|
| 1518 |
+
return torch.cat([sigmas, sigmas.new_zeros([1])])
|
sd_samplers_pseudo_hires_loader.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from modules import sd_samplers_common
|
| 2 |
+
from modules.sd_samplers_kdiffusion import (
|
| 3 |
+
KDiffusionSampler,
|
| 4 |
+
samplers_data_k_diffusion,
|
| 5 |
+
)
|
| 6 |
+
|
| 7 |
+
from modules.sd_samplers_pseudo_hires import (
|
| 8 |
+
sample_pseudo_hires_soft,
|
| 9 |
+
sample_pseudo_hires_sharp,
|
| 10 |
+
sample_pseudo_hires_ultra,
|
| 11 |
+
sample_dpmpp_2m_pseudo_hires,
|
| 12 |
+
sample_pseudo_hires_detail,
|
| 13 |
+
sample_agga_dmd_turbo,
|
| 14 |
+
sample_agga_herrscher_native,
|
| 15 |
+
sample_agga_detail_native,
|
| 16 |
+
sample_agga_smart_combo,
|
| 17 |
+
sample_agga_hyper_detail_hybrid,
|
| 18 |
+
sample_agga_structural_detail,
|
| 19 |
+
sample_agga_style_repair_pro,
|
| 20 |
+
sample_agga_style_repair_prompt_aware,
|
| 21 |
+
sample_agga_style_repair_ultra,
|
| 22 |
+
sample_agga_lora_bridge,
|
| 23 |
+
sample_agga_lora_bridge_stable,
|
| 24 |
+
sample_agga_lora_bridge_sharp,
|
| 25 |
+
sample_agga_lora_bridge_ultra_sharp,
|
| 26 |
+
sample_agga_universal_bridge,
|
| 27 |
+
sample_agga_pixel_master,
|
| 28 |
+
)
|
| 29 |
+
|
| 30 |
+
def register():
|
| 31 |
+
existing = [s.name for s in samplers_data_k_diffusion]
|
| 32 |
+
count = 0
|
| 33 |
+
|
| 34 |
+
# =========================================================
|
| 35 |
+
# CONFIGURACIÓN: Samplers!
|
| 36 |
+
# Formato: (Nombre Visible, Función, [Alias1, Alias2...])
|
| 37 |
+
# =========================================================
|
| 38 |
+
agga_samplers_config = [
|
| 39 |
+
("AGGA Pseudo-HiRes Soft", sample_pseudo_hires_soft, ["AGGA_ph_soft"]),
|
| 40 |
+
("AGGA Pseudo-HiRes Sharp", sample_pseudo_hires_sharp, ["AGGA_ph_sharp"]),
|
| 41 |
+
("AGGA Pseudo-HiRes Ultra", sample_pseudo_hires_ultra, ["AGGA_ph_ultra"]),
|
| 42 |
+
("AGGA Pseudo-HiRes DPM++ 2M", sample_dpmpp_2m_pseudo_hires, ["agga_ph_dpm2m"]),
|
| 43 |
+
("AGGA Pseudo-HiRes Flash", sample_agga_smart_combo, ["agga_ph_flash_NTV"]),
|
| 44 |
+
("AGGA Pseudo-HiRes Detail", sample_pseudo_hires_detail, ["agga_ph_detail"]),
|
| 45 |
+
("AGGA DMD-Turbo Landing", sample_agga_dmd_turbo, ["agga_dmd_turbo"]),
|
| 46 |
+
("AGGA Herrscher-Native", sample_agga_herrscher_native, ["agga_herrscher_v6"]),
|
| 47 |
+
("AGGA-Detail-Native (LCM)", sample_agga_detail_native, ["agga_dn"]),
|
| 48 |
+
("AGGA-Structural-Detail", sample_agga_structural_detail, ["agga_struct_detail"]),
|
| 49 |
+
("AGGA Hyper-Detail Hybrid", sample_agga_hyper_detail_hybrid, ["agga_hyper_detail_hybrid"]),
|
| 50 |
+
("AGGA Style-Repair (Test)", sample_agga_style_repair_pro, ["agga_sr"]),
|
| 51 |
+
("AGGA Style-Repair (Prompt-Aware)", sample_agga_style_repair_prompt_aware, ["agga_sr_prompt"]),
|
| 52 |
+
("AGGA Style-Repair Ultra", sample_agga_style_repair_ultra, ["agga_sru"]),
|
| 53 |
+
("AGGA PDXL-Lora Adapted", sample_agga_lora_bridge, ["agga_LA"]),
|
| 54 |
+
("AGGA PDXL-Lora Adapted Stable", sample_agga_lora_bridge_stable, ["agga_LAS"]),
|
| 55 |
+
("AGGA PDXL-Lora Adapted Sharp", sample_agga_lora_bridge_sharp, ["agga_LA_Sharp"]),
|
| 56 |
+
("AGGA PDXL-Lora Adapted Ultra-Sharp", sample_agga_lora_bridge_ultra_sharp, ["agga_LA_US"]),
|
| 57 |
+
("AGGA Lora universal Bridge", sample_agga_universal_bridge, ["agga_L_UB"]),
|
| 58 |
+
("AGGA Pixel-Master (Test)", sample_agga_pixel_master, ["agga_pixel"]),
|
| 59 |
+
]
|
| 60 |
+
|
| 61 |
+
# =========================================================
|
| 62 |
+
# BUCLE DE REGISTRO AUTOMÁTICO
|
| 63 |
+
# =========================================================
|
| 64 |
+
for name, func, aliases in agga_samplers_config:
|
| 65 |
+
if name not in existing:
|
| 66 |
+
# Creamos el objeto Data
|
| 67 |
+
# 'f=func' es vital para capturar el valor actual del bucle en la lambda
|
| 68 |
+
s_data = sd_samplers_common.SamplerData(
|
| 69 |
+
name,
|
| 70 |
+
lambda model, f=func: KDiffusionSampler(f, model),
|
| 71 |
+
aliases=aliases,
|
| 72 |
+
options={}
|
| 73 |
+
)
|
| 74 |
+
|
| 75 |
+
# Inyectamos en la lista oficial de A1111
|
| 76 |
+
samplers_data_k_diffusion.append(s_data)
|
| 77 |
+
count += 1
|
| 78 |
+
|
| 79 |
+
print(f"[AGGA Module] {count} Samplers registered successfully.")
|
| 80 |
+
|
| 81 |
+
register()
|