mellum2-max
AGENTS.md1 starsChanged 5 months agoApache-2.0View on GitHub
Agent instructions for this project. Read this before answering any user request inside this repo. Compatible with the cross-tool AGENTS.md convention (Codex CLI, Cursor, GitHub Copilot, Gemini CLI, Aider, Sourcegraph Amp, Windsurf, Zed, Continue, RooCode, Cline, Factory). Claude Code reads CLAUDE.md, which is a symlink to this file. This repo ports new Hugging Face model architectures into MAX as custom architectures. The workhorse is the import-model agent skill, vendored under .agents/skills/import-model/. A bring-up writes five files under <slug>/: arch.py, model_config.py,…
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,542 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository2 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- import-modelSkill
The file
We split this AGENTS.md into the rules it gives an agent
5 rules. About 0 are common, 2 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 25
Every bring-up is driven by a plan document at .agents/plans/<model>.plan.md.
- Distinctive: line 32
When the user asks to bring up a new model:
- Very specific: line 38
Run Phase 1 (inspect, list-keys, check-walls) to fill in the new plan's delta list and donor choice.
- Distinctive: line 107
When implementing or reviewing a port, hold these as hard rules:
- Very specific: line 112
Docstring audit is mandatory: After scaffold, donor lineage strings (gpt_oss, llama, qwen, single-GPU, etc.) are still in module docstrings …
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md
Agent instructions for this project. Read this before answering any user request inside this repo.
Compatible with the cross-tool AGENTS.md convention
(Codex CLI, Cursor, GitHub Copilot, Gemini CLI, Aider, Sourcegraph Amp,
Windsurf, Zed, Continue, RooCode, Cline, Factory). Claude Code reads
CLAUDE.md, which is a symlink to this file.
Project scope
This repo ports new Hugging Face model architectures into
MAX as custom architectures. The
workhorse is the import-model
agent skill, vendored under .agents/skills/import-model/.
A bring-up writes five files under <slug>/: arch.py, model_config.py,
model.py, weight_adapters.py, <slug>.py (the graph). The port is done
when MAX greedy output matches the HF reference byte-for-byte (or
near-identical past BF16 rounding).
How to start a bring-up
Every bring-up is driven by a plan document at
.agents/plans/<model>.plan.md. The plan is the spec — donor choice, delta
list, per-file edit order, verification gates with pass criteria. The
canonical worked example is
.agents/plans/mellum2-bring-up.plan.md
(the JetBrains Mellum2 port that lives at mellum/).
When the user asks to bring up a new model:
- Copy the Mellum plan as a template:
cp .agents/plans/mellum2-bring-up.plan.md .agents/plans/<your-model>.plan.md - Run Phase 1 (
inspect,list-keys,check-walls) to fill in the new plan's delta list and donor choice. - Confirm the plan with the user. Then execute it phase-by-phase, marking
todos
completedin the plan frontmatter as gates pass. - Read
.agents/skills/import-model/SKILL.mdalongside the plan — it contains the work-order rules (e.g. scaffold before edit, audit before serve) the plan assumes.
Reference docs live in .agents/skills/import-model/references/ (20+
topic-indexed files). Two that get linked from every plan:
implement-graph.md— edit order + completion criteria for Phase 2divergences.md— symptom → cause table for Phase 3 debugging
Run everything through pixi
There are two pixi workspaces. Do not call bare python / max /
transformers — always pixi run. List tasks with pixi task list.
Project root (./pixi.toml):
| Task | Purpose |
pixi run install-skill | npx skills add modular/skills --skill import-model |
pixi run update-skill | npx skills update |
pixi run smoke-skill | CPU-only smoke test of every skill script (no GPU needed) |
Skill env (./.agents/skills/import-model/pixi.toml) — cd there first.
Tasks that take filesystem paths (--output-dir, --port-dir,
--custom-architectures) resolve them relative to the skill root, so use
../../../<slug>/ (or an absolute path) to point at a port folder at the
repo root.
| Phase | Task | Script |
| 1 | pixi run inspect <HF_ID> | inspect_hf.py — config + native-arch check |
| 1 | pixi run list-keys <HF_ID> | list_checkpoint_keys.py — safetensor key dump |
| 1 | pixi run list-archs [--match X] | list_native_archs.py — registered MAX slugs |
| 1 | pixi run check-walls <HF_ID> | check_walls.py — ALiBi / FP8 / SSM blockers |
| 2 | pixi run scaffold <HF_ID> --start-from <donor> --output-dir ../../../ | scaffold.py — copy donor → <slug>/ at repo root |
| 2 | pixi run gates <HF_ID> --port-dir ../../../<slug>/ | run_oss_gates.py — walls, metadata, arch checks |
| 3 | pixi run serve --model <HF_ID> --custom-architectures ../../../<slug> ... | _serve_wrapper.py — max serve with Pydantic kick |
| 3 | pixi run compare <HF_ID> --slug <slug> --port 8000 --prompt "…" | compare_layers.py — top-1 logprob diff vs HF |
| 3 | pixi run hf-precompute | _hf_precompute.py — Mellum-specific HF dump |
| 3 | pixi run max-check | _max_check.py — Mellum-specific MAX vs HF |
| — | pixi run test-scripts | test_scripts.py — CPU smoke test |
Reference serve invocation (Mellum, BF16 weights = 24 GB, single GPU):
cd .agents/skills/import-model
pixi run serve \
--model JetBrains/Mellum2-12B-A2.5B-Thinking \
--custom-architectures ../../../mellum \
--quantization-encoding bfloat16 \
--trust-remote-code \
--port 8000
# Add --device-memory-utilization 0.45 ONLY when HF reference must
# coexist on the same GPU (validation workflow on 80 GB card).
# On a 40 GB card pass --device-memory-utilization 0.85 instead;
# default 0.9 leaves too little headroom. ≥48 GB: default works._serve_wrapper.py exists because new transformers versions need
torch imported and model_rebuild() called on PipelineConfig /
MAXModelConfig before max serve boots. Do not bypass it.
Conventions
When implementing or reviewing a port, hold these as hard rules:
- Scaffold ≠ port.
scaffold.pyonly copies the donor's graph. Do notmax serveuntil every row in the plan's delta list is implemented in<slug>.py. - Docstring audit is mandatory. After scaffold, donor lineage strings
(
gpt_oss,llama,qwen,single-GPU, etc.) are still in module docstrings and comments. Run the grep recipe fromhonest-docstrings.mdand classify every hit OK / Lie / Stale before declaring Phase 2 done. - State-dict coverage. Wire the audit from
state-dict-audit.mdafter editingweight_adapters.py. Orphan keys or missing experts will fail at load. - Preflight before serve. Four local checks (import smoke, graph
dry-build, adapter↔graph key diff, weights-format preflight) from
serve-and-iterate.mdmust pass beforemax serve. Cold compile is 5–25 minutes; do not eat that cost on a broken graph. - Read HF modeling code, not just config.json. The Hub config's field
names are not authoritative. The Mellum plan's delta list said "no
QK-norm" —
modeling_mellum.pyclearly has per-head RMSNorm on Q and K before RoPE. Trust the modeling code. --custom-architecturestakes the port dir, not its parent. MAX addsdirname(<port_dir>)tosys.pathand importsbasename(<port_dir>). Pass<repo_root>/<slug>/, not<repo_root>/.
Pitfalls (Mellum bring-up)
These bit the worked-example port and are likely to bite any port that
involves MoE, multi-GPU sharding, or recent transformers builds:
- MoE gate sharding. A custom
MoEGate.__call__that adds softmax /norm_topk_probrenormalization must also overrideMoEGate.shard(). The base implementation returns plainMoEGateinstances and silently strips the subclass routing logic. Canonical examples:Qwen3MoEGate.shard(),mellum/mellum.py::MellumMoEGate.shard. - Override
shard()whenever you override__call__on any shardable MAX module. Same failure mode as MoE gate above. - Empty
token_logprobsfrom custom archs. The donorPipelineModeldoesn't implementcompute_log_probabilities, so the OpenAI completion route returnstoken_logprobs: []. Substitute top-1 token parity at varied prefix lengths — see_compare_top1.pyfor the pattern. - GPU memory contention. MAX reserves 90% of the card by default
(
--device-memory-utilization 0.9), somax serve+ an HF reference on the same GPU OOMs unless you either (a) precompute HF answers while MAX is stopped (_hf_precompute.py_max_check.py) — the workflow used for the Mellum port — or (b) pass MAX--device-memory-utilization 0.45so both fit on an 80 GB card. On smaller GPUs (40 GB), default0.9is already too tight; lower to0.85.
- RoPE
max_seq_lenis the precompute budget, not a position cap. Sliding-attention layers still see absolute positions up tomax_position_embeddings. Do not shrink the sliding RoPE'smax_seq_lentosliding_window. - Pydantic forward-reference.
transformersfrommaintriggersPydanticUserError: 'PipelineConfig' is not fully defineduntiltorchis imported andmodel_rebuild()is called. Always launchmax servevia_serve_wrapper.py(pixi run serve). - NVML driver/library mismatch.
nvidia-smireturns "Failed to initialize NVML: Driver/library version mismatch" and MAX cannot use the GPU. Try:
Both steps can fail:sudo modprobe -r nvidia_uvm nvidia_drm nvidia_modeset nvidia sudo modprobe nvidiamodprobe -rfails when something still holds/dev/nvidia*(kill the offending process first;lsmod | rg nvidiashows the refcount), andmodprobe nvidiafails when the running kernel has no matching module in/lib/modules/$(uname -r)(kernel ↔ driver skew on containerized / coder workspaces). When unloading isn't possible, reboot the workspace — that re-aligns the kernel with whatever NVIDIA driver package is installed.
Full pitfall index:
pitfalls.md.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

