Token Classification
Transformers
ONNX
Safetensors
English
kompress_v2
text-compression
modernbert
lora
kompress
Instructions to use chopratejas/kompress-v2-base with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use chopratejas/kompress-v2-base with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("token-classification", model="chopratejas/kompress-v2-base")# Load model directly from transformers import HeadroomCompressorV2 model = HeadroomCompressorV2.from_pretrained("chopratejas/kompress-v2-base", device_map="auto") - Notebooks
- Google Colab
- Kaggle
model card: metrics re-measured on the leak-free v2.1 test split
Browse files
README.md
CHANGED
|
@@ -16,123 +16,162 @@ pipeline_tag: token-classification
|
|
| 16 |
|
| 17 |
Extractive prompt compressor for LLM proxies. Predicts a keep/drop label per
|
| 18 |
token; the surviving tokens form a compressed version of the input that
|
| 19 |
-
preserves meaning while reducing token count.
|
|
|
|
| 20 |
|
| 21 |
-
Based on **ModernBERT-base** (
|
| 22 |
-
params, 2.
|
| 23 |
-
Trained on 126,617 accepted Pipeline A+B
|
| 24 |
-
judge) across 17
|
| 25 |
-
finance, government, scientific, web, summary,
|
|
|
|
| 26 |
|
| 27 |
-
|
| 28 |
|
| 29 |
-
|
| 30 |
-
import torch
|
| 31 |
-
from transformers import AutoTokenizer
|
| 32 |
|
| 33 |
-
|
| 34 |
-
|
| 35 |
|
| 36 |
-
|
| 37 |
-
from
|
| 38 |
-
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
cfg = V2_BASE # or rebuild from cfg_dict
|
| 44 |
-
model = HeadroomCompressorV2(cfg)
|
| 45 |
-
model.load_state_dict(torch.load("merged.pt", map_location="cpu"), strict=False)
|
| 46 |
-
model.eval().cuda()
|
| 47 |
|
| 48 |
-
|
| 49 |
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
with torch.no_grad():
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
|
|
|
| 59 |
```
|
| 60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
## Threshold tuning
|
| 62 |
|
| 63 |
-
The model emits `final_scores ∈ [0, 1]` per subword.
|
| 64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
| **0.30** | 0.917 (8% drop) | 0.994 | 0.904 | Conservative |
|
| 69 |
-
| **0.40** | 0.867 (13% drop) | 0.987 | 0.913 | Safe |
|
| 70 |
-
| **0.50** (default) | 0.815 (18% drop) | 0.974 | **0.918** | Balanced |
|
| 71 |
-
| **0.60** | 0.765 (23% drop) | 0.950 | 0.915 | Aggressive |
|
| 72 |
-
| **0.70** | 0.705 (30% drop) | 0.908 | 0.898 | Very aggressive |
|
| 73 |
|
| 74 |
-
|
| 75 |
|
| 76 |
## Training data
|
| 77 |
|
| 78 |
- **126,617 labeled examples** after `min_drop_ratio=0.05` filtering and
|
| 79 |
-
same-conversation packing.
|
| 80 |
-
- **Sources**: arxiv, pubmed-scientific, govreport, swe-smith, swe-gym-openhands,
|
| 81 |
-
toolmind, xlam-fc, fineweb-edu, cnn-dailymail, xsum, glaive-fc, lmsys-chat,
|
| 82 |
-
claude-code-sessions, meetingbank, the-stack-smol-md, samsum, swe-bench-verified.
|
| 83 |
- **Labeler**: DeepSeek-V4-Flash (compressor) + DeepSeek-V4-Pro (judge) with
|
| 84 |
Pipeline A + B faithfulness loop. Hard-keep overlay enforces names, dates,
|
| 85 |
numbers, URLs, code identifiers via GLiNER + regex + lexicons.
|
| 86 |
-
- **Bucket split**: short=48%, mid=31%, long=21% (max_length 8,192 native
|
| 87 |
-
ModernBERT context).
|
| 88 |
- **Split**: train=126,617 / val=7,037 / test=7,037.
|
|
|
|
|
|
|
| 89 |
|
| 90 |
## Training details
|
| 91 |
|
| 92 |
-
- Base: ModernBERT-base (
|
| 93 |
- Encoder fine-tuning: **LoRA** (r=16, alpha=32, target_modules=Wqkv/Wi/Wo)
|
| 94 |
- Heads: per-token CE (must-keep loss weight = 3.0) + 1-D span conv (BCE,
|
| 95 |
weight 0.3 on total loss)
|
| 96 |
-
- Trainable params:
|
| 97 |
-
- Loss: weighted cross-entropy on token head + BCE-with-logits on span head
|
| 98 |
- Optim: AdamW (lr=2e-4 cosine, warmup_ratio=0.06, weight_decay=0.01)
|
| 99 |
-
- Effective batch: 48
|
| 100 |
-
- Epochs: 3
|
| 101 |
-
- Precision: bf16 with FlashAttention-2 + gradient checkpointing
|
| 102 |
- Hardware: 1×H100 80GB, ~39 min wall-clock
|
| 103 |
|
| 104 |
-
##
|
| 105 |
|
| 106 |
-
|
| 107 |
-
-
|
| 108 |
-
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
|
| 111 |
## Files in this repo
|
| 112 |
|
| 113 |
```
|
| 114 |
-
config.json
|
| 115 |
-
model.safetensors
|
| 116 |
-
merged.pt
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
adapter/
|
| 121 |
-
|
| 122 |
-
adapter_model.safetensors
|
| 123 |
token_head.pt
|
| 124 |
span_conv.pt
|
| 125 |
-
|
|
|
|
|
|
|
|
|
|
| 126 |
```
|
| 127 |
|
| 128 |
## License
|
| 129 |
|
| 130 |
-
Apache 2.0
|
|
|
|
| 131 |
|
| 132 |
## See also
|
| 133 |
|
|
|
|
|
|
|
| 134 |
- [`chopratejas/kompress-v2-large`](https://huggingface.co/chopratejas/kompress-v2-large)
|
| 135 |
-
—
|
| 136 |
- Headroom proxy integration guide:
|
| 137 |
[docs/CUSTOMER_QUICKSTART.md](https://github.com/chopratejas/kompress/blob/main/docs/CUSTOMER_QUICKSTART.md)
|
| 138 |
- Per-org fine-tuning (LoRA stacking):
|
|
|
|
| 16 |
|
| 17 |
Extractive prompt compressor for LLM proxies. Predicts a keep/drop label per
|
| 18 |
token; the surviving tokens form a compressed version of the input that
|
| 19 |
+
preserves meaning while reducing token count. It has no decoder: the output is
|
| 20 |
+
always a subsequence of the input, in the original order.
|
| 21 |
|
| 22 |
+
Based on **ModernBERT-base** (150M params) with a LoRA adapter
|
| 23 |
+
(4.4M trainable params, 2.9%) plus a custom dual head
|
| 24 |
+
(token classifier + 1-D span conv). Trained on 126,617 accepted Pipeline A+B
|
| 25 |
+
labels (compressor + faithfulness judge) across 17 sources: narrative, dialog,
|
| 26 |
+
code, agent traces, healthcare, finance, government, scientific, web, summary,
|
| 27 |
+
and tool-calling.
|
| 28 |
|
| 29 |
+
**Distribution.** Public. Apache 2.0, free for commercial use.
|
| 30 |
|
| 31 |
+
## Use with Headroom (recommended)
|
|
|
|
|
|
|
| 32 |
|
| 33 |
+
Headroom's proxy loads `onnx/kompress-int8-wo.onnx` from this repo and runs it
|
| 34 |
+
on CPU with ONNX Runtime; no torch needed. Point it at this repo:
|
| 35 |
|
| 36 |
+
```python
|
| 37 |
+
from headroom.transforms.kompress_compressor import KompressCompressor, KompressConfig
|
| 38 |
+
|
| 39 |
+
compressor = KompressCompressor(KompressConfig(model_id="chopratejas/kompress-v2-base"))
|
| 40 |
+
result = compressor.compress(long_tool_output)
|
| 41 |
+
print(result.compressed, result.compression_ratio)
|
| 42 |
+
```
|
| 43 |
|
| 44 |
+
Or serve it as an endpoint from this repository's `modal_jobs/modal_serve.py`
|
| 45 |
+
with `KOMPRESS_MODEL_ID=chopratejas/kompress-v2-base` set at deploy time.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
|
| 47 |
+
## Use directly (PyTorch)
|
| 48 |
|
| 49 |
+
```python
|
| 50 |
+
import torch
|
| 51 |
+
from transformers import AutoModel, AutoTokenizer
|
| 52 |
+
from huggingface_hub import hf_hub_download
|
| 53 |
+
|
| 54 |
+
ckpt = torch.load(hf_hub_download("chopratejas/kompress-v2-base", "merged.pt"), map_location="cpu", weights_only=False)
|
| 55 |
+
encoder = AutoModel.from_pretrained("answerdotai/ModernBERT-base", attn_implementation="eager")
|
| 56 |
+
encoder.load_state_dict({k: v.float() for k, v in ckpt["encoder_state_dict"].items()})
|
| 57 |
+
H = encoder.config.hidden_size
|
| 58 |
+
token_head = torch.nn.Linear(H, 2)
|
| 59 |
+
span_conv = torch.nn.Sequential(torch.nn.Conv1d(H, 256, 5, padding=2), torch.nn.GELU(),
|
| 60 |
+
torch.nn.Conv1d(256, 1, 3, padding=1))
|
| 61 |
+
token_head.load_state_dict(ckpt["token_head_state_dict"])
|
| 62 |
+
span_conv.load_state_dict(ckpt["span_conv_state_dict"])
|
| 63 |
+
|
| 64 |
+
tok = AutoTokenizer.from_pretrained("chopratejas/kompress-v2-base")
|
| 65 |
+
enc = tok("The quick brown fox jumps over the lazy dog.", return_tensors="pt")
|
| 66 |
with torch.no_grad():
|
| 67 |
+
h = encoder(**enc).last_hidden_state
|
| 68 |
+
p_keep = torch.softmax(token_head(h), -1)[..., 1]
|
| 69 |
+
span = torch.sigmoid(span_conv(h.transpose(1, 2)).squeeze(1))
|
| 70 |
+
scores = p_keep * (0.5 + 0.5 * span) # final_scores in [0, 1]
|
| 71 |
+
kept = enc["input_ids"][0][scores[0] >= 0.5]
|
| 72 |
+
print(tok.decode(kept, skip_special_tokens=True))
|
| 73 |
```
|
| 74 |
|
| 75 |
+
`model.safetensors` is the HF Trainer checkpoint of `HeadroomCompressorV2`
|
| 76 |
+
(PEFT-wrapped encoder + LoRA + heads) and loads through the `kompress` package;
|
| 77 |
+
`merged.pt` is the same model with LoRA folded into the encoder and is what the
|
| 78 |
+
ONNX exports were traced from.
|
| 79 |
+
|
| 80 |
## Threshold tuning
|
| 81 |
|
| 82 |
+
The model emits `final_scores ∈ [0, 1]` per subword. Raise the threshold
|
| 83 |
+
to compress harder; lower it to protect must-keep recall.
|
| 84 |
+
|
| 85 |
+
| Threshold | keep_rate | must_keep_recall | F1 | precision | recall |
|
| 86 |
+
|---|---|---|---|---|---|
|
| 87 |
+
| **0.30** | 0.946 (5% drop) | 0.997 | 0.942 | 0.920 | 0.964 |
|
| 88 |
+
| **0.40** | 0.910 (9% drop) | 0.994 | 0.933 | 0.929 | 0.937 |
|
| 89 |
+
| **0.50** (default) | 0.866 (13% drop) | 0.989 | 0.920 | 0.940 | 0.901 |
|
| 90 |
+
| **0.60** | 0.818 (18% drop) | 0.980 | 0.902 | 0.949 | 0.860 |
|
| 91 |
+
| **0.70** | 0.752 (25% drop) | 0.953 | 0.870 | 0.958 | 0.798 |
|
| 92 |
+
|
| 93 |
+
Measured on the held-out test split (n=12,697 rows, 16,827,490 scored subwords), checkpoint `best`, PyTorch bf16 on H100.
|
| 94 |
|
| 95 |
+
**Test split.** `dataset_v2_v2.1-f00` test: split by source document, exact and near duplicates of training rows removed. An earlier version of this card reported metrics on the v2.0 split, where 12.2% of test rows were byte-identical to training rows; those numbers were optimistic by roughly 0.02 F1 and have been replaced.
|
| 96 |
+
**At the default threshold (0.5):** F1 0.920, must-keep recall 0.989, keep rate 0.866 (13% of subwords removed).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
+
On the subset the labeller actually compressed (it dropped at least 5% of the words, 6,559,681 subwords), at 0.5: F1 0.893, must-keep recall 0.986, keep rate 0.853. The rest of the split is text where almost every word should be kept, which inflates F1 for any model.
|
| 99 |
|
| 100 |
## Training data
|
| 101 |
|
| 102 |
- **126,617 labeled examples** after `min_drop_ratio=0.05` filtering and
|
| 103 |
+
same-conversation packing (from 367,525 accepted labels).
|
| 104 |
+
- **Sources**: arxiv, pubmed-scientific, govreport, swe-smith, swe-gym-openhands, toolmind, xlam-fc, fineweb-edu, cnn-dailymail, xsum, glaive-fc, lmsys-chat, claude-code-sessions, meetingbank, the-stack-smol-md, samsum, swe-bench-verified.
|
|
|
|
|
|
|
| 105 |
- **Labeler**: DeepSeek-V4-Flash (compressor) + DeepSeek-V4-Pro (judge) with
|
| 106 |
Pipeline A + B faithfulness loop. Hard-keep overlay enforces names, dates,
|
| 107 |
numbers, URLs, code identifiers via GLiNER + regex + lexicons.
|
| 108 |
+
- **Bucket split**: short=48%, mid=31%, long=21% (max_length 8,192 native ModernBERT context).
|
|
|
|
| 109 |
- **Split**: train=126,617 / val=7,037 / test=7,037.
|
| 110 |
+
- Data card, per-source licences and the two non-commercial sources (4.78% of
|
| 111 |
+
the corpus): `DATA.md` and `LICENSES.md` in the training repository.
|
| 112 |
|
| 113 |
## Training details
|
| 114 |
|
| 115 |
+
- Base: ModernBERT-base (150M params)
|
| 116 |
- Encoder fine-tuning: **LoRA** (r=16, alpha=32, target_modules=Wqkv/Wi/Wo)
|
| 117 |
- Heads: per-token CE (must-keep loss weight = 3.0) + 1-D span conv (BCE,
|
| 118 |
weight 0.3 on total loss)
|
| 119 |
+
- Trainable params: 4.4M (2.9% of total)
|
|
|
|
| 120 |
- Optim: AdamW (lr=2e-4 cosine, warmup_ratio=0.06, weight_decay=0.01)
|
| 121 |
+
- Effective batch: 48; epochs: 3; bf16 with FlashAttention-2 + gradient checkpointing
|
|
|
|
|
|
|
| 122 |
- Hardware: 1×H100 80GB, ~39 min wall-clock
|
| 123 |
|
| 124 |
+
## Validation curve (n=7,037, threshold=0.5)
|
| 125 |
|
| 126 |
+
| step | epoch | eval_loss | F1 | must_keep_recall | keep_rate | precision |
|
| 127 |
+
|---|---|---|---|---|---|---|
|
| 128 |
+
| 2000 | 0.76 | 0.347 | 0.905 | 0.9849 | 0.867 | 0.868 |
|
| 129 |
+
| 4000 ← selected (best must_keep_recall) | 1.52 | 0.342 | 0.905 | 0.9909 | 0.900 | 0.852 |
|
| 130 |
+
| 6000 | 2.27 | 0.338 | 0.907 | 0.9865 | 0.881 | 0.863 |
|
| 131 |
+
|
| 132 |
+
The shipped weights are the checkpoint with the best validation must-keep recall (`metric_for_best_model`), evaluated every 2,000 steps.
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
## ONNX (what Headroom loads)
|
| 136 |
+
|
| 137 |
+
| artifact | size | notes |
|
| 138 |
+
|---|---|---|
|
| 139 |
+
| `onnx/kompress-int8-wo.onnx` | 274 MB | weight-only int8 (MatMulNBits), the default artifact; needs `onnxruntime>=1.24` |
|
| 140 |
+
| `onnx/kompress-fp32.onnx` | 601 MB | lossless reference |
|
| 141 |
+
|
| 142 |
+
Weight-only int8 agrees with fp32 on 99.6% of keep decisions. Headroom tries
|
| 143 |
+
`int8-wo` first and falls back to `fp32` on runtimes without the 8-bit kernel.
|
| 144 |
|
| 145 |
## Files in this repo
|
| 146 |
|
| 147 |
```
|
| 148 |
+
config.json # KompressV2Config + arch metadata
|
| 149 |
+
model.safetensors # HF Trainer checkpoint (PEFT-wrapped encoder + LoRA + heads)
|
| 150 |
+
merged.pt # LoRA merged into the encoder; source of the ONNX exports
|
| 151 |
+
onnx/kompress-int8-wo.onnx # weight-only int8, Headroom's default artifact
|
| 152 |
+
onnx/kompress-fp32.onnx # lossless reference
|
| 153 |
+
adapter/ # LoRA adapter + heads only, for stacking per-org adapters
|
| 154 |
+
adapter/adapter_config.json
|
| 155 |
+
adapter/adapter_model.safetensors
|
|
|
|
| 156 |
token_head.pt
|
| 157 |
span_conv.pt
|
| 158 |
+
tokenizer.json # answerdotai/ModernBERT-base tokenizer
|
| 159 |
+
tokenizer_config.json
|
| 160 |
+
special_tokens_map.json
|
| 161 |
+
README.md # this file
|
| 162 |
```
|
| 163 |
|
| 164 |
## License
|
| 165 |
|
| 166 |
+
Apache 2.0 for the model artifact. ModernBERT-base is also Apache 2.0. Training-data
|
| 167 |
+
licences are per source; see `LICENSES.md` in the training repository.
|
| 168 |
|
| 169 |
## See also
|
| 170 |
|
| 171 |
+
- [`chopratejas/kompress-v2-base`](https://huggingface.co/chopratejas/kompress-v2-base)
|
| 172 |
+
— ModernBERT-base variant (149M params, public)
|
| 173 |
- [`chopratejas/kompress-v2-large`](https://huggingface.co/chopratejas/kompress-v2-large)
|
| 174 |
+
— ModernBERT-large variant (395M params, private/enterprise)
|
| 175 |
- Headroom proxy integration guide:
|
| 176 |
[docs/CUSTOMER_QUICKSTART.md](https://github.com/chopratejas/kompress/blob/main/docs/CUSTOMER_QUICKSTART.md)
|
| 177 |
- Per-org fine-tuning (LoRA stacking):
|