Nodes//Nougan Refmod Baker 🧬
ComfyUI Node

Nougan Refmod Baker 🧬

Baking chat characters into safetensors

By WinnouganΒ·Created 3 months agoΒ·Updated about 16 hours agoΒ· 10
Nougan Refmod Baker 🧬
  • image
  • saved_path
  • character_name
β—„json_textβ€”β–Ί
β—„filename_prefixRefmods/%name%β–Ί
β—„base_refmod(none - character-only file)β–Ί
β—„avatar_max_size512β–Ί
β—„fill_missing_fieldstrueβ–Ί
β—„system_promptβ€”β–Ί
β—„base_refmod_pathβ–Ί

Character cards are PNGs with JSON jammed into a text chunk. Which means every time someone re-saves one - through a screenshot tool, a chat app, a "compress this image" shortcut - the character evaporates and you're left with a nice picture of an anime girl and no personality. Same failure as re-encoding a ComfyUI output and losing the embedded workflow.

Nougan Refmod Baker 🧬 puts the card somewhere that survives: inside the __metadata__ header of a .safetensors file. The safetensors format is a JSON header plus raw tensor bytes, and loaders ignore header keys they don't recognise, so this is a legal, if cheeky, use of the format. It's the twin of Nougan Character Chat πŸ’¬, which reads these files.

What actually gets written

Four keys, all strings, none of them touching the tensors:

nougan_character_card             Character Card V2 JSON
nougan_character_system_prompt    optional system prompt
nougan_character_avatar_png_b64   avatar as base64 PNG
nougan_character_name             plain name, for fast listing

That's why the chat node can load a 4GB file instantly: it reads only the header. The tensors are never parsed.

The two kinds of file you can produce

base_refmod decides. Leave it on (none - character-only file) and you get a tiny file that exists purely to carry a character - great for chatting, useless as a video reference, because there's no model data in it.

Pick an existing refmod and the node copies it, embeds the character into the copy, and leaves the original untouched. Tensors are streamed across byte-for-byte (offsets in a safetensors header are relative to the data section, so they stay valid), then the result is read back and compared before success is reported. The payoff is a hybrid: one file that works as an H3 character reference and as a chat character. That's genuinely neat - a single artifact for both halves of a character pipeline.

base_refmod_path takes a full path to a refmod anywhere on disk and overrides the dropdown.

Inputs

image - the avatar. Only the first image of a batch is used. avatar_max_size (default 512, longest side) keeps it small, because it's base64 in a JSON header - the docs say "keep it small" and they mean it.

json_text - the card JSON. Paste it, or build it upstream.

filename_prefix - default Refmods/%name%, where %name% becomes the character's name. Saved under ComfyUI's output folder.

fill_missing_fields (on) - patches absent fields so the chat node doesn't choke on a partial card.

system_prompt (optional) - stored in the file and used instead of the card's own system prompt. Handy for locking a character's behaviour without editing the card.

Outputs: saved_path and character_name.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/Winnougan/Nougan_Nodes
# restart ComfyUI

Or ComfyUI Manager β†’ "Nougan". No dependencies, no model downloads. The baker needs nougan_refmod_io.py beside it (it ships in the pack - don't hand-copy individual files around, or the import fails). Hard-refresh after restart if the card preview looks unstyled.

Then the load side, in the chat node, in order of convenience:

  1. card_path - full path to the .safetensors, works immediately, no restart.
  2. Drop it in models/refmods (or a folder in NOUGAN_REFMOD_DIR), press ↻, pick refmod:<name>.
  3. ⬆ Card upload - fine for small character-only files, painful for multi-GB hybrids.

Where people get burned

Huge avatars. avatar_max_size at 2048 with a 3MB PNG puts megabytes of base64 into a header that every load has to read and JSON-parse. 512 is the sane default; leave it.

Expecting a character-only file to work in a video graph. It's a chat container. No tensors worth speaking of, nothing for a VAE to reference. Bake with a base refmod if you want both.

A plain refmod that won't show up in the chat dropdown. It has no character in its header - the chat node deliberately hides plain refmods. Run it through this baker.

Filenames as identity. A copy inherits the base refmod's name unless your prefix says otherwise; %name% comes from the card. If two characters overwrite each other, your prefix is the culprit.

CategoryNougan

Inputs (8)

NameTypeDefaultDescription
imageIMAGEAvatar. Only the first image of a batch is used.
json_textSTRINGβ€”
filename_prefixSTRINGRefmods/%name%%name% is replaced by the character's name. Saved in the ComfyUI output folder.
base_refmodCOMBO(none - character-only file)Existing refmod to copy and embed the character into. The original is never modified.
avatar_max_sizeINT51264–2048Avatar is downscaled so its longest side is at most this. Keep it small: it is stored in the file header.
fill_missing_fieldsBOOLEANtrueβ€”
system_promptoptSTRINGOptional. Stored in the file and used by the chat node instead of the card's own system prompt.
base_refmod_pathoptSTRINGOptional full path to a refmod anywhere on disk. Overrides the dropdown.

Outputs (2)

NameTypeDescription
saved_pathSTRINGβ€”
character_nameSTRINGβ€”