Diffusion Model Dtype Conversion
Resize a diffusion model's precision without re-downloading it
- output_path
- conversion_report
Sometimes you don't want a different model, you want the same model at a different precision. An fp32 UNet is twice the size of its fp16 version; a bf16 version is the size that fits. This node does that conversion for standalone diffusion models in models/diffusion_models, streaming tensor by tensor so a multi-gigabyte file doesn't need to load into RAM all at once. It's the precision resize tool for the "this model won't fit / this model is too big to merge comfortably" problem.
How it works
Pick a file, pick a target dtype (fp32, fp16, or bf16), give the output a name, run it. The node streams the safetensors through the pack's Unified Efficient Loader, converts every floating tensor to the target dtype, preserves all non-floating tensors exactly as-is, and writes the result atomically to models/diffusion_models. Because it streams, it works on models far larger than your RAM - the memory footprint stays bounded by a single work unit.
The interesting control is exclude_patterns. It's a multiline field of Python regexes, one per line; any tensor key matching a pattern keeps its original dtype instead of converting. This exists because not every floating tensor wants to live at reduced precision - the classic case is small bookkeeping tensors like norms and scalers, or a conditioning embedding you want to keep in fp32 for precision. The regex gets a clear error if you feed it something unparseable, and an invalid key pattern fails loudly on the line number, so debugging a typo is painless.
One hard rule in the code: the output path must differ from the input path. You can't convert a file over itself, which is a good guardrail - you'd rather end up with two files than a corrupted one.
Inputs that matter
- model_name - the diffusion-model file to convert.
- target_dtype -
fp32,fp16, orbf16. - exclude_patterns - regex lines for tensors that keep their original dtype. Leave empty to convert everything floating.
- output_filename (default
converted_model) - no extension, written tomodels/diffusion_models.
Outputs
output_path (the written file - the node is an output/terminal node, so it just reports where the file landed) and conversion_report (a text summary of what was converted and what was preserved).
Why you'd reach for it
Two realistic reasons. Downcast: you have an fp32 diffusion model and you want the fp16/bf16 version without hunting for a re-upload - this halves the file and the VRAM cost at negligible quality cost for most content. Upcast: you're about to feed the file into a merge, and CWB does its arithmetic in fp32, so converting a model that's been living in bf16 up to fp32 first can avoid precision surprises in the merged result. The exclude patterns are what make it safe for the first case - keep the fragile tensors high-precision and the bulk at half precision.
Install
Part of Model Utility Toolkit (silveroxides/ComfyUI-ModelUtils). ComfyUI Manager → search "Model Utility Toolkit", or:
cd ComfyUI/custom_nodes
git clone https://github.com/silveroxides/ComfyUI-ModelUtils
Restart ComfyUI. Real dependency: unifiedefficientloader (UEL) for the streaming loads. Keep ComfyUI current - the pack uses the newer extension API.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| model_name | COMBO | Diffusion-model file whose floating tensors will be converted. | |
| target_dtype | COMBO | Target dtype for floating tensors not matched by an exclusion pattern. | |
| exclude_patterns | STRING | Optional Python regex patterns, one per line. Matching tensor keys retain their original dtype. | |
| output_filename | STRING | converted_model | Output filename without extension, written under ComfyUI's diffusion-model directory. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| output_path | * | — |
| conversion_report | STRING | — |