边缘计算

在 NVIDIA DGX Spark 上提升 MoE 推理的 3 种方法

更快地生成 token 的第一步是确定限制推理性能的因素。在 NVIDIA DGX Spark 上的 Inclusion AI 对 Ling-3.0-flash 进行的 batch-size-1 评估中,分析表明解码受内存限制:读取模型权重会延长执行时间。有两个运算比较突出:混合专家模型 (MoE) 计算和输出层投影,这两个运算可在模型词汇表中生成分数。

这些发现指出了两种提高性能的方法:减少每个解码步骤中的权重流量,以及在每一轮验证中生成更多 token。本文将探讨解决这些成本的三种方法:

  • Humming MXFP4 MoE 内核,以改进路由专家计算的执行。
  • 输出层 (LM head) 的在线 FP8 量化,以减少其权重读取量。
  • 使用 NEXTN 进行多 token 预测 (MTP) 预测解码,同时起草和验证多个token。

本文将解释每次优化的工作原理、衡量其效果,并探讨可能导致组合配置比基准慢的集成问题。Ling Cookbook 中提供了代码和部署说明。

模型和基准配置

该评估使用了 Ling-3.0-flash-fp4,这是一个混合专家模型,每个 token 有 1240 亿个总参数和 51 亿个活动参数。该模型有 42 层:35 个 Kimi Delta Attention (KDA) 线性注意力层和 7 个多头潜在注意力 (MLA) 层。每个 MoE 层将每个 token 分发给 512 个路由专家中的 8 个,以及一名共享专家。

对于智能体工作流,Ling-3.0-flash 提供原生的 256K Token 上下文窗口,可扩展至 100 万 token。与之前的 Ling 闪存模型相比,它提高了长视距任务稳定性、工具调用准确性和线束兼容性。开发者可以为复杂的智能体任务启用推理,也可以将其禁用以进行延迟敏感型交互。改进的空间理解支持构建物理场景网格,并对编码任务中的相对位置进行推理。

该基准遵循官方指南的 W4A8 配置:FlashInfer MXFP4 MoE 内核、NVIDIA CUTLASS 密集 GEMM 和 – enable-fp32-lm-head 选项。LM 头将隐藏维度 2560 投射到包含 157184 个token的词汇表中。

有关标准 MXFP4 部署说明,请遵循 MXFP4 部署 Notebook。

优化 1:Humming MXFP4 MoE 后端

第一种优化将 flashinfer_mxfp4 MoE 执行后端替换为嗡嗡声。Humming 是一个独立的内核库,可通过 humming-kernels pip 包获取。

与 FlashInfer CUTLASS 路径不同,Humming 使用 NVIDIA CUDA 运行时编译 (NVRTC) 在运行时针对实际的 M/ N/ K 维度、数据类型和 GPU 架构生成和编译 CUBIN。它会将编译的二进制文件缓存在~/.humming/cache 中。此内核专门用于 Ling-3.0 – Flash 形状,包括其相对较窄的_ 中间_ 大小为 768。此外,它还能以更精细的粒度进行编译:单个内核可在几秒钟内完成,而 FlashInfer CUTLASS 路径则使用忍者来编译 97 个目标,所需时间大约为几十分钟。性能报告为每输出token (TPOT) 所需的时间,并解码吞吐量 (以每秒token为单位) 。

配置 TPOT 解码吞吐量 相对于基准
基准 27.71 毫秒 36.09 托克/ 秒 —
Humming 的 MoE 后端 25.35 毫秒 39.45 tok/ s +9.3%
表 1. Humming MoE 后端对 NVIDIA DGX Spark 上 Ling-3.0 闪存推理的影响,使用具有 32K 输入token、2K 输出token和批量大小 1 的合成工作负载

优化 2:在线 FP8 LM 头部量化

在检查点中,LM 头存储在 BF16 中,并在 modules_to_not_convert 中列出,因此在加载期间不会进行量化。其词汇表 GEMM 为 157184 × 2560,并且必须为每个生成的 token 读取整个权重块。因此,在带宽瓶颈下,它是压缩的高价值目标。

优化仅在构建 LM 头时应用动态 FP8 量化配置。模型的其余部分继续加载检查点的 FP8/ MXFP4 配置。将 LM-head 权重从 BF16 移动到 FP8 可将此层的读取量减半。此配置通过 SGLANG_ENABLE_FP8_LM_HEAD = 1 启用。

此设置与 baseline – enable-fp32-lm-head 选项互斥,后者以 FP32 格式输出 logits,并使用较慢的词汇表 – GEMM 路径。

配置 TPOT 解码吞吐量 相对于基准
基准 27.71 毫秒 36.09 托克/ 秒 —
Humming 的 MoE 后端 25.35 毫秒 39.45 tok/ s +9.3%
* 在线 FP8 LM head 22.76 毫秒 43.94 tok/ s +21.7%
表 2. Humming 和在线 FP8 LM head 量化对 NVIDIA DGX Spark 的累积影响,使用具有 32K 输入token、2K 输出token和批量大小 1 的合成工作负载。与仅使用 Humming 相比,添加 FP8 可将解码吞吐量提高 11.4%

优化 3:使用 NEXTN 进行 MTP 预测解码

前两项优化可降低每个解码步骤的成本。预测解码遵循不同的路径:它减少了解码步骤的数量。

Ling-3.0-flash 包含一个 NEXTN 预测层 (num_nextn_predict_layers:1) ,可直接用作草稿模型,无需额外训练或下载。该配置使用三个草稿步骤和一个四token验证窗口。在每一轮中,草稿按顺序预测三个token,目标一次验证四个位置,接受正确的前缀。

收益取决于两个数量:接受长度,每轮接受的 token 的平均数量,以及验证成本比率,即一个验证步骤相对于正常解码步骤的成本。所测量的比率约为 2.26。验证成本的主要来源不是注意力计算;在批量大小为 1 时,KV 读取相对于权重读取而言较小。相反,成本来自激活 MoE 专家:正常解码为一个 token 激活 8 个专家,而验证则处理 4 个 token,最多激活 32 个专家。

注意:

当同时启用在线 FP8 LM-head 量化和 MTP 时,草稿模型必须与目标共享整个 LM-head 模块,而不仅仅是其权重张量。最初的 Ling NEXTN 实现并未公开此接口。如果没有它,框架会悄无声息地回落:草稿接收 FP8 权重,但将其解释为 BF16,接受长度下降到 1.00,吞吐量低于未优化的配置。通过此接口共享完整的 LM-head 模块可恢复正常的 token 接受度。按照 Ling 指南,同时启用 FP8 LM-head 量化和 MTP。

配置 TPOT 解码吞吐量 相对于基准
基准 27.71 毫秒 36.09 托克/ 秒 —
Humming 的 MoE 后端 25.35 毫秒 39.45 tok/ s +9.3%
* 在线 FP8 LM 头 22.76 毫秒 43.94 tok/ s +21.7%
MTP ( NEXTN,steps = 3/ topk = 1/ draft_tokens = 4) 9.72 毫秒 102.88 tok/ s +185.1%
表 3. 三种优化对 NVIDIA DGX Spark 的累积影响,使用具有 32K 个输入token、2K 个输出token和批量大小 1 的合成工作负载。MTP 接受长度达到每轮 3.90 个 token;这些合成结果无法在其他工作负载上获得收益

GSM8K 上的端到端结果

上述组件级结果使用合成的 32K 输入/ 2K 输出工作负载。合成工作负载有助于隔离个人收益,但其重复输出和简单采样系统地过高估了预测解码的好处。评估还包括对所有 1319 GSM8K 问题进行严格的端到端比较。

该评估使用了五步提示词,其中包括训练集和完整测试集的演示,用于评估温度 0.6、top_p 0.95、top_k 29、max_tokens 22768,并启用了思维链。除了这三种优化之外,两种评估都对齐了所有变量:采样参数、解析器、五步协议、随机种子和内存分配。第一个token生成时间 (TTFT) 用于测量第一个输出token之前的延迟。

指标 基准 三种优化 差异
MoE 后端 flashinfer_mxfp4 嗡嗡作响
LM 头 FP32 在线 FP8
预测解码 无 MTP3
TPOT 26.45 毫秒 18.56 毫秒 增加 29.8%
解码吞吐量 37.81 tok/ s 53.89 tok/ s +42.5%
GSM8K 精度 96.89% 96.82% + 0.08 分
MTP 接受长度 — 2.68
平均延迟 15.21 秒 11.49 秒 增加 24.5%
延迟 P50/ P95 8.36/ 50.20 秒 6.11/ 38.60 秒 + 27 ℃/+ 23 ℃
平均 TTFT 0.207 秒 0.214 秒
请求错误/ 截断 0 / 0 0 / 0
表 4. 基于 NVIDIA DGX Spark 对批量大小为 1 的所有 1319 GSM8K 测试问题进行基准和优化的 Ling-3.0 闪存推理。对于基准和优化运行,平均输出长度分别为 567 和 607 个token;中值输出长度约为 310 个token,P95 输出长度范围约为 1900 至 2060 个token

合成工作负载和真实工作负载为何不同

  • 合成输出的重复性更高,因此草稿预测更容易被接受。合成工作负载的接收长度为 3.90,而 GSM8K 的接收长度为 2.68。
  • 采样参数各不相同。合成测试使用贪婪解码,而实际评估使用温度 = 0.6、top_p = 0.95 和 top_k = 29。
  • 输出长度分布各不相同。合成工作负载将输出固定为 2K token,而 GSM8K 的中值输出约为 310 token。这会将前两次优化的固定开销减少幅度分散到更短的输出上。

在 DGX Spark 上评估这些优化时,请使用反映预期部署的工作负载。在合成测试中测得的吞吐量增益为 185.1%,但这并不能为其他工作负载建立增益。

总结

在完整的 GSM8K 评估中,三项优化将解码吞吐量提高了 42.5%,将端到端平均延迟降低了 24.5%,并且未产生任何统计上可检测到的准确性变化。它们的机制并不重叠:嗡嗡声和 FP8 LM 头降低了每个步骤的成本,而 MTP 减少了步骤数,因此可以组合使用这些技术。

然而,堆叠并不是自动的。每个优化都是独立工作的,但启用这三个优化需要草稿模型共享完整的 LM-head 模块。否则,系统会悄无声息地降级为比未优化的基准慢的配置。在部署期间,验证每次优化在启动时是否处于活动状态;这比根据后续性能数据推断配置状态更可靠。

标签