afoolishman's picture
Add README.md
7122b24 verified
|
Raw History Blame Contribute Delete
4.82 kB
---
language:
- en
library_name: pytorch
pipeline_tag: text-generation
tags:
- speculative-decoding
- memory-layers
- n-gram-memory
- lngram
- interpretability
- research
datasets:
- OptimalScale/ClimbMix
---
# Self-Drafting Latent Memory: model collection
Weights for the paper *"Self-Drafting Latent Memory: What an n-gram Memory Learns, and When It Can Draft for Its Own Model"*.
These are **research checkpoints**: 370M-parameter decoder language models with a route n-gram memory ([Lngram](https://github.com/zyaaa-ux/Lngram) v2) at layer 1. Each was trained on 1B tokens of ClimbMix (2B for the dense control). They are not instruction-tuned and are not intended for deployment.
In the self-drafting variants, the memory's router reads only token embeddings. A small *draft head* can therefore read the memory table **without running the transformer backbone**, and propose tokens for speculative decoding of its own model. The draft head is trained jointly with the language model.
## Models
| Folder | Model | Description | Non-embedding params | Val loss (1B tok) |
|---|---|---|---|---|
| [`sb-run1/`](sb-run1) | SB, run 1 | Baseline: Lngram v2 at layer 1, hidden-state router, 184 routes | 369.78M | 2.7127 |
| [`sb-run2/`](sb-run2) | SB, run 2 | Same recipe, second training run (replicate) | 369.78M | 2.7107 |
| [`sd-b/`](sd-b) | SD-B | Token-embedding router + jointly trained draft head, 182 routes | 369.93M | 2.7159 |
| [`sd-c/`](sd-c) | SD-C | SD-B + 256-channel diagonal SSM feeding router and draft query, 181 routes | 369.88M | 2.7111 |
| [`d270/`](d270) | D270 | Dense control: no memory, same active params per token, **2B tokens** | 269.80M | 2.5147 (2B) |
| [`posthoc-drafters/`](posthoc-drafters) | post-hoc drafters | Token router + draft readout fitted to frozen SB run 1, without / with SSM | ~2–2.5M each | — |
## Key results
- **Self-drafting is free.** Loss changes by +0.0004 to +0.003 nats against the baseline, and the two baseline runs themselves differ by 0.002. There's no significant difference on HellaSwag, MMLU-cloze, SciQ, WinoGrande, PIQA or ARC-Easy.
- **Joint training makes a far better drafter than post-hoc fitting.** Top-1 agreement with the target is 0.45 (SD-C) vs 0.30, and accepted length roughly doubles.
- **Acceptance at γ=4 with code-keyed online counts:** 2.5–2.6 tokens per verification step. That beats prompt lookup on open-ended text. A hybrid (prompt lookup, else the draft head) beats prompt lookup on every model and text type.
- **The drafter's own confidence predicts agreement.** Gating at 0.5 gives 88% agreement on 18% of positions.
All numbers, logs and analysis code are in the GitHub repository [MorbiusPlexus/lngram-decode](https://github.com/MorbiusPlexus/lngram-decode). Training curves for every model are in the W&B project [morbius-wave3](https://forge.coreweave.com/wandb/kishor-iiit-hyderabad/morbius-wave3).
## Usage
The checkpoints use the `ffnmem` code from [MorbiusPlexus/lngram-decode](https://github.com/MorbiusPlexus/lngram-decode): a custom architecture, so it isn't loadable through `transformers`.
```python
import torch
from ffnmem.infer import load_model, greedy_generate
model, cfg = load_model("sd-c/model.pt", device="cuda") # weights + resolved config
prompt = torch.tensor([[...token ids...]], device="cuda") # tokenizer: data/tokenizer/tokenizer.json in the repo
tokens, _ = greedy_generate(model, prompt, n_new=64, amp_dtype=torch.float16)
# Self-drafting models: draft logits from token ids alone (no backbone forward)
b = torch.zeros(prompt.shape[1], dtype=torch.long, device="cuda")
t = torch.arange(prompt.shape[1], device="cuda")
draft_logits = model.draft_logits(prompt, b, t) # SD-B / SD-C only
```
Each `model.pt` is a dict `{"model": state_dict, "config": resolved config, "step": int, "params": counts}`. `config.json` duplicates the config for inspection.
## Training data and procedure
- **Data:** ClimbMix, tokenised with a 32,768-token byte-level BPE (in the repository).
- **Batch and schedule:** global batch 256 × 2048 tokens; 1,907 steps (1B tokens); cosine learning rate 6e-4 → 6e-5 with 100 warmup steps.
- **Optimisation:** AdamW (0.9, 0.95), weight decay 0.1; memory tables use a 4× learning rate without decay.
- **Precision:** fp16 with GradScaler.
- **Draft loss:** λ = 0.1 × KL(sg(p) ‖ q) on 25% of positions.
## Limitations
- **Small models:** 370M parameters trained on 1B tokens, with performance near chance on MMLU and WinoGrande.
- **No safety work:** not aligned or safety-tuned; outputs can be incorrect or inappropriate.
- **Seeds:** one seed per model, except the baseline, which was trained twice.
- **Speed:** measured offline under greedy decoding. The released live speculative loop isn't optimised and doesn't yet realise a speedup.