Skip to main content

PyTorch Precision Converter

PyPI Tests Python PyTorch License: MIT

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_ids or step counters keep their dtype instead of turning into floats.
  • No silent inf or NaN. 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-only puts 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 .ckpt can'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-only used 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 fp32 used 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-load for 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)

Source distribution for pytorch-precision-converter 2.0.0
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)

Table of built distributions (wheels) for pytorch-precision-converter 2.0.0
File Interpreter ABI Platform Actions
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 log

Release 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 log

Security 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.

Select from 2 files

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 log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page