Files

253 lines
9.8 KiB
Markdown

# ComfyUI-SaveCheckpointWithMetadata
Save `.safetensors` files with custom metadata and explicit filename behavior in ComfyUI.
This extension provides two nodes:
- `Save Checkpoint with Metadata` - saves a checkpoint-style `.safetensors` file from `MODEL`, with optional `CLIP`, `VAE`, and `CLIP_VISION` inputs.
- `Save Diffusion Model with Metadata` - saves only a `MODEL` / diffusion-model-style `.safetensors` file, without `CLIP`, `VAE`, or `CLIP_VISION` inputs.
Both nodes share the same metadata control and filename behavior:
- Write exactly the header you want via `metadata_json`.
- Optional `prompt_override` to replace the hidden `PROMPT`.
- Merge mode to include hidden `EXTRA_PNGINFO`.
- Filename modes:
- `smart_counter`: first save uses unsuffixed `prefix.safetensors` if free, next saves continue from the next free counter without going backwards.
- `no_counter_overwrite`: always write to `prefix.safetensors` and overwrite if it exists.
## Install
### ComfyUI Manager
1) Manager -> Install via Git URL -> paste:
```text
https://github.com/a-l-e-x-d-s-9/ComfyUI-SaveCheckpointWithMetadata.git
```
2) Restart ComfyUI.
If Manager shows a security level error, either install manually or add the repo to the Manager catalog. See Troubleshooting below.
### Manual
```bash
cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/a-l-e-x-d-s-9/ComfyUI-SaveCheckpointWithMetadata.git
# optional deps
python3 -m pip install -r ComfyUI-SaveCheckpointWithMetadata/requirements.txt
# optional post-install hook
python3 ComfyUI-SaveCheckpointWithMetadata/install.py || true
```
Restart ComfyUI.
## Node location
- Category: `advanced/model_merging`
- Display names:
- `Save Checkpoint with Metadata`
- `Save Diffusion Model with Metadata`
## Which node should I use?
### Use `Save Checkpoint with Metadata` when:
- You want to save a checkpoint-style file.
- You want optional `CLIP`, `VAE`, or `CLIP_VISION` saved into the file.
- You want the default prefix to point to `checkpoints/CustomMeta`.
### Use `Save Diffusion Model with Metadata` when:
- You want a model-only file similar in purpose to ComfyUI's built-in `ModelSave` node.
- You only want to provide a single `MODEL` input.
- You do not want `CLIP`, `VAE`, or `CLIP_VISION` inputs on the node.
- You want the default prefix to point to `diffusion_models/CustomMeta`.
## Quick start - checkpoint save
1) Add `Save Checkpoint with Metadata`.
2) Wire your `MODEL` into the node.
3) Optionally wire `CLIP`, `VAE`, and/or `CLIP_VISION`.
4) Choose `filename_prefix`, for example `checkpoints/MyModel`.
5) Pick `filename_mode`:
- `smart_counter` for automatic unique names.
- `no_counter_overwrite` to always write `prefix.safetensors`.
6) Pick `metadata_mode`:
- `replace` to write only your `metadata_json`.
- `merge_minimal` to start with prompt plus optional `EXTRA_PNGINFO`, then apply `metadata_json`.
7) Fill `metadata_json` with a JSON object of header keys.
8) Optionally set `prompt_override` to replace the hidden `PROMPT` in merge mode.
9) Queue. Your checkpoint is saved in ComfyUI's output directory under the resolved subfolder.
## Quick start - diffusion model save
1) Add `Save Diffusion Model with Metadata`.
2) Wire your `MODEL` into the node.
3) Choose `filename_prefix`, for example `diffusion_models/MyModel`.
4) Pick `filename_mode`:
- `smart_counter` for automatic unique names.
- `no_counter_overwrite` to always write `prefix.safetensors`.
5) Pick `metadata_mode`:
- `replace` to write only your `metadata_json`.
- `merge_minimal` to start with prompt plus optional `EXTRA_PNGINFO`, then apply `metadata_json`.
6) Fill `metadata_json` with a JSON object of header keys.
7) Optionally set `prompt_override` to replace the hidden `PROMPT` in merge mode.
8) Queue. Your model file is saved in ComfyUI's output directory under the resolved subfolder.
## Inputs
### Shared inputs
Both nodes have these inputs:
| Input | Type | Description |
|------|------|-------------|
| model | MODEL | The model to serialize into a `.safetensors` file. |
| filename_prefix | STRING | Subfolder and base name under ComfyUI output directory, for example `checkpoints/MyModel` or `diffusion_models/MyModel`. |
| filename_mode | DROPDOWN | `smart_counter` or `no_counter_overwrite`. See Filename behavior. |
| metadata_json | STRING (multiline) | JSON object of header keys to write. Values must be strings; non-strings are JSON-encoded for you. Example: `{"author":"Alex","training":{"epochs":80}}`. |
| metadata_mode | DROPDOWN | `replace`: write only `metadata_json`. `merge_minimal`: base header includes prompt and, optionally, `EXTRA_PNGINFO`, then your `metadata_json` overwrites or adds keys. |
| include_extra_pnginfo | BOOLEAN | Used only in `merge_minimal`. When on, copy keys from hidden `EXTRA_PNGINFO` into the base header. |
| prompt_override | STRING (multiline) | Optional override for the hidden `PROMPT`. Ignored in `replace`. In `merge_minimal`, becomes the base `prompt` unless you also set `prompt` in `metadata_json`. |
### Extra inputs on `Save Checkpoint with Metadata`
Only `Save Checkpoint with Metadata` has these optional inputs:
| Input | Type | Description |
|------|------|-------------|
| clip | CLIP (optional) | Embed CLIP in the checkpoint. |
| vae | VAE (optional) | Embed VAE in the checkpoint. |
| clip_vision | CLIP_VISION (optional) | Embed CLIP_VISION in the checkpoint. |
`Save Diffusion Model with Metadata` intentionally does not expose these inputs.
Tip: To see tooltips, enable ComfyUI Settings -> Nodes -> Enable Tooltips.
## Outputs
Both nodes output text values so you can inspect what was written:
| Output | Description |
|--------|-------------|
| saved path | Full path to the saved `.safetensors` file. Named `ckpt_path` on the checkpoint node and `model_path` on the diffusion model node. |
| saved_metadata | Final metadata dictionary written to the safetensors header, formatted as JSON. |
| saved_prompt | The final `prompt` metadata value, if present. |
| saved_extra_pnginfo | The subset of `EXTRA_PNGINFO` copied into metadata when using `merge_minimal`. |
## Filename behavior
### `smart_counter`
- If `prefix.safetensors` does not exist, write there.
- Otherwise continue with `prefix_00001_.safetensors`, `prefix_00002_.safetensors`, etc.
- The node scans existing files and uses the next free suffix.
### `no_counter_overwrite`
- Always write to `prefix.safetensors`.
- If the file exists, it is overwritten.
## Metadata behavior
### `replace`
The final safetensors header contains only the keys from `metadata_json`.
`prompt_override`, hidden `PROMPT`, and hidden `EXTRA_PNGINFO` are ignored.
### `merge_minimal`
The node builds a small base metadata dictionary first:
1) Adds `prompt` from `prompt_override`, if provided.
2) Otherwise adds `prompt` from hidden ComfyUI `PROMPT`, if available.
3) Adds hidden `EXTRA_PNGINFO` keys if `include_extra_pnginfo` is enabled.
4) Applies `metadata_json` last.
Keys in `metadata_json` win over keys from the base metadata.
## Examples
### Replace-only header
- metadata_mode: `replace`
- metadata_json:
```json
{"author":"author","project":"Flux-Kontext","modelspec.architecture":"sdxl"}
```
Result: header contains exactly those keys.
### Merge prompt and extra info, then override
- metadata_mode: `merge_minimal`
- prompt_override: paste your workflow JSON or plain text
- include_extra_pnginfo: on
- metadata_json:
```json
{"prompt":"OVERRIDE","author":"Alex","training":{"epochs":80}}
```
Result: the final `prompt` value is `OVERRIDE`, because `metadata_json` is applied last.
### Save a model-only file
Use `Save Diffusion Model with Metadata` with:
- filename_prefix: `diffusion_models/MyModel`
- metadata_mode: `replace`
- metadata_json:
```json
{"author":"Alex","model_type":"diffusion_model","modelspec.architecture":"flux"}
```
## Notes
- Safetensors metadata requires `dict[str, str]`. Non-string values are JSON-encoded by the node.
- These nodes do not follow the stock `--disable-metadata` flag. They write the metadata you specify.
- Hidden inputs `PROMPT` and `EXTRA_PNGINFO` are provided by ComfyUI runtime. The nodes only read them when `merge_minimal` is selected.
- `Save Diffusion Model with Metadata` saves only the `MODEL` object and ignores CLIP/VAE/CLIP_VISION by design.
- For maximum compatibility, test the output of `Save Diffusion Model with Metadata` by loading it through the same ComfyUI loader you normally use for diffusion model files.
## Troubleshooting
### Manager shows: This action is not allowed with this security level configuration.
- Option A: Manual install by `git clone` into `ComfyUI/custom_nodes/`.
- Option B: Lower Manager `security_level` to `middle` or `weak` in its `config.ini`, then restart ComfyUI.
- Option C: Submit your repo to the ComfyUI-Manager catalog (`custom-node-list.json`) so it can be installed at normal security. Until the PR is merged, users can use Install via Git URL or manual install.
### I see `prefix_00001_.safetensors` even on the first save
In `smart_counter`, the node prefers `prefix.safetensors` if it does not exist. If you still get a numbered file, check that a file named `prefix.safetensors` is not already present in the resolved output folder.
### I want modelspec.* keys like the stock node adds
Add them to `metadata_json` explicitly. Example:
```json
{"modelspec.architecture":"sdxl","modelspec.vision":"clip"}
```
### The diffusion model file does not load where I expected
`Save Diffusion Model with Metadata` is intended for model-only saves, but exact compatibility can depend on the model type and the loader you use later. Try loading the output with the same ComfyUI model-only loader you normally use. If you need full checkpoint behavior with CLIP/VAE included, use `Save Checkpoint with Metadata` instead.
## License
No.
## Credits
Author: alexds9
Inspired by ComfyUI stock saving logic, with explicit metadata and naming control.