Nodes/ComfyUI_LucidNFT/LucidNFT Condition (text+redux+control+lora)
ComfyUI Node

LucidNFT Condition (text+redux+control+lora)

Text, Redux, Control, LoRA, Guidance

By smthemex·Created 7 months ago·Updated 6 days ago· 21
LucidNFT Condition (text+redux+control+lora)
  • lq
  • ldr
  • clip_vision
  • positive
  • CONDITIONING
◄control_file▾►
◄condition_lora▾►
◄lora_strength1.00►
◄embedding▾►
◄connector▾►
◄siglip▾►
◄guidance4.0►
◄dtypebf16►

What it's for

A normal Flux workflow chains CLIP text encode, a Redux style model, a ControlNet apply and a guidance value across four or five nodes. This does all of it in one - and it's where your graph dies if a file is missing, because it's the only place the weights load.

It exists because LucidNFT isn't Flux plus a patch: it's LucidFlux, a dual-condition DiT with preference-optimisation LoRAs, whose conditioning wants two image hints and no text encoder.

How it works

Text comes from a file, not a model. It reads the official prompt_embeddings.pt - a precomputed txt (512×4096) and vec (768). No CLIP, no T5, nothing loads to encode a prompt, which is why there's no prompt textbox: the prompt is baked into that file. It's the biggest point of confusion around the sibling LucidFlux pack: people can't tell whether they need CLIP or the .pt.

Image conditioning goes SigLIP → Redux. ldr goes through SigLIP2-so400m at 512px (stretched, not cropped, as in the official pipeline), then a connector that is a ReduxImageEncoder, and the 1024×4096 tokens get concatenated after the text tokens - the Flux Redux layout, which is why the connector loads into comfy's own Redux class.

Then the actual LucidNFT part. lucidflux.pth holds two condition branches - one for the degraded lq, one for the restored ldr - plus modulation modules. The pack wraps them as a comfy.controlnet.ControlBase subclass, so the two branch blocks' residuals are modulated out into all 19 of the main DiT's double-block slots and added into the Flux stream by the native sampler.

The condition LoRA merges in memory. lora_condition is a PEFT adapter directory, not a Comfy LoRA file - its targets aren't in the base model, so it can't be one. The node parses adapter_config.json + adapter_model.safetensors and merges at load, scaled by lora_strength. The other LoRA, lora_dit, does target the main DiT and gets converted for LoraLoaderModelOnly.

Guidance rides on the conditioning. guidance isn't CFG: Flux dev is guidance-distilled, so there's no real negative pass and you move a guidance scale instead. The value gets stuffed into the conditioning dict and read by the control branch every step. Your sampler's cfg stays at 1.

The fields you actually set

Six dropdowns, and five of them need thought:

  • control_file - lucidflux.pth. The dropdown lists anything in models/LucidFlux/ with "lucid" in the name, including lucid_connector.pth; pick that and you get a missing-weights error.
  • condition_lora - lora_condition, scanned from models/LucidFlux/*/adapter_config.json. none gives you plain LucidFlux conditioning with no preference tuning, which is a fine debug step.
  • embedding - prompt_embeddings.pt. Set it to none only if you're wiring the optional positive input instead, and that conditioning must carry a pooled_output or the node raises.
  • connector and siglip - lucid_connector.pth, and your SigLIP2 file in models/clip_vision/. If you've already got a SigLIP loaded, wire the optional clip_vision input and it skips its own.
  • lq and ldr - both from LucidNFT DiffBIR, in that order.
  • guidance (default 4.0) and dtype. Leave dtype on bf16 unless debugging; fp32 roughly doubles the memory this eats.

Output is a single CONDITIONING into LucidNFT Sampler's positive. There's no negative; the pack doesn't have one.

Installing it

ComfyUI Manager → search LucidNFT → install → restart. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/smthemex/ComfyUI_LucidNFT

requirements.txt is torch and einops - the model was reimplemented in comfy's native layers rather than importing diffusers, transformers and peft. Nothing to pip-install.

The weights are the work. Everything goes under ComfyUI/models/LucidFlux/, registered by the pack and shared with ComfyUI_LucidFlux:

ComfyUI/models/LucidFlux/
├── lucidflux.pth                     # W2GenAI/LucidFlux
├── prompt_embeddings.pt              # same repo
├── lucid_connector.pth               # smthem/LucidFLUX-connector
├── general_swinir_v1.ckpt            # lxq007/DiffBIR
└── lora_condition/{adapter_config.json, adapter_model.safetensors}

The SigLIP2 single-file model goes in models/clip_vision/, renamed to siglip2-so400m-patch16-512.safetensors. The siglip dropdown only lists filenames containing "siglip", and every HF download arrives as model.safetensors - leave it and it never appears, which is an evening you don't get back.

Where people get burned

Everything loads lazily and stays loaded. lucidflux.pth is a multi-GB checkpoint kept in a module-level cache alongside the connector and SigLIP, so re-queues don't re-read it. On a small card, that plus a Flux DiT plus a Flux-shaped control branch is a lot. Threads about the sibling LucidFlux pack have people OOM'ing on 32GB cards and finding it was system RAM, not VRAM. Watch both.

Bad hint images degrade quietly. lq and ldr get bilinear-resized to latent×8 if they don't match. Wrong size doesn't error; it just feeds the branch a blurry reference. Keep DiffBIR's width/height at latent×8.

Don't hand-roll the conditioning. Substituting a CLIPTextEncode doesn't work - without the control tensor on the conditioning dict, the sampler runs as a plain Flux model with no restoration signal, and the output looks like an ordinary Flux re-render.

CategoryLucidNFT

Inputs (12)

NameTypeDefaultDescription
control_fileCOMBOlucidflux.pth(双条件分支)
condition_loraCOMBOmodels/LucidFlux/lora_condition(LucidNFT 的条件分支 LoRA);none = 纯 LucidFlux 分支
lora_strengthFLOAT1.000–4—
embeddingCOMBOprompt_embeddings.pt(官方预计算文本 embedding)
connectorCOMBOlucid_connector.pth;也可直接给含 connector 段的 lucidflux.pth
siglipCOMBOmodels/clip_vision 下的 SigLIP2-512;接了 clip_vision 输入则忽略此项
lqIMAGE低质输入(DiffBIR 的 lq,尺寸 = latent×8)
ldrIMAGEDiffBIR 复原结果(SwinIR 输出)
guidanceFLOAT4.00–100—
dtypeCOMBObf162 options: bf16, fp32
clip_visionoptCLIP_VISION可选:外部已加载的 SigLIP(省一次加载)
positiveoptCONDITIONING可选:embedding 设成 none 时,用这里的 txt/pooled 代替官方 pt

Outputs (1)

NameTypeDescription
CONDITIONINGCONDITIONING—