← All courses ← Course home

Lesson 03 of 08

Pick a base LLM

Choose a small instruct model the official catalog can export. Then record context, tokenizer, memory, and the macOS versus iOS preset you will actually ship.

Agent brief (llms.md)

Why the base model has to fit

You cannot personalize a model you cannot bake. A large 30B checkpoint that will not fit the phone is not a device model. Start from a catalog instruct preset that already has a Core AI recipe. Then adapt it locally so the device never needs your writing.

macOS and iOS presets differ. Compression, context, and embedding quantization (how numbers are stored) are not the same across platforms. Pick the platform first.

The steps, one box at a time

Start in the official list.

CatalogSmall instruct preset

Check whether the context and memory budget match the chat the app needs.

CatalogSmall instruct preset
FitContext and memory

Confirm the export recipe for that short-name and platform exists on the tools you installed.

CatalogSmall instruct preset
FitContext and memory
ExportSupported Core AI recipe

Environment setup

curl -LsSf https://astral.sh/uv/install.sh | sh
mkdir -p writing-style-lora && cd writing-style-lora
uv init --python 3.11
uv venv
uv add torch torchvision transformers peft datasets accelerate safetensors coreai-torch
uv run python -c "import torch; print(torch.__version__); print('MPS:', torch.backends.mps.is_available())"
uv run coreai.llm.export --list-models
uv run coreai.llm.export qwen3-0.6b --platform iOS --dry-run

Worked path

Course examples are qwen3-0.6b and the small smollm2 instruct presets listed in Core AI models, typed. Treat them as starting points. Confirm the current short-name, Hugging Face id, and platform variant before you download.

{
  "base_short_name": "qwen3-0.6b",
  "base_hf_id": "Qwen/Qwen3-0.6B",
  "base_revision": "pin-this",
  "platform": "iOS",
  "max_context_length": "from-preset",
  "tokenizer": "same revision as the base",
  "instruction_format": "the model's chat template",
  "runtime_lora_swap": false
}

Run a few base samples before you train. If the untouched model cannot follow a short rewrite request, a LoRA will not fix that. Record the chat template. Training must use the same template the export and the app will use.

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

name = "Qwen/Qwen3-0.6B"
revision = "pin-this"
device = "mps" if torch.backends.mps.is_available() else "cpu"
tok = AutoTokenizer.from_pretrained(name, revision=revision)
model = AutoModelForCausalLM.from_pretrained(name, revision=revision).to(device)
messages = [{"role": "user", "content": "Rewrite clearly: circle back tomorrow on the numbers"}]
prompt = tok.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
ids = tok(prompt, return_tensors="pt").to(device)
out = model.generate(**ids, max_new_tokens=64)
print(tok.decode(out[0], skip_special_tokens=True))

A smaller model that fits is more useful than a larger model that swaps to disk. Context length is prompt plus response. Leave room for the reply. Test the longest conversation the app needs, not the longest the card claims.

Failure modes

Done when

Keep learning

PyTorch to Core AI in Xcode · From the metal to the model · Core AI models, typed · Model architectures in plain English · Diffusion LoRA to Core AI on device

Key concepts

  • Choose a catalog instruct preset that has a Core AI export recipe.
  • macOS and iOS presets differ in compression and context.
  • Confirm with coreai.llm.export --list-models and --dry-run.
  • Pin base revision, tokenizer, chat template, platform, and context budget.

Takeaways

  • Run base samples before training. A LoRA will not fix a model that cannot follow rewrites.
  • The training chat template must match export and the app.
  • A smaller model that fits beats a larger model that swaps to disk.