djdeniro commited on
Commit
92d90e3
·
verified ·
1 Parent(s): 2975547

Update README with RDNA4 deployment guide and performance stats

Browse files
Files changed (1) hide show
  1. README.md +57 -148
README.md CHANGED
@@ -25,115 +25,45 @@ tags:
25
 
26
  This is an **MXFP4-16** (Mixed-precision 4-bit with 16-element group size) quantized variant of [MiniMaxAI/MiniMax-M2.7](https://huggingface.co/MiniMaxAI/MiniMax-M2.7), produced using compressed-tensors with an **IQ4_NL** codebook.
27
 
28
- The quantization scheme:
29
- - **Weight bits:** 4-bit per group of 16 elements
30
- - **Codebook:** IQ4_NL (Improved Q4 Normal) — 16 entries, asymmetric, FP4-like scale
31
- - **Target:** All `Linear` layers (MoE experts + FFN + attention projections)
32
- - **Excluded:** Attention `qkv_proj` scales, `block_sparse_moe.gate`, `lm_head`, `embed_tokens`, MTP layers, norms
33
- - **KV cache:** FP8 (e4m3), no dynamic quantization
34
 
35
- The result is a model that retains near-BF16 quality while fitting in significantly less VRAM, friendly to high-memory systems (128GB+ unified memory, multi-GPU 4×48 setups, RDNA4/GFX12xx GPUs).
36
 
37
  ---
38
 
39
  ## 2. Model Architecture
40
 
41
- MiniMax-M2.7 is a **456B-parameter sparse MoE** model with:
42
- - **456B total parameters** (sparse), **~30B activated** per token
43
- - **256 routed experts** per MoE layer, top-8 routing
44
- - **62 transformer layers**
45
- - **3 MTP (Multi-Token Prediction)** layers for speculative decoding
46
  - **200k context window**
47
  - Native tool-calling support
48
 
49
- Key architectural details from `config.json`:
50
- - `hidden_size`: 3072, `num_attention_heads`: 48, `num_key_value_heads`: 8, `head_dim`: 128
51
- - `num_local_experts`: 256, `num_experts_per_tok`: 8
52
- - `rope_theta`: 5,000,000, `max_position_embeddings`: 204,800
53
-
54
- ---
55
-
56
- ## 3. Quantization Details
57
-
58
- ### What was quantized
59
-
60
- | Layer type | Quantization | Notes |
61
- |---|---|---|
62
- | MoE expert weights (w1/w3/w2) | MXFP4-16, IQ4_NL | Merged `w13_weight_packed` + scales |
63
- | FFN intermediate (gate/up/proj) | MXFP4-16, IQ4_NL | Standard linear layers |
64
- | Attention projections (qkv) | MXFP4-16, IQ4_NL | QKV split handled correctly |
65
-
66
- ### What was NOT quantized
67
-
68
- | Layer | Reason |
69
- |---|---|
70
- | `self_attn.{k,v}_proj` scales | Per-tensor FP16 (no quantization) |
71
- | `block_sparse_moe.gate` | Router — kept BF16 |
72
- | `e_score_correction_bias` | MoE bias — kept BF16 |
73
- | `lm_head` | Output projection — kept BF16 |
74
- | `embed_tokens` | Embedding — kept BF16 |
75
- | MTP layers | Speculative decoding heads — kept BF16 |
76
- | RMSNorm layers | Normalizations — kept BF16 |
77
- | KV cache | FP8 (e4m3), calibrated scales |
78
-
79
- ### KV Cache
80
-
81
- FP8 (e4m3) KV cache is used at runtime (`--kv-cache-dtype fp8_e4m3`). Per-layer scales are calibrated during quantization and stored alongside weights.
82
-
83
  ---
84
 
85
- ## 4. Runtime Requirements
86
 
87
- ### Hardware
 
 
88
 
89
- - **GPU:** RDNA 4 (gfx12xx) — tested on 4× RX 9700 (RDNA4)
90
- - **Memory:** 128GB+ recommended for long-context workloads
91
- - **OS:** Linux with ROCm support
92
-
93
- ### Docker Runtime
94
-
95
- The **only** validated way to run this model is with the prebuilt RDNA4 vLLM image:
96
-
97
- ```bash
98
- # Pull the runtime image
99
- docker pull tcclaviger/vllm22:latest
100
-
101
- # Run with 8 GPUs
102
- ./run-minimax-m2.7-mxfp416.sh <container_name> <port>
103
- ```
104
-
105
- This image includes:
106
- - Custom Triton attention kernels tuned for RDNA4 (10× faster than ROCm attention at long context)
107
- - Fixed FP8 KV-cache quantization path (2× throughput improvement)
108
- - Tuned GEMM configs for RX 9700
109
- - MXFP4-16 kernels compiled for gfx12xx
110
 
111
  ---
112
 
113
- ## 5. Local Deployment
114
 
115
- ### vLLM (Recommended)
116
 
117
- Using the RDNA4 Docker image:
118
-
119
- ```bash
120
- vllm serve djdeniro/MiniMax-M2.7-MXFP416 \
121
- --served-model-name minimax-m2.7-mxfp416 \
122
- --tensor-parallel-size 8 \
123
- --enable-expert-parallel \
124
- --disable-cascade-attn \
125
- --reasoning-parser minimax_m2 \
126
- --enable-auto-tool-choice \
127
- --tool-call-parser minimax_m2 \
128
- --trust-remote-code \
129
- --gpu-memory-utilization 0.93 \
130
- --max-model-len 180000 \
131
- --kv-cache-dtype fp8_e4m3 \
132
- --attention-backend TRITON_ATTN \
133
- --override-generation-config '{"max_tokens": 16384}'
134
- ```
135
-
136
- Or with Docker:
137
 
138
  ```bash
139
  docker run --name minimax-mxfp416 \
@@ -150,44 +80,54 @@ docker run --name minimax-mxfp416 \
150
  -e HIP_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
151
  -e ROCR_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
152
  -e TRUST_REMOTE_CODE=1 \
153
- -e PYTORCH_TUNABLEOP_ENABLED=1 \
154
- -e PYTORCH_TUNABLEOP_TUNING=0 \
155
  -p 8000:8000 \
156
  tcclaviger/vllm22:latest \
157
  bash -c "cp /patches/vllm22_minimax_m2.py /app/vllm/vllm/model_executor/models/minimax_m2.py && \
158
- /app/.venv/bin/pip install -q sentencepiece && \
159
- exec /app/.venv/bin/vllm serve \
160
- /app/models/models/vllm/MiniMax-M2.7-MXFP416 \
161
  --served-model-name minimax-m2.7-mxfp416 \
162
- --host 0.0.0.0 --port 8000 \
163
- --trust-remote-code \
164
- --tensor-parallel-size 8 \
165
  --disable-cascade-attn \
166
  --reasoning-parser minimax_m2 \
167
  --enable-auto-tool-choice --tool-call-parser minimax_m2 \
168
  --enable-prefix-caching --gpu-memory-utilization 0.93 \
169
  --max-model-len 180000 --max-num-seqs 48 --max-num-batched-tokens 2048 \
170
- --kv-cache-dtype fp8_e4m3 \
171
- --enable-expert-parallel \
172
- --attention-backend TRITON_ATTN \
173
  --override-generation-config '{\"max_tokens\": 16384}'"
174
  ```
175
 
176
- ### API Usage (OpenAI-compatible)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
 
178
  ```python
179
  from openai import OpenAI
180
 
181
- client = OpenAI(
182
- base_url="http://localhost:8000/v1",
183
- api_key="EMPTY",
184
- )
185
 
186
  completion = client.chat.completions.create(
187
  model="minimax-m2.7-mxfp416",
188
  messages=[
189
  {"role": "system", "content": "You are a helpful assistant."},
190
- {"role": "user", "content": "Explain what MXFP4 quantization is."}
191
  ],
192
  temperature=1.0,
193
  max_tokens=1024,
@@ -195,74 +135,43 @@ completion = client.chat.completions.create(
195
  print(completion.choices[0].message.content)
196
  ```
197
 
198
- ### Tool Calling
199
-
200
- MiniMax-M2.7 has native function calling support. Use `reasoning_parser=minimax_m2` and `tool_call_parser=minimax_m2`:
201
-
202
- ```python
203
- messages = [
204
- {"role": "user", "content": [
205
- {"type": "text", "text": "What's the weather in Tokyo?"},
206
- ]}
207
- ]
208
- # The model will generate tool calls with the correct format
209
- ```
210
-
211
  ---
212
 
213
  ## 6. Chat Template
214
 
215
- The model uses a custom Jinja chat template supporting:
216
-
217
- - **System messages** with dynamic tool injection
218
- - **Tool calls** in XML format (`<minimax:tool_call>` / `</minimax:tool_call>`)
219
- - **Reasoning content** (`<think>` / `</think>`)
220
- - **Tool responses** with `<response>` XML tags
221
- - **Generation prompts** with thinking prefix
222
-
223
- Example with `apply_chat_template`:
224
 
225
  ```python
226
  from transformers import AutoProcessor, AutoModelForCausalLM
227
 
228
  processor = AutoProcessor.from_pretrained(
229
- "djdeniro/MiniMax-M2.7-MXFP416",
230
- trust_remote_code=True
231
  )
232
  model = AutoModelForCausalLM.from_pretrained(
233
  "djdeniro/MiniMax-M2.7-MXFP416",
234
- device_map="auto",
235
- dtype="auto",
236
- trust_remote_code=True
237
  )
238
 
239
  messages = [
240
  {"role": "system", "content": "You are a helpful assistant."},
241
  {"role": "user", "content": "Hello, how are you?"}
242
  ]
243
-
244
  inputs = processor.apply_chat_template(
245
- messages,
246
- tokenize=True,
247
- add_generation_prompt=True,
248
- return_dict=True,
249
- return_tensors="pt",
250
  ).to(model.device)
251
-
252
- generated_ids = model.generate(**inputs, max_new_tokens=128, do_sample=False)
253
- output = processor.decode(generated_ids[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
254
- print(output)
255
  ```
256
 
257
  ---
258
 
259
  ## 7. Inference Parameters
260
 
261
- Recommended defaults:
262
  - `temperature`: 1.0
263
  - `top_p`: 0.95
264
  - `top_k`: 40
265
- - `max_tokens`: 16384 (configurable)
266
 
267
  ---
268
 
@@ -276,4 +185,4 @@ Recommended defaults:
276
 
277
  ## 9. License
278
 
279
- This quantized variant inherits the [Apache 2.0 license](https://github.com/MiniMax-AI/MiniMax-M2.7/blob/main/LICENSE) from the base model.
 
25
 
26
  This is an **MXFP4-16** (Mixed-precision 4-bit with 16-element group size) quantized variant of [MiniMaxAI/MiniMax-M2.7](https://huggingface.co/MiniMaxAI/MiniMax-M2.7), produced using compressed-tensors with an **IQ4_NL** codebook.
27
 
28
+ The quantization:
29
+ - **4-bit** weights with 16-element group size, IQ4_NL codebook
30
+ - All `Linear` layers quantized (MoE experts, FFN, attention projections)
31
+ - Attention `k/v_proj` scales, router gate, MTP layers, norms, embeddings kept BF16
32
+ - KV cache: FP8 (e4m3), calibrated scales baked into checkpoint
 
33
 
34
+ The result fits in ~17.5 GiB per GPU (TP8) while retaining near-BF16 quality.
35
 
36
  ---
37
 
38
  ## 2. Model Architecture
39
 
40
+ - **456B total params** (sparse), **~30B activated** per token
41
+ - **256 experts** per MoE layer, top-8 routing, 62 transformer layers
42
+ - **3 MTP layers** for speculative decoding
 
 
43
  - **200k context window**
44
  - Native tool-calling support
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  ---
47
 
48
+ ## 3. Runtime Requirements
49
 
50
+ - **GPU:** RDNA 4 (gfx12xx) — 4× or 8× RX 9700 recommended
51
+ - **Memory:** 128GB+ system RAM
52
+ - **Docker:** `tcclaviger/vllm22:latest` — only validated runtime
53
 
54
+ The Docker image includes:
55
+ - Custom Triton attention kernels tuned for RDNA4
56
+ - Fixed FP8 KV-cache quantization path
57
+ - Pre-tuned GEMM configs for RX 9700
58
+ - MXFP4-16 kernels for gfx12xx
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
  ---
61
 
62
+ ## 4. Deployment
63
 
64
+ **Full deployment guide (RDNA4 / RX 9700):** [docs/vllm_deploy_guide.md](./docs/vllm_deploy_guide.md)
65
 
66
+ Quick-start:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
  ```bash
69
  docker run --name minimax-mxfp416 \
 
80
  -e HIP_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
81
  -e ROCR_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
82
  -e TRUST_REMOTE_CODE=1 \
83
+ -v /path/to/models:/app/models:ro \
84
+ -v /path/to/patches:/patches:ro \
85
  -p 8000:8000 \
86
  tcclaviger/vllm22:latest \
87
  bash -c "cp /patches/vllm22_minimax_m2.py /app/vllm/vllm/model_executor/models/minimax_m2.py && \
88
+ pip install -q sentencepiece && \
89
+ exec vllm serve /app/models/MiniMax-M2.7-MXFP416 \
 
90
  --served-model-name minimax-m2.7-mxfp416 \
91
+ --host 0.0.0.0 --port 8000 --trust-remote-code \
92
+ --tensor-parallel-size 8 --enable-expert-parallel \
 
93
  --disable-cascade-attn \
94
  --reasoning-parser minimax_m2 \
95
  --enable-auto-tool-choice --tool-call-parser minimax_m2 \
96
  --enable-prefix-caching --gpu-memory-utilization 0.93 \
97
  --max-model-len 180000 --max-num-seqs 48 --max-num-batched-tokens 2048 \
98
+ --kv-cache-dtype fp8_e4m3 --attention-backend TRITON_ATTN \
 
 
99
  --override-generation-config '{\"max_tokens\": 16384}'"
100
  ```
101
 
102
+ ### Performance (8× RX 9700, 210W power limit)
103
+
104
+ | Metric | Value |
105
+ |--------|-------|
106
+ | Generation throughput | ~50–80 tokens/s |
107
+ | Prefill throughput | up to 2,190 tokens/s (w/ prefix cache) |
108
+ | Prefix cache hit rate | ~93% |
109
+ | KV cache memory | 11.35 GiB |
110
+ | KV cache capacity | 767,856 tokens |
111
+ | Max context per request | 180,000 tokens |
112
+ | Max concurrent (180k) | 4 requests |
113
+ | Model weight memory (TP8) | ~17.5 GiB/GPU |
114
+
115
+ > **Power tip:** Set `rocm-smi --setpowerlimit <i> 210` per GPU. At 210W sustained throughput is higher than at full 300W due to reduced thermal throttling.
116
+
117
+ ---
118
+
119
+ ## 5. API Usage
120
 
121
  ```python
122
  from openai import OpenAI
123
 
124
+ client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
 
 
 
125
 
126
  completion = client.chat.completions.create(
127
  model="minimax-m2.7-mxfp416",
128
  messages=[
129
  {"role": "system", "content": "You are a helpful assistant."},
130
+ {"role": "user", "content": "Hello!"}
131
  ],
132
  temperature=1.0,
133
  max_tokens=1024,
 
135
  print(completion.choices[0].message.content)
136
  ```
137
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  ---
139
 
140
  ## 6. Chat Template
141
 
142
+ The model uses a Jinja chat template supporting system messages, tool calls (`<minimax:tool_call>`/`</minimax:tool_call>`), reasoning content (`<think>`/`</think>`), and tool responses (`<response>`).
 
 
 
 
 
 
 
 
143
 
144
  ```python
145
  from transformers import AutoProcessor, AutoModelForCausalLM
146
 
147
  processor = AutoProcessor.from_pretrained(
148
+ "djdeniro/MiniMax-M2.7-MXFP416", trust_remote_code=True
 
149
  )
150
  model = AutoModelForCausalLM.from_pretrained(
151
  "djdeniro/MiniMax-M2.7-MXFP416",
152
+ device_map="auto", dtype="auto", trust_remote_code=True
 
 
153
  )
154
 
155
  messages = [
156
  {"role": "system", "content": "You are a helpful assistant."},
157
  {"role": "user", "content": "Hello, how are you?"}
158
  ]
 
159
  inputs = processor.apply_chat_template(
160
+ messages, tokenize=True, add_generation_prompt=True,
161
+ return_dict=True, return_tensors="pt"
 
 
 
162
  ).to(model.device)
163
+ out = model.generate(**inputs, max_new_tokens=128, do_sample=False)
164
+ print(processor.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True))
 
 
165
  ```
166
 
167
  ---
168
 
169
  ## 7. Inference Parameters
170
 
 
171
  - `temperature`: 1.0
172
  - `top_p`: 0.95
173
  - `top_k`: 40
174
+ - `max_tokens`: 16384 (default)
175
 
176
  ---
177
 
 
185
 
186
  ## 9. License
187
 
188
+ Apache 2.0 — inherits from [base model](https://github.com/MiniMax-AI/MiniMax-M2.7/blob/main/LICENSE).