agentleFS
ehsanmokehsanmok/mellum2-max/AGENTS.md

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.

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
  1. Very specific:

    Every bring-up is driven by a plan document at .agents/plans/<model>.plan.md.

    line 25
  2. Distinctive:

    When the user asks to bring up a new model:

    line 32
  3. Very specific:

    Run Phase 1 (inspect, list-keys, check-walls) to fill in the new plan's delta list and donor choice.

    line 38
  4. Distinctive:

    When implementing or reviewing a port, hold these as hard rules:

    line 107
  5. Very specific:

    Docstring audit is mandatory: After scaffold, donor lineage strings (gpt_oss, llama, qwen, single-GPU, etc.) are still in module docstrings …

    line 112

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

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:

  1. Copy the Mellum plan as a template:
    cp .agents/plans/mellum2-bring-up.plan.md .agents/plans/<your-model>.plan.md
  2. Run Phase 1 (inspect, list-keys, check-walls) to fill in the new plan's delta list and donor choice.
  3. Confirm the plan with the user. Then execute it phase-by-phase, marking todos completed in the plan frontmatter as gates pass.
  4. Read .agents/skills/import-model/SKILL.md alongside 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 2
  • divergences.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):

TaskPurpose
pixi run install-skillnpx skills add modular/skills --skill import-model
pixi run update-skillnpx skills update
pixi run smoke-skillCPU-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.

PhaseTaskScript
1pixi run inspect <HF_ID>inspect_hf.py — config + native-arch check
1pixi run list-keys <HF_ID>list_checkpoint_keys.py — safetensor key dump
1pixi run list-archs [--match X]list_native_archs.py — registered MAX slugs
1pixi run check-walls <HF_ID>check_walls.py — ALiBi / FP8 / SSM blockers
2pixi run scaffold <HF_ID> --start-from <donor> --output-dir ../../../scaffold.py — copy donor → <slug>/ at repo root
2pixi run gates <HF_ID> --port-dir ../../../<slug>/run_oss_gates.py — walls, metadata, arch checks
3pixi run serve --model <HF_ID> --custom-architectures ../../../<slug> ..._serve_wrapper.py — max serve with Pydantic kick
3pixi run compare <HF_ID> --slug <slug> --port 8000 --prompt "…"compare_layers.py — top-1 logprob diff vs HF
3pixi run hf-precompute_hf_precompute.py — Mellum-specific HF dump
3pixi run max-check_max_check.py — Mellum-specific MAX vs HF
—pixi run test-scriptstest_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.py only copies the donor's graph. Do not max serve until 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 from honest-docstrings.md and classify every hit OK / Lie / Stale before declaring Phase 2 done.
  • State-dict coverage. Wire the audit from state-dict-audit.md after editing weight_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.md must pass before max 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.py clearly has per-head RMSNorm on Q and K before RoPE. Trust the modeling code.
  • --custom-architectures takes the port dir, not its parent. MAX adds dirname(<port_dir>) to sys.path and imports basename(<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_prob renormalization must also override MoEGate.shard(). The base implementation returns plain MoEGate instances 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_logprobs from custom archs. The donor PipelineModel doesn't implement compute_log_probabilities, so the OpenAI completion route returns token_logprobs: []. Substitute top-1 token parity at varied prefix lengths — see _compare_top1.py for the pattern.
  • GPU memory contention. MAX reserves 90% of the card by default (--device-memory-utilization 0.9), so max 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.45 so both fit on an 80 GB card. On smaller GPUs (40 GB), default 0.9 is already too tight; lower to 0.85.
  • RoPE max_seq_len is the precompute budget, not a position cap. Sliding-attention layers still see absolute positions up to max_position_embeddings. Do not shrink the sliding RoPE's max_seq_len to sliding_window.
  • Pydantic forward-reference. transformers from main triggers PydanticUserError: 'PipelineConfig' is not fully defined until torch is imported and model_rebuild() is called. Always launch max serve via _serve_wrapper.py (pixi run serve).
  • NVML driver/library mismatch. nvidia-smi returns "Failed to initialize NVML: Driver/library version mismatch" and MAX cannot use the GPU. Try:
    sudo modprobe -r nvidia_uvm nvidia_drm nvidia_modeset nvidia
    sudo modprobe nvidia
    Both steps can fail: modprobe -r fails when something still holds /dev/nvidia* (kill the offending process first; lsmod | rg nvidia shows the refcount), and modprobe nvidia fails 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.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.