Add DeepSeek-V4 model and safetensors/tokenizer fallback handling - #1190
Add DeepSeek-V4 model and safetensors/tokenizer fallback handling#1190austinbv wants to merge 1 commit into
Conversation
Adds deepseek_v4.py implementing DeepSeek-V4-Flash architecture: MLA attention with inverse RoPE, hash-based expert routing (HC-Sinkhorn), MXFP8-quantized MoE layers, and sliding-window/full-attention interleaving. Adds _load_weights_file() to handle safetensors shards that contain F8_E8M0 block-scale tensors (which mx.load rejects). The fallback parser decodes F8_E8M0 as unsigned exponents (2^(b-127)), BF16 via uint16 view, and maps F8_E4M3/F8_E5M2 to uint8 to satisfy mx.from_fp8's documented input contract. Wraps AutoTokenizer.from_pretrained in a try/except so models whose model_type is unknown to transformers fall back to PreTrainedTokenizerFast.
|
Hey @austinbv I would recommend you check Deepseek v3 for the FP8 quantisation part. It can be done in the Regarding the tokenizer, I wouldn't patch it at all, because it's a matter of waiting for this PR to be merged into transformers. So a simple note about it would suffice. |
|
Ran this PR against What works
>>> generate(model, tok, prompt="The capital of France is", max_tokens=50)
"Paris.\nThe capital of France is Paris.\nThe capital of France is Paris..."(It loops after the correct first answer, but that's just the default sampler with no repetition penalty. The first token is right and the model is clearly running.) What doesn'tStarting python -m mlx_lm.server --model mlx-community/deepseek-ai-DeepSeek-V4-Flash-8bit \
--host 127.0.0.1 --port 18082 &
# wait for "Starting httpd at..."
curl -s -X POST http://127.0.0.1:18082/v1/completions \
-H 'Content-Type: application/json' \
-d '{"model": "mlx-community/deepseek-ai-DeepSeek-V4-Flash-8bit",
"prompt": "The capital of France is",
"max_tokens": 15}'
# → choices[0].text = "otold , , ( ("
The chat-template path and the raw My guess (haven't confirmed with a patch): the server's token-by-token detokenizer is emitting individual bytes for deepseek_v4's tokenizer output rather than waiting for complete surface-form pieces. The tokenizer-fallback handling in this PR's Suggested next stepA server smoke test that runs Side observation
Scoreboard for referenceI ran the three open V4 PRs through the same harness on the same machine + the same repo:
So this PR is currently the only one that loads the public weights at all. That's a big deal worth landing, but the server bug should probably be resolved first since |
|
Closing as there are better options |
Adds deepseek_v4.py implementing DeepSeek-V4-Flash architecture: MLA attention with inverse RoPE, hash-based expert routing (HC-Sinkhorn), MXFP8-quantized MoE layers, and sliding-window/full-attention interleaving.
Adds _load_weights_file() to handle safetensors shards that contain F8_E8M0 block-scale tensors (which mx.load rejects). The fallback parser decodes F8_E8M0 as unsigned exponents (2^(b-127)), BF16 via uint16 view, and maps F8_E4M3/F8_E5M2 to uint8 to satisfy mx.from_fp8's documented input contract.
Wraps AutoTokenizer.from_pretrained in a try/except so models whose model_type is unknown to transformers fall back to PreTrainedTokenizerFast.