Update z-prompt-fusion-extension/scripts/promptlang.py
Browse files
z-prompt-fusion-extension/scripts/promptlang.py
CHANGED
|
@@ -73,7 +73,6 @@ def _wrap_cond_any(raw_cond):
|
|
| 73 |
"""
|
| 74 |
Заворачивает сырое cond (dict[str, Tensor] или Tensor) в обёртки,
|
| 75 |
которые понимает логика интерполяции (DictCondWrapper/TensorCondWrapper).
|
| 76 |
-
Ничего не индексируем — считаем, что пришёл «одиночный» cond.
|
| 77 |
"""
|
| 78 |
if isinstance(raw_cond, dict):
|
| 79 |
return interpolation_tensor.DictCondWrapper(raw_cond)
|
|
@@ -95,7 +94,7 @@ def _adapt_flattened_schedules(result: Any, total_steps: int):
|
|
| 95 |
if isinstance(result, list) and (len(result) == 0 or isinstance(result[0], list)):
|
| 96 |
return result
|
| 97 |
|
| 98 |
-
# 2)
|
| 99 |
batch = getattr(result, "batch", None)
|
| 100 |
if batch is not None:
|
| 101 |
adapted = []
|
|
@@ -189,7 +188,6 @@ def _build_tensor_for_prompt(
|
|
| 189 |
flat_prompts = tensor_builder.get_prompt_database()
|
| 190 |
|
| 191 |
# Сохраняем поведение A1111: в некоторых версиях промпт-объект содержит флаг негативности.
|
| 192 |
-
# Сделаем list-обёртку с тем же атрибутом, если он есть у исходного prompts.
|
| 193 |
class _SdLike(list):
|
| 194 |
pass
|
| 195 |
|
|
@@ -200,7 +198,9 @@ def _build_tensor_for_prompt(
|
|
| 200 |
else:
|
| 201 |
flat_input = flat_prompts
|
| 202 |
|
| 203 |
-
|
|
|
|
|
|
|
| 204 |
flattened = _adapt_flattened_schedules(flattened, total_steps)
|
| 205 |
|
| 206 |
# 3) Обернуть cond-значения
|
|
@@ -215,54 +215,52 @@ def _build_tensor_for_prompt(
|
|
| 215 |
]
|
| 216 |
wrapped_conds.append(wrapped_sched)
|
| 217 |
|
| 218 |
-
|
| 219 |
-
|
| 220 |
|
| 221 |
-
|
| 222 |
-
|
| 223 |
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
)
|
| 232 |
-
|
| 233 |
-
# Сформировать расписание, склеивая одинаковые соседние сегменты
|
| 234 |
-
schedules: List[prompt_parser.ScheduledPromptConditioning] = []
|
| 235 |
-
prev_wrapper = None
|
| 236 |
-
for step in range(total_steps):
|
| 237 |
-
params = interpolation_tensor.InterpolationParams(
|
| 238 |
-
t=step / max(1, total_steps - 1),
|
| 239 |
-
step=step,
|
| 240 |
-
total_steps=total_steps,
|
| 241 |
-
slerp_scale=slerp_scale,
|
| 242 |
-
slerp_epsilon=slerp_epsilon,
|
| 243 |
)
|
| 244 |
-
origin = global_state.get_origin_cond_at(step, is_hires=is_hires)
|
| 245 |
-
cond_wrapper = tensor.interpolate(params, origin, empty_cond.get())
|
| 246 |
-
|
| 247 |
-
if prev_wrapper is not None and cond_wrapper == prev_wrapper:
|
| 248 |
-
# Было: schedules[-1].end_at_step = step (иммутабельно -> нельзя)
|
| 249 |
-
_extend_last_segment_to(step)
|
| 250 |
-
else:
|
| 251 |
-
raw = getattr(cond_wrapper, "original_cond", cond_wrapper)
|
| 252 |
-
schedules.append(
|
| 253 |
-
prompt_parser.ScheduledPromptConditioning(
|
| 254 |
-
end_at_step=step,
|
| 255 |
-
cond=raw,
|
| 256 |
-
)
|
| 257 |
-
)
|
| 258 |
-
prev_wrapper = cond_wrapper
|
| 259 |
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 263 |
|
| 264 |
-
|
|
|
|
|
|
|
| 265 |
|
|
|
|
| 266 |
|
| 267 |
|
| 268 |
# -----------------------------------------------------------------------------
|
|
@@ -351,7 +349,7 @@ def _fusion_get_multicond_learned_conditioning(
|
|
| 351 |
|
| 352 |
|
| 353 |
# -----------------------------------------------------------------------------
|
| 354 |
-
# WebUI script shim (
|
| 355 |
# -----------------------------------------------------------------------------
|
| 356 |
|
| 357 |
class PromptFusionScript(scripts.Script):
|
|
|
|
| 73 |
"""
|
| 74 |
Заворачивает сырое cond (dict[str, Tensor] или Tensor) в обёртки,
|
| 75 |
которые понимает логика интерполяции (DictCondWrapper/TensorCondWrapper).
|
|
|
|
| 76 |
"""
|
| 77 |
if isinstance(raw_cond, dict):
|
| 78 |
return interpolation_tensor.DictCondWrapper(raw_cond)
|
|
|
|
| 94 |
if isinstance(result, list) and (len(result) == 0 or isinstance(result[0], list)):
|
| 95 |
return result
|
| 96 |
|
| 97 |
+
# 2) Duck typing: MulticondLearnedConditioning
|
| 98 |
batch = getattr(result, "batch", None)
|
| 99 |
if batch is not None:
|
| 100 |
adapted = []
|
|
|
|
| 188 |
flat_prompts = tensor_builder.get_prompt_database()
|
| 189 |
|
| 190 |
# Сохраняем поведение A1111: в некоторых версиях промпт-объект содержит флаг негативности.
|
|
|
|
| 191 |
class _SdLike(list):
|
| 192 |
pass
|
| 193 |
|
|
|
|
| 198 |
else:
|
| 199 |
flat_input = flat_prompts
|
| 200 |
|
| 201 |
+
# Важно: пробрасываем hires_steps и use_old_scheduling, как в A1111
|
| 202 |
+
hires_steps_arg = total_steps if is_hires else None
|
| 203 |
+
flattened = original_function(model, flat_input, total_steps, hires_steps_arg, use_old_scheduling)
|
| 204 |
flattened = _adapt_flattened_schedules(flattened, total_steps)
|
| 205 |
|
| 206 |
# 3) Обернуть cond-значения
|
|
|
|
| 215 |
]
|
| 216 |
wrapped_conds.append(wrapped_sched)
|
| 217 |
|
| 218 |
+
# 4) Собрать интерполяционный тензор и вычислить расписания по шагам
|
| 219 |
+
tensor = tensor_builder.build(wrapped_conds, empty_cond.get())
|
| 220 |
|
| 221 |
+
slerp_scale = global_state.get_slerp_scale()
|
| 222 |
+
slerp_epsilon = global_state.get_slerp_epsilon()
|
| 223 |
|
| 224 |
+
# Вспомогалка: безопасно «продлить» последний сегмент до step (иммутабельные namedtuple)
|
| 225 |
+
def _extend_last_segment_to(schedules_list: List[prompt_parser.ScheduledPromptConditioning], step_val: int):
|
| 226 |
+
last = schedules_list[-1]
|
| 227 |
+
if getattr(last, "end_at_step", None) != step_val:
|
| 228 |
+
schedules_list[-1] = prompt_parser.ScheduledPromptConditioning(
|
| 229 |
+
end_at_step=step_val,
|
| 230 |
+
cond=last.cond,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 231 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 232 |
|
| 233 |
+
# Сформировать расписание, склеивая одинаковые соседние сегменты
|
| 234 |
+
schedules: List[prompt_parser.ScheduledPromptConditioning] = []
|
| 235 |
+
prev_wrapper = None
|
| 236 |
+
for step in range(total_steps):
|
| 237 |
+
params = interpolation_tensor.InterpolationParams(
|
| 238 |
+
t=step / max(1, total_steps - 1),
|
| 239 |
+
step=step,
|
| 240 |
+
total_steps=total_steps,
|
| 241 |
+
slerp_scale=slerp_scale,
|
| 242 |
+
slerp_epsilon=slerp_epsilon,
|
| 243 |
+
)
|
| 244 |
+
origin = global_state.get_origin_cond_at(step, is_hires=is_hires)
|
| 245 |
+
cond_wrapper = tensor.interpolate(params, origin, empty_cond.get())
|
| 246 |
+
|
| 247 |
+
if prev_wrapper is not None and cond_wrapper == prev_wrapper:
|
| 248 |
+
_extend_last_segment_to(schedules, step)
|
| 249 |
+
else:
|
| 250 |
+
raw = getattr(cond_wrapper, "original_cond", cond_wrapper)
|
| 251 |
+
schedules.append(
|
| 252 |
+
prompt_parser.ScheduledPromptConditioning(
|
| 253 |
+
end_at_step=step,
|
| 254 |
+
cond=raw,
|
| 255 |
+
)
|
| 256 |
+
)
|
| 257 |
+
prev_wrapper = cond_wrapper
|
| 258 |
|
| 259 |
+
# Финализировать последний сегмент на последний шаг
|
| 260 |
+
if schedules:
|
| 261 |
+
_extend_last_segment_to(schedules, total_steps - 1)
|
| 262 |
|
| 263 |
+
return schedules
|
| 264 |
|
| 265 |
|
| 266 |
# -----------------------------------------------------------------------------
|
|
|
|
| 349 |
|
| 350 |
|
| 351 |
# -----------------------------------------------------------------------------
|
| 352 |
+
# WebUI script shim (сброс состояния между генерациями)
|
| 353 |
# -----------------------------------------------------------------------------
|
| 354 |
|
| 355 |
class PromptFusionScript(scripts.Script):
|