Core API
Sparsification
- compresso.topk_ste(x, k, dim=-1, score_mode='abs', ste_alpha=0.0)[source]
Hard top-k forward with alpha-scaled STE on non-selected entries.
Forward keeps exactly
ksigned values per slice (others are zero). Backward uses gradient scale1.0on selected top-k entries andste_alphaon all non-selected entries.- Return type:
Tensor- Parameters:
x (Tensor)
k (int)
dim (int)
score_mode (str)
ste_alpha (float)
- class compresso.TopKSparsify(k, dim=-1, score_mode='abs', ste_alpha=0.0)[source]
Activation layer that applies hard top-k sparsification with STE.
- Parameters:
k (
int) – Number of entries to keep along dim.dim (
int) – Dimension along which to select (default-1).score_mode (
str) – Scoring mode for top-k ranking (abs,raw,relu).ste_alpha (
float) – Backward gradient scale for non-selected positions.
Initialize internal Module state, shared by both nn.Module and ScriptModule.
- forward(x)[source]
Apply top-k sparsification to an input tensor.
The forward pass keeps the
khighest-scoring entries alongdimand sets all other entries to zero. Ranking is controlled byscore_modeand gradients for non-selected entries are scaled byste_alphathrough the straight-through estimator.- Parameters:
x (
Tensor) – Input tensor to sparsify.- Returns:
Tensor with the same shape as
xand at mostknon-zero entries alongdim.- Return type:
Tensor
Sparse Representations
- class compresso.SRPTensor(*, cols, vals, shape, prefix_shape=None, validate=True)[source]
Minimal SRP tensor container.
Stores a row-packed sparse matrix with fixed
knonzeros per row. The representation usescolsandvalstensors of shape(rows, k)with logical dense shape(rows, cols_total).Optionally carries
prefix_shapeso callers can restore(*prefix, cols_total).- Parameters:
cols (Tensor)
vals (Tensor)
shape (Tuple[int, int])
prefix_shape (Tuple[int, ...] | None)
validate (bool)
- select_rows(row_indices)[source]
Alias for gradient-preserving row indexing.
- Return type:
- Parameters:
row_indices (slice | Tensor | Sequence[int])
- to_coo()[source]
Convert to a coalesced 2D PyTorch sparse COO tensor.
The returned tensor has logical shape
(rows, cols_total). Duplicate SRP columns in a row are summed by COO coalescing, matchingto_dense()scatter-add semantics.- Return type:
Tensor
- to_bsr(blocksize)[source]
Convert to a 2D PyTorch sparse BSR tensor.
- Parameters:
blocksize (
tuple[int,int]) – Sparse block size(row_block, col_block). Both dimensions must divide the logical dense shape.- Return type:
Tensor
- to_bsc(blocksize)[source]
Convert to a 2D PyTorch sparse BSC tensor.
- Parameters:
blocksize (
tuple[int,int]) – Sparse block size(row_block, col_block). Both dimensions must divide the logical dense shape.- Return type:
Tensor
- to_scipy_coo()[source]
Convert to a SciPy
coo_matrixon CPU.This conversion detaches tensors and therefore does not preserve autograd history.
- to_numpy_dict()[source]
Return a structural NumPy representation.
The returned dictionary contains
cols,vals,shape, andprefix_shape. It is intentionally not dense; usesrp.to_dense().cpu().numpy()when a dense NumPy array is desired.- Return type:
dict[str,Any]
- numpy()[source]
Alias for
to_numpy_dict().SRPTensoris structurally represented by bothcolsandvals, so this method returns structural arrays rather than a dense matrix.- Return type:
dict[str,Any]
- static from_dict(payload, *, validate=True)[source]
Deserialize SRPTensor from payload produced by
to_dict().- Return type:
- Parameters:
payload (dict[str, Any])
validate (bool)
- static from_dense(x, k, *, score_mode='abs')[source]
Project dense tensor to fixed-k SRP row-packed representation.
Accepts shape
(*prefix, cols_total)and flattens prefix dims into rows. Stores signed values gathered from originalxat selected indices.- Return type:
- Parameters:
x (Tensor)
k (int)
score_mode (Literal['abs', 'raw', 'relu'])
Sparse Autoencoders
- class compresso.TopKSAE(input_dim, hidden_dim, k, tied=False, decoder_bias=False, pre_act=None, post_sparsify=None, encoder=None, decoder=None, sparsify_score_mode='abs', sparsify_ste_alpha=0.0)[source]
Sparse autoencoder with hard top-k bottleneck.
- Parameters:
input_dim (
int) – Dimensionality of the input (and reconstruction).hidden_dim (
int) – Width of the sparse code layer.k (
int) – Number of active features per sample.tied (
bool) – IfTrue, decoder weight is the transpose of the encoder weight.pre_act (
Optional[Module]) – Optional activation applied to encoder output before sparsification.decoder_bias (bool)
post_sparsify (Optional[nn.Module])
encoder (Optional[nn.Module])
decoder (Optional[nn.Module])
sparsify_score_mode (str)
sparsify_ste_alpha (float)
Initialize internal Module state, shared by both nn.Module and ScriptModule.
- class compresso.TopKSAEConfig(hidden_dim=4096, k=128, decoder_bias=False, pre_act=None, post_sparsify=None, encoder=None, decoder=None, sparsify_score_mode='abs', sparsify_ste_alpha=0.01, noise_type='none', noise_scale='global_rms', noise_level=0.1, standard_scaler_mean=False, standard_scaler_scale='none', standard_scaler_loss_space='original', alpha_loss=0.01, l1_penalty=0.0, batch_size=128, shuffle=True, seed=42, epochs=10, validation_frac=None, patience=None, min_delta=0.0, restore_best_weights=True, lr=0.001, weight_decay=0.0, decay=False, compile=False, device='cpu', show_progress=True, srp_score_mode='abs', log_prefix='TopKSAE', log_every_n_steps=0)[source]
Configuration for
TopKSAETrainer.- Parameters:
hidden_dim (
int) – Width of the SAE code layer.k (
int) – Number of active code features per row.decoder_bias (
bool) – Whether the default decoder linear layer uses a bias.pre_act (
Module|None) – Optional module applied to encoder output before sparsification.post_sparsify (
Module|None) – Optional module applied to sparse codes after top-k. For example,L1Normalize().encoder (
Module|None) – Optional custom modules. When omitted,TopKSAEuses linear encoder and decoder layers.decoder (
Module|None) – Optional custom modules. When omitted,TopKSAEuses linear encoder and decoder layers.sparsify_score_mode (
Literal['abs','raw','relu']) – Top-k scoring mode:"abs","raw", or"relu".sparsify_ste_alpha (
float) – Straight-through estimator leakage for non-selected positions.noise_type (
Literal['none','gaussian']) – Optional corruption applied to training inputs."none"leaves inputs unchanged and"gaussian"adds Gaussian noise.noise_scale (
Literal['absolute','global_rms','feature_std']) – Scaling used for Gaussian noise."absolute"uses embedding coordinate units,"global_rms"uses one training-set-derived scale, and"feature_std"scales each input feature separately.noise_level (
float) – Gaussian standard deviation for absolute scaling, or a dimensionless multiplier for adaptive scaling.standard_scaler_mean (
bool) – Subtract the per-feature training mean from inputs before the SAE, and add it back on its reconstruction. Off by default.standard_scaler_scale (
Literal['none','feature_std','global_rms']) –Division applied after centering, and undone on the reconstruction.
"none"leaves magnitudes alone."feature_std"divides each feature by its own standard deviation, matchingsklearn.preprocessing.StandardScaler; it gives every feature unit variance, which flattens the relative importance of coordinates and bends the embedding geometry, so adaptivenoise_scaleis rejected alongside it."global_rms"divides everything by one scalar, the root mean per-feature variance: coordinates land at unit scale for the encoder while every angle and every distance ratio is preserved exactly, since a uniform scale is not a distortion.Statistics are fitted on the training rows with
correction=0, and constant features keep a scale of1.Neither scaling mode sits well with a normalizing
post_sparsify: unit-norm codes carry no magnitude, so the rescale has to be undone by the decoder alone and converges several times worse. That combination warns rather than raising, since it is merely a bad trade rather than a contradiction.standard_scaler_meanis unaffected, because centering barely moves the magnitude.standard_scaler_loss_space (
Literal['original','scaled']) – Space the reconstruction loss is measured in when standard scaling is active."original"un-scales the reconstruction and compares it to the raw input, keeping the objective and reported metrics identical to an unscaled run."scaled"compares in standardized space, which weights every feature equally instead of by its variance.alpha_loss (
float) – Mixture weight for cosine loss. Training loss isalpha_loss * (1 - cosine_similarity) + (1 - alpha_loss) * mse.l1_penalty (
float) – Optional penalty on mean absolute sparse code activation.batch_size (
int) – Number of embedding rows per training batch.shuffle (
bool) – Whether to shuffle training rows between epochs.seed (
int) – Random seed used for row shuffling and Torch initialization.epochs (
int) – Maximum number of training epochs. Early stopping can end training before this many epochs have run.validation_frac (
float|None) – Optional fraction of input rows held out for validation. Mutually exclusive with thevalidation_embeddingsargument ofTopKSAETrainer.fit(). When both are unset, no validation pass runs and early stopping is unavailable.patience (
int|None) – Number of consecutive epochs without a validation improvement tolerated before training stops.Nonedisables early stopping. Requires a validation set.min_delta (
float) – Smallest decrease in validation loss that counts as an improvement.restore_best_weights (
bool) – IfTrue, reload the weights of the best-scoring epoch once training ends. Only applies when validation is active.lr (
float) – AdamW optimizer parameters.weight_decay (
float) – AdamW optimizer parameters.decay (
bool) – IfTrue, use cosine learning-rate decay fromlrto zero across the configured training epochs.compile (
bool) – IfTrue, calltorch.compileon the SAE when available.device (
str|device) – Device used for training and transforms.show_progress (
bool) – Whether to show a tqdm progress bar when tqdm is installed. Ignored whenever aloggeris in play, since a bar and a log stream would report the same numbers twice; that rule is absolute, so a per-callshow_progress=Truedoes not reinstate the bar alongside a logger. Individual calls can override this default.srp_score_mode (
Literal['abs','raw','relu']) – Score mode used bySRPTensor.from_denseduringtransform.log_prefix (
str) – Bracketed tag put in front of every logged line, so one job’s output stays greppable when several share a log stream.log_every_n_steps (
int) – With alogger, also log everyN-th batch of an epoch or of an inference pass.0logs epoch and pass boundaries only, which is enough unless a single epoch or pass runs for minutes.
TopKSAETrainer builds on the sparse embedding compression method described
in Sparse embedding compression and TopKSAETrainer.
- class compresso.TopKSAETrainer(config=None, logger=None)[source]
Efficient fit/transform wrapper around
compresso.TopKSAE.The trainer is intended for dense embedding matrices, such as item embeddings from a recommender or semantic embeddings from a text encoder. It exposes a compact sklearn-like API:
>>> trainer = TopKSAETrainer(TopKSAEConfig(k=32, epochs=300)) >>> trainer.fit(embeddings) >>> sparse = trainer.transform(embeddings)
transformreturns anSRPTensorcontaining sparse codes. Usereconstructif dense reconstructions are needed.- Parameters:
config (
TopKSAEConfig|None) – Trainer configuration. Defaults toTopKSAEConfig.logger (
Any|None) –Default sink for progress lines, any object with an
info(str)method: alogging.Logger, a service’s own logger, or a shim aroundprint. Duck-typed on purpose, so compresso needs no logging dependency and callers keep their own. When given, runs report themselves line by line instead of through tqdm, which suits a container with no tty; when omitted, nothing about the trainer changes.fit,fit_transform,encode,reconstruct, andtransformeach takeloggerandshow_progressof their own, overriding this one for a single call. A sink describes the job that is running rather than the model, so it is never saved instate_dict()and never carried byfrom_state_dict()— which is also what keeps a checkpoint picklable when the sink holds a socket or an HTTP session.
- property is_built: bool
Whether the underlying
TopKSAEmodel has been initialized.
- build(input_dim)[source]
Initialize model and optimizer for inputs of size
input_dim.- Return type:
- Parameters:
input_dim (int)
- to(device)[source]
Move the underlying model to
deviceand returnself.- Return type:
- Parameters:
device (str | device)
- train_step(batch)[source]
Run one optimization step and return detached training stats.
- Return type:
dict[str,Tensor]- Parameters:
batch (Tensor)
- eval_step(batch)[source]
Score one batch without corruption and return detached stats.
Validation inputs are never passed through
_corrupt(), so the reported loss is free of the per-epoch noise draw that makes training loss a poor early-stopping signal for denoising configurations.- Return type:
dict[str,Tensor]- Parameters:
batch (Tensor)
- fit(embeddings, *, validation_embeddings=None, logger=<inherit>, show_progress=<inherit>)[source]
Train the SAE on dense embeddings and return
self.- Parameters:
embeddings (
ndarray|Tensor) – Training rows. Whenconfig.validation_fracis set, the held-out part is split off from these rows before any training statistics, including adaptive noise scales, are fitted.validation_embeddings (
ndarray|Tensor|None) – Explicit validation rows, for when the split is made by the caller. Mutually exclusive withconfig.validation_frac.logger (
Any|None) – Reporting sink for this call only, overriding the one given to the constructor.Nonedisables log lines and drops an inherited progress bar unlessshow_progressis passed explicitly.show_progress (
bool|_Inherit) – tqdm bar for this call only, overridingconfig.show_progress. A logger suppresses the bar either way.
- Return type:
- encode(embeddings, *, logger=<inherit>, show_progress=<inherit>)[source]
Return dense sparse-code tensor produced by the trained SAE.
- Parameters:
embeddings (
ndarray|Tensor) – Rows to run through the fitted SAE.logger (
Any|None) – Reporting sink for this call only, overriding the one given to the constructor.Nonedisables log lines and drops an inherited progress bar unlessshow_progressis passed explicitly.show_progress (
bool|_Inherit) – tqdm bar for this call only, overridingconfig.show_progress. A logger suppresses the bar either way.
- Return type:
Tensor
- reconstruct(embeddings, *, logger=<inherit>, show_progress=<inherit>)[source]
Return dense reconstructions for
embeddings.- Parameters:
embeddings (
ndarray|Tensor) – Rows to run through the fitted SAE.logger (
Any|None) – Reporting sink for this call only, overriding the one given to the constructor.Nonedisables log lines and drops an inherited progress bar unlessshow_progressis passed explicitly.show_progress (
bool|_Inherit) – tqdm bar for this call only, overridingconfig.show_progress. A logger suppresses the bar either way.
- Return type:
Tensor
- transform(embeddings, *, logger=<inherit>, show_progress=<inherit>)[source]
Encode
embeddingsand return sparse codes as anSRPTensor.Each batch is packed as it is produced, so the dense
(n, hidden_dim)code matrix is never held whole: peak memory is the packed(n, k)result plus one batch. Top-k runs per row, so the result is identical to packing the full dense matrix in one go.loggerandshow_progressoverride the trainer’s own reporting for this call, as onencode(). In particular,logger=Nonedisables log lines and drops an inherited progress bar unlessshow_progressis passed explicitly.- Return type:
- Parameters:
embeddings (ndarray | Tensor)
logger (Any | None)
show_progress (bool | _Inherit)
- fit_transform(embeddings, *, validation_embeddings=None, logger=<inherit>, show_progress=<inherit>)[source]
Fit the SAE and return encoded sparse codes as an
SRPTensor.Codes are returned for every row of
embeddings, including any rows held out for validation byconfig.validation_frac.loggerandshow_progresscover both phases, so a long transform is reported by whatever reported the fit. In particular,logger=Nonedisables log lines and drops an inherited progress bar unlessshow_progressis passed explicitly.- Return type:
- Parameters:
embeddings (ndarray | Tensor)
validation_embeddings (ndarray | Tensor | None)
logger (Any | None)
show_progress (bool | _Inherit)
- load_state_dict(state, *, load_optimizer=True)[source]
Restore trainer state, including fitted denoising statistics.
- Return type:
- Parameters:
state (dict[str, Any])
load_optimizer (bool)
- classmethod from_state_dict(state, *, device=None, load_optimizer=True)[source]
Construct a trainer from
state_dict()output.- Return type:
- Parameters:
state (dict[str, Any])
device (str | device | None)
load_optimizer (bool)
- class compresso.L1Normalize(*args, **kwargs)[source]
Apply row-wise L1 normalization.
Initialize internal Module state, shared by both nn.Module and ScriptModule.
- Parameters:
args (Any)
kwargs (Any)
Sparse Parameters
- class compresso.MaskedParam(weight, k_target, k_schedule=None, num_stages=10, stability_window=5, change_threshold=0.01, sparsity='row', allow_regrowth=True, score_mode='abs', ste_alpha=1.0, post_norm_l1=False)[source]
Dense parameter with a binary mask and an internal pruning schedule.
Initialize internal Module state, shared by both nn.Module and ScriptModule.
- Parameters:
weight (Tensor)
k_target (int)
k_schedule (Sequence[int] | None)
num_stages (int)
stability_window (int)
change_threshold (float)
sparsity (Literal['row', 'col'])
score_mode (Literal['abs', 'raw', 'relu'])
ste_alpha (float)
post_norm_l1 (bool)
- forward()[source]
Return the current masked or top-k-projected weight tensor.
When the mask is frozen, the stored binary mask is applied directly to
weight. Otherwise, a differentiable top-k projection is computed using the current pruning stage and straight-through estimator settings.- Returns:
Dense weight tensor with inactive entries set to zero.
- Return type:
torch.Tensor
- select_rows(row_indices)[source]
Alias for row indexing without full masked-weight materialization.
- Return type:
Tensor- Parameters:
row_indices (slice | Tensor | Sequence[int])
- maskedparam_to_coo()[source]
Export packed fixed-k COO according to self.dim: - dim==1 -> row-packed, fixed k per row - dim==0 -> col-packed, fixed k per col
- maskedparam_to_srp()[source]
Compatibility alias for
to_srp_param().- Return type:
- class compresso.SRPParam(cols, values, shape, *, validate=True)[source]
Structured row-packed sparse parameter.
Represents a matrix
Aof shape(rows, cols_total)stored as fixed-knonzeros per row.Storage:
cols:(rows, k)int64 buffer with fixed indices per row.values:(rows, k)trainable parameter.
Semantics:
A[r, cols[r, j]] += values[r, j]Duplicates within a row accumulate with scatter-add semantics. This format is useful for row-packed sparse matrix multiplication against a dense matrix
Bwith shape(cols_total, out).Initialize internal Module state, shared by both nn.Module and ScriptModule.
- Parameters:
cols (Tensor)
values (Tensor)
shape (Tuple[int, int])
validate (bool)
- extra_repr()[source]
Return the extra representation of the module.
To print customized extra information, you should re-implement this method in your own modules. Both single-line and multi-line strings are acceptable.
- Return type:
str
- build_coo(*, dtype=None, coalesce=True)[source]
Convert to a torch sparse COO tensor (rows, cols_total). Duplicates are kept; coalesce() will sum them.
- Return type:
Tensor- Parameters:
dtype (dtype | None)
coalesce (bool)
- select_rows(row_indices)[source]
Alias for gradient-preserving row indexing.
- Return type:
- Parameters:
row_indices (slice | Tensor | Sequence[int])
- static from_dense(A, k, *, mode='topk_abs', allow_duplicates=False)[source]
Build SRPParam from a dense matrix.
mode:
"topk_abs": pick top-k absolute values per row and store signed values."random_k": pick k random columns per row and store those values.
Note: this is a projection of dense -> fixed-k sparse.
- Return type:
- Parameters:
A (Tensor)
k (int)
mode (Literal['topk_abs', 'random_k'])
allow_duplicates (bool)
- static from_sparse_coo(sp, *, k=None, require_row_packed_fixed_k=True)[source]
Convert from a COO sparse tensor to SRPParam.
- Return type:
- Parameters:
sp (Tensor)
k (int | None)
require_row_packed_fixed_k (bool)
- Cases:
- If require_row_packed_fixed_k=True:
expects exactly k nnz per row (same k for all rows), and we will pack rows. If k is None, we infer it. If not possible -> error.
- If require_row_packed_fixed_k=False:
we will project each row to top-k by abs value (needs k provided).
Utilities
- class compresso.SparsityController(model, mask_update_interval=10, freeze_at_schedule_end=True, method='all')[source]
Global dispatcher for MaskedParam-based pruning.
- Responsibilities:
Keep track of global step.
Every mask_update_interval steps, call step_mask() on all MaskedParams.
If any MaskedParam’s stage is completed, call rewind() on all of them and signal that the optimizer should be reset.
Once all MaskedParams have schedule_done=True, optionally freeze masks and stop scheduling.
- Parameters:
model (Module)
mask_update_interval (int)
freeze_at_schedule_end (bool)
- compresso.exponential_decay(n_init, n_final, k)[source]
Smooth exponential decay from n_init to n_final across k steps, guaranteed never to go below n_final.
- compresso.save_srp_tensor(path, srp)[source]
Save SRPTensor payload with torch.save.
- Return type:
None- Parameters:
path (str | Path)
srp (SRPTensor)
- compresso.load_srp_tensor(path, map_location=None, *, validate=True)[source]
Load SRPTensor payload produced by
save_srp_tensor().- Return type:
- Parameters:
path (str | Path)
validate (bool)