Skip to main content

Config-driven framework to pretrain and fine-tune Librarian-family GPT models from clean local data

Project description

librarian-press

Bring clean data, get a trained LLM. A config-driven framework for pretraining and fine-tuning Librarian-family GPT models — from a few-million-parameter toy to billion-parameter models — driven entirely by one JSON file.

Like the printing press did for the written word, librarian-press takes LLM training out of the lab: you supply cleaned Parquet/.txt data and a config, and it handles tokenizer training → tokenization → packing → training → evaluation → inference. Pretraining and supervised fine-tuning (SFT) are separable — run one, the other, or both end-to-end.


Highlights

  • One config, three modespretrain, sft, or both from a single JSON file.
  • Bring-your-own data — local Parquet and .txt; no scraping, no hidden cleaning.
  • Modern architecture — GPT with RoPE, RMSNorm, SwiGLU MLP, weight tying.
  • Fine-tuning built in — LoRA, BitFit, or full fine-tune, with completion-only masked loss.
  • Resumable pipeline — every data stage is shard-tracked with atomic, restart-safe manifests.
  • Multi-GPU — data-parallel (DDP) via torchrun, single-GPU path unchanged.
  • Export & chat — bundle a trained run into a portable folder and chat with it, Ollama-style.
  • Observable — opt-in Prometheus-style /metrics endpoint for Grafana, with zero extra dependencies.

Installation

pip install librarian-press

This provides the librarian-press command (short alias lpress).

From source (development):

git clone <repo-url> && cd librarian-fw
uv sync          # or:  pip install -e .

Requirements: Python 3.12–3.13, PyTorch ≥ 2.6 (CUDA build recommended). All other dependencies (numpy, tokenizers, pyarrow, tqdm, tensorboard, requests) install automatically.


Quickstart

A complete CPU-only run is included for a fast end-to-end smoke test:

# pretrain a tiny model, then SFT it, all from bundled fixtures
librarian-press run --config configs/run_dummy.json

# package the result into a portable model and chat with it
librarian-press export --config configs/run_dummy.json --name demo
librarian-press chat demo

For a real run, point a config at your data and go:

librarian-press pretrain --config configs/pretrain_130M.json

Concepts

Modes. The top-level mode selects the pipeline:

Mode Pipeline
pretrain ingest → train tokenizer → tokenize → pack → train → eval
sft ingest → prepare (masked) → train → eval
both pretrain, then SFT auto-wired onto the fresh checkpoint + tokenizer

Run directory. Everything for a run lives under runs/<name>/:

runs/<name>/
  data/          ingested shards, tokenized shards, packed splits
  manifests/     per-stage progress (resume-safe)
  tokenizer/     trained tokenizer
  checkpoints/   pretrain/  and  sft/<method>/   (best.pt, last.pt, step_*.pt)
  logs/          eval results

Data stages are skipped automatically when their manifest is already complete, so re-running a command resumes rather than recomputes.


CLI reference

librarian-press <command> [options]      # alias: lpress
Command Purpose
pretrain --config <cfg> Run the pretraining pipeline
sft --config <cfg> Run the supervised fine-tuning pipeline
run --config <cfg> Pretrain then SFT end-to-end (config mode must be both)
tokenizer --config <cfg> Train the tokenizer only
eval --config <cfg> [--checkpoint CKPT] Evaluate a trained checkpoint
infer --config <cfg> --checkpoint CKPT [--prompt "..."] One-off generation / ad-hoc chat
export --config <cfg> --name NAME Bundle a trained run into a portable model
chat <model-name> Interactive streaming chat with an exported model
models List exported models

Common options

Option Applies to Meaning
--start-from <stage> pretrain, sft Resume the pipeline from a specific stage
--resume <checkpoint> pretrain, sft Resume training from a checkpoint
--cleanup pretrain, run Delete intermediate artifacts after success (opt-in)
--metrics-port <port> training + chat Expose Prometheus-style metrics (see Monitoring)
--from pretrain|sft, --checkpoint export Choose which half / which checkpoint to export
--temperature, --top-k, --max-new-tokens export Default sampling parameters baked into the bundle

Configuration

A single JSON file. Shared model and tokenizer sections, plus a pretrain and/or sft section depending on mode.

Top level

Field Type Notes
name string Run name; defines runs/<name>/
mode enum pretrain · sft · both
model object Architecture (below), or {"config_path": "model_130M.json"}
tokenizer object Tokenizer config (below)
pretrain object Required for pretrain/both
sft object Required for sft/both

model

Field Default Notes
vocab_size 16000 Must be < 65536 (tokens stored as uint16)
dim 512 Must be divisible by n_heads; head dim should be even
n_layers 12
n_heads 8
hidden_dim 2048 MLP inner size (commonly 4 × dim)
max_seq_len 512 Context length
dropout 0.1
rope_theta 10000.0 RoPE base
tie_embeddings true Share input/output embeddings

tokenizer

Field Default Notes
path Where the tokenizer is / will be written
train_if_missing false Pretrain may train one; SFT must reuse an existing one
vocab_size 32000 Must equal model.vocab_size
min_frequency 2 BPE merge threshold
special_tokens ["<pad>","<bos>","<eos>","<unk>"]

training (per mode)

lr, min_lr, warmup_steps, total_steps, batch_size, grad_accum, weight_decay, mixed_precision, eval_interval, save_interval, device. Cosine schedule with warmup; AdamW with decoupled weight decay; AMP + gradient accumulation + gradient clipping.

pretrain.data

Field Default Notes
inputs List of file paths / globs
format auto txt · parquet · auto
text_column text Parquet column holding text
txt_granularity line line (one doc per line) or document (whole file)
seq_len 512 Packed sequence length (≤ model.max_seq_len)
val_frac / test_frac 0.005 / 0.0 Deterministic hash split

sft.data

Field Default Notes
inputs {"train": [...], "val": [...]} or {"all": [...]}
format auto Parquet rows, or JSON-per-line .txt
prompt_template "{prompt}" e.g. "Context: {context}\nQuestion: {question}\nAnswer:"
completion_field "completion" Dotted/array fields supported, e.g. answers.text[0]
max_prompt_len / max_completion_len 384 / 128 Token caps

sft.finetune

Field Default Notes
method lora lora · bitfit · full
base_checkpoint null Pretrained weights; auto-wired in both
lora {rank:8, alpha:16, dropout:0.05} LoRA hyperparameters
eval_metric perplexity perplexity · exact_match · f1

Example (mode: both)

{
  "name": "my-model",
  "mode": "both",
  "model": { "vocab_size": 32000, "dim": 768, "n_layers": 12, "n_heads": 12,
             "hidden_dim": 3072, "max_seq_len": 1024 },
  "tokenizer": { "path": "runs/my-model/tokenizer/tokenizer.json",
                 "train_if_missing": true, "vocab_size": 32000 },
  "pretrain": {
    "data": { "inputs": ["./data/corpus/*.parquet"], "text_column": "text",
              "seq_len": 1024, "val_frac": 0.005 },
    "training": { "lr": 3e-4, "total_steps": 100000, "batch_size": 32, "grad_accum": 4 }
  },
  "sft": {
    "finetune": { "method": "lora", "base_checkpoint": null, "eval_metric": "f1" },
    "data": { "inputs": { "train": ["./sft/train/*.parquet"], "val": ["./sft/val/*.parquet"] },
              "prompt_template": "Q: {question}\nA:", "completion_field": "answer" },
    "training": { "lr": 2e-4, "total_steps": 5000, "batch_size": 16, "grad_accum": 4 }
  }
}

See configs/ for runnable examples.


Data you provide

You own data cleanliness — the framework parses, it does not scrape or quality-filter.

  • Pretraining.txt (one document per line, or the whole file as one document) and/or .parquet with a configurable text_column.
  • SFT.parquet rows or JSON-per-line .txt, mapped through prompt_template + completion_field. Loss is computed on completion tokens only; prompt tokens are masked out.

Inference: export & chat

Consolidate a trained run into a portable, self-contained model folder, then chat with it from the terminal:

# bundle -> ~/.librarian-press/models/<name>/  (override with LIBRARIAN_PRESS_HOME)
librarian-press export --config configs/run_both.json --name my-bot

# stream tokens until you type /bye
librarian-press chat my-bot

librarian-press models     # list exported models

export merges LoRA/BitFit adapters into the base weights, writing a single plain weights file plus the tokenizer and a bundle.json (model config, chat prompt template, sampling defaults). The folder is fully standalone — copy or share it freely.


Multi-GPU (DDP)

Launch any training command under torchrun to data-parallelize across GPUs:

torchrun --nproc_per_node=4 --module librarian_press.cli.main \
  pretrain --config configs/pretrain_130M.json

Each GPU holds a full model copy; gradients all-reduce at the accumulation boundary, so the effective batch is batch_size × grad_accum × num_gpus. Data stages and evaluation run on rank 0; only rank 0 writes checkpoints and logs. Running without torchrun is the unchanged single-GPU path. DDP scales throughput — the model must still fit on one GPU (FSDP/sharding is not built in).


Monitoring

Add --metrics-port <port> to any training or chat command to expose a Prometheus-style metrics endpoint — pull model, plain text exposition format, no prometheus_client dependency:

librarian-press run  --config configs/run_both.json --metrics-port 9099
curl http://localhost:9099/metrics

Point Prometheus (or Grafana Alloy/Agent) at /metrics and dashboard it in Grafana. Under DDP only rank 0 serves. Configurable via LIBRARIAN_PRESS_METRICS_PORT / LIBRARIAN_PRESS_METRICS_HOST.

Metric Type Labels
librarian_train_loss, librarian_val_loss gauge run, mode
librarian_train_learning_rate, librarian_train_grad_norm, librarian_train_step gauge run, mode
librarian_train_tokens_per_second, librarian_gpu_memory_bytes gauge run, mode
librarian_train_steps_total counter run, mode
librarian_inference_requests_total, librarian_inference_generated_tokens_total counter model
librarian_inference_tokens_per_second, librarian_inference_latency_seconds gauge model

Project layout

src/librarian_press/
  cli/          command-line entrypoint
  config/       JSON schema, loading, run paths
  model/        GPT, attention, RoPE, RMSNorm, MLP, LoRA, build/load
  tokenizer/    BPE training + loading
  data/         ingest, shard, tokenize, pack, prepare_sft, datasets
  pipeline/     manifests, atomic writers, cleanup, stage orchestration
  training/     trainer, optimizer, scheduler, checkpoints
  evaluation/   perplexity, generation metrics, router
  inference/    sampling, generation, method-aware loading
  serve/        export bundles, registry, chat REPL
  metrics/      Prometheus-style registry + HTTP server
  utils/        logging, device, distributed

License

See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

librarian_press-0.1.0.tar.gz (75.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

librarian_press-0.1.0-py3-none-any.whl (69.3 kB view details)

Uploaded Python 3

File details

Details for the file librarian_press-0.1.0.tar.gz.

File metadata

  • Download URL: librarian_press-0.1.0.tar.gz
  • Upload date:
  • Size: 75.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for librarian_press-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3bc7a3fea6a25cc949c014bec9acf4c97a8b9a165e9c12f2930fc17b0877445f
MD5 a1919372919fced3148a852f795544af
BLAKE2b-256 3b30eca1122fcaaefbaa2c80e07d4d095a201f1d1f09dc0f37ae6afd7ac5b7b9

See more details on using hashes here.

File details

Details for the file librarian_press-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for librarian_press-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bf55567e6f3807863833d8f281d0ffcdb8ed3249ef6247c9b9c103d1267e5884
MD5 40ffb5b3df2805afac53f1b7ad411f1a
BLAKE2b-256 369bf7b1e615c5e42493465a9fd5db90cf17fd1ee9e686f081114e5838a4f737

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page