Nodes/ComfyUI-Precision-Model-Save/Precision Model Save (FP32 Materialise)
ComfyUI Node

Precision Model Save (FP32 Materialise)

FP32 materialise, no more mystery drift

By TiwazM·Created about a month ago·Updated about a month ago· 1
Precision Model Save (FP32 Materialise)
  • model
  • saved_path
filename_prefixdiffusion_models/precision_merge
save_dtypefp32
strip_diffusion_model_prefixtrue

Ever merged two checkpoints in ComfyUI, watched the preview come out great, hit save, and then loaded the file back only to find it renders differently? That's the classic "saved merge doesn't match the live merge" curse, and it's usually a dtype problem, not a you problem. Precision Model Save (FP32 Materialise) is a small diagnostic node built to make that discrepancy bite-sized: it saves the exact merged MODEL object you're rendering, in FP32, so the file on disk and the graph in front of you finally agree.

Why this node exists

ComfyUI's normal ModelSave path goes through comfy.sd.save_checkpoint(), which materialises and casts your merge through the source checkpoint's dtype. Merge in fp16, save in fp16, and every weighted average gets rounded back to fp16 along the way - the file you get is a slightly different model than the one that made your preview. Merging is just a weighted average of existing weights (a few minutes, no training), so this is a super common workflow; people bake merges into standalone safetensors constantly, and the drift is exactly the kind of thing that makes you doubt your own seed.

This node refuses to play that game. It never calls save_checkpoint(). Instead it reads the live patch descriptions straight off your model with model.get_key_patches(), materialises every merged tensor on CPU in FP32 (interpolation happens at full precision, not rounded to the source dtype), applies any LoRA-style patches through comfy.lora.calculate_weight with an fp32 intermediate, and only at the very end casts to the file dtype you picked. Result: the saved weights are what the live graph actually computes.

The inputs that matter

Four required inputs, and honestly you'll touch two of them:

  • model - the live merged MODEL. Wire in the output of your ModelMergeSimple/ModelMergeBlockNumber (or any MODEL socket downstream of your merge).
  • filename_prefix - defaults to diffusion_models/precision_merge. That's deliberate: it writes into output/diffusion_models/, which is where ComfyUI's Load Diffusion Model looks, so your saved file shows up there ready to load.
  • save_dtype - fp32, bf16, or fp16. Start with fp32, per the author.
  • strip_diffusion_model_prefix - leave it on true. It removes the diffusion_model. key prefix so the output is a clean standalone diffusion model instead of a raw state dict.

The single output is saved_path - the full filesystem path of the file it just wrote, handy if you're doing anything scripted.

Install

Two options, both painless, and there's nothing to download beyond the node:

  • ComfyUI Manager: search "ComfyUI-Precision-Model-Save", install, restart.
  • Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/TiwazM/ComfyUI-Precision-Model-Save

Then restart ComfyUI. It has zero dependencies - no requirements.txt, no model files to fetch, just Python on top of ComfyUI's own torch. Find it under model/merging → Precision Model Save (FP32 Materialise).

The test protocol (and the gotchas)

The README's suggested test is the whole point of the tool: feed your exact live merge, save as fp32, fully unload models (or restart), load the file with Load Diffusion Model, and re-render with the same seed, prompt, sampler, scheduler, guidance, and steps. If fp32 matches but bf16/fp16 drift, you've caught the dtype. If fp32 still differs, your problem isn't the final save dtype - look elsewhere.

Where people trip:

  • FP32 is fat and hungry. It's roughly twice the size of BF16, and the whole model gets materialised in system RAM during save. A 6.5 GB fp16 SDXL becomes ~13 GB on disk and needs real headroom while writing; giant models like Flux fp32 can be genuinely uncomfortable. Free up RAM or expect a slow, swapping save.
  • It saves a diffusion model, not a full checkpoint. No CLIP, no VAE - that's what "strip diffusion model prefix" means. Load it via Load Diffusion Model and pair it with your usual text encoder/VAE; don't drop it in a Checkpoint Loader.
  • It's for ordinary float models. Quantised tensors (fp8, GGUF) aren't plain torch tensors, and the code will throw a TypeError ("unsupported base weight type") or produce nonsense - the author is upfront that quantized formats "may need architecture-specific handling."

It's an experimental diagnostic saver, not your everyday export tool. But for its one job - proving whether your saved merge is faithful - it's the fastest honest answer you'll get.

Categorymodel/merging

Inputs (4)

NameTypeDefaultDescription
modelMODEL
filename_prefixSTRINGdiffusion_models/precision_merge
save_dtypeCOMBOfp323 options: fp32, bf16, fp16
strip_diffusion_model_prefixBOOLEANtrue

Outputs (1)

NameTypeDescription
saved_pathSTRING