# Models

Turn model-family configuration into a shared decoder plan.

[View canonical HTML](https://pllm.run/sdk/build/model-adapters/)

Document ID: `pllm.docs.build.models`  
Release: `0.1.0`

Current semantic adapters cover dense Qwen2 and Qwen3 configuration contracts plus pinned Qwen3.5-4B, Phi-4-mini-instruct, Gemma 4 E2B, and Gemma 4 E4B text-decoder configurations described by package tests. Lowering reads configuration only. It does not load checkpoints, tokenizers, weights, devices, or runtime state.

## One model source and loader

`pllm.Model` is the typed public source specification used by `Pipeline.model`, SDK loading, runtime model requests, and CLI resolution. `Model(source)` remains the canonical shorthand for an unpinned Hugging Face source. Use `Model.hf(...)` for an explicit revision, `Model.path(...)`/`BundleModel(...)` for a local Hugging Face, Safetensors, MLX, or GGUF source, and `Model.tiny()`/`TinyModel()` for the deterministic tiny Qwen2 fixture used by local functional tests.

`pllm.load_model(model)` is the sole public loading entry. For Hugging Face identifiers it calls the canonical resumable resolver; for local sources it validates the selected format. It returns `ModelManifest`, not a live engine. Loading hashes the actual checkpoint/config/tokenizer files, checks resolver-recorded hashes when present, and records path-independent `checkpoint_digest` and `source_lock_digest` values. Tokens, API keys, cache directories, devices, and live handles are operational arguments and never enter the model specification or source lock.

The checked Python example below includes both source loading and configuration-only lowering. Loading can download and hash a checkpoint; `TinyModel` instead materializes deterministic local files under the selected cache without network access. It does not quantize weights, allocate private material, start a service, or claim that the model has a complete execution profile.

## Add an adapter

1. Parse one explicit public model-family configuration and reject unknown variants.
2. Emit bounded prefill and decode semantics in neutral `DecoderPlan`; do not select protocol, provider, or device.
3. Preserve operation order, shapes, [numeric semantics](/learn/numeric-semantics-and-model-quality/), state, output selection, and token feedback.
4. Add adapter fixtures, structural tests, and rejection tests.
5. Measure compiler operator coverage separately; never call semantic lowering executable support.

See [package structure](https://github.com/blairhudson/pllm/blob/main/design/package-structure.md), [Python API contract](https://github.com/blairhudson/pllm/blob/main/design/python-api.md), and [decoder-plan schema](https://github.com/blairhudson/pllm/blob/main/schemas/decoder-plan.schema.json).

Current [generation quality evidence](/research/evidence/): not recorded. Current
deployment maturity for these semantic plans: not recorded.

## Python SDK example

```python
from pllm import TinyModel, load_model, lower_model

model = TinyModel()
manifest = load_model(model)
assert manifest.checkpoint_digest is not None

config = {
    "model_type": "qwen2",
    "hidden_size": 64,
    "intermediate_size": 192,
    "num_hidden_layers": 2,
    "num_attention_heads": 4,
    "num_key_value_heads": 2,
    "vocab_size": 256,
    "max_position_embeddings": 128,
    "hidden_act": "silu",
    "rms_norm_eps": 1e-6,
    "rope_theta": 10000.0,
    "tie_word_embeddings": True,
}
plan = lower_model(config, batch=1, max_input_tokens=16, max_new_tokens=4)
assert plan.to_dict()["adapter"] == "pllm.qwen2.v1"
assert plan.prefill["query_sequence"] == 16
```

API: [Python SDK objects and signatures](/sdk/reference/python/pllm/#objects-and-signatures)

Lowering does not load or execute weights.
