Model Stock
The mergekit stock recipe, now streaming on your GPU (or your CPU)
- deltas (delta)
- cos_eps (1e-06)
- recipe
Model Stock (class Model Stock For Tensor Mecha Recipe) is a port of the mergekit "model stock" method into the mecha recipe graph. If you've only ever used weighted sums, this is your first taste of the fancier end of merging - the methods that treat multiple fine-tunes as directions in weight space and try to average them without just blandly lerping everything together.
The short version: where a plain average gives every parameter the same say, model stock weights the average by how much the different models agree on each weight direction. Deltas pointing the same way get boosted; deltas pointing every which way get suppressed.
How it works
You feed it deltas - the difference between each fine-tune and a shared base - as a list. The method then:
- Computes the plain average of all deltas.
- Measures the cosine similarity between consecutive deltas, per tensor, and averages those similarities.
- Scales the averaged delta by
t = n·cos(θ) / (1 + (n−1)·cos(θ)), wherenis the count of deltas. When the deltas agree (cos(θ) near 1),tstays high; when they disagree, it collapses toward 0. - Strips any NaNs before returning.
The result is a single delta - the "stock" of what all those models share. The implementation is borrowed from mergekit, and it's the same idea that powers the "TIES-STOCK" and DARE-family merges, which comfy-mecha also ships (Add Difference Ties Extended has apply_stock for exactly this).
Inputs that matter:
- deltas (delta) (
MECHA_RECIPE_LIST) - the deltas to combine. Wire them in via aSubtract Recipe List(base → each model) orMecha Recipe List. At least two make sense. - cos_eps (1e-06) - the epsilon for cosine similarity, so division near zero doesn't explode. You basically never touch this.
- recipe (output, delta space) - feed it to a node that takes deltas, like
Add Difference(base + this delta) orAdd Difference Ties, then to Mecha Merger.
Because everything is a recipe until the merge actually runs, this node inherits the pack's memory story: sd-mecha processes keys one at a time and can stream a huge multi-model merge without ever holding the full tensors in VRAM.
Install
It's part of the Mecha Merge Node Pack (ljleb/comfy-mecha):
- ComfyUI Manager → Install Custom Nodes → search "mecha" → Mecha Merge Node Pack, or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/ljleb/comfy-mecha.git
pip install -r comfy-mecha/requirements.txt
Restart ComfyUI afterward. The pack's only declared dependency is sd-mecha==1.1.7, and nothing here downloads models.
Common issues
- You must feed it deltas, not full models. The input label says
(delta)for a reason. If you wire in checkpoints, the merge-space validation will refuse - and if you do feed real deltas, remember the output is still a delta. It has to be added back to a base before you have a usable model. This is the single most common mecha mistake, and the node's error messages are fairly good about catching it. - Fewer than two deltas is a no-op. With one delta,
tmath doesn't do anything interesting; you basically get the delta back. - Expect it to be slower than a plain average. Cosine similarity per tensor across the whole model is more work than a lerp. Fine - that's the price of a smarter average.
If you're already comfortable with Add Difference Ties, Model Stock is the natural next knob to turn. If you're still on weighted sums, try it once on a project you care about and A/B the output; the difference is subtle on some merges and obvious on others.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| deltas (delta)opt | MECHA_RECIPE_LIST | — | |
| cos_eps (1e-06)opt | MECHA_RECIPE | 0.000001 | — |
| merge_checkpointingopt | BOOLEAN | false | Speeds up an entire branch of a merge graph that does not change often in exchange of memory. - true: store the first output of this recipe node on cpu memory in fp16. On subsequent workflow executions, as long as the inputs do not change, the cached keys are returned after being cast to the original device and dtype. - false: do not store the output. The recipe and its inputs will re-execute on subsequent workflow executions. Note that the memory used to checkpoint the output is distinct from the cache feature. In general, you probably want to either use this *or* a cache unit, but not both at the same time because the memory adds up. The difference between merge checkpointing and cache is that merge checkpointing completely re-merges from scratch if any input changes. Merge checkpointing is also generally much faster than cache in the fast path. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| recipe | MECHA_RECIPE | — |