(WIP) WanVideo LoRA Optimizer
Merge Wan LoRAs before they fight each other on the sampler
- model
- lora_stack
- model
- analysis_report
- lora_data
Stacking LoRAs on Wan video has the same problem it has on image models, plus a compounding one: one user reported likeness getting worse than plain Wan 2.2 once LoRAs were stacked, and that's before you factor in that Wan LoRAs come from a wider mix of trainers than most image ecosystems - Kohya, LyCORIS, diffusers, Musubi Tuner, Fun LoRA, finetrainer variants all circulate. This node is the LoRA Optimizer's engine - TIES-Merging, DARE/DELLA sparsification, per-layer conflict resolution - wired specifically for kijai's ComfyUI-WanVideoWrapper, the third-party wrapper that became the primary way people run Wan with extras like SageAttention and TeaCache. The regular LoRA Optimizer takes a MODEL; this one takes a WANVIDEOMODEL, because that's what the wrapper's loader produces instead.
One honest flag before you build around it: the node's display name literally reads "(WIP)". It's functional and shares the same battle-tested merge engine as the rest of the pack, but expect it to be the least stable corner of this node suite - rougher edges, more likely to change than the image-side nodes.
How it works
Same engine as the standard optimizer, pointed at a different model object with no CLIP branch - Wan wrapper models don't use text-encoder patching, so this node skips it and applies merged patches in-memory. Everything else carries over: the two-pass analyze-then-merge pipeline, per-layer strategy selection (weighted_sum where only one LoRA touches a group, TIES where sign conflicts are real), DARE/DELLA sparsification, and optional merge refinement. Key normalization matters more here than on image models - Wan's T2V/I2V/VACE variants share roughly 90% of their weights but each has unique keys, named differently by different trainers. That's why this node flips a few defaults relative to the plain Optimizer: normalize_keys on (mixed-trainer Wan stacks are the norm), cache_patches off (video models are large enough that caching eats real RAM), and architecture_preset defaulting to dit instead of auto - the right thresholds for Wan are already known, so it skips the guess.
The inputs and outputs that matter
model(required,WANVIDEOMODEL) - fromWanVideoModelLoader, not a regular checkpoint loader.lora_stack(required) - same LoRA Stack node you'd use anywhere else in this pack.output_strength(default 1.0,-1for auto) - master volume on the merge, identical behavior to the image-side node.auto_strength(default enabled) - turns down individual LoRA strengths automatically when stacking, the same anti-oversaturation lever as the standard optimizer. Worth double-checking it's on here specifically, since Wan stacks are exactly the "3+ LoRAs, high risk of stepping on each other" case this setting exists for.- Everything past that -
sparsification,merge_refinement,strategy_set,decision_smoothing- mirrors the standard LoRA Optimizer's advanced knobs, just defaulted for video.
Outputs: model (a WANVIDEOMODEL, feed it straight to WanVideoSampler), analysis_report (STRING - connect to Show Text to see which layers got merged how), and lora_data (feeds Save Merged LoRA if you want the result as a portable file). There's no clip output here, unlike the standard optimizer - Wan wrapper models don't carry one.
Workflow shape:
WanVideoModelLoader → WANVIDEOMODEL → WanVideo LoRA Optimizer → WANVIDEOMODEL → WanVideoSampler
▲
LoRA Stack ────────────┘
You can also chain it with individually-applied (non-merged) LoRAs coming from WanVideoLoraSelect upstream - the merged optimizer output and unmerged loader patches coexist fine in the same model patcher.
Installing it
Two things need to be present, not one. First, this pack, same as always:
cd ComfyUI/custom_nodes/
git clone https://github.com/ethanfel/ComfyUI-LoRA-Optimizer.git
(or search "LoRA Optimizer" in ComfyUI Manager). Second - and this is the part specific to this node - you need kijai's ComfyUI-WanVideoWrapper installed separately, since that's what actually produces the WANVIDEOMODEL type this node consumes. This pack doesn't bundle it. Restart ComfyUI after both are in place; nodes land under loaders.
Common issues & troubleshooting
Distillation LoRAs (CausVid, Lightx2v) don't belong in the stack. Same warning as the image-side optimizer, and it matters more here - Wan's own community has documented these speed LoRAs degrading motion and lighting and giving "flux level plastic skin" even applied alone, so merging them into a conflict-resolved stack is asking for trouble. Apply CausVid/Lightx2v through a standard loader upstream and keep only style/character LoRAs in this node's stack.
Merge feels slow or heavy on RAM. cache_patches defaults off here specifically because video models are big; that's correct behavior, not a bug - turning it on for repeated re-runs on a large stack will cost you real system RAM.
It doesn't work with your Inline Chain workflow. The pack is explicit that WanVideo wrapper models are not supported by LoRA Optimizer (Inline Chain) - this dedicated node exists precisely because that one doesn't handle WANVIDEOMODEL. If your workflow already runs LoRAs through WanVideoLoraSelect, you'll need to route through a LoRA Stack and this node instead to get the conflict-aware merge.
Results feel unstable or the node's behavior changes between pack updates. That's the honest cost of the "(WIP)" label - treat this node as more likely to shift than the rest of the suite, and keep an eye on the pack's changelog if you're relying on it for production work.
Inputs (20)
| Name | Type | Default | Description |
|---|---|---|---|
| model | WANVIDEOMODEL | Your WanVideo model from WanVideoModelLoader. | |
| lora_stack | LORA_STACK | Connect a LoRA Stack node here. This is the list of LoRAs you want to merge together. | |
| output_strength | FLOAT | 1.00-1–10 | Master volume for the merged result. 1.0 = full effect, 0.5 = half, 0 = disabled. Set to -1 for auto: uses the suggested max strength (compensates for energy lost during merge). |
| auto_strengthopt | COMBO | enabled | Automatically turns down individual LoRA strengths when combining many LoRAs to avoid oversaturated or distorted results. Useful when stacking 3+ LoRAs. |
| auto_strength_flooropt | FLOAT | -1.00-1–1 | Floor on how much auto-strength may shrink your LoRA strengths — a uniform down-scale multiplier (never scales UP, never flips signs). 1.0 = don't shrink at all, 0.5 = shrink to at most half, 0 = no floor at all (remove the limit — auto-strength may shrink strengths all the way down), -1 = architecture-aware default (higher for motion-heavy video, lower for image models). Applies to negative LoRAs by magnitude (−1.75 → −1.49 at 0.85, sign kept) and to >1.0 strengths. An explicit value ≥0 applies to EVERY stack, not just orthogonal ones. |
| vram_budgetopt | FLOAT | 0.000–1 | Fraction of free VRAM to use for storing merged patches. 0 = all CPU (default), 1.0 = use all free VRAM. Reduces RAM usage on GPU systems. |
| optimization_modeopt | COMBO | per_prefix | How the optimizer decides to combine LoRAs. 'per_prefix' (recommended): automatically picks the best method for each layer. 'global': uses one method everywhere. 'additive': simple weighted addition with no conflict resolution — preserves all weights exactly. Use for edit, distillation, or DPO LoRAs. (Previously: 'additive' was called 'weighted_sum_only'.) |
| cache_patchesopt | COMBO | disabled | Keep the merge result in memory so re-running the workflow is instant. Disabled by default for large video models to save RAM. |
| patch_compressionopt | COMBO | smart | Shrink the merged result to use less memory. 'smart' (recommended): compresses layers where it's lossless, skips layers that already went through rank reduction. 'aggressive': compresses everything including rank-reduced layers — saves the most memory but slightly lossy. 'disabled': no compression, uses more RAM. (Previously: this setting was called 'compress_patches' with values non_ties/all/disabled.) |
| svd_deviceopt | COMBO | gpu | Where to run compression math. GPU is much faster (10-50x). Switch to CPU only if you get out-of-memory errors during the merge. |
| normalize_keysopt | COMBO | enabled | Normalizes LoRA keys from different training tools (LyCORIS, diffusers, finetrainer, etc.) to a common format. Enabled by default for WanVideo LoRAs. |
| sparsificationopt | COMBO | disabled | Reduces interference between LoRAs by sparsifying weights before merging. DARE: random dropout everywhere. DELLA: magnitude-aware dropout everywhere. Conflict variants (recommended): same algorithms but ONLY applied where LoRAs push in opposite directions — unique contributions are preserved untouched. |
| sparsification_densityopt | FLOAT | 0.700.01–1 | What percentage of weights to keep (0.7 = keep 70%, drop 30%). Lower values drop more weights — reduces interference but may lose detail. At 1.0, no weights are dropped (equivalent to disabled). Note: in TIES mode, sparsification replaces the trim step — setting density to 1.0 disables both sparsification AND trimming. |
| dare_dampeningopt | FLOAT | 0.000–1 | DAREx dampening: reduces the aggressiveness of DARE's rescaling factor. At 0.0 (default): standard DARE rescaling (1/density). At higher values: dampened rescaling that reduces noise amplification at low density values. Only affects DARE/DARE-conflict modes. Based on DAREx (ICLR 2025). |
| merge_refinementopt | COMBO | none | Optional preprocessing steps applied to weight diffs before merging. none: merge as-is, no extra processing. refine: adds direction orthogonalization + selfish weight protection (TALL-masks) to reduce interference between LoRAs (minimal extra compute). full: adds SVD alignment (KnOTS) on top of refine for maximum interference reduction (uses more VRAM for SVD decomposition). Higher levels help most when LoRAs have high conflict; for low-conflict or orthogonal LoRAs, 'none' is usually fine. (Previously: this setting was called 'merge_quality' with values standard/enhanced/maximum.) |
| strategy_setopt | COMBO | full | Which merge strategies the auto-selector can choose from. 'full': all strategies available (consensus, SLERP, orthogonal detection). 'no_slerp': same detection logic but SLERP is excluded (weighted_average stays as-is). 'basic': only TIES vs weighted_average, no advanced strategy selection. (Previously: this setting was called 'behavior_profile' with values v1.2/no_slerp/classic.) |
| architecture_presetopt | COMBO | dit | Architecture-aware threshold tuning. Default 'dit' for WanVideo models. 'auto' detects from LoRA keys. |
| merge_strategy_overrideopt | STRING | Connect the merge_strategy output from a LoRA Conflict Editor to override the optimizer's auto-detected strategy. | |
| decision_smoothingopt | FLOAT | 0.250–1 | Smooth per-group strategy metrics toward each block's average before Pass 2 decisions. 0 disables smoothing; 0.2-0.4 usually removes noisy mode flips without washing out real differences. |
| smooth_slerp_gateopt | BOOLEAN | false | When enabled, uses smoothed cosine (decision_cosine) for SLERP gate instead of raw avg_cos_sim. Can affect SLERP/weighted_average ratio. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| model | WANVIDEOMODEL | — |
| analysis_report | STRING | — |
| lora_data | LORA_DATA | — |