| --- |
| base_model: |
| - MiniMaxAI/MiniMax-M3 |
| base_model_relation: finetune |
| license: other |
| license_name: minimax-model-license |
| license_link: https://huggingface.co/MiniMaxAI/MiniMax-M3 |
| language: |
| - en |
| pipeline_tag: text-generation |
| library_name: vllm |
| tags: |
| - minimax |
| - minimax-m3 |
| - moe |
| - mixture-of-experts |
| - reap |
| - pruned |
| - quantized |
| - rfi |
| - code |
| - rocm |
| - gfx1201 |
| - rdna4 |
| --- |
| |
| > # ⚠️ Vision is not yet working — text-only for now. |
| > Image/video input is **not functional** in this build. The MiniMax-M3 vision |
| > tower has an unresolved rotary-embedding bug, so multimodal input is disabled |
| > in the serving config. **Text generation works**; treat this as a text-only |
| > coder model until vision is fixed. |
|
|
| # MiniMax-M3-Coder (RFI) |
|
|
| A REAP-pruned, RFI-quantized **coder** build of MiniMax-M3, packaged to serve on |
| AMD ROCm / RDNA4 (gfx1201) through a custom vLLM fork. |
|
|
| > ### ⚠️ Experimental — in active development |
| > This model is **functional but experimental**. It runs and produces coherent |
| > long-context output, but it has not been broadly evaluated, the quantization |
| > recipe is still being tuned, and behavior may change between revisions. Do not |
| > rely on it for production workloads. Use at your own risk. |
|
|
| --- |
|
|
| ## What this is |
|
|
| `MiniMax-M3-Coder` is a derivative of **[MiniMaxAI/MiniMax-M3](https://huggingface.co/MiniMaxAI/MiniMax-M3)**: |
|
|
| 1. **Expert pruning (REAP).** The set of routed experts to drop was taken from the |
| expert inventory of |
| **[JANGQ-AI/MiniMax-M3-REAP22-Coder](https://huggingface.co/JANGQ-AI/MiniMax-M3-REAP22-Coder)**. |
| The surviving experts are renumbered contiguously and the router gate/bias are |
| sliced to match. This build carries **100 routed experts** (top-4) plus 1 |
| shared expert. |
| 2. **Mixed-precision RFI quantization.** A composite, mostly-low-bit scheme |
| (details below) whose *mixed format* was inspired by the REAP22-Coder model. |
| 3. **Runtime.** Serving support (custom RFI quant kernels + MiniMax-M3 sparse |
| "lightning indexer" attention) lives in the `tcclaviger/vllm22` vLLM fork, |
| published as the **`:dev`** image. |
|
|
| ### Sources & credits |
|
|
| | Role | Source | |
| | --- | --- | |
| | Original base model (we are a derivative / fine-tune of it) | [MiniMaxAI/MiniMax-M3](https://huggingface.co/MiniMaxAI/MiniMax-M3) | |
| | Expert-prune inventory (which experts to drop) + mixed-quant inspiration | [JANGQ-AI/MiniMax-M3-REAP22-Coder](https://huggingface.co/JANGQ-AI/MiniMax-M3-REAP22-Coder) | |
| | Concept inspiration (the idea of an M3 Coder build) | **JANG2_L (vMLX)** | |
| | Pruning + RFI quantization + vLLM serving fork | [tcclaviger](https://huggingface.co/tcclaviger) | |
| |
| All rights, the license, and the underlying model belong to **MiniMaxAI**; this |
| repository is a derivative work and inherits the |
| [MiniMax-M3 license](https://huggingface.co/MiniMaxAI/MiniMax-M3). Thanks to |
| MiniMaxAI for the base model, to JANGQ-AI for the REAP expert inventory and the |
| mixed-quant direction, and to JANG2_L (vMLX) for the original M3-Coder mixed precision idea. |
| |
| --- |
| |
| ## Architecture (post-prune) |
| |
| | Field | Value | |
| | --- | --- | |
| | Backbone | MiniMax-M3 sparse MoE (DSA "lightning indexer" attention) | |
| | Hidden size | 6144 | |
| | Layers | 60 | |
| | Attention heads / KV heads | 64 / 4 (head dim 128, partial RoPE 0.5, θ=5e6) | |
| | Routed experts (post-REAP) | 100, top-4 | |
| | Shared experts | 1 | |
| | Expert intermediate size | 3072 | |
| | Sparse indexer | index dim 128, 4 index heads, top-k 16 blocks × 128 | |
| | Vocab | 200,064 | |
| | Max context | 1,048,576 (1M) | |
| | Multimodal | vision tower present in weights, **not yet functional** (rotary bug) — disabled in the serving config | |
|
|
| --- |
|
|
| ## Quantization schema — RFI composite v1.0 |
|
|
| **RFI** is a rotation-based composite integer scheme (`quant_method: rfi`, |
| `format: rfi-quantized`, `version: rfi-composite-1.0`, status `compressed`). |
|
|
| **Global settings (all quantized Linears):** |
| - **Rotation:** FWHT-32 (`hadamard32`) applied before quantization. |
| - **Granularity:** per-group, `group_size = 32`, **symmetric**. |
| - **Scales:** block-float, int8 mantissa + int8 exponent |
| (`scale_encoding: block_float_i8m_i8e`). |
| - Target: `Linear` layers. |
|
|
| **Per-component bit widths (mixed):** |
|
|
| | Component | Bits | Notes | |
| | --- | --- | --- | |
| | Routed MoE experts (`block_sparse_moe.experts`) | **2-bit** | codebook `{-10, -3, 3, 10}` — the bulk of the weights | |
| | Shared expert (`shared_experts`) | **6-bit** | | |
| | Vision tower / multimodal projector / patch-merge MLP | **6-bit** | | |
| | Everything else (attention q/k/v/o, dense MLP, …) | **8-bit** | int, default group | |
|
|
| **Kept unquantized (fp16 / bf16 — in the `ignore` list):** |
| - Router gates: `block_sparse_moe.gate` (per-layer) and `gate.weight` |
| - Token embeddings: `model.embed_tokens` |
| - Output head: `lm_head` |
| - **Lightning-indexer projections: `index_q_proj`, `index_k_proj`** |
|
|
| --- |
|
|
| ## Running it |
|
|
| Serving requires the custom fork image (stock vLLM does **not** include the RFI |
| quant kernels or the MiniMax-M3 sparse-attention path): |
|
|
| - **Docker image:** [`tcclaviger/vllm22`](https://hub.docker.com/repository/docker/tcclaviger/vllm22/general) — use the **`:dev`** tag. |
|
|
| ```bash |
| docker pull tcclaviger/vllm22:dev |
| ``` |
|
|
| ### Reference hardware: 4× AMD Radeon AI Pro R9700 |
|
|
| This model runs on **4× AMD AI Pro R9700** (gfx1201 / RDNA4, 32 GB each; |
| ROCm 7.2.1) at **tensor-parallel 4**, weighing in at **~106.9 GB total / ~26.7 GB |
| per GPU** (~2.53 bpw). It runs with these **KV-cache type and memory/space |
| parameters** — most importantly: |
|
|
| | Parameter | Value | Why | |
| | --- | --- | --- | |
| | `--kv-cache-dtype` | `fp8` | halves KV-cache footprint — the "kv type" | |
| | `--gpu-memory-utilization` | `0.94` | the per-GPU "space" budget | |
| | `--max-model-len` | `150000` | usable context within that budget | |
| | `--max-num-batched-tokens` | `1024` | chunked-prefill chunk size | |
| | `--max-num-seqs` | `1` | single-stream (KV-space bound) | |
| | `--block-size` | `128` | matches the M3 sparse-attention / indexer page size | |
| | `--tensor-parallel-size` | `4` | one shard per R9700 | |
|
|
| Equivalent `docker run` invocation: |
|
|
| ```bash |
| docker run --rm \ |
| --device /dev/kfd --device /dev/dri --group-add video \ |
| --cap-add SYS_PTRACE --security-opt seccomp=unconfined \ |
| --ipc host --network host --shm-size 32g \ |
| -e HIP_VISIBLE_DEVICES=0,1,2,3 \ |
| -v /path/to/MiniMax-M3-Coder:/app/models \ |
| tcclaviger/vllm22:dev \ |
| /app/models \ |
| --served-model-name M3-Coder \ |
| --tensor-parallel-size 4 \ |
| --gpu-memory-utilization 0.94 \ |
| --max-model-len 150000 \ |
| --kv-cache-dtype fp8 \ |
| --block-size 128 \ |
| --max-num-seqs 1 \ |
| --max-num-batched-tokens 1024 \ |
| --enable-chunked-prefill \ |
| --enable-prefix-caching \ |
| --chat-template /app/models/chat_template.jinja \ |
| --reasoning-parser minimax_m3 \ |
| --tool-call-parser minimax_m3 --enable-auto-tool-choice \ |
| --default-chat-template-kwargs '{"enable_thinking": true}' \ |
| --host 0.0.0.0 --port 8078 |
| ``` |
|
|
| `--quantization` is auto-detected from the checkpoint (`quant_method: rfi`). The |
| sparse lightning-indexer, RFI dequant, and mixed-bit experts are handled |
| automatically by the image. `HIP_VISIBLE_DEVICES=0,1,2,3` pins the four R9700s |
| and excludes the Raphael iGPU. |
|
|
| ## Speculative decoding — bundled EAGLE3 draft (`eagle3/`) |
|
|
| This repo bundles an **RFI6-quantized EAGLE3 draft** under [`eagle3/`](./eagle3) |
| for roughly **2× faster decoding** via speculative decoding. It is the |
| [Inferact/MiniMax-M3-EAGLE3](https://huggingface.co/Inferact/MiniMax-M3-EAGLE3) |
| drafter (a 1-layer head trained with TorchSpec on M3-regenerated code/math), |
| here quantized to **RFI6** — 6-bit rotation-int RFI on attention + MLP + the |
| EAGLE3 `fc` fusion, with embeddings / lm_head / norms kept BF16 (5.5 GB). At |
| serve time it shares this model's embedding + LM head. |
| |
| Enable it by adding `--speculative-config` pointing at the subfolder (the draft |
| mounts with the model at `/app/models`): |
| |
| ```bash |
| # ...same serve flags as above... |
| --speculative-config '{"method": "eagle3", "model": "/app/models/eagle3", "num_speculative_tokens": 4}' |
| ``` |
| |
| Speculative decoding is **lossless** — the target verifies every drafted token, |
| so output is byte-identical to running without the draft; only speed changes. |
| |
| **Measured on this stack** (4× R9700, `num_speculative_tokens=4`) — *mean accepted |
| length* is tokens emitted per target forward pass (the direct speedup proxy): |
| |
| | Workload | Draft accept rate | Mean accepted length | Per-position accept (pos 1–4) | |
| | --- | --- | --- | --- | |
| | Math / reasoning (low temp) | ~76% | **~4.0 tokens/step** | 0.91 / 0.80 / 0.71 / 0.61 | |
| | Coding (low temp) | ~53% | **~3.1 tokens/step** | 0.78 / 0.58 / 0.44 / 0.33 | |
| | Agentic chat (sampled) | ~36% | **~2.4 tokens/step** | 0.64 / 0.40 / 0.25 / 0.14 | |
| |
| Math/reasoning is the most predictable (near the `k+1=5` ceiling), then coding, |
| then sampled agentic chat; net **~2.4–4× fewer target forward passes**, i.e. the |
| observed **>2× decode speedup**. |
| (Measured on the more-aggressively-pruned 87-expert "Lite" build; this 100-expert |
| model should match or slightly exceed these.) The draft was trained against the |
| full 128-expert MXFP8 M3, so acceptance on a REAP-pruned RFI target runs below the |
| drafter's published numbers but is still a clear win. Requires |
| `tcclaviger/vllm22:dev`, whose RFI runtime loads the RFI6 draft directly. Credit: |
| original EAGLE3 drafter by [Inferact](https://huggingface.co/Inferact/MiniMax-M3-EAGLE3) |
| (TorchSpec); RFI6 quantization by tcclaviger. |
| |
| ## Server-side features (tooling & thinking) |
| |
| These are handled **at the server/model level** — no client-side changes are |
| required: |
| |
| - **Custom Python tool-call parser.** Tool calling uses a **Python** |
| tool-call parser (`--tool-call-parser minimax_m3` with |
| `--enable-auto-tool-choice`) written for this model. It runs on vLLM's Python |
| parsing path — the Rust (`vllm-rs`) tool-parser components are **not** used. |
| - **Qwen-style thinking toggle.** Reasoning is enabled/disabled with a simple |
| boolean, Qwen-style: `--default-chat-template-kwargs '{"enable_thinking": true}'` |
| (or `false`), and per-request via the same `enable_thinking` chat-template |
| kwarg. The chat template and the reasoning parser were modified to map this |
| boolean to the model's thinking mode. |
| - **Guarded thinking tags (both families).** The chat template and reasoning |
| parser are guarded so that **both** `<think>…</think>` **and** |
| `<mm:think>…</mm:think>` are accepted, normalized, and resolved correctly — |
| including in replayed conversation history — entirely on the server. Clients |
| can send either tag family (or none) without any special handling. |
|
|
| --- |
|
|
| ## Disclaimer |
|
|
| This is an **experimental, in-development** research artifact provided as-is, with |
| no warranty. It is a derivative of MiniMax-M3 and is subject to the upstream |
| MiniMax-M3 license and usage terms. Evaluate quality and safety yourself before |
| any use. |
|
|