ComfyUI Node

LM Loader

The node that picks your chat model and loads absolutely nothing

By 0xBeycan·Created about a month ago·Updated 21 days ago· 2
LM Loader
    • lm
    ◄familyQwen LM►
    ◄modelQwen3.5-9B►
    ◄precisionINT8 ConvRot►
    ◄loraNone►
    ◄lora_strength1.00►
    ◄keep_model_loadedtrue►

    The name is misleading in a way that's actually good design. LM Loader does not load a model. Its one output is a description - family, model, precision, LoRA, strength, whether to keep it resident - and the node that receives it does the loading when the graph runs.

    That sounds like pointless indirection until you use it. Captioner and Prompter have no model widgets of their own. They take their model from an LM Loader. So one loader sits upstream, and both wrappers follow it. Swap Qwen3.5-9B for Qwen3-VL-8B Instruct Abliterated in one place and every node downstream runs the new model on the next queue. Change the LoRA strength from 1.0 to 0.6, same deal.

    It also means the wrappers hardcode no family. The loader's family widget is the one that says which catalog, which model folder (models/Qwen-LM) and which chat templates apply - today there's exactly one entry, Qwen LM, but that's a seam the author left open on purpose. A wrapper written against a BC_LM description never has to know.

    What you set

    family - Qwen LM, and that's the whole list right now. It's the catalog the rest of the widgets come from.

    model - the built-in six (Qwen3.5-4B, Qwen3.5-9B, Qwen3.5-9B Abliterated, Qwen3-VL-8B Instruct, Qwen3-VL-8B Instruct Abliterated, Qwen3.8-27B) plus anything your own models.yaml adds. All of them see images.

    precision - only the selected model's are listed. BF16, INT8 ConvRot, and W4A8 for the 27B. Default INT8 ConvRot is the sane starting point; it's about half the size of BF16 and the quality difference is not what's going to make or break a caption.

    lora and lora_strength - one LoRA, picked from models/Qwen-LM/loras. Either a single .safetensors (PEFT names or ComfyUI key names) or a PEFT folder with adapter_config.json + adapter_model.safetensors. The alpha is resolved from the file, its metadata, or the config file, because PEFT never writes alpha tensors and core would otherwise assume scale 1.0 - so an adapter trained at rank 16 / alpha 32 runs at 2.0, as trained. A LoRA trained on a different base is refused rather than half-applied, which is the behaviour you want: core alone would happily patch whatever matched and skip the rest in silence.

    keep_model_loaded - on by default. The model and its LoRA copy stay resident after the wrapper that ran them finishes. Off, the wrapper unloads it once when its call ends - after an error too. There's a single LM model slot shared across the whole pack, so a second LM node with a different file replaces the first.

    The lora list is read when node definitions load, so a LoRA you just dropped into the folder needs Refresh Node Definitions (R) or a restart before it appears. Same for a models.yaml that adds models or precisions.

    The plumbing you don't see

    lora_strength is core's math: strength × alpha / rank × (B @ A). Set it to 0 and the LoRA isn't read at all, so you get the plain model back without removing the widget value. The default of 1.0 applies the adapter as trained, which is what you want unless you're deliberately dialling one back.

    The loader also validates as much as it can without touching disk - a family that isn't registered, a model name that isn't in the catalog, a precision that model doesn't have, a LoRA that isn't in the list. Each error names the valid options. A LoRA file that gets deleted after that check, or a model file that's missing and can't be downloaded, surfaces as the wrapper's error when it runs instead. Slightly annoying to debug the first time; not mysterious once you know which node owns which failure.

    Install

    cd ComfyUI/custom_nodes
    git clone https://github.com/0xBeycan/ComfyUI-BCNodes
    pip install -r ComfyUI-BCNodes/requirements.txt
    

    Restart. LM Loader needs no third-party Python at all - the requirements.txt line items (opencv-python, postfx, caption-audit) belong to the mask and PostFx nodes. If the old ComfyUI-AutoBypass folder is still around, delete it; it's this pack under a previous name.

    Getting burned

    A saved workflow keeps what it was saved with. Values don't get "fixed" on load. So if you pick a model whose list no longer offers your precision - because a models.yaml broke, say - the run stops with an error naming what to change. The lists themselves do narrow to the selected family and model, but on load, the saved values come back as saved.

    Autocomplete on the API side. ComfyUI validates widget values against the declared list, and the loader declares every family's values, narrowing them in the frontend. That's the right way round, but it means a name that comes over a link from an any-type * output skips validation entirely and lands in the LoRA reader's own error. Same message, different route.

    keep_model_loaded off is not free. If you're batching a dataset you'll feel it - the wrapper unloads once per call, so a list of batches with keep-off reloads per batch. Leave it on while you caption, turn it off when you're done and want your VRAM back for a sampler.

    CategoryBCNodes/lm

    Inputs (6)

    NameTypeDefaultDescription
    familyCOMBOQwen LMThe LM family: the catalog, folder and chat templates the model comes from. The model, precision and lora lists show the selected family's; a value of another family is an error that names this family's.
    modelCOMBOQwen3.5-9BThe chat model (the built-in ones all see images): the built-in list plus the models.yaml in models/Qwen-LM. The file is looked for by name in models/Qwen-LM (subfolders too), then anywhere under models/text_encoders, and downloaded into models/Qwen-LM when missing.
    precisionCOMBOINT8 ConvRotThe model file's weights: BF16 (full), INT8 ConvRot (8-bit, about half the size), W4A8 (4-bit, Qwen3.8-27B only). Only the selected model's precisions are shown; another one is an error.
    loraCOMBONoneA LoRA from models/Qwen-LM/loras: a .safetensors file (PEFT or ComfyUI key names) or a PEFT folder (adapter_config.json + adapter_model.safetensors). Its alpha is read from the file, its metadata or its config file (a file in ComfyUI's names without one: alpha = rank, core's convention); a LoRA trained on another base model is refused. Only the selected family's LoRAs are shown.
    lora_strengthFLOAT1.00-100–100How strongly the LoRA changes the model: strength x alpha / rank x B @ A, core's LoRA math. 0 runs the model without it.
    keep_model_loadedBOOLEANtrueOn: the model (with its LoRA) stays loaded after the node that runs it, for the next run; one LM model is held at a time, shared with the other LM nodes. Off: that node unloads it once when its call ends, after an error too.

    Outputs (1)

    NameTypeDescription
    lmBC_LMThe model for a wrapper node's lm input (Captioner, Prompter): a description, nothing is loaded here.