Embedder Training
This guide covers all three ways to train a DantinoX model as a sentence encoder for RAG.
Mode |
When to use |
Entry point |
|---|---|---|
Unsupervised (SimCSE) |
No labelled data, any flat text corpus |
|
Supervised pairs |
(anchor, positive) pairs available |
|
Fine-tuning |
Pretrained AR / Discrete model → encoder |
|
1. Unsupervised — SimCSE
EmbedderParadigm plugs directly into the stock Trainer.
Each [B, T] token window is encoded twice with different dropout masks — the two views act as anchor / positive in the InfoNCE loss. No labelled pairs required.
One-liner
import dantinox as dx
run_dir = dx.fit(
"embedder", # paradigm string
"data/corpus.txt", # flat text file or HuggingFace dataset name
# ── model ──────────────────────────────────────────────
dim=256, n_heads=4, head_size=64, num_blocks=6,
vocab_size=32_000,
causal=False, # bidirectional — strongly recommended
dropout=0.1, # REQUIRED: SimCSE needs dropout > 0
# ── embedder-specific ──────────────────────────────────
pooling="mean", temperature=0.05,
# ── training ───────────────────────────────────────────
lr=3e-4, epochs=10, batch_size=64,
)
With a HuggingFace dataset (no local file needed)
import dantinox as dx
cfg = dx.ModelConfig(
dim=256, n_heads=4, head_size=64, num_blocks=6,
vocab_size=32_000, causal=False, dropout=0.1,
)
paradigm = dx.EmbedderParadigm(cfg, pooling="mean", temperature=0.05)
train_cfg = dx.TrainingConfig(
dataset_source="huggingface",
dataset_name="wikitext",
dataset_config="wikitext-103-raw-v1",
dataset_text_field="text",
tokenizer_type="bpe",
lr=3e-4, epochs=10, batch_size=64,
warmup_steps=500,
)
run_dir = dx.train(paradigm, training_config=train_cfg)
Full control via Trainer
trainer = dx.Trainer(paradigm, train_cfg)
run_dir = trainer.fit("data/corpus.txt")
!!! tip “Batch size and in-batch negatives”
Larger batch sizes mean more in-batch negatives and a stronger InfoNCE signal. On a single 40 GB GPU, batch_size=256 is usually achievable with dim≤512.
2. Supervised Pairs
Use EmbedderTrainer when you have labelled (anchor, positive) pairs. The trainer is single-device — it reads CUDA_VISIBLE_DEVICES automatically from the environment.
Data formats
=== “List of tuples”
python pairs = [ ("How does JAX work?", "JAX is a NumPy-compatible library with JIT on GPU/TPU."), ("What is diffusion?", "Diffusion iteratively denoises a noisy input."), # ... ]
=== “JSONL file”
json {"anchor": "How does JAX work?", "positive": "JAX is a NumPy-compatible library..."} {"anchor": "What is diffusion?", "positive": "Diffusion iteratively denoises..."}
=== “TSV file”
How does JAX work?\tJAX is a NumPy-compatible library with JIT on GPU/TPU. What is diffusion?\tDiffusion iteratively denoises a noisy input.
Training
import dantinox as dx
from dantinox.utils.tokenizer import BPETokenizer
tok = BPETokenizer()
tok.train_from_text(open("data/corpus.txt").read(), vocab_size=32_000)
cfg = dx.ModelConfig(
dim=256, n_heads=4, head_size=64, num_blocks=6,
vocab_size=tok.vocab_size, causal=False, dropout=0.1, max_context=256,
)
paradigm = dx.EmbedderParadigm(cfg, pooling="mean", temperature=0.05)
trainer = dx.EmbedderTrainer(
paradigm, tok,
dx.TrainingConfig(lr=2e-4, epochs=20, batch_size=64),
)
run_dir = trainer.fit_pairs("data/pairs.jsonl") # or list of tuples
Checkpoint layout
fit_pairs() writes a run directory compatible with Embedder.from_run():
runs/embedder_supervised/
checkpoint_best.msgpack # best epoch by training loss
checkpoint_latest.msgpack # most recent epoch
tokenizer.json # saved tokenizer for Embedder.from_run()
config.yaml # ModelConfig
3. Fine-Tuning a Pretrained Model
Any DantinoX AR or Discrete checkpoint can be converted into an embedder by wrapping it in EmbedderParadigm and running a few supervised epochs. The pretrained weights give the model a strong language prior, so a small number of pairs is sufficient.
import dantinox as dx
from dantinox.utils.tokenizer import load_tokenizer_from_file
pretrained_run = "runs/my_discrete_run"
cfg = dx.ModelConfig.from_yaml(f"{pretrained_run}/config.yaml")
model = dx.load(pretrained_run) # loads weights from checkpoint_best.msgpack
tok = load_tokenizer_from_file(f"{pretrained_run}/tokenizer.json")
# Wrap in EmbedderParadigm — same architecture, new contrastive loss
paradigm = dx.EmbedderParadigm(cfg, pooling="mean", temperature=0.05)
trainer = dx.EmbedderTrainer(
paradigm, tok,
dx.TrainingConfig(
lr=5e-5, # lower LR for fine-tuning
epochs=5,
batch_size=32,
),
)
# Pass model= to inject pretrained weights instead of starting from scratch
run_dir = trainer.fit_pairs(pairs, model=model, run_dir="runs/embedder_finetuned")
!!! tip “How many pairs do you need?” - Fine-tuning from a pretrained checkpoint: 1 000 – 10 000 pairs typically suffice. - Training from scratch (supervised only): aim for 50 000+ pairs. - Unsupervised SimCSE on a large corpus is a good substitute for labelled pairs when they are unavailable.
Hyperparameter Guide
Model architecture
Parameter |
Recommended |
Notes |
|---|---|---|
|
|
Bidirectional attention gives better embeddings |
|
|
Required for SimCSE; keep at 0.1 even for supervised |
|
256–768 |
Larger = better quality, higher inference cost |
|
4–12 |
Deeper = richer representations |
|
128–512 |
Must cover your longest document |
InfoNCE / contrastive
Parameter |
Recommended |
Notes |
|---|---|---|
|
|
Lower = sharper, stronger gradient |
|
64–256 |
More in-batch negatives → better loss |
|
|
Best for bidirectional models |
Optimisation
Parameter |
Unsupervised |
Supervised |
Fine-tuning |
|---|---|---|---|
|
|
|
|
|
5–20 |
10–30 |
3–10 |
|
200–500 |
100–200 |
50–100 |
|
|
|
|
Multi-GPU Note
EmbedderTrainer is single-device by design — it runs on whichever GPU is selected by CUDA_VISIBLE_DEVICES. For multi-GPU training, use EmbedderParadigm with the stock Trainer, which supports full data-parallel sharding:
# Multi-GPU: use stock Trainer with EmbedderParadigm
trainer = dx.Trainer(paradigm, dx.TrainingConfig(lr=3e-4, epochs=10, n_devices=4))
run_dir = trainer.fit("data/corpus.txt")
See Multi-GPU Training for details.
See Also
Retriever Paradigm — architecture and InfoNCE math
RAG Tutorial — FAISS, LangChain, ChromaDB