mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-24 06:32:12 -03:00
feat: add "Respect Recommended Strength" feature to LoRA Randomizer
Add support for respecting recommended strength values from LoRA usage_tips when randomizing LoRA selection. Features: - New toggle setting to enable/disable recommended strength respect (default off) - Scale range slider (0-2, default 0.5-1.0) to adjust recommended values - Uses recommended strength × random(scale) when feature enabled - Fallbacks to original Model/Clip Strength range when no recommendation exists - Clip strength recommendations only apply when using Custom Range mode Backend changes: - Parse usage_tips JSON string to extract strength/clipStrength - Apply scale factor to recommended values during randomization - Pass new parameters through API route and node Frontend changes: - Update RandomizerConfig type with new properties - Add new UI section with toggle and dual-range slider - Wire up state management and event handlers - No layout shift (removed description text) Tests: - Add tests for enabled/disabled recommended strength in API routes - Add test verifying config passed to service - All existing tests pass Build: Include compiled Vue widgets
This commit is contained in:
@@ -152,6 +152,15 @@ class LoraRandomizerNode:
|
||||
use_same_clip_strength = randomizer_config.get("use_same_clip_strength", True)
|
||||
clip_strength_min = randomizer_config.get("clip_strength_min", 0.0)
|
||||
clip_strength_max = randomizer_config.get("clip_strength_max", 1.0)
|
||||
use_recommended_strength = randomizer_config.get(
|
||||
"use_recommended_strength", False
|
||||
)
|
||||
recommended_strength_scale_min = randomizer_config.get(
|
||||
"recommended_strength_scale_min", 0.5
|
||||
)
|
||||
recommended_strength_scale_max = randomizer_config.get(
|
||||
"recommended_strength_scale_max", 1.0
|
||||
)
|
||||
|
||||
# Extract locked LoRAs from input
|
||||
locked_loras = [lora for lora in input_loras if lora.get("locked", False)]
|
||||
@@ -170,6 +179,9 @@ class LoraRandomizerNode:
|
||||
count_mode=count_mode,
|
||||
count_min=count_min,
|
||||
count_max=count_max,
|
||||
use_recommended_strength=use_recommended_strength,
|
||||
recommended_strength_scale_min=recommended_strength_scale_min,
|
||||
recommended_strength_scale_max=recommended_strength_scale_max,
|
||||
)
|
||||
|
||||
return result_loras
|
||||
|
||||
@@ -225,6 +225,13 @@ class LoraRoutes(BaseModelRoutes):
|
||||
clip_strength_max = float(json_data.get("clip_strength_max", 1.0))
|
||||
locked_loras = json_data.get("locked_loras", [])
|
||||
pool_config = json_data.get("pool_config")
|
||||
use_recommended_strength = json_data.get("use_recommended_strength", False)
|
||||
recommended_strength_scale_min = float(
|
||||
json_data.get("recommended_strength_scale_min", 0.5)
|
||||
)
|
||||
recommended_strength_scale_max = float(
|
||||
json_data.get("recommended_strength_scale_max", 1.0)
|
||||
)
|
||||
|
||||
# Determine target count
|
||||
if count_min is not None and count_max is not None:
|
||||
@@ -260,6 +267,9 @@ class LoraRoutes(BaseModelRoutes):
|
||||
clip_strength_max=clip_strength_max,
|
||||
locked_loras=locked_loras,
|
||||
pool_config=pool_config,
|
||||
use_recommended_strength=use_recommended_strength,
|
||||
recommended_strength_scale_min=recommended_strength_scale_min,
|
||||
recommended_strength_scale_max=recommended_strength_scale_max,
|
||||
)
|
||||
|
||||
return web.json_response(
|
||||
|
||||
@@ -228,6 +228,9 @@ class LoraService(BaseModelService):
|
||||
count_mode: str = "fixed",
|
||||
count_min: int = 3,
|
||||
count_max: int = 7,
|
||||
use_recommended_strength: bool = False,
|
||||
recommended_strength_scale_min: float = 0.5,
|
||||
recommended_strength_scale_max: float = 1.0,
|
||||
) -> List[Dict]:
|
||||
"""
|
||||
Get random LoRAs with specified strength ranges.
|
||||
@@ -244,11 +247,37 @@ class LoraService(BaseModelService):
|
||||
count_mode: How to determine count ('fixed' or 'range')
|
||||
count_min: Minimum count for range mode
|
||||
count_max: Maximum count for range mode
|
||||
use_recommended_strength: Whether to use recommended strength from usage_tips
|
||||
recommended_strength_scale_min: Minimum scale factor for recommended strength
|
||||
recommended_strength_scale_max: Maximum scale factor for recommended strength
|
||||
|
||||
Returns:
|
||||
List of LoRA dicts with randomized strengths
|
||||
"""
|
||||
import random
|
||||
import json
|
||||
|
||||
def get_recommended_strength(lora_data: Dict) -> Optional[float]:
|
||||
"""Parse usage_tips JSON and extract recommended strength"""
|
||||
try:
|
||||
usage_tips = lora_data.get("usage_tips", "")
|
||||
if not usage_tips:
|
||||
return None
|
||||
tips_data = json.loads(usage_tips)
|
||||
return tips_data.get("strength")
|
||||
except (json.JSONDecodeError, TypeError, AttributeError):
|
||||
return None
|
||||
|
||||
def get_recommended_clip_strength(lora_data: Dict) -> Optional[float]:
|
||||
"""Parse usage_tips JSON and extract recommended clip strength"""
|
||||
try:
|
||||
usage_tips = lora_data.get("usage_tips", "")
|
||||
if not usage_tips:
|
||||
return None
|
||||
tips_data = json.loads(usage_tips)
|
||||
return tips_data.get("clipStrength")
|
||||
except (json.JSONDecodeError, TypeError, AttributeError):
|
||||
return None
|
||||
|
||||
if locked_loras is None:
|
||||
locked_loras = []
|
||||
@@ -296,10 +325,35 @@ class LoraService(BaseModelService):
|
||||
# Generate random strengths for selected LoRAs
|
||||
result_loras = []
|
||||
for lora in selected:
|
||||
model_str = round(random.uniform(model_strength_min, model_strength_max), 2)
|
||||
if use_recommended_strength:
|
||||
recommended_strength = get_recommended_strength(lora)
|
||||
if recommended_strength is not None:
|
||||
scale = random.uniform(
|
||||
recommended_strength_scale_min, recommended_strength_scale_max
|
||||
)
|
||||
model_str = round(recommended_strength * scale, 2)
|
||||
else:
|
||||
model_str = round(
|
||||
random.uniform(model_strength_min, model_strength_max), 2
|
||||
)
|
||||
else:
|
||||
model_str = round(
|
||||
random.uniform(model_strength_min, model_strength_max), 2
|
||||
)
|
||||
|
||||
if use_same_clip_strength:
|
||||
clip_str = model_str
|
||||
elif use_recommended_strength:
|
||||
recommended_clip_strength = get_recommended_clip_strength(lora)
|
||||
if recommended_clip_strength is not None:
|
||||
scale = random.uniform(
|
||||
recommended_strength_scale_min, recommended_strength_scale_max
|
||||
)
|
||||
clip_str = round(recommended_clip_strength * scale, 2)
|
||||
else:
|
||||
clip_str = round(
|
||||
random.uniform(clip_strength_min, clip_strength_max), 2
|
||||
)
|
||||
else:
|
||||
clip_str = round(
|
||||
random.uniform(clip_strength_min, clip_strength_max), 2
|
||||
|
||||
Reference in New Issue
Block a user