--- base_model: zai-org/GLM-5.3 base_model_relation: quantized language: - zh - en library_name: vllm license: mit pipeline_tag: text-generation tags: - glm - glm_moe_dsa - mixture-of-experts - w4a8 - int4 - fp8 - quantized - reasoning - vllm - sglang - hopper --- # GLM-5.3-W4A8 GLM-5.3 的 Hopper 原生 W4A8 量化版。路由专家为 INT4(group size 128),激活与非专家层保持 FP8。在 8×H20 上由 CUTLASS W4A8 grouped GEMM 直接推理,无需反量化到 BF16。**同一份权重 vLLM 与 SGLang 都能加载**,不必下载两套。 它的两个关键价值: - **权重减半,KV cache 翻倍。** 检查点从 704 GB 压到 372 GB。8×H20(约 1128 GB)上,KV cache 从 60.8 万 token 提到 125.7 万 token(+107%)。 - **精度无可测量损失。** GPQA-Diamond 与 teacher-forced NLL 均落在官方 FP8 发布版的采样噪声内;MTP 投机解码开箱即用。 > [!NOTE] > 本模型保留了 GLM-5.3 完整的约 753B 参数。侧边栏若显示约 370B,是计数假象:每个 int32 存储槽里塞了 8 个 4-bit 权重,元数据统计的是存储槽数量,而非参数量。 **已在 8×H20-3e 上于两个引擎完整验证**:vLLM nightly(`0.26.1rc1.dev229+g124154a88`)与 SGLang dev(`0.0.0.dev1+gbb5e61986`)。SGLang 请用 `lmsysorg/sglang:dev`,v0.5.16 未通过验证。 存储格式是 compressed-tensors:路由专家 `pack-quantized` INT4,非专家层 `float-quantized` FP8 128×128 block。这**不是** SGLang 原生的 `w4afp8` 打包,两边分别走 vLLM 的 `CompressedTensorsW4A8Fp8MoEMethod` 和 SGLang 的 `CompressedTensorsW4AFP8MoE`,底层都是 SM90 专用的 CUTLASS W4A8 kernel。vLLM 可直接拉起;SGLang 需要多一个 `PYTHONPATH`,见「部署 / SGLang」。 ## 与其他 4-bit 版本的差异 | 项目 | 本仓库(skyai/GLM-5.3-W4A8) | 官方 FP8 | PhalaCloud/GLM-5.3-W4AFP8 | |---|---|---|---| | 体积 | **372.3 GiB** | 703.7 GiB | 372.3 GiB | | 专家权重 | INT4 group-128(RTN + 逐组 MSE 裁剪搜索) | FP8 block 128×128 | INT4 group-128(AWQ 校准) | | 量化来源 | 由官方 FP8 发布版反量化后再量化 | 官方发布 | 由 BF16 母版量化 | | 非专家层 | FP8 block(逐字节未改) | FP8 block | FP8 block | | 激活 | FP8 per-token 动态 | FP8 动态 | FP8 动态 | | 格式 | compressed-tensors(专家 pack-quantized,非专家 float-quantized) | fp8 | w4afp8(SGLang 原生) | | 推理引擎 | **vLLM / SGLang** | vLLM / SGLang | SGLang | 从 FP8 二次量化会多一层误差,但实测 NLL 只差 +0.001 nats/token。换来的是 vLLM 现成可部署、无需等上游 `w4afp8` PR,同时 SGLang 也能用同一份权重。 ## 精度评测 在 8×H20 上用 vLLM 实测(TP8,`--kv-cache-dtype fp8_ds_mla`,temperature 1.0、top_p 0.95,thinking 默认开启)。官方 FP8 与本仓库用**完全相同**的提示、选项打乱顺序和采样协议。PhalaCloud 一列为该仓库模型卡公布值(SGLang,协议不同,不能直接做减法)。 | 基准 | GLM-5.3(FP8,本地) | GLM-5.3-W4A8(本地) | PhalaCloud W4AFP8(公布值) | |---|---|---|---| | GPQA-Diamond pass@1(198 题 × 4 采样) | 89.65% | **90.28%**(+0.63pp) | 91.92%(182/198) | | GPQA-Diamond majority@4 | 90.91% | 90.91% | — | | Teacher-forced NLL(64×2048 token 留出文本) | 0.8929 nats | 0.8940 nats(+0.001) | 相对 BF16 +0.282 nats | | 困惑度 PPL | 2.442 | 2.445 | — | | AA-LCR | — | — | 73.0 | | BFCL(45 项 live 子集) | — | — | 82.2 | | NIAH @ ~93 万 token | KV 只有 60.8 万,装不下 | 理论上可测(KV 125.7 万) | 3/3 | GPQA 答案解析失败均为 0。W4A8 的 pass@1 略高于 FP8,差值约等于 5 个样本,处于 792 次采样的噪声范围内;majority@4 完全一致。NLL 窗口间标准误约 0.074,+0.001 远小于噪声。 PhalaCloud 的 GPQA 高约 1.6 个百分点,主要来自 AWQ 校准、从 BF16 母版量化(避免二次量化),以及不同引擎/截断重试协议。 ## 性能(8×H20-3e,单节点) MoE 后端:vLLM auto 选中 CUTLASS W4A8。注意力:`--kv-cache-dtype fp8_ds_mla` 切到 FLASHMLA_SPARSE。W4A8 必须开 `--enable-expert-parallel`;FP8 不开 EP 更快。 离线批处理(无速率控制,`max_model_len=16384`)。prefill 行是输入吞吐;decode 行是输出 token / 含首次 prefill 的总墙钟时间。 | 配置 | 权重显存/卡 | KV 容量 | prefill 8 并发 × 8K 入 | decode 128 并发 × 128 入 → 256 出 | decode 256 并发 × 128 入 → 256 出 | |---|---|---|---|---|---| | FP8 TP8 | ~88 GiB | 608,128 | **3675** tok/s | 1686 tok/s | 2094 tok/s | | W4A8 TP8 + EP | 52.6 GiB | **1,257,280** | 3441 tok/s | 1617 tok/s | 1779 tok/s | | **W4A8 2×(TP4+EP)** | 93 GiB | 638,336 | **5993** tok/s | **2256** tok/s | **3249** tok/s | 单实例 TP8 下,W4A8 不比 FP8 快(prefill 0.94x,decode 0.85–0.96x):H20 带宽富余,CUTLASS 反量化开销吃掉了带宽收益。真正的价值是: 1. **KV cache 2.07 倍**,同样 8 卡能撑更长上下文、更高并发。 2. **能跑 TP4 双副本**。372 GiB / 4 = 每卡 93 GiB,塞得进 141 GiB;FP8 的 704 GiB / 4 = 176 GiB,物理上放不下。双副本聚合吞吐相对 FP8 TP8:prefill **1.63x**、decode 128 并发 **1.34x**、256 并发 **1.55x**。 ## MTP / 投机解码 vLLM 通过 `glm_moe_dsa → deepseek_mtp → DeepSeekMTPModel` 加载第 78 层草稿头。测试:512 token 输入 / 256 token 输出,`num_speculative_tokens=1`。 | 检查点 | 并发 1 | 并发 4 | 并发 16 | 并发 64 | |---|---|---|---|---| | FP8 无 MTP → 开 MTP | 86 → 149 tok/s(**1.72x**) | 265 → 350(1.32x) | 551 → 695(1.26x) | 1105 → 1306(1.18x) | | W4A8 无 MTP → 开 MTP | 66 → 104 tok/s(**1.56x**) | 196 → 282(1.44x) | 480 → 572(1.19x) | 963 → 1190(1.24x) | 量化没有破坏 MTP。PhalaCloud 公布的 EAGLE steps=3 接受长度约 2.93,与此处 `num_speculative_tokens=1` 口径不同。 ## 部署 环境要求:**Hopper GPU(H20 / H100 / H200,算力恰好 SM90)**。Ada(SM89)与 Blackwell(SM100 / SM120)都不支持,原因见「局限性」。引擎二选一: - **vLLM nightly**(建议 0.26.1rc1 及更新;v0.26.0 正式版不一定齐 GLM-5.3 DSA + SM90 W4A8)。下面 vLLM 的例子开箱即用。 - **SGLang dev**(`lmsysorg/sglang:dev`,验证于 `0.0.0.dev1+gbb5e61986`)。需要多加一个 `PYTHONPATH`,见本节末尾。发布版 v0.5.16 未在本仓库上验证通过,请用 dev 镜像。 以下性能数字均来自 vLLM。 ### 追求吞吐:两副本 × TP4(推荐) ```bash M=skyai/GLM-5.3-W4A8 for i in 0 1; do [ $i -eq 0 ] && D='"device=0,1,2,3"' PORT=8000 || D='"device=4,5,6,7"' PORT=8001 eval docker run -d --name glm53-r$i --gpus "$D" --ipc=host --shm-size=32g \ -p $PORT:8000 \ vllm/vllm-openai:nightly \ --model $M --served-model-name GLM-5.3 \ --tensor-parallel-size 4 --enable-expert-parallel \ --kv-cache-dtype fp8_ds_mla \ --gpu-memory-utilization 0.92 --max-model-len 65536 --trust-remote-code done ``` ### 追求长上下文:单实例 TP8 ```bash docker run -d --name glm53 --gpus all --ipc=host --shm-size=32g \ -p 8000:8000 \ vllm/vllm-openai:nightly \ --model skyai/GLM-5.3-W4A8 \ --tensor-parallel-size 8 --enable-expert-parallel \ --kv-cache-dtype fp8_ds_mla \ --gpu-memory-utilization 0.90 --max-model-len 262144 --trust-remote-code ``` 开启 MTP 投机解码时加上: ```bash --speculative-config '{"method":"mtp","num_speculative_tokens":1}' ``` 服务端暴露标准 OpenAI 兼容 API。采样默认值在 `generation_config.json`:temperature 1.0、top_p 0.95。思考模式由 chat template 默认开启(``)。 **不要**指定 `--moe-backend marlin` 或 `triton`:W4A8 在 SM90 上只有 CUTLASS 一条路,auto 会选中它。**必须**加 `--enable-expert-parallel`,否则每卡 256 专家 × 中间维 256,CUTLASS grouped GEMM 会明显变慢。 ### SGLang 同一份权重也能在 SGLang 上跑,只需把仓库目录加进 `PYTHONPATH`。**请用 `lmsysorg/sglang:dev`**,发布版 v0.5.16 未在本仓库上验证通过: ```bash M=/path/to/GLM-5.3-W4A8 docker run -d --name glm53-sgl --gpus all --ipc=host --shm-size=32g \ -p 30000:30000 -v $M:$M \ -e PYTHONPATH=$M \ lmsysorg/sglang:dev \ python3 -m sglang.launch_server --model-path $M \ --tp 8 --trust-remote-code --mem-fraction-static 0.85 \ --reasoning-parser glm45 --tool-call-parser glm45 \ --host 0.0.0.0 --port 30000 ``` `PYTHONPATH` 让 Python 在每个 worker 进程自动加载仓库里的 `sitecustomize.py`。它在读取检查点时,把非专家层 FP8 scale 的名字从 `weight_scale` 改成 `weight_scale_inv`:SGLang 的 `Fp8LinearMethod` 和 DSA indexer 融合都硬编码了后者,vLLM 要的却是前者。两个名字**不能同时存在于磁盘**——两个引擎遇到没有对应参数的 tensor 都会直接 `KeyError`,所以只能在读取时改名。权重本身仍然只有一份,一个字节都没有为此改动。 vLLM 不需要、也不会加载这个文件。在 `sglang:dev` 上实测:TP8 下 48.2 GiB/卡,`max_total_num_tokens=803264`。 想彻底去掉这一步,需要 SGLang 上游修三处硬编码(截至 dev `gbb5e61986` 均未修): | 位置 | 问题 | |---|---| | `compressed_tensors_w4a8_fp8_moe.py` | MoE 从 `target_scheme_map["Linear"]` 取 `num_bits`,要求它是 INT4 | | `compressed_tensors.py` 的 `weight_block_size` | 从**同一个** key 取 `block_structure`,要求它是 FP8 block | | `deepseek_weight_loader.py` | DSA indexer 融合写死 `.weight_scale_inv` | 前两条互相矛盾,而 `compressed_tensors` 的 schema 禁止 `block_structure` 与 group 策略共存,因此不存在能同时满足二者的合法 config。 ### 采样默认值 与基座模型一致:temperature 1.0、top_p 0.95。不做 top-p 截断时,thinking 模式可能偶发重复循环。 ## 量化方式 - **路由专家**(约 734B 参数,占整模型 96%):FP8 block 反量化到 float32 后,做对称 INT4、group size 128。每个 group 在 11 个收缩比例(1.00 → 0.70)上搜 MSE 最优 scale,再按 compressed-tensors `pack-quantized` 打成 uint4b8 / int32。实测相对 L2 误差约 0.103,优于朴素 RTN(0.124)和 MXFP4 group-32(0.113)。 - **注意力 / 共享专家 / dense MLP / DSA indexer**:保持官方 FP8 128×128 block,**逐字节未改**,只把 scale 张量名从官方的 `weight_scale_inv` 改成 compressed-tensors 的 `weight_scale`。SGLang 期望的仍是前者,因此仓库附带 `sitecustomize.py` 在读取时改回去。 - **embedding、lm_head、router、各种 norm**:保持 BF16。 - 激活在运行时做 FP8 per-token 动态量化,与官方 FP8 路径一致。 Hopper 上没有 FP4 张量核,MXFP4 只能走 Marlin W4A16(算力腰斩)。本仓库因此选择 INT4-W4A8:权重 4-bit 存储,kernel 内反量化成 FP8 再走 wgmma,峰值仍是 296 TFLOPS。 ## 局限性 - **只支持 Hopper(SM90)**,即 H100 / H200 / H20。这不是保守估计:vLLM 选择 W4A8 CUTLASS 路径的判据是 `_check_scheme_supported(90, match_exact=True)`,要求算力**恰好等于 9.0**,而非「9.0 及以上」。因此 Ada(SM89,L40S / L4 / 4090)、**Blackwell(SM100,B200 / GB200)**、RTX 5090 / Pro 6000(SM120)**都不支持**——后两者比 Hopper 更新也没用。Blackwell 上应该用 NVFP4,它有原生 FP4 张量核。 - 在非 SM90 卡上**不会得到干净的报错**。vLLM 的 `_is_dynamic_token_w4a8_int` 只比较 `num_bits`、不检查激活类型,本仓库的配置会误命中它并转去 `CompressedTensorsW4A8Int8MoEMethod`;那条路期望 int4-as-int8 的未打包 `torch.int8` 权重,而本仓库是 `pack-quantized` int32,会在加载权重时以形状 / dtype 错误失败。SGLang 更松:它的 MoE 路径完全不校验算力,会直接调用只存在于 SM90 的 CUTLASS kernel,在运行时失败。 - 格式是 compressed-tensors,不是 SGLang 的 `--quantization w4afp8`。vLLM 可直接加载;SGLang 能加载但要靠 `PYTHONPATH` 引入仓库附带的 `sitecustomize.py`,且必须用 `lmsysorg/sglang:dev`(发布版 v0.5.16 未通过验证),见「部署 / SGLang」。 - 精度与性能数字均在 vLLM 上测得。SGLang 侧只做了加载与生成的正确性验证,未做基准评测;两引擎 kernel 实现不同,数字不能直接套用。 - 由官方 FP8 二次量化,理论上略逊于从 BF16 + AWQ 的路径;本地 GPQA / NLL 显示差距在噪声内。 - TP 切分要求:`moe_intermediate_size` 按 TP 切开后必须能被 256 整除。TP8 下 2048/8=256,可以;TP16 会变成 128,不行。 - 继承基座模型 GLM-5.3 的能力与局限。 ## 许可证 MIT,继承自 [GLM-5.3](https://huggingface.co/zai-org/GLM-5.3)。请引用原始 GLM-5.3 工作。 --- # 原始模型卡(官方) > 以下内容摘自基座模型官方仓库,未作改动。完整原文见 [zai-org/GLM-5.3](https://huggingface.co/zai-org/GLM-5.3)。 ## 简介 GLM-5.3 与 GLM-5.2 共用同一基座,所有提升来自后训练。相比 GLM-5.2,它在复杂编码与长周期任务上明显更强: - **更强的编码**:开源权重里最强的编码模型,内部 Z.ai Code Bench 比 GLM-5.2 提升 50%;Terminal Bench 3.0 与 Agents' Last Exam 上达到开源 SOTA。 - **涌现的安全研究能力**:后训练放大后,安全研究相关能力提升快于预期。 官方公布参考值(模型卡):HLE 62.5(带工具)、Deep-SWE 66.9、Terminal-Bench 2.1 88.2、Terminal-Bench 3.0 28.3。