PyTorch Precision Converter
Make PyTorch checkpoints and safetensors files half the size (a quarter with fp8) by converting them to
fp16, bf16 or fp8, and strip the EMA weights you don't need for inference. One command, no model code
needed, runs on the CPU.
$ precision-convert model.ckpt -p fp16 -t ema-only -st
Converted 280 tensors to fp16, left 1 unchanged, dropped 242 EMA entries
Used the EMA weights for 240 tensors
Saved model-ema-only-fp16.safetensors (29.93 MB, 27% of 109.23 MB)
Why not just call .half()?
A one-line cast quietly breaks things. This tool handles the details:
- Only floating-point tensors are cast. Integer and bool tensors like
position_idsor step counters keep their dtype instead of turning into floats. - No silent
inforNaN. fp16 tops out at 65,504 and fp8 at 448. Values beyond the range are clamped to it and you get a warning, rather than infinities appearing in your weights. - Real EMA extraction.
-t ema-onlyputs the EMA weights where the model loads them from, for Stable Diffusion and other latent-diffusion checkpoints (model_ema.*), then drops the duplicates. - safetensors metadata survives. LoRA training info (
ss_*keys) and other metadata is copied to the output. - Safe by default. PyTorch checkpoints load with
weights_only=True, so a malicious.ckptcan't run code. Files that need full unpickling require an explicit--unsafe-load. - Your files are safe too. Output is written to a temporary file and moved into place when complete, the
input is never replaced, and existing files are only overwritten with
--overwrite. - Mixed precision when you need it.
--keep-original "first_stage_model.*"keeps matching tensors (here the VAE) in their original dtype.
Install
pip install pytorch-precision-converter
For the latest unreleased changes, install from GitHub instead:
pip install git+https://github.com/angelolamonaca/PyTorch-Precision-Converter.
Either way you get the precision-convert command (python -m precision_converter works too). It needs Python 3.9+,
PyTorch 2.1+ and safetensors.
Usage
precision-convert INPUT [-p PRECISION] [-t TYPE] [-st] [-o OUTPUT] [options]
| Option | What it does |
|---|---|
INPUT |
.safetensors file or PyTorch checkpoint (.ckpt, .pt, .pth, .bin). -f INPUT works too. |
-p, --precision |
fp32, fp16, bf16, fp8_e4m3fn, fp8_e5m2, or keep (default: change no dtypes). |
-t, --type |
full keeps everything (default). ema-only uses the EMA weights. no-ema drops the EMA weights. |
-st, --safe-tensors |
Save as .safetensors instead of a PyTorch .ckpt. |
-o, --output |
Output path; its extension picks the format. Default: <input>-<type>-<precision> next to the input. |
--keep-original PATTERN |
Leave tensors whose key matches the glob in their original dtype. Repeatable. |
--info |
Show the tensors, dtypes, sizes, EMA and metadata in the file, then exit. |
--unsafe-load |
Fully unpickle PyTorch checkpoints. Only for files you trust. |
--overwrite |
Replace the output file if it exists. |
-v, --verbose |
List each tensor that had values clamped. |
Recipes
Shrink a Stable Diffusion training checkpoint for inference (EMA weights, fp16, safetensors):
precision-convert model.ckpt -p fp16 -t ema-only -st
Convert a LoRA to fp16 and keep its training metadata:
precision-convert my-lora.safetensors -p fp16 -o my-lora-fp16.safetensors
Store a large model in fp8 for UIs that load fp8 weights, such as ComfyUI, keeping normalization layers precise:
precision-convert model.safetensors -p fp8_e4m3fn -st --keep-original "*norm*"
Keep the VAE in fp32 (fp16 VAEs can produce NaNs and black images in some models):
precision-convert model.safetensors -p fp16 -st --keep-original "first_stage_model.*"
Turn a pickled checkpoint into safetensors without changing precision:
precision-convert model.ckpt -st
Check what's inside a file before converting:
$ precision-convert model.ckpt --info
model.ckpt: 523 tensors, 27,274,319 values, 109.10 MB
float32 521 tensors 109.10 MB
int64 1 tensor 616 B
int32 1 tensor 4 B
EMA: 242 model_ema.* tensors (-t ema-only or -t no-ema removes them)
Which precision should I pick?
| Precision | Bytes per value | Largest value | Good for |
|---|---|---|---|
fp32 |
4 | 3.4 × 10³⁸ | Training, reference copies, upcasting half-precision files |
bf16 |
2 | 3.4 × 10³⁸ | The safe 2-byte choice: same range as fp32, so nothing overflows |
fp16 |
2 | 65,504 | GPUs without fast bf16, and tools that expect fp16 |
fp8_e4m3fn |
1 | 448 | Smallest files, for inference in tools that load fp8 weights; some quality loss |
fp8_e5m2 |
1 | 57,344 | fp8 with more range and less precision than e4m3fn |
The fp8 options cast each value directly, without per-tensor scaling factors.
Python API
from precision_converter import convert_state_dict, load_checkpoint, save_checkpoint
state_dict, metadata = load_checkpoint("model.safetensors")
converted, report = convert_state_dict(state_dict, precision="bf16", conversion="no-ema")
save_checkpoint(converted, "model-bf16.safetensors", metadata=metadata)
print(f"{report.converted} tensors converted, {len(report.clamped)} had values clamped")
convert_state_dict takes any mapping of tensors, so model.state_dict() works too.
Upgrading from 1.x
python convert.py ... still works, but 2.0 fixes bugs that changed what earlier versions wrote:
-t ema-onlyused to keep the regular weights and store the EMA weights under keys no model loads. It now outputs the actual EMA weights.- Integer tensors are no longer cast to floating point, and overflowing values are clamped instead of
becoming
inf. - The default precision is now
keep.-p fp32used to change nothing; it now converts fp16 and bf16 tensors to fp32. With the default precision the output name no longer ends in-fp32. - Checkpoints are loaded with
weights_only=True. Use--unsafe-loadfor trusted files that need more. - Existing output files are no longer overwritten unless you pass
--overwrite.
See CHANGELOG.md for details.
Contributing
Issues and pull requests are welcome. To run the tests:
pip install -e ".[test]"
pytest
License
MIT. See LICENSE.
Metadata
Release files for pytorch-precision-converter 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pytorch_precision_converter-2.0.0.tar.gz | 16.3 kB | With provenance | Details for pytorch_precision_converter-2.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pytorch_precision_converter-2.0.0-py3-none-any.whl | Python 3 | none | any | Details for pytorch_precision_converter-2.0.0-py3-none-any.whl |
Total release size: 28.7 kB
Release files / pytorch_precision_converter-2.0.0.tar.gz
| Download URL | pytorch_precision_converter-2.0.0.tar.gz |
|---|---|
| Size | 16.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
896ad291440514414d5ddc6c633b8c4cc181f70d3c4a8bf29a0481cfa0d8479c
|
|
BLAKE2b-256 checksum How to use checksums |
f72f95d331380c4ae0654965bf7e1952e142fb293ed9dac05a3eff039f682b89
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.
Transparency logRelease files / pytorch_precision_converter-2.0.0-py3-none-any.whl
| Download URL | pytorch_precision_converter-2.0.0-py3-none-any.whl |
|---|---|
| Size | 12.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
819de5bee29eac11c11c5b86256f47bbb2d526f3b6315c64f969e74ac04c631f
|
|
BLAKE2b-256 checksum How to use checksums |
02117c1c4f148052197b3d0607169ad1ce633fa0fb517b6159b38638f2a4f055
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.
Transparency logSecurity for pytorch-precision-converter 2.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for pytorch_precision_converter-2.0.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.