Skip to main content
File added late

1 file was added to this release more than 14 days after its initial publication. Inspect the release files before installing.

Differentiable Model Compression via Pseudo Quantization Noise

linter badge tests badge cov badge

DiffQ performs differentiable quantization using pseudo quantization noise. It can automatically tune the number of bits used per weight or group of weights, in order to achieve a given trade-off between model size and accuracy.

Go read our paper for more details.

What's up?

See the changelog for details on releases.

  • 2022-08-24: v0.2.3: fixed a bug when loading old quantized states.
  • 2021-11-25: version 0.2.2: adding support for torchscript.

Requirements

DiffQ requires Python 3.7, and a reasonably recent version of PyTorch (1.7.1 ideally). To install DiffQ, you can run from the root of the repository:

pip install .

You can also install directly from PyPI with pip install diffq.

Usage

import torch
from torch.nn import functional as F
import diffq
from diffq import DiffQuantizer

model = MyModel()
optim = ...  # The optimizer must be created before the quantizer
quantizer = DiffQuantizer(model)
quantizer.setup_optimizer(optim)

# Distributed data parallel must be created after DiffQuantizer!
dmodel = torch.distributed.DistributedDataParallel(...)

penalty = 1e-3
model.train()  # call model.eval() on eval to automatically use true quantized weights.
for batch in loader:
    ...
    optim.zero_grad()

    # The `penalty` parameter here will control the tradeoff between model size and model accuracy.
    loss = F.mse_loss(x, y) + penalty * quantizer.model_size()
    optim.step()

# To get the true model size with when doing proper bit packing.
print(f"Model is {quantizer.true_model_size():.1f} MB")

# When you want to dump your final model:
torch.save(quantizer.get_quantized_state(), "some_file.th")

# You can later load back the model with
model = MyModel()
diffq.restore_quantized_state(model, torch.load("some_file.th"))

# For DiffQ models, we support exporting the model to Torscript with optimal storage.
# Once loaded, the model will be stored in fp32 in memory (int8 support coming up).
from diffq.ts_export import export
export(quantizer, 'quantized.ts')

Documentation

See the API documentation for detailed documentation. We cover hereafter a few aspects.

Quantizer object

A Quantizer is attached to a model at its creation. All Quantizer objects provide the same basic capabilities:

  • automatically switches to quantized weights on the forward if the model is in eval mode.
  • quantizer-specific code on training forward (e.g. STE for UniformQuantizer with QAT, noise injection for DiffQ).
  • provide access to the quantized model size and state.

Quantized size and state

The method quantizer.model_size() provide a differentiable model size (for DiffQ), while quantizer.true_model_size() provide the true, optimally bit-packed, model size (non differentiable). With quantizer.compressed_model_size() you can get the model size using gzip. This can actually be larger than the true model size, and reveals interesting information on the entropy usage of a specific quantization method.

The bit-packed quantized state is obtained with quantizer.get_quantized_state() , and restored with quantizer.restore_quantized_state(). Bit packing is optimized for speed and can suffer from some overhead (in practice no more than 120B for Uniform and LSQ, and not more than 1kB for DiffQ).

If you do not have access to the original quantizer, for instance at inference time, you can load the state with diffq.restore_quantized_state(model, quantized_state).

Quantizer and optimization

Some quantizer will add extra optimizable parameters (DiffQuantizer and LSQ). Those parameters can require different optimizers or hyper-parameters than the main model weights. Typically, DiffQ bits parameters are always optimized with Adam. For that reason, you should always create the main optimizer before the quantizer. You can then setup the quantizer with this optimizer or another:

model = MyModel(...)
opt = torch.optim.Adam(model.parameters())
quantizer = diffq.DiffQuantizer(model)
quantizer.setup_optimizer(opt, **optim_overrides)

This offers the freedom to use a separate hyper-params. For instance, DiffQuantizer will always deactivate weight_decay for the bits parameters.

If the main optimizer is SGD, it is advised to have a second Adam optimizer for the quantizer.

Warning: you must always wrap your model with DistributedDataParallel after having created the quantizer, otherwise the quantizer parameters won't be optimized!

TorchScript support

At the moment the TorchScript support is experimental. We support saving the model with TorchScript to disk with optimal storage. Once loaded, the model is stored in FP32 in memory. We are working towards adding support for int8 in memory. See the diffq.ts_export.export function in the API.

Examples

We provide three examples in the examples/ folder. One is for CIFAR-10/100, using standard architecture such as Wide-ResNet, ResNet or MobileNet. The second is based on the DeiT visual transformer. The third is a language modeling task on Wikitext-103, using Fairseq

The DeiT and Fairseq examples are provided as a patch on the original codebase at a specific commit. You can initialize the git submodule and apply the patches by running

make examples

For more details on each example, go checkout their specific READMEs:

Installation for development

This will install the dependencies and a diffq in developer mode (changes to the files will directly reflect), along with the dependencies to run unit tests.

pip install -e '.[dev]'

Updating the patch based examples

In order to update the patches, first run make examples to properly initialize the sub repos. Then perform all the changes you want, commit them and run make patches. This will update the patches for each repo. Once this is done, and you checked that all the changes you did are properly included in the new patch files, you can run make reset (this will remove all your changes you did from the submodules, so do check the patch files before calling this) before calling git add -u .; git commit -m "my changes" and pushing.

Test

You can run the unit tests with

make tests

Citation

If you use this code or results in your paper, please cite our work as:

@article{defossez2021differentiable,
  title={Differentiable Model Compression via Pseudo Quantization Noise},
  author={D{\'e}fossez, Alexandre and Adi, Yossi and Synnaeve, Gabriel},
  journal={TMLR},
  year={2022}
}

License

This repository is released under the CC-BY-NC 4.0. license as found in the LICENSE file, except for the following parts that is under the MIT license. The files examples/cifar/src/mobilenet.py and examples/cifar/src/src/resnet.py are taken from kuangliu/pytorch-cifar, released as MIT. The file examples/cifar/src/wide_resnet.py is taken from meliketoy/wide-resnet, released as MIT. See each file headers for the detailed license.

Metadata

Release files for diffq-fixed 0.2.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

File added late

1 file was uploaded more than 14 days after the first file in this release.

While project maintainers occasionally add legitimate files to an existing release, late additions can also indicate a security compromise.

We recommend inspecting the release files before installing.

Source distribution (sdist)

Source distribution for diffq-fixed 0.2.4
File Size Uploaded
diffq_fixed-0.2.4.tar.gz 189.7 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for diffq-fixed 0.2.4
File
diffq_fixed-0.2.4-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details
diffq_fixed-0.2.4-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
diffq_fixed-0.2.4-cp312-cp312-manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ x86-64 Details
diffq_fixed-0.2.4-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details
diffq_fixed-0.2.4-cp311-cp311-manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ x86-64 Details
diffq_fixed-0.2.4-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details
diffq_fixed-0.2.4-cp310-cp310-manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ x86-64 Details

Total release size: 2.3 MB

Release files / diffq_fixed-0.2.4.tar.gz

Download URL diffq_fixed-0.2.4.tar.gz
Size 189.7 kB
Tags Source
SHA-256 checksum
How to use checksums
cbc906b76fa23d1cf3c0ae517fbab744d9624980a068fe7fbb00dede1d83208d
BLAKE2b-256 checksum
How to use checksums
be968ca5acf5ecfd4108aa6f345cef171f2fda0c081cf0e7430671712586f172
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.12.7

Release files / diffq_fixed-0.2.4-cp313-cp313-win_amd64.whl

File added late

This file was uploaded more than 14 days after the first file in this release.

While project maintainers occasionally add legitimate files to an existing release, late additions can also indicate a security compromise.

We recommend inspecting the release file before installing.

Download URL diffq_fixed-0.2.4-cp313-cp313-win_amd64.whl
Size 106.0 kB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
cd5a12f0da04394c8bd9d2d6bc69a120dce0848c2fb59ddae06b959fb5db8ae3
BLAKE2b-256 checksum
How to use checksums
28fd049873cb31ebd5c9d1d2fac9b3ff645513af1e8b98f295c3188b9c4fbce3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.2

Release files / diffq_fixed-0.2.4-cp312-cp312-win_amd64.whl

Download URL diffq_fixed-0.2.4-cp312-cp312-win_amd64.whl
Size 106.2 kB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
81087279979db570723ca0911265635d7c3132cc8b74bc52bdea94881440ce96
BLAKE2b-256 checksum
How to use checksums
331494327d99f551136ac95bdc9697a1738f78ab3bb63afe8ce58b2b9854cd3a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.12.7

Release files / diffq_fixed-0.2.4-cp312-cp312-manylinux_2_28_x86_64.whl

Download URL diffq_fixed-0.2.4-cp312-cp312-manylinux_2_28_x86_64.whl
Size 569.2 kB
Tags CPython 3.12 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
5aea342125e12b9388f23a4f5bf40cf9ea3fc3888d755e848864546b104443ab
BLAKE2b-256 checksum
How to use checksums
f7ea9d831d1fd2c78432282d8e876d6896bb4f098637ce6e48afc2f0ee8775eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.12.7

Release files / diffq_fixed-0.2.4-cp311-cp311-win_amd64.whl

Download URL diffq_fixed-0.2.4-cp311-cp311-win_amd64.whl
Size 106.3 kB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
67798dccc9b4f46196071953d52fafbef0751c5d0acb064e0883c7a8509d84f9
BLAKE2b-256 checksum
How to use checksums
4c70a11838773e1c2bd9fa47d5016a90b7584b4052179407fb934eb89499552e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.11.9

Release files / diffq_fixed-0.2.4-cp311-cp311-manylinux_2_28_x86_64.whl

Download URL diffq_fixed-0.2.4-cp311-cp311-manylinux_2_28_x86_64.whl
Size 575.7 kB
Tags CPython 3.11 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
6cc6c47820b7823fda855f8793ff48bc33a3d9f0f0e7dee6e430dade25085c9a
BLAKE2b-256 checksum
How to use checksums
87d04a763200110bbc04aa4599f6163da7e486e0855f81404b1225839fb515c3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.11.10

Release files / diffq_fixed-0.2.4-cp310-cp310-win_amd64.whl

Download URL diffq_fixed-0.2.4-cp310-cp310-win_amd64.whl
Size 106.2 kB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
d6fc81bd6ca17ebc04b8a163f9efae5afedf3274a4eee473f6742471a8d904bc
BLAKE2b-256 checksum
How to use checksums
0fa9b3bf2493447a7492c4208ee9003514017e9ee009798df34abada3666211b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.10.11

Release files / diffq_fixed-0.2.4-cp310-cp310-manylinux_2_28_x86_64.whl

Download URL diffq_fixed-0.2.4-cp310-cp310-manylinux_2_28_x86_64.whl
Size 536.9 kB
Tags CPython 3.10 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
c911cda65ddebb672aaa8d80d902259ffc4ee469ce231021544093d83372ed15
BLAKE2b-256 checksum
How to use checksums
0a1a4e6981b6ac4b876526e354bae41a27f704508580d74bac93c8be56fe7804
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.10.15

Release history Release notifications | RSS feed

This release

0.2.4 This release

8 release files

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