The Problem

Training or fine-tuning LLMs typically means assembling a fragile stack: model code, tokenizer, data pipeline, distributed strategy, and checkpoint conversion scripts that must all agree. LitGPT removes that glue by shipping from-scratch implementations of 20+ models with recipes for pretraining, fine-tuning (LoRA, QLoRA, Adapter), and deployment in one package.

What This Does

This is a fork of Lightning-AI/litgpt (13,621 stars upstream). The core package lives in litgpt/ with model definitions in model.py, fine-tuning variants in adapter.py, adapter_v2.py, and lora.py, and a high-level LLM API in api.py. The config_hub/ directory holds 47 YAML recipes covering model-specific fine-tuning configurations.

The repo also includes extensions/ for Thunder and XLA backends, plus a deploy/serve.py for running an inference server. Tutorials and 64 test files round out the package.

How It Is Wired

Execution starts at main in litgpt/__main__.py:65, which reaches 192 functions. The call graph shows fit is the workhorse, calling gradient_accumulation_iters 23 times and validate 21 times. The LLM class in api.py is the primary user-facing entry point, with from_name called from 88 places and GPT from 70.

The dependency graph is hub-and-spoke: litgpt/utils.py is imported by 58 modules and participates in a circular import cycle. litgpt/data/__init__.py (32 importers) and litgpt/__init__.py (39 importers) are also in cycles. This makes changes to utils.py high-blast-radius—touching it risks breaking a large portion of the codebase.

A run leaves the process through setup (filesystem via out_dir.mkdir), predict (model inference via self.llm.generate), and run_server (subprocess via subprocess.Popen). The system reads/writes files in 48 functions and makes 3 outbound network calls.

How To Use It

git clone https://github.com/moses-y/litgpt
cd litgpt
pip install -e .

Basic inference:

from litgpt import LLM

llm = LLM.load("microsoft/phi-2")
text = llm.generate("Fix the spelling: Every fall, the family goes to the mountains.")

Fine-tuning recipes are YAML files in config_hub/finetune/—for example, config_hub/finetune/llama-3-8b/lora.yaml. The litgpt/__main__.py CLI dispatches to fine-tune, pretrain, and generate subcommands.

Real-World Use

A typical workflow: download a pretrained checkpoint, apply LoRA fine-tuning on a domain dataset using a recipe from config_hub/finetune/, then deploy via litgpt/deploy/serve.py. The LLM API abstracts model loading and generation, while the underlying lora.py and adapter.py modules handle parameter-efficient fine-tuning.

Code Health & Issues

Static analysis found 68 issues: 38 high, 28 medium, 2 low. Key findings:

  • High — Import cycles: 27 modules participate in circular dependencies (litgpt/utils.py, litgpt/__init__.py, litgpt/data/__init__.py).
  • High — Deep nesting: max indentation depth of 7 in litgpt/utils.py, litgpt/tokenizer.py, litgpt/prompts.py.
  • High — Oversized files: utils.py has 858 code lines; config.py and model.py are similarly large.
  • High — Hub modules: 58 modules depend on utils.py, making it high-blast-radius for changes.
  • High — Duplicated code: 1,464 repeated 6-line blocks across 74 files.
  • Medium — Broad exception handling in litgpt/utils.py, data/prepare_starcoder.py, and tests/test_cli.py.
  • Medium — Files opened without context managers in eval/evaluate.py and data/prepare_slimpajama.py.

Security audit found one critical issue: .github/workflows/cpu-tests.yml exposes HF_TOKEN to contributor-triggered workflows—a PR could exfiltrate credentials. No lockfile exists (pyproject.toml only), so builds aren't reproducible. CI lacks dependency vulnerability scanning.

The Bottom Line

A solid, well-tested LLM training/inference toolkit with good model coverage and recipes. The codebase works but has real maintainability debt: circular imports, oversized hub modules, and no lockfile. Forking from a mature upstream project means the core is proven; the fork itself adds no visible changes. Suitable for teams needing a self-contained LLM fine-tuning stack who can tolerate the coupling in utils.py.