| assets | ||
| chat_templates | ||
| configs | ||
| data | ||
| demo | ||
| examples | ||
| scripts | ||
| src/ctx_to_lora | ||
| tests | ||
| webui | ||
| .gitattributes | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| accelerate_config.yaml | ||
| install.sh | ||
| pyproject.toml | ||
| README.md | ||
| run_eval.py | ||
| setup.py | ||
| train.py | ||
| uv.lock | ||
| watcher.py | ||
Doc-to-LoRA (D2L): Learning to Instantly Internalize Contexts
📰X | 📜Paper | 🤗Hugging Face | :octocat:GitHubA reference implementation of Doc-to-LoRA (D2L).
🛠️ Installation
curl -LsSf https://astral.sh/uv/install.sh | sh
./install.sh
🤗 Pre-Trained Models
uv run huggingface-cli login
uv run huggingface-cli download SakanaAI/doc-to-lora --local-dir . --include "trained_t2l/*"
🚀 Python API Usage
# caveat: this interface only supports non-batched inputs
# for batched inference please see `src/ctx_to_lora/modeling/hypernet.py`
import torch
from ctx_to_lora.model_loading import get_tokenizer
from ctx_to_lora.modeling.hypernet import ModulatedPretrainedModel
# model loading
checkpoint_path = ...
state_dict = torch.load(checkpoint_path, weights_only=False)
model = ModulatedPretrainedModel.from_state_dict(
state_dict, train=False, use_sequence_packing=False
)
model.reset()
tokenizer = get_tokenizer(model.base_model.name_or_path)
# prepare data
doc = open("data/sakana_wiki.txt", "r").read()
chat = [{"role": "user", "content": "Summarize what Sakana AI does."}]
chat_ids = tokenizer.apply_chat_template(
chat,
add_special_tokens=False,
return_attention_mask=False,
add_generation_prompt=True,
return_tensors="pt",
).to(model.device)
# calls after internalization will be influenced by internalized info
model.internalize(doc)
outputs = model.generate(input_ids=chat_ids, max_new_tokens=256)
print(tokenizer.decode(outputs[0]))
# remove internalized info
model.reset()
outputs = model.generate(input_ids=chat_ids, max_new_tokens=256)
print(tokenizer.decode(outputs[0]))
🎮 Interactive Demo
uv run demo/app.py
🧪 Experimental Scripts
To run any of the following scripts, use uv run $PATH_TO_SCRIPT from the root of this project.
| Experiment | Data prep | Training | Evaluation | Notes |
|---|---|---|---|---|
| Main experiment | scripts/main_exp/0-download_data.sh |
scripts/main_exp/1-train.sh |
scripts/main_exp/eval/*.sh |
Downloading data is fastest; regenerate only if you need fresh synthetic data. Evaluation scripts reproduce the main paper metrics. |
| NIAH | scripts/niah/0-gen_data.sh |
scripts/niah/1-train.sh |
scripts/niah/2-eval.sh |
Run the scripts in order; data generation only needs to happen once |
scripts/main_exp/eval/clipper.sh adds the CLIPPER long-context benchmark to the eval pipeline via the public chtmp223/CLIPPER Hugging Face dataset.
scripts/main_exp/eval/rag.sh runs a lightweight BM25-style RAG baseline over each example's context field. It keeps dataset-side context chunking disabled and performs retrieval chunking inside the eval-time wrapper.
WANDB_MODE=disabled uv run run_eval.py \
--model_name_or_path google/gemma-2-2b-it \
--datasets squad drop ropes \
--split test \
--eval_batch_size_gen 1 \
--use_rag \
--rag_chunk_size 256 \
--rag_chunk_overlap 64 \
--rag_top_k 4 \
--rag_max_retrieved_tokens 1536
scripts/main_exp/eval/d2l_rag.sh runs a hybrid mode where Doc-to-LoRA internalizes the full document while the same document is also queried with BM25-style retrieval to build a smaller prompt-side evidence block.
WANDB_MODE=disabled uv run run_eval.py \
--checkpoint_path train_outputs/runs/$RUN_NAME/checkpoint-$step/pytorch_model.bin \
--datasets squad drop ropes \
--split test \
--eval_batch_size_gen 1 \
--use_hybrid_rag \
--rag_chunk_size 256 \
--rag_chunk_overlap 64 \
--rag_top_k 4 \
--rag_max_retrieved_tokens 1536
Generated JSONL outputs include compact retrieval metadata under rag_selected_chunks together with prompt/context token counts for debugging.
🔬 Self-Generated Data Viewer
After downloading/generating the data, we can see samples of the data using this script.
uv run webui/self_gen_viewer.py
See more info at webui/SELF_GEN_VIEWER.md.
📚 Citation
@techreport{sakana2025doc-to-lora,
title = {{Doc-to-LoRA: Learning to Instantly Internalize Contexts}},
author = {Rujikorn Charakorn and Edoardo Cetin and Shinnosuke Uesaka and Robert Tjarko Lange},
institution = {Sakana AI},
year = {2026},
month = {Febuary},
note = {Technical Report}
}