Metadata-Version: 2.4
Name: ckptkit
Version: 0.3.0
Summary: Inspect, convert, diff, and merge model checkpoints. The missing Swiss Army knife for ML weights.
Project-URL: Homepage, https://github.com/stef41/ckptkit
Project-URL: Repository, https://github.com/stef41/ckptkit
Project-URL: Issues, https://github.com/stef41/ckptkit/issues
Author: Zacharie B
License: Apache-2.0
License-File: LICENSE
Keywords: checkpoint,diff,inspect,lora,machine-learning,merge,model-weights,pytorch,safetensors
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Python: >=3.9
Provides-Extra: all
Requires-Dist: click>=8.0; extra == 'all'
Requires-Dist: rich>=13.0; extra == 'all'
Requires-Dist: safetensors>=0.4; extra == 'all'
Requires-Dist: torch>=2.0; extra == 'all'
Provides-Extra: cli
Requires-Dist: click>=8.0; extra == 'cli'
Requires-Dist: rich>=13.0; extra == 'cli'
Provides-Extra: safetensors
Requires-Dist: safetensors>=0.4; extra == 'safetensors'
Provides-Extra: torch
Requires-Dist: torch>=2.0; extra == 'torch'
Description-Content-Type: text/markdown

# ckptkit

[![CI](https://github.com/stef41/ckptkit/actions/workflows/ci.yml/badge.svg)](https://github.com/stef41/ckptkit/actions/workflows/ci.yml)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-green.svg)](https://opensource.org/licenses/Apache-2.0)

**The missing Swiss Army knife for model checkpoints.**

ckptkit inspects, diffs, validates, and merges model checkpoints without loading them into GPU memory. Parse SafeTensors headers in milliseconds, compare checkpoints after fine-tuning, merge LoRA adapters, and validate file integrity — all from the command line or Python.

![Inspect](assets/inspect.svg)

## Why ckptkit?

Working with model weights means dealing with:

- "What layers are in this checkpoint?" → `ckptkit info`
- "What changed after fine-tuning?" → `ckptkit diff`
- "Is this download corrupt?" → `ckptkit validate`
- "Merge this LoRA adapter into the base" → `merge_lora_state_dicts()`
- "Show me parameter counts per layer" → `ckptkit stats`

mergekit handles model merging (TIES, DARE, SLERP), but nobody built the everyday checkpoint utility. ckptkit is that tool.

## Install

```bash
pip install ckptkit
```

With SafeTensors support (recommended):

```bash
pip install ckptkit[safetensors]
```

With PyTorch support:

```bash
pip install ckptkit[torch]
```

Everything:

```bash
pip install ckptkit[all]
```

## CLI

### Inspect

```bash
# See what's inside a checkpoint
ckptkit info model.safetensors

# JSON output for scripts
ckptkit info model.safetensors --json | jq '.n_parameters'
```

### Diff

Compare two checkpoints — see what changed during fine-tuning:

![Diff](assets/diff.svg)

```bash
ckptkit diff base_model.safetensors finetuned_model.safetensors
```

### Validate

Check for corruption before a long training run:

```bash
ckptkit validate model.safetensors
# ✓ model.safetensors: valid (safetensors)
```

### Stats

```bash
ckptkit stats model.safetensors
```

## Python API

### Inspect

```python
from ckptkit import inspect

info = inspect("model.safetensors")
print(f"Parameters: {info.n_parameters:,}")
print(f"Tensors: {info.n_tensors}")
print(f"Format: {info.format.value}")

for t in info.tensors[:5]:
    print(f"  {t.name}: {t.shape} {t.dtype.value} ({t.numel:,} params)")
```

### Diff

```python
from ckptkit import diff, format_diff

result = diff("base.safetensors", "finetuned.safetensors")
print(f"Changes: {result.n_changes}")
print(f"Identical: {result.n_identical} / {result.n_shared}")

for entry in result.entries:
    print(f"  {entry.change_type}: {entry.tensor_name} — {entry.details}")
```

### Merge LoRA

```python
import torch
from ckptkit import merge_lora_state_dicts

base = torch.load("base_model.bin", map_location="cpu")
adapter = torch.load("adapter_model.bin", map_location="cpu")

merged = merge_lora_state_dicts(base, adapter, alpha=1.0)
torch.save(merged, "merged_model.bin")
```

### Validate

```python
from ckptkit import validate

result = validate("model.safetensors")
if not result.valid:
    for issue in result.issues:
        print(f"  {issue.severity}: {issue.message}")
```

### Stats

```python
from ckptkit import inspect, stats_from_info

info = inspect("model.safetensors")
stats = stats_from_info(info)

print(f"Total size: {stats.total_size_human}")
for dtype, count in stats.dtype_counts.items():
    print(f"  {dtype}: {count:,} parameters")
```

## Format support

| Format | Inspect | Diff | Validate | Merge |
|--------|---------|------|----------|-------|
| SafeTensors | ✓ (header-only, fast) | ✓ | ✓ (full integrity) | ✓ |
| PyTorch (.bin/.pt) | ✓ (requires torch) | ✓ | basic | ✓ |

## How it works

**SafeTensors inspection is fast** because the format puts all tensor metadata (names, shapes, dtypes, offsets) in a JSON header at the start of the file. ckptkit reads only the first few KB, never loading the actual weight data.

LoRA merging performs `base_weight += alpha * (lora_B @ lora_A)` for each matched layer pair, with automatic key resolution for common adapter formats (PEFT, HuggingFace).

## See Also

Part of the **stef41 LLM toolkit** — open-source tools for every stage of the LLM lifecycle:

| Project | What it does |
|---------|-------------|
| [tokonomics](https://github.com/stef41/tokonomix) | Token counting & cost management for LLM APIs |
| [datacrux](https://github.com/stef41/datacruxai) | Training data quality — dedup, PII, contamination |
| [castwright](https://github.com/stef41/castwright) | Synthetic instruction data generation |
| [datamix](https://github.com/stef41/datamix) | Dataset mixing & curriculum optimization |
| [toksight](https://github.com/stef41/toksight) | Tokenizer analysis & comparison |
| [trainpulse](https://github.com/stef41/trainpulse) | Training health monitoring |
| [quantbench](https://github.com/stef41/quantbenchx) | Quantization quality analysis |
| [infermark](https://github.com/stef41/infermark) | Inference benchmarking |
| [modeldiff](https://github.com/stef41/modeldiffx) | Behavioral regression testing |
| [vibesafe](https://github.com/stef41/vibesafex) | AI-generated code safety scanner |
| [injectionguard](https://github.com/stef41/injectionguard) | Prompt injection detection |

## License

Apache-2.0
