
vLLM 支持Recursive 的 Flint,从发布当天起。其 NVFP4 和 BF16 检查点都能在单张 GPU 上运行,单个请求的解码速度约为约 500 tokens/s,在单张 GB200 上,即使上下文达到 100K tokens 也是如此。
Flint 是一个 40B 参数的 MoE,每个 token 仅激活约 2.5B 参数,大多数层采用滑动窗口注意力,上下文长度为 262K tokens。它以两个独立的检查点形式发布:NVFP4(量化感知训练)和 BF16。
快速开始
发布当天的 Docker 镜像vllm/vllm-openai:flint(x86_64 和 arm64,CUDA 13.0)已内置 Flint 支持:
# NVFP4 检查点(GGUF):配置和分词器来自 BF16 仓库
dockerrun--gpusall--ipc=host-p8000:8000\
-v~/.cache/huggingface:/root/.cache/huggingface\
vllm/vllm-openai:flint\
RecursiveSI/flint-nvfp4-gguf\
--hf-config-pathRecursiveSI/flint--tokenizerRecursiveSI/flint\
--enable-auto-tool-choice--tool-call-parserglm47\
--reasoning-parserglm47--exclude-tools-when-tool-choice-none
# BF16 检查点
dockerrun--gpusall--ipc=host-p8000:8000\
-v~/.cache/huggingface:/root/.cache/huggingface\
vllm/vllm-openai:flint\
RecursiveSI/flint\
--enable-auto-tool-choice--tool-call-parserglm47\
--reasoning-parserglm47--exclude-tools-when-tool-choice-noneFlint 支持正在合并进 vLLM(#62938)。使用包含该支持的 vLLM 构建,以相同方式启动服务:
# NVFP4 检查点(GGUF):配置和分词器来自 BF16 仓库
vllmserveRecursiveSI/flint-nvfp4-gguf\
--hf-config-pathRecursiveSI/flint--tokenizerRecursiveSI/flint\
--enable-auto-tool-choice--tool-call-parserglm47\
--reasoning-parserglm47--exclude-tools-when-tool-choice-none
# BF16 检查点
vllmserveRecursiveSI/flint\
--enable-auto-tool-choice--tool-call-parserglm47\
--reasoning-parserglm47--exclude-tools-when-tool-choice-none模型架构
Flint 是一个 49 层的 pre-norm MoE,隐藏层大小为 2048。它的独特之处在于,只有很少一部分会关注完整上下文。
图 1:Flint 的层堆叠及其两个子层。金色标记的是与标准 pre-norm MoE 不同的部分。全屏打开。
- 以局部注意力为主。35 层使用 RoPE 关注 513 tokens 的滑动窗口;其余 14 层关注完整上下文,且不使用位置编码。只有这 14 层会为整个序列保留 KV,因此缓存开销为每 token 28 KiB。
- 学习到的注意力汇点,GQA 使用 32 个查询头和 4 个 KV 头,以及逐头 Q/K RMSNorm。
- 256 个专家,sigmoid top-6,外加一个共享专家。第 0 层和第 1 层则改用稠密 MLP。
NVFP4 检查点是一个 GGUF 文件,其数据块采用 NVIDIA 的 NVFP4 格式,但字节序不同。vLLM 在加载时无损地重新打包,并以仅权重量化(W4A16)方式运行,激活和 KV 缓存使用 BF16,与 Recursive 的参考实现一致。每个 Flint 内核都遵循参考实现的舍入点,并在 GSM8K、GPQA-Diamond、长上下文 MRCR 和一套工具调用测试上与其精度一致。
优化
我们的第一个实现基于 vLLM 的现成层构建,在小批量下很慢:一个解码步骤运行了 1,096 个内核,其中许多是为大得多的批量调优的。我们逐个替换为 Flint 专用内核,每次改动都与参考实现进行核对。
图 2:每次改动后,在单块 GB200 上的模型前向延迟,针对 100K 上下文下的批量 1 解码和 8,192 token 的预填充。可切换检查点,或查看所有形状的表格。全屏打开。
- 融合 Q/K norm、RoPE 和 KV 缓存写入(−8%):一个内核代替三个。
- 小批量 MoE 内核(−27%):路由器和专家 GEMV 只读取所选专家的权重。这也是最大的预填充收益。
- 小批量稠密 GEMV(−25%),使用与大内核相同的打包 NVFP4 权重。
- Norm 和 SiLU 内核(−10%),遵循参考实现的舍入。
- 解码注意力(−5%),带汇点和滑动窗口,使用 CuTe DSL。
- 低延迟解码路径(−14%),如下所示。
对于最多 8 个请求,低延迟路径将每个 MoE 层作为七个内核运行:Q/K norm、RoPE、路由和专家合并被融合到相邻的 GEMV 内核中。每个内核都通过程序化依赖启动(programmatic dependent launch)启动,因此它在前一个内核仍在运行时加载自己的权重。
图 3:低延迟解码路径上一个 MoE 层的七个内核。
总体来看,NVFP4 解码从 4.81 ms 降至 1.78 ms(2.7×),BF16 解码从 3.53 ms 降至 2.34 ms(1.5×),8K token 的预填充从 207 ms 降至 145 ms(1.4×)。一次前向现在运行 346 个 kernel,而不是 1,096 个。端到端服务时,100K 上下文下 batch-1 解码每 token 耗时 2.06 ms(约 485 tokens/s),这包括前向以及 LM head 和采样。
使用说明
- Flint 输出 GLM-4.7 风格的 tool calls 和 thinking blocks,因此
glm47解析器。--exclude-tools-when-tool-choice-none当tool_choice时,从 prompt 中丢弃工具定义"none",与参考实现一致。 - 默认采样设置为 temperature 1.0、top-p 0.95 和 top-k 20。推理内容计入
max_tokens,因此难题至少预留 32K。 - Flint kernel 面向单块 Blackwell GPU(TP=1,BF16 KV cache);其他配置回退到 vLLM 的标准层。