DKM casts k-means weight clustering as a differentiable attention problem, enabling joint optimization of DNN parameters and clustering centroids through standard backpropagation. Unlike prior weight-clustering methods that rely on hard assignments and approximated gradients, DKM uses soft attention-based assignment that is fully differentiable.
1import torch
2import torch.nn as nn
3from dkm import compress_model
4from dkm.utils import print_compression_summary
56# Load any pre-trained model7model = torchvision.models.resnet18(weights="DEFAULT")89# Compress with DKM (2-bit clustering)10compressor = compress_model(11 model,12 bits=2,# k = 2^bits = 4 clusters13 dim=1,# scalar clustering (dim=1) or multi-dim14 tau=2e-5,# temperature (controls softness of assignment)15 skip_first_last=True,# skip first/last layers (per paper protocol)16)1718# Print compression statistics19info = compressor.get_compression_info()20print_compression_summary(info)2122# Train with standard PyTorch loop (paper: SGD, lr=0.008, momentum=0.9)23optimizer = torch.optim.SGD(compressor.parameters(), lr=0.008, momentum=0.9)24criterion = nn.CrossEntropyLoss()2526compressor.train()27for images, labels in dataloader:28 optimizer.zero_grad()29 outputs = compressor(images)30 loss = criterion(outputs, labels)31 loss.backward()# Gradients flow through DKM attention layers32 optimizer.step()3334# Snap to nearest centroids for inference35compressor.snap_weights()3637# Export compressed model (codebook + assignments)38export = compressor.export_compressed()39torch.save(export,"compressed_model.pt")
Multi-Dimensional Clustering (Section 3.3)
DKM supports multi-dimensional weight clustering for higher compression:
python
1# Paper notation: "bits/dim" e.g., "4/4" means 4 bits, 4 dimensions2# Effective bits-per-weight = bits / dim34# Configuration cv:6/8, fc:6/4 (as in Table 3 of the paper)5compressor = compress_model(6 model,7 bits=6,8 conv_config={"bits":6,"dim":8},# 6 bits, 8 dims → 0.75 bpw9 fc_config={"bits":6,"dim":4},# 6 bits, 4 dims → 1.5 bpw10 tau=2e-5,11)
Config
Clusters
Dim
Effective BPW
3-bit
8
1
3.0
2-bit
4
1
2.0
1-bit
2
1
1.0
4/4
16
4
1.0
8/8
256
8
1.0
4/8
16
8
0.5
8/16
256
16
0.5
Temperature τ Guidelines (Appendix B)
The temperature controls the softness of cluster assignment:
Smaller τ → harder assignment (near one-hot), closer to standard k-means
Larger τ → softer assignment, more gradient flow, better for hard compression tasks
Model
3-bit
2-bit
1-bit
4/4
8/8
ResNet18
8e-6
2e-5
5e-5
5e-5
8e-5
ResNet50
8e-6
2e-5
5e-5
4e-5
OOM
MobileNet-v1
5e-5
1e-4
3e-4
1e-4
1e-4
MobileNet-v2
5e-5
1e-4
1.5e-4
1e-4
1e-4
Architecture
dkm/
├── __init__.py # Package exports
├── dkm_layer.py # Core DKM layer (Section 3.2-3.3)
├── compressor.py # Model wrapper with DKM layers (Section 4)
└── utils.py # Compression analysis utilities
tests/
└── test_dkm.py # 16 comprehensive test groups (all passing)
train.py # Full training pipeline (CIFAR-10 demo)
Core Components
DKMLayer: The differentiable k-means clustering layer. Implements the iterative attention-based clustering from Fig. 2 of the paper, with k-means++ initialization, warm start across batches, and convergence checking.
DKMCompressor: Wraps any PyTorch model by inserting DKM layers via forward pre-hooks. Handles per-layer configuration (different bits/dim for conv vs fc), the paper's protocol for small layers (<10K params → 8-bit), and first/last layer skipping.
compress_model: High-level API matching the paper's notation (cv:bits/dim, fc:bits/dim).
Training Protocol (Section 4)
Following the paper exactly:
Optimizer: SGD with momentum 0.9
Learning rate: 0.008 (fixed, no per-layer tuning)
Loss: Original task loss (no regularizers or modifications)
Epochs: 200 for ImageNet, varies for GLUE
Batch size: 128 per GPU (paper used 8× V100)
Convergence: ε = 1e-4, max 5 DKM iterations per layer
Small layers: Layers with <10,000 parameters get 8-bit clustering
Compressed Model Format
After training, export_compressed() returns:
state_dict: Standard PyTorch state dict (with snapped weights)
codebooks: Per-layer centroid tensors (k × d float32)
assignments: Per-layer cluster index tensors (N/d integers, b bits each)
layer_configs: Per-layer DKM configuration
The actual compressed size = Σ(codebook_bits + assignment_bits) per layer + uncompressed params.
Tests
All 16 test groups pass, covering:
Shape preservation (train & eval)
Distance matrix correctness
Attention matrix properties (row-sum=1, temperature effect)
Centroid convergence to cluster means
Gradient flow (differentiability — key paper contribution)
Multi-dimensional clustering
Iterative convergence
Full compressor pipeline
Weight snapping for inference
Model export
Multi-step training stability
Paper configurations (Table 1)
K-means++ initialization
Warm start across batches
Numerical stability (large/small/uniform weights)
ResNet-like model compression
python tests/test_dkm.py
Citation
bibtex
1@inproceedings{cho2022dkm,
2 title={DKM: Differentiable k-Means Clustering Layer for Neural Network Compression},
3 author={Cho, Minsik and Alizadeh-Vahid, Keivan and Adya, Saurabh and Rastegari, Mohammad},
4 booktitle={International Conference on Learning Representations (ICLR)},
5 year={2022},
6 url={https://openreview.net/forum?id=J_F_qqCE3Z5}
7}
License
This is a research implementation. The original paper is by Apple Research (Cho et al., ICLR 2022).