Pt To Bfloat16
The half-precision cast that keeps your gradients alive
- tens_a
- TENSOR
You're in the middle of a training workflow inside ComfyUI and your tensor is eating half your VRAM as float32. Pt To Bfloat16 is the one-box fix: it casts any TENSOR to bfloat16, the 16-bit format that halves memory and often speeds up matmuls on modern GPUs without wrecking your training.
This node is part of HowToSD's ComfyUI-Pt-Wrapper, the 200-node pack that puts PyTorch model building and training inside the node graph - no Python. It's the spin-off of ComfyUI-Data-Analysis that leans into training, so the whole pack speaks a private type called TENSOR that flows between its nodes. Pt To Bfloat16 is one of the pack's dtype-cast utilities: feed it a tensor, get the same tensor back in a smaller box.
Why bfloat16 and not fp16? The two are different kinds of 16-bit. Regular fp16 keeps lots of precision but a narrow exponent range, which makes training blow up into NaN when values get big. bfloat16 keeps the same exponent range as fp32 and just throws away mantissa bits, so it stays numerically stable in the ranges you actually train in. That's the short version of why bf16 became the default for training and for many inference stacks - the KB's write-ups on model size hammer the same point from the inference side: on consumer cards, how the weights are stored is often the difference between fitting and not. In this pack's training flows, casting activations to bf16 is the standard way to get a bigger batch or a bigger model onto the same card.
How it works: it's a thin wrapper around tens_a.to(torch.bfloat16). One input, one output:
tens_a- anyTENSORfrom another Pt-Wrapper node (an image tensor, a token batch, a model's intermediate activations).- Output
TENSOR- the same data in bfloat16. Wire it anywhere a Pt-Wrapper node expects a tensor.
The gotchas that bite. First, bf16 is a "makes sense on GPU" format. On old pre-Ampere NVIDIA cards (GTX 10-series, most 20-series) bf16 support is missing or emulated, so you can lose the speed benefit and sometimes hit correctness issues. Second, casting loses precision - bf16 has about 3 decimal digits of mantissa. For training that's usually fine (that's the whole point), but don't bf16 the values you're about to use as ground-truth labels or in a comparison you need exact. And remember this is a cast, not quantization: it re-labels and rounds a tensor you already have, it doesn't load anything smaller.
Install: ComfyUI Manager → search "ComfyUI-Pt-Wrapper" → install, or:
cd ComfyUI/custom_nodes
git clone https://github.com/HowToSD/ComfyUI-Pt-Wrapper
then restart ComfyUI. The pack's requirements.txt is genuinely heavy - transformers, datasets, sentencepiece, peft, accelerate, scikit-learn, a pinned gensim==4.3.2 and friends - so the first install takes a while. This node itself needs none of the model downloads; it's just a cast.
Troubleshooting: if a training run starts producing inf/nan only after you add this node, the cast isn't the culprit - it's what you cast. Drop the node and check whether your loss function or labels were also bf16'd. If the node errors with something about dtype or unsupported operation on CPU, that's the old-hardware story above; keep the tensor in fp32 and let the model nodes handle precision. If Manager can't find the pack, install by clone; the pinned gensim is the usual suspect when a shared environment breaks, so uninstall any conflicting gensim version first.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| tens_a | TENSOR | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| TENSOR | TENSOR | — |