Downloads · 30 days
115
2% of all-time downloads
baicai1145/DeepSeek-V4-Flash-0731-W4A16
DeepSeek-V4-Flash-0731-W4A16 is a text generation model from baicai1145. Use it when you need the model to write or continue text. It is set up for vllm. The card lists the license as other.
INT4 (W4A16) 量化版本的 DeepSeek-V4-Flash-0731 (283B params)。 将原始 FP4 experts + FP8 attention 混合精度模型转换为 vLLM 原生的 compressed-tensors 混合精度格式,可在 无 FP4 硬件支持 的 NVIDIA GPU(A100 / L40S / L20 / RTX 4090 等)上推理。
Downloads · 30 days
115
2% of all-time downloads
All-time downloads
5.3K
Public
Parameters
44.9B
177 GB on disk
Likes
9
Public
Click a slice to open those files.
.safetensors177 GB · 100%
How the weights are stored.
I3237B · 83%
From the Hugging Face model README
INT4 (W4A16) 量化版本的 DeepSeek-V4-Flash-0731 (283B params)。
将原始 FP4 experts + FP8 attention 混合精度模型转换为 vLLM 原生的 compressed-tensors 混合精度格式,可在 无 FP4 硬件支持 的 NVIDIA GPU(A100 / L40S / L20 / RTX 4090 等)上推理。
本仓库与原始
deepseek-ai/DeepSeek-V4-Flash-0731模型出自同一权重,仅做格式与精度转换,未做任何微调或蒸馏。
原始 DeepSeek-V4-Flash-0731 采用混合精度:
e2m1fn_x2 打包为 int8,配 e8m0 per-block scale)e4m3,配 e8m0 per-block scale)FP4 是 NVIDIA Blackwell 架构原生格式。A100 / H100 / H20 等非 Blackwell GPU 不支持 FP4 tensor core,无法直接运行原始权重。
本量化版本将 experts 从 FP4 转为 INT4 (group_size=32),保留 attention 为 FP8,使其能在 Hopper / Ampere 架构上通过 vLLM 加载推理。
| 硬件 | 原始模型 | 本 W4A16 版本 |
|---|---|---|
| Blackwell (B200) | ✅ 原生 | ✅ |
| Hopper (H20/H100) | ⚠️ FP8 部分 OK,experts 退化 | ✅ 推荐 |
| Ampere (A100/L40S) | ❌ 不支持 | ⚠️ 需 vLLM 小补丁(见下文) |
本模型采用 compressed-tensors 的 mixed-precision 格式,包含两个 config_group:
| 项 | 值 |
|---|---|
| targets | re:.*attn\.(wq_a|wq_b|wkv|wo_a|wo_b|fused_wqa_wkv)$ |
| weights | FP8 e4m3,block 结构 [128,128],symmetric |
| input_activations | FP8 dynamic,group_size=128,symmetric |
| 说明 | 直接保留原始模型的 FP8 权重和 scale,未做重采样 |
| 项 | 值 |
|---|---|
| targets | re:.*experts\.\d+\.(w1|w2|w3|gate_proj|up_proj|down_proj|gate_up_proj)$ |
| weights | INT4,group_size=32,symmetric,BF16 scale |
| input_activations | 无(W4A16:激活在 BF16 计算) |
| 说明 | 由原始 FP4 权重经最优 scale 网格搜索转换而来(见下文) |
lm_head、embed_tokens、所有 norm、router gate、shared_experts、compressor、indexer.weights_proj、hyper-connection 参数等保持 BF16(与原始非 FP4 部分一致)。
这是本仓库的核心技术点。原始 experts 的 FP4 权重并非直接 round 到 INT4,而是经过两步:
原始 FP4 (e2m1fn_x2) 每个元素是 4 bit 索引,通过查找表还原:
FP4_TABLE = [0, 0.5, 1, 1.5, 2, 3, 4, 6,
0, -0.5, -1, -1.5, -2, -3, -4, -6]
# code (4bit) → FP4_TABLE[code] × scale(e8m0) = 真实权重值
由于 FP4 每个权重值已是离散点,反量化到 BF16 是精确无损的(只是把离散值用 BF16 表示)。
INT4 量化采用 group_size=32(与 FP4 的 [128,128] block 对齐,32 是 FP4 一个 e8m0 scale 覆盖 128 元素时的细分子组),对称量化:
# 对每个 group, 搜索最优的 round-rate r
for r in [6/7, 0.9, 0.95, 1.0, 1.05, 1.1]:
scale = amax(group) * r / 7
q = clamp(round(w / scale), -8, 7)
mse = mean((w - q*scale)²)
# 保留 MSE 最小的 (q, scale)
普通 INT4 量化固定用 r = 1.0(scale = amax/7)。本转换额外搜索 6 个 r 候选,对每个 group 选取 MSE 最小的组合,显著降低量化误差。
| 来源 | 误差 | 是否可消除 |
|---|---|---|
| FP4 → BF16 反量化 | 0(精确) | — |
| BF16 → INT4 量化误差 | 非零 | ❌ 不可避免(信息论下界) |
严格意义上,FP4 → INT4 不是数学无损的,因为 INT4 的 16 个量化电平与 FP4 的 16 个电平分布不同:
{0, ±0.5, ±1, ±1.5, ±2, ±3, ±4, ±6} —— 非均匀,覆盖大动态范围{0, ±1, ±2, ±3, ±4, ±5, ±6, ±7} × scale/7 —— 均匀但通过最优 scale 搜索 + group_size=32 细粒度,实际量化误差被压到极低。实测信噪比(SNR):
SNR(FP4 → INT4, group_size=32) ≈ 25.8 dB
这对应约 0.26% 的相对均方误差(RMSE ≈ 5.1% 相对幅度),在 LLM 推理中通常对最终输出无可感知影响(见下方实测结果)。
| 类别 | 原始 FP4+FP8 | 本 W4A16 | 差异 |
|---|---|---|---|
| 数学 (10题) | 100% | 100% | 0 |
| 代码 (10题) | 100% | 100% | 0 |
| 常识 (10题) | 100% | 100% | 0 |
| 逻辑 (10题) | 100% | 100% | 0 |
| 指令遵循 (10题) | 100% | 100% | 0 |
| 总计 (50题) | 100% | 100% | 0 |
两个模型答错/答对的题完全相同,包括同一个 Unicode 下标表达的边缘 case。在 50 题评测集上 INT4 量化零质量损失。
注:50 题评测集偏简单,主要验证"没把模型搞坏"。如需更高置信度,建议跑 GSM8K / MMLU。
| 指标 | 原始 FP4+FP8 | 本 W4A16 |
|---|---|---|
| 整体 token 接受率 | 38.1% | 41.7% (+3.6pp) |
| 每步平均接受 token | 2.67 | 2.92 |
| pos0(首个 spec)接受率 | 72.3% | 72.7% |
接受率不降反升,因为 DSpark 的 draft 与 main 用同一套权重,接受率取决于两者一致性而非绝对精度。
| 配置 | 原始 FP4+FP8 | 本 W4A16 |
|---|---|---|
| 2×H20 | 21.7 tok/s | 21.4 tok/s |
H20 原生支持 FP4,INT4 在 Hopper 上无速度优势;A100 上情况反转(原始 FP4 跑不了,只有 W4A16 能跑)。
DeepSeek-V4-Flash-0731-W4A16/
├── config.json # 含 quantization_config (mixed-precision)
├── generation_config.json
├── model-00001-of-00034.safetensors # 34 个分片, 约 166GB
├── ...
├── model-00034-of-00034.safetensors
├── model.safetensors.index.json
├── encoding/ # 官方 chat prompt 编码模块
│ ├── encoding_dsv4.py
│ └── README.md
└── README.md
总大小:~166 GB(原始 156 GB,略大因 shared/compressor/indexer 从 FP8 升级到 BF16)。
DeepSeek-V4-Flash 使用非标准的 chat template,不能用 apply_chat_template。本仓库附带官方的 encoding/ 目录,使用方法:
import sys
sys.path.insert(0, "encoding")
from encoding_dsv4 import encode_messages
prompt = encode_messages(
[{"role": "user", "content": "你好"}],
thinking_mode="chat", # 或 "thinking"
reasoning_effort="low", # low / high / max
)
# prompt 是已编码的字符串, 直接喂给 llm.generate([prompt], ...)
from vllm import LLM, SamplingParams
llm = LLM(
model="your-username/DeepSeek-V4-Flash-0731-W4A16",
tensor_parallel_size=2,
dtype="bfloat16",
kv_cache_dtype="fp8", # 必须,DSpark MLA 要求
gpu_memory_utilization=0.95,
trust_remote_code=True,
max_model_len=4096,
# 可选: DSpark 投机解码
speculative_config={
"method": "dspark",
"num_speculative_tokens": 7,
"draft_sample_method": "greedy",
},
)
Ampere 架构不支持 FP8 tensor core。本模型的 attention 仍是 FP8,vLLM 的 deep_gemm_fp8_o_proj 在 A100 上会失败。需要给 vLLM 打一个小补丁,把 o_proj 的 FP8 einsum 换成 BF16 fallback 路径。
补丁位置:vllm/models/deepseek_v4/nvidia/ops/o_proj.py
# 原始(仅 FP8):
(wo_a.weight, wo_a.weight_scale_inv)
# 补丁后(自动 fallback):
_ws_inv = getattr(wo_a, 'weight_scale_inv', None)
_wo_scale = _ws_inv if _ws_inv is not None else wo_a.weight_scale
(wo_a.weight, _wo_scale)
注:在 H20 上也建议打此补丁(用
is not None判断,对原生 FP8 模型行为无影响,但能让 compressed-tensors 格式的 FP8 attention 正常工作)。完整的 A100 支持需要进一步把 attention 从 FP8 改为 BF16/INT16,这是后续工作。
python -m vllm.entrypoints.openai.api_server \
--model your-username/DeepSeek-V4-Flash-0731-W4A16 \
--tensor-parallel-size 2 \
--dtype bfloat16 \
--kv-cache-dtype fp8 \
--trust-remote-code \
--max-model-len 4096 \
--gpu-memory-utilization 0.95
转换脚本见 convert_v4.py(本仓库未附,核心逻辑如下,约 150 行):
import torch, re
from safetensors import safe_open
FP4_TABLE = torch.tensor([0,0.5,1,1.5,2,3,4,6,0,-0.5,-1,-1.5,-2,-3,-4,-6])
GROUP = 32
def dequant_fp4(w_fp4, scale_e8m0):
"""FP4 e2m1fn_x2 → BF16, 无损"""
codes = w_fp4.view(torch.uint8) # 2个FP4 packed in 1 uint8
hi = codes >> 4; lo = codes & 0xF
vals = torch.stack([FP4_TABLE[hi], FP4_TABLE[lo]], -1).flatten()
return (vals.reshape(*w_fp4.shape[:-1], -1) * scale_e8m0).to(torch.bfloat16)
def quant_int4(w_bf16, gs=GROUP):
"""BF16 → INT4, 网格搜索最优 scale"""
out, in_ = w_bf16.shape; ng = in_ // gs
w = w_bf16.float().reshape(out, ng, gs)
amax = w.abs().amax(-1, keepdim=True).clamp(1e-8)
best = None
for r in [6/7, 0.9, 0.95, 1.0, 1.05, 1.1]: # 6个候选
s = amax * r / 7
q = torch.clamp(torch.round(w / s), -8, 7)
mse = ((w - q * s) ** 2).mean(-1, keepdim=True)
# 保留每个 group MSE 最小的
...
# pack 8×int4 → 1×int32
...
return packed_int32, scale_bf16, shape
完整流程:
FP4 → BF16 (无损) → INT4 g32 (网格搜索).scale 重命名为 compressed-tensors 期望的 .weight_scale)config.json 的 quantization_config同原始模型,详见 DeepSeek License。