---
name: diffusion-lora-coreai lesson 03
description: >-
  Agent recipe for lesson 03: produce a reproducible diffusion LoRA checkpoint
  with PyTorch on a Mac using MPS or CPU.
---
# Train a LoRA on a Mac

**Lesson id:** `03`  
**One-line goal:** Produce a reproducible diffusion LoRA checkpoint with PyTorch on MPS when available or CPU otherwise.

## Why this matters on a phone

Keep the training images on the Mac you control. The checkpoint is a middle step. The device never sees the adapter as a hot-swap file.

## Prerequisites

Lessons 01 and 02. Licensed images, captions, holdout prompts, and a pinned `sd-1.5` or `sd-2.1` revision.

## Inputs

Dataset, pinned environment, device choice, base revision, and training settings.

## Outputs and artifacts

LoRA directory, `manifest.json`, holdout previews for base and adapter.

## Executable steps

1. Create the `uv` project before any training (`uv init --python 3.11`, `uv venv`, `uv add`).
2. Select `mps` if `torch.backends.mps.is_available()`, else `cpu`. Never CUDA.
3. Load the pinned base. Freeze VAE, text encoder, and UNet. Attach PEFT LoRA to attention projections.
4. Run the noise-prediction loop with `uv run python train_lora.py`.
5. Save adapter weights plus manifest (base, revision, device, rank, steps, `runtime_lora_swap: false`).
6. Render the same holdout prompt and seed with the base and with the adapter attached.

## Constraints

The script is a working sketch, not a universal trainer. Keep Core AI export in lesson 04. No quizzes, Mermaid, or em dashes.

## Failure modes

CUDA assumptions, unsupported MPS ops without a CPU fallback, saving the full pipeline as if it were a LoRA, skipping holdout, trying to load the adapter in Core AI.

## Key concepts

- Train locally on MPS or CPU. Sensitive images stay on your Mac.
- PEFT updates LoRA ranks on a frozen UNet. The checkpoint is a middle artifact.
- Compare holdout prompts on base versus adapter with a fixed seed.
- If MPS lacks an op, move that step to CPU. Never add CUDA.

## Takeaways

- Save the adapter and a manifest with base, revision, device, rank, and steps.
- Overfit looks like memorized backgrounds. Fix data before merge.
- Core AI will not load the adapter directly.

## Done when

The adapter directory and manifest exist. Device is MPS or CPU. Holdout previews exist. The adapter is not described as the shippable `.aimodel`.

## Environment setup

```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
mkdir -p diffusion-lora-coreai && cd diffusion-lora-coreai
uv init --python 3.11
uv venv
uv add torch torchvision diffusers peft transformers accelerate datasets safetensors coreai-torch
uv run python -c "import torch; print(torch.__version__); print('MPS:', torch.backends.mps.is_available())"
uv run python train_lora.py
```

**Human lesson:** [Train a LoRA on a Mac](03-train-lora-on-mac.html)
