Nodes/ComfyUI-BFSNodes/BFS LoRA Surgery (save)
ComfyUI Node

BFS LoRA Surgery (save)

Turn a Recipe Into a Real .safetensors

By alisson-anjos·Created 7 months ago·Updated about 8 hours ago· 126
BFS LoRA Surgery (save)
    • path
    ◄lora_name▾►
    ◄rules[]►
    ◄filename►
    ◄subfoldersurgery►
    ◄save_dtype▾►
    ◄overwritefalse►

    Ablating a LoRA live is how you find the fix. Once you've found it, you want it to stop being a settings panel you have to remember. BFS LoRA Surgery (save) takes the same rules and writes a real .safetensors into models/loras, so the corrected adapter can be shared, reused in another ComfyUI install, or loaded at plain strength 1.0 with a normal LoRA loader and no rule set in sight.

    It's the file-writing half of the pair. Same rules, same code path - the panel's own save as file button calls this same function.

    What it actually does

    It re-loads lora_name from disk, parses the rules JSON, applies the identical module scaling and dropping that BFS LoRA Surgery applies in memory, casts the tensors to whatever save_dtype asks for, and writes the result into models/loras/<subfolder>.

    The thing to notice is that it has no model input at all. It never touches your GPU pipeline, so it runs out-of-band: queue the workflow, get the file. It's registered as an output node, which is why the save happens even when nothing downstream consumes its output.

    The inputs and the one output

    lora_name must be the same file the surgery node read - both widgets read the same dropdown, so keep them pointed at the same entry. rules is the JSON recipe. Wire it from the surgery node's rules output and you never copy JSON by hand, which is the only reason that output exists. Leave filename empty and the name is built from the rules themselves:

    mylora__attn-x1.15__gate_up-b8_15-off__all-b16_23-off.safetensors
    

    That's worth having. A file that says what was done to it beats v2_final_real.safetensors every time. Long source names and 30-rule recipes still produce a legal name - when it won't fit, both halves get trimmed and a short hash of the full recipe is appended, so two different recipes can't collapse onto the same filename.

    Three inputs you'll actually decide on. subfolder defaults to surgery, which keeps the experiments out of your main LoRA list (leaving it blank writes into the loras root instead - and the subfolder becomes part of the name you see in every dropdown). save_dtype is keep, float16, bfloat16 or float32: leave it on keep unless you need the disk space, because a downcast can't be undone. overwrite is off by default, so a repeat run produces _1, _2 rather than destroying the last good file.

    The single output is path, a STRING. It also prints in the console, and the node shows the result inline.

    The file explains itself later

    Alongside your original metadata, untouched, the writer adds three things. bfs_surgery_summary is one readable line that any metadata viewer shows without knowing this tool exists:

    136/192 modules kept: dropped img_mlp.gate_up in blocks 8-15; all modules in blocks 16-23, scaled attn.* x1.15 (from mylora.safetensors)
    

    bfs_surgery is the full JSON record: tool and UTC timestamp, the source filename and its sha256, the recipe, the exact rule list, and the module counts. And ss_output_name is updated to the new name. Safetensors' __metadata__ is just a free-form string map, so all of this travels inside the file. Practically: a LoRA you share in six months can still say what was done to it, and can be traced back to the checkpoint it came from even if somebody renamed both.

    Install

    Same pack, so the same one-time step - ComfyUI Manager and search the pack title, or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/alisson-anjos/ComfyUI-BFSNodes.git
    # restart ComfyUI
    

    This node adds no dependencies of its own; it needs torch, safetensors and ComfyUI. Skip pip install -r requirements.txt unless you also want the pack's head-swap and video nodes - that file's insightface, onnxruntime and opencv-python are for those. The pack README doesn't mention the surgery nodes at all, so don't go looking for them there.

    Common issues

    The new file isn't in the LoRA dropdown. ComfyUI caches folder listings, so a file you just wrote often needs a refresh of node definitions (or a page reload) before it appears.

    "Undefined" LoRA in a later run. If you renamed or moved the source file, lora_name falls back to nothing and the node raises LoRA not found. Recipes in workflows point at filenames, not at file contents, so a rename breaks the pair.

    Files piling up. With overwrite off, iterating gives you _1, _2, _3. That's the safe default; just be the kind of person who deletes them.

    A recipe that belonged to a different LoRA. The save node applies whatever rules it's handed to whatever lora_name it's pointed at, with no compatibility check. If you retarget one widget and not the other, you get a perfectly valid file with the wrong surgery applied. Both widgets, every time.

    Careful with float16 on anything you'll keep training. Downcasting is one-way, so keep the original adapter if the file might end up in a trainer or a merge later.

    CategoryBFS/lora

    Inputs (6)

    NameTypeDefaultDescription
    lora_nameCOMBO0 options:
    rulesSTRING[]Same JSON the surgery panel writes.
    filenameSTRINGLeave empty to name it after the rules.
    subfolderSTRINGsurgery—
    save_dtypeCOMBO4 options: keep, float16, bfloat16, float32
    overwriteBOOLEANfalse—

    Outputs (1)

    NameTypeDescription
    pathSTRING—