2026-03-05 · 4 min read
Base Checkpoint Management in a Registry
Adapters are ephemeral; base models are long-lived. A registry must manage the relationship carefully so that an adapter trained on Qwen-v1.0 still works when Qwen-v2.0 is released.
The versioning problem
User downloads adapter sdxl-watercolor-lora-1.4.0 trained on stabilityai/stable-diffusion-xl-base-1.0 at revision abc123.
Six months later, Stability AI releases a patched version with a bug fix (revision xyz789). The revision hashes differ.
Does the adapter still work? Maybe. Maybe not. The mismatch is silent.
Solution: pin the exact revision in adapter metadata.
Metadata with revision pinning
{
"slug": "sdxl-watercolor-lora",
"version": "1.4.0",
"base_model": "stabilityai/stable-diffusion-xl-base-1.0",
"base_model_revision": "abc123def456789abcdef",
"base_model_sha256": "sha256_of_model_weights",
"created_at": "2025-07-01T10:00:00Z",
"compatibility": [
{
"base_model": "stabilityai/stable-diffusion-xl-base-1.0",
"revision": "abc123def456789abcdef",
"tested": true
}
]
}
The base_model_revision is non-negotiable. It's what prevents silent breakage.
Storing base model copies
Option 1: Let HuggingFace host (linked). - Pro: No storage cost - Con: Depends on external service; if they remove the model, your adapter is orphaned
Option 2: Mirror base models in your registry. - Pro: Independent; guaranteed availability - Con: Storage cost (7B model = 14 GB × 5 versions = 70 GB per base)
Hybrid: hot base models stored locally, cold ones on S3:
Hot (used by >10 adapters):
- stabilityai/stable-diffusion-xl-base-1.0
- Qwen/Qwen2.5-7B-Instruct
→ Local storage (fast downloads)
Cold (used by <3 adapters):
- llama3-8b-changelog-writer base
- flux-linework-lora base
→ S3 (cheap, slower fetch)
Migration workflow
When a base model is updated (Qwen2.5-7B-Instruct v1 → v2):
-
Index affected adapters:
sql SELECT * FROM adapters WHERE base_model = "Qwen/Qwen2.5-7B-Instruct" -- Result: 5 adapters depend on this base -
Test compatibility:
bash for adapter in $(list_adapters_on_base "Qwen/Qwen2.5-7B-Instruct"); do python test_compatibility.py --adapter $adapter --base-revision new_hash done -
Document findings:
json { "base_model_update": { "model": "Qwen/Qwen2.5-7B-Instruct", "from_revision": "old_hash", "to_revision": "new_hash", "tested_adapters": [ { "adapter": "qwen25-7b-support-tone", "status": "compatible", "regression": 0.0 }, { "adapter": "mistral-7b-json-extract", "status": "compatible", "regression": 0.005 } ], "action": "advisory: upgrade optional" } } -
Release advisory:
- If regression > 2% for any adapter: "Breaking change; adapters may need retraining"
-
If regression < 1% for all: "Compatible; upgrade recommended"
-
Update adapter metadata (optional, if new base is better):
json { "compatibility": [ { "revision": "old_hash", "status": "deprecated" }, { "revision": "new_hash", "status": "current" } ] }
Health checks
Periodically verify that adapters still load:
def health_check_adapter(adapter_slug, base_model_id, base_revision):
"""Can this adapter load on the base model?"""
try:
base = AutoModelForCausalLM.from_pretrained(
base_model_id,
revision=base_revision
)
adapter = PeftModel.from_pretrained(base, adapter_slug)
# Quick sanity: generate 5 tokens
test_input = tokenizer("Test", return_tensors="pt")
_ = adapter.generate(**test_input, max_length=10)
return True, "OK"
except Exception as e:
return False, str(e)
# Run weekly on all adapters
for adapter in registry.list_adapters():
ok, msg = health_check_adapter(adapter.slug, adapter.base_model, adapter.base_revision)
if not ok:
alert(f"Health check failed: {adapter.slug} - {msg}")
Lifecycle
Mark base model versions with status:
proposed → active → deprecated → archived → deleted
- Proposed: New version, not yet recommended
- Active: Stable, recommended (latest)
- Deprecated: Older but still works; plan to stop supporting
- Archived: No longer in main catalog, but available for rollback
- Deleted: Removed entirely (rare)
Example timeline for Qwen2.5-7B-Instruct:
2025-01-10 v1.0 released → active
2025-06-15 v2.0 released → proposed (test period)
2025-07-01 v2.0 → active; v1.0 → deprecated
2025-10-01 v1.0 → archived (still downloadable, no longer recommended)
2026-01-01 v1.0 deleted (rarely used; storage freed)
Communicating to users
When base model is deprecated, notify:
┌─ Adapter: qwen25-7b-support-tone v1.2.0
│
├─ ⚠️ Base model Qwen/Qwen2.5-7B-Instruct v1.0 is deprecated
├─ Consider upgrading to v2.0 (compatible, slight improvement)
│
├─ How to migrate:
│ mfl pull qwen25-7b-support-tone --base-version v2.0
│ (Retrains adapter on new base if needed)
│
└─ Deadline: 2025-10-01 (v1.0 will no longer be available)
Users have time to migrate; no surprise breakage.
Storage math
For a registry with 5 base models × 3 versions each:
Model Versions Size/version Total
-------- -------- ----------- -----
SDXL 3 6 GB 18 GB
Qwen2.5-7B 3 14 GB 42 GB
Llama3-8B 3 16 GB 48 GB
FLUX.1-dev 3 24 GB 72 GB
Phi3-mini 3 4 GB 12 GB
-------- ----
Total: 192 GB
At $0.023/GB/month (S3 standard): - Hot storage (local SSD, maybe 100 GB): $0 - Cold storage (S3, 92 GB): $2.10/month
Negligible cost to maintain version history.
Immutable downloads
Link adapters to specific base model versions:
/download/qwen25-7b-support-tone-1.2.0?base-revision=abc123
/download/qwen25-7b-support-tone-1.2.0?base-revision=xyz789 (if compatible)
Users can explicitly choose which base version to download the adapter for. Reproducibility guaranteed.
Base checkpoint management is not exciting, but it's what separates a "registry that works for 6 months" from a "registry that works for 5 years."