Skip to content

FusionBrainLab/progressive_cramming

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

38 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Progressive Cramming

Reliable token compression into learnable memory embeddings โ€” and what it reveals.
Reference implementation for the paper
Progressive Cramming: Reliable Token Compression and What It Reveals
(Tarasov, Lashukov, Goncharova, Kuznetsov).

โ–ถ Videoย slides ยท Demo ยท Quickstart ยท Methods ยท Reproduce ยท Dataset ยท Cite

Open In Colab


What is "cramming"?

Cramming compresses a span of text into one (or a few) learnable memory embeddings: we freeze a pretrained language model and optimise a small set of input embeddings โ€” by gradient descent โ€” until the frozen model reconstructs the original tokens from them. The text never updates the model's weights; all the information is squeezed into the optimised embedding. How much text a single embedding can hold (its compression horizon), and how the optimisation gets there, is what this repository measures.

This repo ships a lean, self-contained implementation of the three core methods:

Method What it does Selected by
Full cramming Optimise a memory embedding to reconstruct a fixed-length text span. (default)
Progressive cramming Grow the target span stage by stage, only extending once the current span reconstructs exactly โ€” finding the compression horizon. --progressive_train
Low-dim projection Optimise the embedding inside a learned rank-k subspace instead of full hidden size. --low_dim_train

This is a focused reproducibility release: the three methods above plus their evaluation. The broader research codebase (ablations, compression-head training, topology analysis) is intentionally not included.


๐ŸŽฎ Interactive demo (Colab)

Open In Colab

A self-contained notebook (notebooks/progressive_cramming_demo.ipynb) that runs on a free Colab T4 GPU with Llama-3.2-1B. It lets you:

  • reconstruct a pre-compressed gallery of 5 domains (literature / code / news / poetry / science) from embeddings cached on the Hub โ€” one click each;
  • compare total vs progressive cramming side by side on one example;
  • compress your own text and watch the optimisation live (loss/reconstruction curves
    • the embedding's PCA trajectory), then download the resulting embedding.

The gallery embeddings are produced by scripts/build_demo_gallery.py (run once on a GPU) and published as a small Hugging Face dataset the notebook reads at runtime.


๐Ÿ“ฆ Repository layout

progressive_cramming/
โ”œโ”€โ”€ src/progressive_cramming/      # the installable package
โ”‚   โ”œโ”€โ”€ run.py                     # entry point: model+data load, trainer select, train
โ”‚   โ”œโ”€โ”€ train/
โ”‚   โ”‚   โ”œโ”€โ”€ arguments.py           # MyTrainingArguments โ€” every CLI flag
โ”‚   โ”‚   โ”œโ”€โ”€ trainers/              # FullCramming / Progressive / LowDim trainers
โ”‚   โ”‚   โ”œโ”€โ”€ parametrization.py     # direct / low-dim / PCA embedding parametrizations
โ”‚   โ”‚   โ”œโ”€โ”€ embedding_init.py      # init strategies (random0.02, mvnormal, pca, ...)
โ”‚   โ”‚   โ”œโ”€โ”€ loss.py, inputs.py, optimization.py
โ”‚   โ”œโ”€โ”€ analysis/                  # convergence tracking + information gain
โ”‚   โ”œโ”€โ”€ inference/                 # generation from a compression embedding
โ”‚   โ”œโ”€โ”€ data/                      # dataset tokenization + caching
โ”‚   โ”œโ”€โ”€ demo/                     # cram/reconstruct helpers for the Colab demo notebook
โ”‚   โ””โ”€โ”€ utils/
โ”œโ”€โ”€ scripts/run_cramming.py        # shell wrapper around run.py
โ”œโ”€โ”€ scripts/build_demo_gallery.py  # builds + uploads the demo's pre-computed embedding gallery
โ”œโ”€โ”€ examples/quickstart.py         # runs all 3 methods on a small model (this README's demo)
โ”œโ”€โ”€ notebooks/progressive_cramming_demo.ipynb  # interactive Colab demo
โ””โ”€โ”€ presentation/                  # the reveal.js video deck (deployed to GitHub Pages)

๐Ÿ›  Installation

Python โ‰ฅ 3.11 and a recent PyTorch. A CUDA GPU is recommended (the quickstart runs in minutes on one GPU; CPU works but is much slower).

git clone https://github.com/FusionBrainLab/progressive_cramming.git
cd progressive_cramming

python -m venv .venv && source .venv/bin/activate     # or use uv / conda
pip install -e .

This installs the progressive_cramming package and the progressive-cramming console script. Models and datasets are pulled from the Hugging Face Hub on first use.


๐Ÿš€ Quickstart (minutes on 1 GPU)

Run all three methods on a small model (SmolLM2-135M) over a couple of PG-19 samples and print each method's headline metric (~10 minutes total on one GPU โ€” a couple of minutes per method; progressive cramming is the slowest):

python examples/quickstart.py

Example output (measured on one A100; numbers vary slightly with hardware/seed):

QUICKSTART RESULTS
======================================================================
{
  "method": "full_cramming",
  "samples": 2,
  "mean_reconstruction": 0.992,          # ~exact token reconstruction
  "mean_steps_to_converge": 2614.0
}
{
  "method": "low_dim_projection(k=32)",
  "samples": 2,
  "mean_reconstruction": 1.0             # exact, in a rank-32 subspace
}
{
  "method": "progressive_cramming",
  "samples": 2,
  "mean_converged_horizon_tokens": 29.0, # longest prefix reconstructed exactly
  "max_sequence_length": 64,
  "mean_stages": 5.5
}

Metrics and tiny artifacts are written to runs/quickstart/. Useful flags:

python examples/quickstart.py --model HuggingFaceTB/SmolLM2-360M --seq-len 96 --samples 4
python examples/quickstart.py --methods full progressive       # subset of methods

How to read the metrics

  • mean_reconstruction โ€” fraction of tokens the frozen model decodes correctly from the compression embedding (teacher-forced). 1.0 = exact reconstruction.
  • mean_converged_horizon_tokens โ€” for progressive cramming, the longest prefix (in tokens) that a single embedding reconstructs exactly โ€” the compression horizon.

๐Ÿงช The three methods

All three run through the same entry point; the trainer is chosen by CLI flags. Replace the model/dataset/lengths as you like.

Full cramming

python scripts/run_cramming.py \
    --model_checkpoint HuggingFaceTB/SmolLM2-135M \
    --dataset_name LarryLovestein/pg19_1k \
    --max_sequence_length 64 --limit_dataset_items 4 \
    --embedding_init_method random0.02 \
    --learning_rate 0.1 --max_optimization_steps_per_sample 4000 \
    --output_dir runs/full_demo

Progressive cramming

python scripts/run_cramming.py --progressive_train 1 \
    --model_checkpoint HuggingFaceTB/SmolLM2-135M \
    --dataset_name LarryLovestein/pg19_1k \
    --max_sequence_length 64 --limit_dataset_items 4 \
    --embedding_init_method random0.02 --learning_rate 0.1 \
    --progressive_min_seq_len 1 --progressive_step 8 \
    --max_optimization_steps_per_token 500 \
    --output_dir runs/progressive_demo

Low-dim projection

python scripts/run_cramming.py --low_dim_train --low_dim_size 32 \
    --model_checkpoint HuggingFaceTB/SmolLM2-135M \
    --dataset_name LarryLovestein/pg19_1k \
    --max_sequence_length 64 --limit_dataset_items 4 \
    --embedding_init_method random0.02 --learning_rate 0.1 \
    --max_optimization_steps_per_sample 4000 \
    --output_dir runs/lowdim_demo

Run python scripts/run_cramming.py --help to see every flag (defined in src/progressive_cramming/train/arguments.py).


๐Ÿ“Š Reproducing the paper experiments

The paper's numbers come from larger models, the full PG-19 benchmark, and long optimisation budgets โ€” they require a GPU (the original runs used one A100 per job). The settings below are the exact recipe (mirrors the internal job launcher).

Common setup

Setting Value
Dataset LarryLovestein/pg19_1k
Samples (--limit_dataset_items) 50
--max_sequence_length 4096
--max_optimization_steps_per_sample 10000
--max_optimization_steps_per_token 1000
--embedding_init_method random0.02
--warmup_steps 100
Attention backend flash_attention_2 (install flash-attn) or sdpa

Per-model learning rate / batch size / low-dim size

Model --learning_rate --per_device_train_batch_size --low_dim_size
unsloth/Meta-Llama-3.1-8B 0.1 10 256
EleutherAI/pythia-1.4b 0.5 25 256
HuggingFaceTB/SmolLM2-1.7B 0.1 25 256
unsloth/gemma-3-4b-pt 0.1 10 32

Example โ€” progressive cramming, SmolLM2-1.7B, paper settings:

python scripts/run_cramming.py --progressive_train 1 \
    --model_checkpoint HuggingFaceTB/SmolLM2-1.7B \
    --dataset_name LarryLovestein/pg19_1k --limit_dataset_items 50 \
    --max_sequence_length 4096 \
    --embedding_init_method random0.02 \
    --learning_rate 0.1 --per_device_train_batch_size 25 \
    --warmup_steps 100 \
    --max_optimization_steps_per_sample 10000 \
    --max_optimization_steps_per_token 1000 \
    --attn_implementation flash_attention_2 \
    --output_dir runs/progressive_smollm2_1.7b

For multi-GPU, launch with accelerate launch scripts/run_cramming.py ... โ€” the dataset is tokenized once by the main process and shared.

The paper's variants (beyond the three core methods) combine these flags:

  • hybrid (activation alignment): --loss_type cosine --hybrid_alpha 1.0 --num_alignment_layers 8
  • hybrid + low-dim: add --low_dim_projection --low_dim_size <k>
  • no-BOS: --no_bos_token

๐Ÿ—‚ Outputs

Each run writes a Hugging Face Dataset of per-sample (per-stage for progressive) rows under --output_dir:

  • compressed_prefixes/ (full, low-dim) or progressive_prefixes/ (progressive)
  • compression_embeddings.pt, and for low-dim low_dim_projection.pt
  • TensorBoard logs

Key row fields: final_convergence (reconstruction accuracy), information_gain_bits, embedding, text, plus stage_seq_len / steps_taken for progressive. Load with:

from datasets import load_from_disk
ds = load_from_disk("runs/progressive_demo/progressive_prefixes")
print(ds[0]["final_convergence"], ds[0]["stage_seq_len"])

Published trajectories

You don't have to re-run the paper's experiments to inspect them. The exact progressive-cramming trajectories behind the paper's progressive_modifications table are published on the Hugging Face Hub:

mrsndmn/progressive_cramming_trajectories

One config per model family (Llama-3.1-8B, pythia-1.4b, SmolLM2-1.7B, gemma-3-4b-pt), each with a baseline and a lowdim split. Every row is one converged stage; reconstruct a document's trajectory by taking all rows with the same sample_id and sorting by (stage_index, stage_seq_len).

from datasets import load_dataset
ds = load_dataset("mrsndmn/progressive_cramming_trajectories", "SmolLM2-1.7B", split="baseline")

See the dataset card for the full column schema and a note on the saved-embedding offset.


๐ŸŽฌ Video presentation

A self-contained reveal.js deck lives in presentation/ and is deployed to GitHub Pages on every change (see .github/workflows/deploy-presentation.yml):

โ–ถ https://fusionbrainlab.github.io/progressive_cramming/slides/ (the bare site root redirects here)


๐Ÿ“ Citation

@inproceedings{tarasov2026progressive,
  title     = {Progressive Cramming: Reliable Token Compression and What It Reveals},
  author    = {Tarasov, Dmitrii and Lashukov and Goncharova, Elena and Kuznetsov, Andrey},
  year      = {2026},
}

See CITATION.cff.

๐Ÿ“„ License

MIT.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors