张量池化合并
Pool a tensor down to one vector, and optionally merge it with another
- tensor1
- tensor2
- mask1
- mask2
- merged_tensor
The tensor-level version of ConditioningPooledMerge, with one useful trick up its sleeve: tensor2 is optional. Wire nothing into it and the node becomes a plain pooling operation - collapse a [B, S, H] embedding down to [B, H] by averaging (or masked-averaging) over pool_dim. Wire tensor2 in and it pools both, then merges the two vectors with your chosen strategy.
So it does double duty. Single-input mode is your "give me the gist of this sequence" tool; two-input mode is "average (or add, or concat, or max) the gist of two sequences." Given how often you want just the pooling half, that optional input is a genuinely good design choice.
The controls:
tensor1(required) andtensor2(optional) - the tensors.pool_dim(default 1) - which axis to average over. Default 1 is the sequence axis on a[B, S, H]tensor, which is the one you want. Negatives count from the end.merge_strategy-concat,add,mean,max, defaultmean.mask1,mask2(optional) - masks that make the pooling masked: entries marked 0 are excluded from the average. Same 1=keep/0=drop convention asAllOnesMaskGeneratorand the conditioning nodes. If you have ragged sequences or padding, this is what keeps the pool honest.
Mechanically it normalizes negative dims, pools (masked when masks are present), and if both pooled vectors have mismatched feature widths it forces the second through a random nn.Linear projection - the pack's standing "make shapes compatible, don't ask what it means" move. concat is the one strategy that doubles the output width; the others keep it.
Honest expectations, same as the whole pack: this is vector arithmetic, not a learned blend. mean of two unrelated embeddings is genuinely the average of them - useful for experiments in pooled space (SDXL's pooled path), not a semantic fusion. And the masks only matter if your tensor world carries them; plain text-encoder output usually doesn't, so mask1/mask2 will mostly sit empty until you build them with AllOnesMaskGenerator or pull them off a conditioning with ConditioningInspector.
Install
ComfyUI Manager, search comfyui-spawner-nodes, install, restart. Or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/spawner1145/comfyui-spawner-nodes
Light pure-Python deps (piexif, pypng, xmltodict), no models, nothing heavy. README is a stub, UI is Chinese-labeled, author is the same Chinese-speaking dev behind the rest of the pack (and a Wan2.1 SD extension). It works; documentation is thin.
Troubleshooting
- Output width doubled when you expected it to stay -
concatstrategy. Switch tomean/add/maxif you need a fixed width. - Masked pooling gives different results than plain pooling - that's the point of the mask. If you fed an all-zeros mask (0 everywhere), everything gets excluded and you get a divide-by-clamp-to-tiny-number artifact. Ones = keep, zeros = drop.
- Dim errors after a
concat- the doubled width propagates. Shape-check withTensorInspectorbefore blaming the next node.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| tensor1 | TENSOR | — | |
| pool_dim | INT | 1-4–4 | — |
| merge_strategy | COMBO | mean | 4 options: concat, add, mean, max |
| tensor2opt | TENSOR | — | |
| mask1opt | TENSOR | — | |
| mask2opt | TENSOR | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| merged_tensor | TENSOR | — |