diff --git a/CHANGELOG.md b/CHANGELOG.md index 6297aba..1c8cfe6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,29 @@ All notable changes to this project will be documented in this file. +## [1.4.0] - 2026-09-24 + +### Changed + +#### ⚠️ `positive_text` no longer contains LoRA syntax; new `lora_text` output +- `positive_text` is now the positive prompt **without** `` tags — exactly what is encoded into the `positive` CONDITIONING output — so it can be fed straight into a text encoder +- The previous content, tags included, now comes from a new **`lora_text`** output, added as the **last** slot +- All other outputs keep their positions and types, so existing workflow connections stay valid (ComfyUI connects outputs by position) +- Action for existing workflows: + - `positive_text` fed a text encoder: nothing to do + - `positive_text` was used to record the LoRA syntax (saved prompts, metadata): reconnect that link to `lora_text` +- Applies to all three nodes (Random LoRA Loader, Filtered Random LoRA Loader, Filtered Random LoRA Loader (LBW)) + +#### ⚠️ Filtered nodes: cleaner encoded prompt +- Filtered Random LoRA Loader / (LBW) removed `` tags before encoding but left the separators behind, so the positive conditioning was encoded from text like `masterpiece, , trig_a, , , trig_c` +- Runs of commas and leading/trailing commas are now tidied before encoding, matching the 3-folder node. This applies to the negative prompt too (e.g. a trailing `, ` is no longer encoded) +- Because the encoded text changes, **results with the same seed may differ from 1.3.0 and earlier**. Keep using an earlier version if identical results are required + +### Fixed +- Random LoRA Loader: a run of three or more commas left after removing tags from the additional prompt was only partly collapsed + +--- + ## [1.3.0] - 2026-09-11 ### Fixed diff --git a/README.md b/README.md index c28a875..dcf7a5c 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Advanced node with LoRA Block Weight (LBW) support for precise effect control. - `json_sample_prompt`: Randomly retrieve sample prompts - `metadata`: Read directly from embedded metadata - **Sample Prompt Optimization**: Automatically remove LoRA syntax from samples and apply node-configured strength -- **Dual Text Outputs**: Separate positive_text and negative_text outputs +- **Text Outputs**: `positive_text` / `negative_text`, plus `lora_text` carrying the LoRA syntax (v1.4.0) - **ComfyUI Standard Seed Control**: Supports fixed/randomize/increment/decrement - **Wildcard Encode Integration**: Works seamlessly with Wildcard Encode (Inspire) - **LoRA Syntax Auto-Removal**: Cleans up LoRA syntax in additional_prompt to prevent noise @@ -176,6 +176,7 @@ Or manually delete the RandomLoRALoader folder and restart ComfyUI. - `MODEL` / `CLIP`: Connect to KSampler - `positive` / `negative`: Connect to Set Conditioning or KSampler - `positive_text` / `negative_text`: Connect to Show Text for verification (recommended) + - `lora_text`: Connect to Show Text or a prompt/metadata saving node to record which LoRAs were picked ### Wildcard Encode Integration (Recommended) @@ -508,23 +509,33 @@ All nodes provide the following outputs: | `CLIP` | CLIP | CLIP with LoRAs applied | | `positive` | CONDITIONING | Positive conditioning (LoRA syntax removed) | | `negative` | CONDITIONING | Negative conditioning | -| `positive_text` | STRING | Full positive prompt text with LoRA syntax | +| `positive_text` | STRING | Positive prompt text **without** LoRA syntax — exactly what is encoded into `positive` (v1.4.0) | | `negative_text` | STRING | Full negative prompt text | | `preview` | IMAGE | Batch of preview images for selected LoRAs (v1.1.0) | +| `lora_text` | STRING | Positive prompt text **with** LoRA syntax (the former `positive_text` content, v1.4.0) | + +> ⚠️ **Output changes in v1.4.0** +> +> `positive_text` no longer contains `` tags; the previous content now comes from the new `lora_text` output (last slot). All other outputs keep their positions and types, so existing connections stay valid. +> +> - `positive_text` fed a text encoder: no rewiring needed. The tags are no longer read as text +> - `positive_text` was used to record the LoRA syntax (saved prompts, metadata): reconnect that to `lora_text` +> +> The Filtered nodes also now tidy the stray `, ,` left behind after removing tags (and leading/trailing commas) before encoding, as the 3-folder node already did. Because the encoded text changes, **results with the same seed may differ from earlier versions**. If you need identical results to an earlier version, keep using that version. ### Text Output Format -**positive_text example:** +**lora_text example:** ``` , , anime style, alice, blonde hair, 1girl, beautiful ``` -**LBW node positive_text example:** +**LBW node lora_text example:** ``` , anime style, 1girl, beautiful ``` -**positive (CONDITIONING) content:** +**positive_text / positive (CONDITIONING) content:** ``` anime style, alice, blonde hair, 1girl, beautiful (LoRA syntax removed for clean prompt) diff --git a/README_LBW.md b/README_LBW.md index c864ba4..685e1d4 100644 --- a/README_LBW.md +++ b/README_LBW.md @@ -6,9 +6,15 @@ --- +## Overview + +Filtered Random LoRA Loader (LBW) is the Filtered Random LoRA Loader with LoRA Block Weight (LBW) support added. It lets you control precisely which parts of the U-Net a LoRA is applied to. + +--- + ## Features -### **Core Features (from Filtered Random LoRA Loader)** +### **Core Features (shared with Filtered Random LoRA Loader)** - ✅ Random LoRA selection from a single folder - ✅ Keyword filtering (AND/OR modes) - ✅ Metadata search (filename or embedded metadata) @@ -18,7 +24,7 @@ - ✅ Direct serial connection support ### **Advanced Features (LBW)** -- ✅ **LoRA Block Weight (LBW) support** +- ✅ **LoRA Block Weight (LBW) support**: set a separate strength for each U-Net block to control style, character, composition and so on independently - ✅ **Automatic SD1.5/SDXL detection** - ✅ **4 preset modes + custom input** - ✅ **Automatic weight adjustment** @@ -29,13 +35,17 @@ ### **What is LBW?** -LoRA Block Weight allows you to control which parts of the U-Net model are affected by the LoRA: +LoRA Block Weight lets you control which parts of the U-Net the LoRA affects. The Stable Diffusion U-Net is made up of three parts: -- **INPUT blocks**: Structure, composition, layout -- **MIDDLE block**: Overall features -- **OUTPUT blocks**: Style, details, fine-tuning +``` +INPUT blocks → Structure, composition, layout + ↓ +MIDDLE block → Overall features + ↓ +OUTPUT blocks → Style, details, fine-tuning +``` -By adjusting weights for each block, you can precisely control the LoRA's effect. +By adjusting the weight of each block, you can precisely control the LoRA's effect. --- @@ -47,33 +57,33 @@ All blocks weighted at 1.0 (standard LoRA application, no LBW). --- ### **2. Style Focused** -Emphasizes OUTPUT blocks only. - -**Best for:** -- Style LoRAs -- Art style transfer -- Visual aesthetic changes +Enables OUTPUT blocks only. **SDXL:** `1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1` **SD1.5:** `1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1` +**Best for:** +- Style LoRAs (anime style, watercolor, etc.) +- Art style and effect LoRAs +- Changing the visual aesthetic + **Effect:** - ✅ Strong style changes -- ❌ Minimal structure/character changes +- ❌ Minimal structure/character changes (ideal when you want to keep the existing composition) --- ### **3. Character Focused** -Emphasizes INPUT (early) + MIDDLE + OUTPUT blocks. - -**Best for:** -- Character LoRAs -- Face/feature preservation -- Balanced application +Enables INPUT (early) + MIDDLE + OUTPUT blocks. **SDXL:** `1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1` **SD1.5:** `1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1` +**Best for:** +- Character and person LoRAs +- Concept LoRAs +- Preserving faces/features + **Effect:** - ✅ Strong character features - ✅ Balanced overall effect @@ -81,16 +91,15 @@ Emphasizes INPUT (early) + MIDDLE + OUTPUT blocks. --- ### **4. Structure/Composition Only** -Emphasizes INPUT + MIDDLE blocks only. - -**Best for:** -- Pose LoRAs -- Composition LoRAs -- Layout/structure control +Enables INPUT + MIDDLE blocks only. **SDXL:** `1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0` **SD1.5:** `1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0` +**Best for:** +- Pose LoRAs +- Composition and layout LoRAs + **Effect:** - ✅ Strong structure/pose changes - ❌ Minimal style changes @@ -98,24 +107,29 @@ Emphasizes INPUT + MIDDLE blocks only. --- ### **5. Balanced / Soft** -Soft application across selected blocks. - -**Best for:** -- Subtle effects -- Multi-LoRA workflows -- General-purpose LoRAs +Soft application across selected blocks. The later OUTPUT blocks are turned down to avoid over-application. **SDXL:** `1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0` **SD1.5:** `1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0` +**Best for:** +- Subtle effects and fine adjustment +- Multi-LoRA workflows +- General-purpose LoRAs + **Effect:** -- ✅ Balanced, gentle application +- ✅ Balanced, gentle application with a natural finish - ✅ Good for stacking multiple LoRAs --- ### **6. Preset: Random** -Randomly selects one of the 4 presets above. +Randomly picks one of the 4 presets above on each run. + +``` +weight_mode: "Preset: Random" +→ One of the 4 presets is picked on each run +``` **Best for:** - Experimentation @@ -133,7 +147,8 @@ Custom weight specification. **Example (SDXL):** ``` -1,0.5,0.5,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.7,0.7,0.7,1,1,1,1,1,1,1 +weight_mode: "Direct Input" +lbw_input: "1,0.5,0.5,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.7,0.7,0.7,1,1,1,1,1,1,1" ``` **Auto-adjustment:** @@ -149,11 +164,39 @@ Custom weight specification. BASE, IN00-IN08 (9), MID (1), OUT00-OUT08 (9) ``` +| Index | Block | Role | +|-------|-------|------| +| 0 | BASE | Overall base | +| 1-9 | INPUT (IN00-08) | Structure/composition | +| 10 | MIDDLE (M00) | Intermediate features | +| 11-19 | OUTPUT (OUT00-08) | Style/details | + +**Weight example:** +``` +1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1 +BASE,IN00-08 (OFF),M00,OUT00-08 (ON) +→ LoRA applied to OUTPUT blocks only (style focused) +``` + ### **SD1.5 (17 elements)** ``` BASE, IN01,IN02,IN04,IN05,IN07,IN08 (6), MID (1), OUT03-OUT11 (9) ``` +| Index | Block | Role | +|-------|-------|------| +| 0 | BASE | Overall base | +| 1-6 | INPUT (IN01,02,04,05,07,08) | Structure/composition | +| 7 | MIDDLE (M00) | Intermediate features | +| 8-16 | OUTPUT (OUT03-11) | Style/details | + +**Weight example:** +``` +1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1 +BASE,IN (OFF),M00,OUT (ON) +→ LoRA applied to OUTPUT blocks only (style focused) +``` + --- ## Automatic Detection @@ -165,13 +208,18 @@ The node automatically detects whether a LoRA is SD1.5 or SDXL by analyzing the - **SD1.5**: `output_blocks_0` to `output_blocks_11` (12 blocks) - **SDXL**: `output_blocks_0` to `output_blocks_8` (9 blocks) +``` +SDXL detected → 20-element weights are used +SD1.5 detected → 17-element weights are used +``` + **You don't need to specify the model type manually!** ✅ --- ### **Weight Adjustment** -If the number of weights doesn't match the detected LoRA type: +If the number of weights doesn't match the detected LoRA type, it is adjusted automatically: **Example 1: Too few weights** ``` @@ -197,9 +245,34 @@ Detected: SDXL (requires 20) [Filtered Random LoRA Loader (LBW)] MODEL → [KSampler] CLIP → [CLIP Text Encode] - positive_text → [Show Text] (optional, for debugging) + lora_text → [Show Text] (optional, for debugging) ``` +**Steps:** + +1. **Place the node** + ``` + [Filtered Random LoRA Loader (LBW)] + ``` + +2. **Set the folder and keywords** + ``` + lora_folder_path: "path/to/loras" + keyword_filter: "anime style" + num_loras: 1 + ``` + +3. **Choose the LBW mode** + ``` + weight_mode: "Style Focused" + ``` + +4. **Connect MODEL/CLIP** + ``` + MODEL → [KSampler] + CLIP → [CLIP Text Encode] + ``` + ### **Parameters** #### **LoRA Settings** @@ -215,7 +288,7 @@ Detected: SDXL (requires 20) - `filter_mode`: AND / OR - `search_in_metadata`: Search in JSON/embedded metadata (slower) -#### **LBW Settings** (New!) +#### **LBW Settings** - `weight_mode`: Normal / 4 Presets / Random / Direct Input - `lbw_input`: Custom weights (only for Direct Input mode) @@ -229,7 +302,7 @@ Detected: SDXL (requires 20) ### **LBW Syntax** -When LBW is applied, the `positive_text` output includes LBW syntax: +When LBW is applied, the `lora_text` output (`positive_text` before v1.4.0) includes LBW syntax: **Normal (All 1.0):** ``` @@ -241,7 +314,59 @@ When LBW is applied, the `positive_text` output includes LBW syntax: ``` -**Note:** The LBW is applied internally to the MODEL. The syntax in `positive_text` is for reference/re-use with other nodes. +**Note:** The LBW is applied internally to the MODEL. The syntax in `lora_text` is for reference/re-use with other nodes. + +--- + +## Examples + +### **Example 1: Change the style only** + +``` +[Load Checkpoint] → [Filtered Random LoRA Loader (LBW)] + weight_mode: "Style Focused" + keyword_filter: "anime" + ↓ + [KSampler] +``` + +**Result:** The composition stays the same; only the style becomes anime-like + +--- + +### **Example 2: Staged application with multiple LoRAs** + +``` +[Load Checkpoint] + ↓ +[Filtered Random LoRA Loader (LBW)] (Structure/Composition Only) + keyword_filter: "pose" + ↓ +[Filtered Random LoRA Loader (LBW)] (Style Focused) + keyword_filter: "watercolor" + ↓ +[KSampler] +``` + +**Result:** Pose adjustment → watercolor style applied + +--- + +### **Example 3: Character + style** + +``` +[Load Checkpoint] + ↓ +[Filtered Random LoRA Loader (LBW)] (Character Focused) + keyword_filter: "character_name" + ↓ +[Filtered Random LoRA Loader (LBW)] (Style Focused) + keyword_filter: "art_style" + ↓ +[KSampler] +``` + +**Result:** Character features preserved + style changed --- @@ -252,9 +377,9 @@ When LBW is applied, the `positive_text` output includes LBW syntax: | LoRA Type | Recommended Preset | Why | |-----------|-------------------|-----| | Style/Art | Style Focused | OUTPUT blocks control style | -| Character | Character Focused | Balanced IN+MID+OUT for features | +| Character | Character Focused | Balanced IN+MID+OUT preserves features | | Pose/Composition | Structure/Composition Only | INPUT blocks control layout | -| General | Balanced / Soft | Gentle, stackable effect | +| General/fine adjustment | Balanced / Soft | Gentle, stackable effect | --- @@ -268,7 +393,7 @@ The difference between presets is **more visible** with: The difference is **less visible** with: - ⚠️ Weak LoRAs (low model_strength) - ⚠️ Multiple LoRAs applied simultaneously -- ⚠️ LoRAs with evenly distributed training +- ⚠️ LoRAs whose training effect is spread evenly across blocks --- @@ -280,11 +405,17 @@ Setting all weights to 0 completely disables the LoRA effect: ``` This is equivalent to not applying the LoRA at all. +**Weight guide:** +- **0**: Completely off +- **0.5**: Weaker +- **1.0**: Standard +- **1.5 or more**: Stronger (watch for over-application) + --- ### **4. Serial Connection** -For applying different LBW settings to different LoRAs: +For applying different LBW settings to different LoRAs, connect nodes in series: ``` [Filtered Random LoRA Loader (LBW)] (Style Focused) ↓ @@ -295,6 +426,24 @@ For applying different LBW settings to different LoRAs: All LoRAs within a single node instance use the same LBW setting. +**Tips:** +- **Structure → style** is the basic order +- Strength can also be adjusted per node + +--- + +### **5. Troubleshooting** + +**If there is no effect:** +- Check that the weights aren't all 0 +- Check that the LoRA is loaded correctly +- Check the console for the LBW application message + +**If the effect is too strong:** +- Lower model_strength +- Try the Balanced / Soft preset +- Adjust the weights to 0.5–0.8 + --- ## Requirements @@ -336,6 +485,82 @@ Supports the following formats (in priority order): The node automatically searches for preview files matching the LoRA filename. +**File matching:** +- Files that start with the LoRA filename (case-insensitive) +- Example: matches for `style_anime.safetensors`: + - `style_anime.png` ✅ + - `style_anime_preview.jpg` ✅ + - `STYLE_ANIME.PNG` ✅ + +--- + +## Advanced: Custom Presets + +To create your own presets or change the existing ones, you can edit the source file directly. + +### **How to Edit** + +**File location:** +``` +ComfyUI/custom_nodes/RandomLoRALoader/filtered_random_lora_loader_lbw.py +``` + +**Lines to edit:** 29–41 (`SDXL_PRESETS` for SDXL, `SD15_PRESETS` for SD1.5) + +### **Example 1: Add your own preset** + +```python +SDXL_PRESETS = { + "Style Focused": "1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1", + "Character Focused": "1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1", + "Structure/Composition Only": "1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0", + "Balanced / Soft": "1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + # ↓ Your own preset + "My Custom Mix": "0.5,0.5,0.5,0.5,0,0,0,0,0,0,1,0.8,0.8,0.8,0.8,0.8,0.5,0.5,0.5,0.5" +} +``` + +### **Example 2: Adjust an existing preset** + +```python +SDXL_PRESETS = { + # Make Style Focused stronger + "Style Focused": "1,0,0,0,0,0,0,0,0,0,0,1.2,1.2,1.2,1.2,1.2,1.2,1.2,1.2,1.2", + + # Make Character Focused milder + "Character Focused": "0.8,0.8,0.8,0.8,0,0,0,0,0,0,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8", + ... +} +``` + +### **Example 3: Rename presets** + +```python +SDXL_PRESETS = { + "Style Only": "1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1", + "Character First": "1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1", + "Composition Only": "1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0", + ... +} +``` + +### **Important Notes** + +⚠️ **Before editing:** +- Make a backup of the original file +- Watch the Python syntax (commas, quotes) + +⚠️ **Number of weights:** +- SDXL presets: exactly 20 elements +- SD1.5 presets: exactly 17 elements +- Mismatched counts are auto-adjusted, but specifying them exactly is more reliable + +⚠️ **After editing:** +- Fully restart ComfyUI to apply the changes +- Check the console for syntax errors + +💡 **Tip:** If editing the file is a hassle, use the "Direct Input" mode! + --- ## Disclaimer @@ -377,7 +602,7 @@ MIT License ## Author -Your Name +konohana --- diff --git a/README_LBW_ja.md b/README_LBW_ja.md index 732bf03..c9f9e6a 100644 --- a/README_LBW_ja.md +++ b/README_LBW_ja.md @@ -1,6 +1,6 @@ -# Filtered Random LoRA Loader (LBW) - 詳細ガイド +# Filtered Random LoRA Loader (LBW) -**LoRAブロックウェイト(LBW)対応版** +**LoRAブロックウェイト(LBW)対応、SD1.5/SDXL自動検出付き** ![FilteredRandomLoRALoader(LBW)ワークフロー例](./images/lbw_final_single.webp) @@ -8,53 +8,161 @@ ## 概要 -Filtered Random LoRA Loader (LBW) は、LoRAブロックウェイト(LBW)機能を追加した高度なノードです。U-Netのどの部分にLoRAを適用するかを細かく制御できます。 +Filtered Random LoRA Loader (LBW) は、Filtered Random LoRA LoaderにLoRAブロックウェイト(LBW)機能を追加したノードです。U-Netのどの部分にLoRAを適用するかを細かく制御できます。 --- ## 主な機能 -### **✅ LoRAブロックウェイト(LBW)対応** -- U-Netのブロックごとに個別の強度を設定 -- 画風、キャラクター、構図などを分離制御 +### **基本機能(Filtered Random LoRA Loaderと共通)** +- ✅ 1つのフォルダからLoRAをランダム選択 +- ✅ キーワードフィルタ(AND/ORモード) +- ✅ メタデータ検索(ファイル名または埋め込みメタデータ) +- ✅ プレビュー画像(静止画・アニメーション画像・動画に対応) +- ✅ トリガーワードの取得 +- ✅ ファイル名による重複除外 +- ✅ そのまま直列接続が可能 -### **✅ 自動SD1.5/SDXL検出** -- LoRAファイルを自動判定 -- ウェイト数を自動調整 - -### **✅ 4つのプリセットモード** -- Style Focused(画風特化) -- Character Focused(キャラ重視) -- Structure/Composition Only(構造・構図のみ) -- Balanced / Soft(バランス・穏やか) - -### **✅ カスタム入力** -- Direct Inputモードで任意のウェイトを指定 -- Preset: Randomモードでランダムプリセット選択 +### **拡張機能(LBW)** +- ✅ **LoRAブロックウェイト(LBW)対応**:U-Netのブロックごとに個別の強度を設定し、画風・キャラクター・構図などを分離して制御 +- ✅ **SD1.5/SDXLの自動検出** +- ✅ **4つのプリセットモード+カスタム入力** +- ✅ **ウェイト数の自動調整** --- -## LBWとは? +## LoRAブロックウェイト(LBW) -### **LoRAブロックウェイトの仕組み** +### **LBWとは?** -Stable DiffusionのU-Netは以下の3つの部分で構成されています: +LoRAブロックウェイトを使うと、U-Netのどの部分にLoRAを効かせるかを制御できます。Stable DiffusionのU-Netは次の3つの部分で構成されています。 ``` INPUT blocks → 構造、構図、レイアウト ↓ MIDDLE block → 全体的な特徴 ↓ -OUTPUT blocks → 画風、ディテール、細部調整 +OUTPUT blocks → 画風、ディテール、細部の調整 ``` -LBWを使うと、**各ブロックに異なるLoRA強度を設定**できます。 +ブロックごとにウェイトを調整することで、LoRAの効き方を細かく制御できます。 + +--- + +## ウェイトモード + +### **1. Normal (All 1.0)** - デフォルト +すべてのブロックのウェイトが1.0(LBWを使わない通常のLoRA適用)です。 + +--- + +### **2. Style Focused(画風特化)** +OUTPUTブロックのみを有効にします。 + +**SDXL:** `1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1` +**SD1.5:** `1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1` + +**向いているもの:** +- 画風LoRA(アニメ風、水彩風など) +- スタイルLoRA、エフェクトLoRA +- 見た目の雰囲気を変えたい場合 + +**効果:** +- ✅ 画風が強く変わる +- ❌ 構図やキャラクターはほとんど変わらない(既存の構図を保ちたい場合に最適) + +--- + +### **3. Character Focused(キャラ重視)** +INPUT前半+MIDDLE+OUTPUTを有効にします。 + +**SDXL:** `1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1` +**SD1.5:** `1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1` + +**向いているもの:** +- キャラクターLoRA、人物LoRA +- コンセプトLoRA +- 顔や特徴を保ちたい場合 + +**効果:** +- ✅ キャラクターの特徴が強く出る +- ✅ 全体的にバランスの取れた効き方 + +--- + +### **4. Structure/Composition Only(構造・構図のみ)** +INPUT+MIDDLEブロックのみを有効にします。 + +**SDXL:** `1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0` +**SD1.5:** `1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0` + +**向いているもの:** +- ポーズLoRA +- 構図LoRA、レイアウトLoRA + +**効果:** +- ✅ 構造やポーズが強く変わる +- ❌ 画風はほとんど変わらない + +--- + +### **5. Balanced / Soft(バランス・穏やか)** +選んだブロックに穏やかに適用します。OUTPUT後半を弱めて過剰な効きを防ぎます。 + +**SDXL:** `1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0` +**SD1.5:** `1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0` + +**向いているもの:** +- 控えめに効かせたい場合、微調整 +- 複数のLoRAを併用するワークフロー +- 汎用LoRA + +**効果:** +- ✅ バランスの取れた穏やかな効き方で、自然な仕上がり +- ✅ 複数のLoRAを重ねやすい + +--- + +### **6. Preset: Random** +上記4つのプリセットから、実行ごとに1つをランダムに選びます。 + +``` +weight_mode: "Preset: Random" +→ 実行ごとに4つのプリセットから1つ選択 +``` + +**向いているもの:** +- 試行錯誤 +- バリエーションの生成 +- ランダムな効果 + +--- + +### **7. Direct Input** +ウェイトを直接指定します。 + +**形式:** +- SDXL: カンマ区切りで20個の値 +- SD1.5: カンマ区切りで17個の値 + +**例(SDXL):** +``` +weight_mode: "Direct Input" +lbw_input: "1,0.5,0.5,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.7,0.7,0.7,1,1,1,1,1,1,1" +``` + +**自動調整:** +- 要素数が足りない場合:末尾を1.0で埋める +- 要素数が多すぎる場合:末尾から切り詰める --- ## ブロック構造 ### **SDXL(20要素)** +``` +BASE, IN00-IN08 (9), MID (1), OUT00-OUT08 (9) +``` | インデックス | ブロック | 役割 | |------------|---------|------| @@ -70,9 +178,10 @@ BASE,IN00-08 (OFF),M00,OUT00-08 (ON) → OUTPUTブロックのみLoRA適用(画風特化) ``` ---- - ### **SD1.5(17要素)** +``` +BASE, IN01,IN02,IN04,IN05,IN07,IN08 (6), MID (1), OUT03-OUT11 (9) +``` | インデックス | ブロック | 役割 | |------------|---------|------| @@ -90,79 +199,56 @@ BASE,IN (OFF),M00,OUT (ON) --- -## プリセット詳細 +## 自動検出 -### **1. Style Focused(画風特化)** +### **LoRAタイプの検出** -**SDXL:** `1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1` -**SD1.5:** `1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1` +ノードはモデル構造を解析して、LoRAがSD1.5用かSDXL用かを自動で判定します。 -**特徴:** -- OUTPUTブロックのみ有効 -- 構図を変えず画風のみ適用 -- 既存の構図を保ちたい場合に最適 +- **SD1.5**: `output_blocks_0`〜`output_blocks_11`(12ブロック) +- **SDXL**: `output_blocks_0`〜`output_blocks_8`(9ブロック) -**用途:** -- 画風LoRA(アニメ風、水彩風など) -- スタイルLoRA -- エフェクトLoRA +``` +SDXL検出 → 20要素のウェイトを使用 +SD1.5検出 → 17要素のウェイトを使用 +``` + +**モデルの種類を手動で指定する必要はありません** ✅ --- -### **2. Character Focused(キャラ重視)** +### **ウェイト数の自動調整** -**SDXL:** `1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1` -**SD1.5:** `1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1` +入力したウェイトの数が、検出したLoRAタイプと合わない場合は自動で調整します。 -**特徴:** -- INPUT前半 + MIDDLE + OUTPUT有効 -- キャラクターの特徴を保持 -- バランスの取れた適用 +**例1: 足りない場合** +``` +入力: 1,0,0(3要素) +検出: SDXL(20要素必要) +→ 自動調整: 1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +``` -**用途:** -- キャラクターLoRA -- 人物LoRA -- コンセプトLoRA - ---- - -### **3. Structure/Composition Only(構造・構図のみ)** - -**SDXL:** `1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0` -**SD1.5:** `1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0` - -**特徴:** -- INPUT + MIDDLEブロックのみ有効 -- 画風を変えず構図のみ変更 -- ポーズや構図調整に最適 - -**用途:** -- ポーズLoRA -- 構図LoRA -- レイアウトLoRA - ---- - -### **4. Balanced / Soft(バランス・穏やか)** - -**SDXL:** `1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0` -**SD1.5:** `1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0` - -**特徴:** -- 全体的に穏やかな適用 -- OUTPUT後半を弱めて過剰適用を防止 -- 自然な仕上がり - -**用途:** -- 汎用LoRA -- 微調整用 -- 複数LoRA併用時 +**例2: 多すぎる場合** +``` +入力: 1,0,0,...,0,0,0(25要素) +検出: SDXL(20要素必要) +→ 自動調整: 1,0,0,...,0,0,0(先頭20要素のみ) +``` --- ## 使い方 -### **基本的な使い方** +### **基本的なワークフロー** + +``` +[Filtered Random LoRA Loader (LBW)] + MODEL → [KSampler] + CLIP → [CLIP Text Encode] + lora_text → [Show Text](任意、確認用) +``` + +**手順:** 1. **ノードを配置** ``` @@ -176,8 +262,6 @@ BASE,IN (OFF),M00,OUT (ON) num_loras: 1 ``` - > フォルダスキャンの挙動(対象拡張子、シンボリックリンクの追跡、候補リストのソート)は他のノードと共通です。詳細は[README_ja.md の「フォルダスキャンについて」](README_ja.md#フォルダスキャンについて)を参照してください。 - 3. **LBWモードを選択** ``` weight_mode: "Style Focused" @@ -189,33 +273,49 @@ BASE,IN (OFF),M00,OUT (ON) CLIP → [CLIP Text Encode] ``` ---- +### **パラメータ** -### **Direct Inputモード** +#### **LoRA設定** +- `lora_folder_path`: LoRAフォルダのパス +- `num_loras`: 適用するLoRAの数(0〜20) +- `model_strength`: MODELに対するLoRAの強度(例: "1.0" または "0.6-0.9") +- `clip_strength`: CLIPに対するLoRAの強度(例: "1.0" または "0.6-0.9") -カスタムウェイトを直接入力: +> フォルダスキャンの挙動(対象拡張子、シンボリックリンクの追跡、候補リストのソート)は他のノードと共通です。詳細は[README_ja.md の「フォルダスキャンについて」](README_ja.md#フォルダスキャンについて)を参照してください。 -``` -weight_mode: "Direct Input" -lbw_input: "1,0.5,0.5,0,0,0,0,0,0,0,1,1,1,1,1,1,0.5,0.5,0.5,0.5" -``` +#### **キーワードフィルタ** +- `keyword_filter`: スペース区切りのキーワード(例: `style anime` や `"anime style" red`) +- `filter_mode`: AND / OR +- `search_in_metadata`: JSONや埋め込みメタデータも検索対象にする(遅くなります) -**ルール:** -- カンマ区切り -- SDXL: 20要素、SD1.5: 17要素 -- 要素数が合わない場合は自動調整 +#### **LBW設定** +- `weight_mode`: Normal / 4つのプリセット / Random / Direct Input +- `lbw_input`: カスタムウェイト(Direct Inputモードのみ) + +#### **その他** +- `trigger_word_source`: トリガーワードの取得方法 +- `seed`: ランダムシード --- -### **Preset: Randomモード** +## 出力形式 -毎回異なるプリセットをランダム選択: +### **LBW構文** +LBWを適用した場合、`lora_text`出力(v1.4.0より前は`positive_text`)にLBW構文が含まれます。 + +**Normal (All 1.0):** ``` -weight_mode: "Preset: Random" -→ 実行ごとに4つのプリセットから1つ選択 + ``` +**LBW適用時(Style Focused、SDXL):** +``` + +``` + +**注:** LBWはノード内部でMODELに適用済みです。`lora_text`の構文は、記録や他のノードでの再利用のためのものです。 + --- ## 使用例 @@ -274,74 +374,75 @@ weight_mode: "Preset: Random" ### **1. プリセット選択ガイド** -| LoRAタイプ | 推奨プリセット | -|-----------|--------------| -| 画風・スタイル | Style Focused | -| キャラクター | Character Focused | -| ポーズ・構図 | Structure/Composition Only | -| 汎用・微調整 | Balanced / Soft | +| LoRAタイプ | 推奨プリセット | 理由 | +|-----------|--------------|------| +| 画風・スタイル | Style Focused | OUTPUTブロックが画風を担うため | +| キャラクター | Character Focused | IN+MID+OUTのバランスで特徴を保つため | +| ポーズ・構図 | Structure/Composition Only | INPUTブロックがレイアウトを担うため | +| 汎用・微調整 | Balanced / Soft | 穏やかで重ねやすいため | --- -### **2. 直列接続のコツ** +### **2. 効果の見え方** -- **構造 → 画風の順**が基本 -- 各ノードで異なるLBW設定可能 -- 強度も個別に調整可能 +プリセットごとの違いが**見えやすい**条件: +- ✅ 強めのLoRA(model_strengthが高い) +- ✅ 1つだけ適用(num_loras=1) +- ✅ 画風・コンセプト系のLoRA + +違いが**見えにくい**条件: +- ⚠️ 弱めのLoRA(model_strengthが低い) +- ⚠️ 複数のLoRAを同時に適用 +- ⚠️ 学習の効き方がブロック全体に均等に分散しているLoRA --- -### **3. ウェイト調整のコツ** +### **3. ウェイト0 = 効果なし** +すべてのウェイトを0にすると、LoRAの効果は完全に無効になります。 +``` +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +``` +これはLoRAを適用しないのと同じです。 + +**ウェイト調整の目安:** - **0**: 完全無効 - **0.5**: 弱め - **1.0**: 標準 -- **1.5以上**: 強め(過剰に注意) +- **1.5以上**: 強め(効きすぎに注意) --- -### **4. トラブルシューティング** +### **4. 直列接続** + +LoRAごとに異なるLBW設定を使いたい場合は、ノードを直列に接続します。 +``` +[Filtered Random LoRA Loader (LBW)] (Style Focused) + ↓ +[Filtered Random LoRA Loader (LBW)] (Character Focused) + ↓ +[KSampler] +``` + +1つのノード内で選ばれたLoRAは、すべて同じLBW設定で適用されます。 + +**コツ:** +- **構造 → 画風の順**が基本 +- 強度もノードごとに個別に調整可能 + +--- + +### **5. トラブルシューティング** **効果が出ない場合:** -- すべて0になっていないか確認 +- ウェイトがすべて0になっていないか確認 - LoRAが正しく読み込まれているか確認 -- コンソールでLBW適用メッセージを確認 +- コンソールでLBW適用のメッセージを確認 **効果が強すぎる場合:** - model_strengthを下げる - Balanced / Softプリセットを試す -- ウェイトを0.5~0.8に調整 - ---- - -## 自動検出 - -### **SD1.5 / SDXL自動判定** - -ノードは自動的にLoRAタイプを検出: - -``` -SDXL検出 → 20要素ウェイト使用 -SD1.5検出 → 17要素ウェイト使用 -``` - -**ユーザーは何も設定不要** ✨ - ---- - -### **ウェイト数自動調整** - -入力したウェイト数が合わない場合、自動調整: - -``` -入力: 15要素(不足) -検出: SDXL(20要素必要) -→ 末尾に1.0を5個追加 - -入力: 25要素(過剰) -検出: SDXL(20要素必要) -→ 末尾から5個カット -``` +- ウェイトを0.5〜0.8に調整 --- @@ -353,7 +454,7 @@ SD1.5検出 → 17要素ウェイト使用 - ✅ **対応:** Stable Diffusion 1.5、Stable Diffusion XL(SDXL) - ❌ **非対応:** Flux、SD3、SDXL Turbo、Pony、その他のアーキテクチャ -LBW機能は、SD1.5/SDXLのU-Netアーキテクチャ専用に設計されています。他のモデルタイプではLBWが正常に動作しません。 +LBW機能は、SD1.5/SDXLのU-Netアーキテクチャ専用に設計されています。他のモデルタイプでは正常に動作しません。 --- @@ -363,27 +464,29 @@ LBW機能は、SD1.5/SDXLのU-Netアーキテクチャ専用に設計されて - torch(ComfyUIに含まれる) ### **⚠️ オプション: 動画プレビュー** -**動画ファイルプレビュー(.mp4, .webm, .avi, .mov)にはopencv-pythonが必須です:** +**動画ファイルのプレビュー(.mp4, .webm, .avi, .mov)にはopencv-pythonが必要です:** ```bash pip install opencv-python ``` **opencv-pythonなしの場合:** -- ✅ 静止画/アニメ画像は動作 +- ✅ 静止画・アニメーション画像は動作 - ❌ 動画ファイルは黒画面 --- ## プレビュー画像 -以下の形式に対応(優先順位順): +以下の形式に対応しています(優先順位順)。 -1. **静止画像**(.png, .jpg, .jpeg) - 常に動作 -2. **アニメ画像**(.gif, .webp) - 1フレーム目、常に動作 -3. **動画ファイル**(.mp4, .webm, .avi, .mov) - 1フレーム目、opencv-python必要 +1. **静止画像**(.png, .jpg, .jpeg) +2. **アニメーション画像**(.gif, .webp) - 1フレーム目 +3. **動画ファイル**(.mp4, .webm, .avi, .mov) - 1フレーム目(opencv-pythonが必要) + +LoRAのファイル名に一致するプレビューファイルを自動で探します。 **ファイルマッチング:** -- LoRAファイル名で始まるファイル(大文字小文字無視) +- LoRAファイル名で始まるファイル(大文字小文字は区別しない) - 例: `style_anime.safetensors` にマッチ: - `style_anime.png` ✅ - `style_anime_preview.jpg` ✅ @@ -402,7 +505,7 @@ pip install opencv-python ComfyUI/custom_nodes/RandomLoRALoader/filtered_random_lora_loader_lbw.py ``` -**編集箇所:** 29~41行目 +**編集箇所:** 29〜41行目(SDXL用が`SDXL_PRESETS`、SD1.5用が`SD15_PRESETS`) ### **例1: 独自プリセット追加** @@ -450,30 +553,40 @@ SDXL_PRESETS = { ⚠️ **ウェイト数:** - SDXLプリセット: 必ず20要素 - SD1.5プリセット: 必ず17要素 -- 要素数が合わない場合は自動調整されますが、正確に指定する方が良いです +- 要素数が合わない場合は自動調整されますが、正確に指定する方が確実です ⚠️ **編集後:** - ComfyUIを完全に再起動して変更を適用 -- コンソールで構文エラーを確認 +- コンソールで構文エラーが出ていないか確認 -💡 **ヒント:** ファイル編集が面倒な場合は、「Direct Input」モードを使ってください! +💡 **ヒント:** ファイル編集が面倒な場合は「Direct Input」モードを使ってください! + +--- + +## 免責事項 + +- 技術サポートは提供しません +- 動作の保証はありません +- 今後のComfyUIのアップデートとの互換性は保証しません +- バグ報告や機能要望に対応できない場合があります +- 自己責任でご利用ください --- ## 更新履歴 ### v1.2.0(2026-01-13) -- ✅ LoRAブロックウェイト(LBW)対応追加 -- ✅ SD1.5/SDXL自動検出 +- ✅ LoRAブロックウェイト(LBW)対応を追加 +- ✅ SD1.5/SDXLの自動検出 - ✅ 4つのプリセットモード+カスタム入力 -- ✅ ウェイト数自動調整 +- ✅ ウェイト数の自動調整 - ✅ 動画プレビュー対応(.mp4, .webm等) ### v1.1.0(2026-01-04) -- ✅ Filtered Random LoRA Loader追加 -- ✅ キーワードフィルタリング(AND/ORモード) -- ✅ メタデータ検索対応 -- ✅ プレビュー画像表示 +- ✅ Filtered Random LoRA Loaderを追加 +- ✅ キーワードフィルタ(AND/ORモード) +- ✅ メタデータ検索に対応 +- ✅ プレビュー画像の表示 ### v1.0.0(2025-12-30) - ✅ 初回リリース @@ -489,7 +602,7 @@ MIT License ## 作者 -Your Name +konohana --- diff --git a/README_ja.md b/README_ja.md index c307752..7da8204 100644 --- a/README_ja.md +++ b/README_ja.md @@ -78,7 +78,7 @@ LoRAブロックウェイト(LBW)対応の高度なノード。精密な効 - `json_sample_prompt`: 作例プロンプトをランダムに取得 - `metadata`: 埋め込みメタデータから直接読み込み - **作例プロンプト最適化**: LoRA構文を自動除去し、ノード設定の強度を適用 -- **デュアルテキスト出力**: positive_textとnegative_textを分離出力 +- **テキスト出力**: `positive_text` / `negative_text`に加え、LoRA構文付きの`lora_text`(v1.4.0) - **ComfyUI標準シード制御**: 固定/ランダム/増分/減分に対応 - **Wildcard Encode統合**: Wildcard Encode(Inspire)とシームレスに連携 - **LoRA構文自動除去**: additional_prompt内のLoRA構文を自動削除 @@ -176,6 +176,7 @@ rmdir /s RandomLoRALoader - `MODEL` / `CLIP`: KSamplerに接続 - `positive` / `negative`: Set ConditioningまたはKSamplerに接続 - `positive_text` / `negative_text`: Show Textに接続して確認(推奨) + - `lora_text`: Show Textやプロンプト・メタデータ保存系のノードに接続して、選ばれたLoRAを記録 ### Wildcard Encode連携(推奨) @@ -508,23 +509,33 @@ JSONメタデータから作例プロンプトを取得。 | `CLIP` | CLIP | LoRA適用済みCLIP | | `positive` | CONDITIONING | ポジティブコンディショニング(LoRA構文除去) | | `negative` | CONDITIONING | ネガティブコンディショニング | -| `positive_text` | STRING | LoRA構文付き完全ポジティブプロンプトテキスト | +| `positive_text` | STRING | LoRA構文を**含まない**ポジティブプロンプトテキスト。`positive`にエンコードされる内容そのもの(v1.4.0) | | `negative_text` | STRING | 完全ネガティブプロンプトテキスト | | `preview` | IMAGE | 選択されたLoRAのプレビュー画像バッチ(v1.1.0) | +| `lora_text` | STRING | LoRA構文を**含む**ポジティブプロンプトテキスト(旧`positive_text`の内容、v1.4.0) | + +> ⚠️ **v1.4.0での出力の変更** +> +> `positive_text`は``を含まなくなりました。以前の内容は新しい出力`lora_text`(末尾)から出ます。他の出力は位置も型も変わっていないので、既存の接続はそのまま使えます。 +> +> - `positive_text`をテキストエンコーダーに繋いでいた場合:つなぎ直しは不要です。``が文字として読まれなくなります +> - `positive_text`をLoRA構文の記録(プロンプトの保存やメタデータ)に使っていた場合:`lora_text`につなぎ直してください +> +> あわせてFilteredノードでも、3フォルダ版と同様に、構文を除去した跡に残る`, ,`や前後のカンマを整理してからエンコードするようにしました。エンコードされる内容が変わるため、**同じシードでも以前のバージョンと生成結果が変わる場合があります**。以前と同じ結果が必要な場合は、以前のバージョンをお使いください。 ### テキスト出力形式 -**positive_text例:** +**lora_text例:** ``` , , anime style, alice, blonde hair, 1girl, beautiful ``` -**LBWノードのpositive_text例:** +**LBWノードのlora_text例:** ``` , anime style, 1girl, beautiful ``` -**positive(CONDITIONING)内容:** +**positive_text / positive(CONDITIONING)内容:** ``` anime style, alice, blonde hair, 1girl, beautiful (クリーンなプロンプトのためLoRA構文除去) diff --git a/filtered_random_lora_loader.py b/filtered_random_lora_loader.py index c4eaad4..0b6b173 100644 --- a/filtered_random_lora_loader.py +++ b/filtered_random_lora_loader.py @@ -120,8 +120,13 @@ class FilteredRandomLoRALoader: } } - RETURN_TYPES = ("MODEL", "CLIP", "STRING", "STRING", "CONDITIONING", "CONDITIONING", "IMAGE") - RETURN_NAMES = ("MODEL", "CLIP", "positive_text", "negative_text", "positive", "negative", "preview") + RETURN_TYPES = ("MODEL", "CLIP", "STRING", "STRING", "CONDITIONING", "CONDITIONING", "IMAGE", "STRING") + # 0〜6番はv1.4.0以前と位置・型とも同じ(保存済みワークフローは出力を番号で接続するため)。 + # v1.4.0での変更: + # positive_text (2番) … を含まない。positive (CONDITIONING) にエンコード + # される文字列そのもの + # lora_text (7番) … 以前の positive_text の内容( 付き)。記録用 + RETURN_NAMES = ("MODEL", "CLIP", "positive_text", "negative_text", "positive", "negative", "preview", "lora_text") FUNCTION = "load_loras" CATEGORY = "loaders" @@ -678,8 +683,13 @@ class FilteredRandomLoRALoader: def _remove_lora_syntax(self, text): """プロンプトからLoRA構文を削除""" - pattern = r']+>' - return re.sub(pattern, '', text) + if not text: + return text + text = re.sub(r']+>', '', text) + # v1.4.0: 構文を消した跡に残る ", ," を詰める(以前はそのままエンコードしていた)。 + # positive_text 出力として表に出るようになったため、3フォルダ版と同じ後処理に揃えた + text = re.sub(r',(\s*,)+', ',', text) + return text.strip().strip(',').strip() def _load_preview_image_as_tensor(self, lora_path): """ @@ -997,13 +1007,13 @@ class FilteredRandomLoRALoader: def _generate_outputs(self, model, clip, final_positive, final_negative, token_normalization, weight_interpretation, preview_batch): """CONDITIONING生成と出力""" + # LoRA構文を削除してクリーンなプロンプトにする。clean_positive は positive_text + # 出力にもなるので、エラー時の戻り値でも使えるよう try の外で作る + clean_positive = self._remove_lora_syntax(final_positive) if final_positive else "" + clean_negative = self._remove_lora_syntax(final_negative) if final_negative else "" try: from nodes import CLIPTextEncode - # LoRA構文を削除してクリーンなプロンプトにする - clean_positive = self._remove_lora_syntax(final_positive) if final_positive else "" - clean_negative = self._remove_lora_syntax(final_negative) if final_negative else "" - # CONDITIONING生成 positive_conditioning = CLIPTextEncode().encode( clip=clip, @@ -1015,8 +1025,9 @@ class FilteredRandomLoRALoader: text=clean_negative )[0] - return (model, clip, final_positive, final_negative, - positive_conditioning, negative_conditioning, preview_batch) + # positive_text = エンコードした文字列そのもの / lora_text = 付き(旧 positive_text) + return (model, clip, clean_positive, final_negative, + positive_conditioning, negative_conditioning, preview_batch, final_positive) except Exception as e: print(f"[FilteredRandomLoRALoader] Error generating outputs: {e}") # エラー時は黒画像 @@ -1025,7 +1036,7 @@ class FilteredRandomLoRALoader: black_image = torch.zeros((1, 1240, 1240, 3), dtype=torch.float32) except: black_image = None - return (model, clip, final_positive, final_negative, None, None, black_image) + return (model, clip, clean_positive, final_negative, None, None, black_image, final_positive) NODE_CLASS_MAPPINGS = { diff --git a/filtered_random_lora_loader_lbw.py b/filtered_random_lora_loader_lbw.py index b3e3c13..8ac7d22 100644 --- a/filtered_random_lora_loader_lbw.py +++ b/filtered_random_lora_loader_lbw.py @@ -157,8 +157,13 @@ class FilteredRandomLoRALoaderLBW: } } - RETURN_TYPES = ("MODEL", "CLIP", "STRING", "STRING", "CONDITIONING", "CONDITIONING", "IMAGE") - RETURN_NAMES = ("MODEL", "CLIP", "positive_text", "negative_text", "positive", "negative", "preview") + RETURN_TYPES = ("MODEL", "CLIP", "STRING", "STRING", "CONDITIONING", "CONDITIONING", "IMAGE", "STRING") + # 0〜6番はv1.4.0以前と位置・型とも同じ(保存済みワークフローは出力を番号で接続するため)。 + # v1.4.0での変更: + # positive_text (2番) … を含まない。positive (CONDITIONING) にエンコード + # される文字列そのもの + # lora_text (7番) … 以前の positive_text の内容( 付き)。記録用 + RETURN_NAMES = ("MODEL", "CLIP", "positive_text", "negative_text", "positive", "negative", "preview", "lora_text") FUNCTION = "load_loras" CATEGORY = "loaders" @@ -724,8 +729,13 @@ class FilteredRandomLoRALoaderLBW: def _remove_lora_syntax(self, text): """プロンプトからLoRA構文を削除""" - pattern = r']+>' - return re.sub(pattern, '', text) + if not text: + return text + text = re.sub(r']+>', '', text) + # v1.4.0: 構文を消した跡に残る ", ," を詰める(以前はそのままエンコードしていた)。 + # positive_text 出力として表に出るようになったため、3フォルダ版と同じ後処理に揃えた + text = re.sub(r',(\s*,)+', ',', text) + return text.strip().strip(',').strip() def _load_preview_image_as_tensor(self, lora_path): """ @@ -1284,13 +1294,13 @@ class FilteredRandomLoRALoaderLBW: def _generate_outputs(self, model, clip, final_positive, final_negative, token_normalization, weight_interpretation, preview_batch): """CONDITIONING生成と出力""" + # LoRA構文を削除してクリーンなプロンプトにする。clean_positive は positive_text + # 出力にもなるので、エラー時の戻り値でも使えるよう try の外で作る + clean_positive = self._remove_lora_syntax(final_positive) if final_positive else "" + clean_negative = self._remove_lora_syntax(final_negative) if final_negative else "" try: from nodes import CLIPTextEncode - # LoRA構文を削除してクリーンなプロンプトにする - clean_positive = self._remove_lora_syntax(final_positive) if final_positive else "" - clean_negative = self._remove_lora_syntax(final_negative) if final_negative else "" - # CONDITIONING生成 positive_conditioning = CLIPTextEncode().encode( clip=clip, @@ -1302,8 +1312,9 @@ class FilteredRandomLoRALoaderLBW: text=clean_negative )[0] - return (model, clip, final_positive, final_negative, - positive_conditioning, negative_conditioning, preview_batch) + # positive_text = エンコードした文字列そのもの / lora_text = 付き(旧 positive_text) + return (model, clip, clean_positive, final_negative, + positive_conditioning, negative_conditioning, preview_batch, final_positive) except Exception as e: print(f"[FilteredRandomLoRALoaderLBW] Error generating outputs: {e}") # エラー時は黒画像 @@ -1312,4 +1323,4 @@ class FilteredRandomLoRALoaderLBW: black_image = torch.zeros((1, 1240, 1240, 3), dtype=torch.float32) except: black_image = None - return (model, clip, final_positive, final_negative, None, None, black_image) + return (model, clip, clean_positive, final_negative, None, None, black_image, final_positive) diff --git a/pyproject.toml b/pyproject.toml index 1c878bc..d56353d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "randomloraloader" description = "Randomly select and apply LoRAs with keyword filtering, LoRA Block Weight support, preview images, and multiple folder support for ComfyUI" -version = "1.3.0" +version = "1.4.0" license = {file = "LICENSE"} classifiers = [ diff --git a/random_lora_loader.py b/random_lora_loader.py index 9bd1dec..eaa52e9 100644 --- a/random_lora_loader.py +++ b/random_lora_loader.py @@ -215,8 +215,13 @@ class RandomLoRALoader: } } - RETURN_TYPES = ("MODEL", "CLIP", "STRING", "STRING", "CONDITIONING", "CONDITIONING", "IMAGE") - RETURN_NAMES = ("MODEL", "CLIP", "positive_text", "negative_text", "positive", "negative", "preview") + RETURN_TYPES = ("MODEL", "CLIP", "STRING", "STRING", "CONDITIONING", "CONDITIONING", "IMAGE", "STRING") + # 0〜6番はv1.4.0以前と位置・型とも同じ(保存済みワークフローは出力を番号で接続するため)。 + # v1.4.0での変更: + # positive_text (2番) … を含まない。positive (CONDITIONING) にエンコード + # される文字列そのもの + # lora_text (7番) … 以前の positive_text の内容( 付き)。記録用 + RETURN_NAMES = ("MODEL", "CLIP", "positive_text", "negative_text", "positive", "negative", "preview", "lora_text") FUNCTION = "load_random_loras" CATEGORY = "loaders" @@ -777,7 +782,7 @@ class RandomLoRALoader: text = re.sub(r']+>', '', text) # 連続カンマを整理 - text = re.sub(r',\s*,', ',', text) + text = re.sub(r',(\s*,)+', ',', text) # 3つ以上連続しても1回で詰める # 行頭・行末の空白とカンマを削除 text = text.strip().strip(',').strip() @@ -1123,7 +1128,7 @@ class RandomLoRALoader: メイン処理:ランダムLoRA選択・適用(3グループ対応) Returns: - tuple: (MODEL, CLIP, positive_text_output, negative_text_output, positive_conditioning, negative_conditioning) + tuple: (MODEL, CLIP, lora_text_output, negative_text_output, positive_conditioning, negative_conditioning) """ # seedをそのまま使用(ComfyUIのcontrol_before_generateで制御される) print(f"[RandomLoRALoader] 使用seed: {seed}") @@ -1223,18 +1228,18 @@ class RandomLoRALoader: additional_with_comma += ',' if all_text_parts: # LoRAがある場合: 追加プロンプト + LoRA情報 - positive_text_output = additional_with_comma + "\n" + "\n".join(all_text_parts) + lora_text_output = additional_with_comma + "\n" + "\n".join(all_text_parts) else: # LoRAがない場合: 追加プロンプトのみ(末尾カンマなし) - positive_text_output = additional_prompt_positive.strip() + lora_text_output = additional_prompt_positive.strip() else: # 追加プロンプトなし if all_text_parts: # LoRAのみ - positive_text_output = "\n".join(all_text_parts) + lora_text_output = "\n".join(all_text_parts) else: # 何もない - positive_text_output = "" + lora_text_output = "" # negativeテキスト出力 # 1. json_sample_promptからのnegative @@ -1283,4 +1288,6 @@ class RandomLoRALoader: # プレビュー画像バッチ生成 preview_batch = self._generate_preview_batch(preview_images) - return (model, clip, positive_text_output, negative_text_output, positive_conditioning, negative_conditioning, preview_batch) + # positive_text = positive にエンコードした文字列そのもの( なし) + return (model, clip, positive_text, negative_text_output, positive_conditioning, + negative_conditioning, preview_batch, lora_text_output)