Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ once_cell = "1"

criterion = "0.8"

# Renders an HF `chat_template` Jinja byte-identically to
# `transformers.apply_chat_template` (minijinja + a transformers compat
# layer). Two roles, one version: the test-only reference behind the template
# BYTE gate, and — behind mummu's non-default `jinja-template` feature — the
# fallback renderer for checkpoints with no hardcoded family renderer.
hf-chat-template = "0.2.1"

[profile.release]
# Thin LTO: inference is GPU-kernel-bound, so fat LTO's extra minutes per link
# buy almost nothing here while tripling the verify-loop cost. Revisit against
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ It exists because two local-first apps — **[laurelane](https://github.com/phys
neither → no behavior change). On a successful safetensors load the parsed `TokenizerConfig` is surfaced
on the returned `Loaded{Qwen2,Qwen3,Lfm2}` struct (`tokenizer_config`), so a consumer reads config-driven
EOS/BOS/PAD ids straight off the model; a GGUF load surfaces `None` (self-contained).
- **Fallback chat renderer for un-ported models** (optional feature `jinja-template`) —
`mummu::template::ImportedTemplate` renders a checkpoint's **own** imported `chat_template` Jinja, so a
model whose family has no hardcoded renderer is still promptable from the authority on its prompt
format: its own template. The selection rule ships as a value — `Renderer::for_checkpoint(family, dir)`
takes a byte-verified family renderer when one exists and falls back to the template otherwise, never
second-guessing the family renderer. Bounded and fail-loud (no template → `Absent`, bad Jinja →
`Jinja`, a runaway render → `TooLarge` at 8 MiB), with the config's BOS/EOS/PAD/UNK reaching the render
context and assistant tool calls passed **structurally** so the template writes its own call markers
instead of inheriting Hermes'. Verified against the from-scratch path on real checkpoints
(`tests/imported_render.rs`): byte-identical to `ChatMl::qwen3()` on plain (142 B), tools (748 B) and
full FC history (324 B), and to `ChatMl::lfm2()` on plain (157 B) and tools (379 B) — the LFM leg also
proving the standalone `chat_template.jinja` fallback and the `bos_token` injection. The feature is
**off by default**: the zoo's from-scratch renderers cover it byte-for-byte, and a default build carries
no Jinja engine.
- **Import validation** — a two-stage error taxonomy: `ImportError` for the file→module stage (missing
file, parse, load, and an `Incomplete` per-tensor missing/errored diff) and `SanityError` for the
runtime liveness a checked load can't see — NaN/Inf logits, a vocab-width mismatch, or a
Expand Down
Loading