跳到正文
vLLM 官方博客· Inferact and Recursive·· 19 小时前精选AI 评分67

vLLM 提供 Recursive Flint 40B MoE 模型的 Day-0 支持

Day-0 Support for Flint on vLLM

AI 导读

vLLM 宣布 Day-0 支持 Recursive 的 Flint 模型,提供内置支持的 Docker 镜像 vllm/vllm-openai:flint,支持正在合并(#62938)。

推荐理由

原文给出 Flint 在 vLLM 上的架构细节、内核优化幅度和单卡部署用法,读者可直接照做并评估性能。

正文 · AI 翻译

vLLM 从第 0 天起就支持 Recursive 的 Flint。其 NVFP4 和 BF16 检查点均可在单块 GPU 上运行,在单块 GB200 上,即使上下文长达 100K token,单个请求的解码速度也约为 500 token/s。

Flint 是一个 40B 参数的 MoE,每个 token 仅激活约 2.5B 参数,大多数层采用滑动窗口注意力,上下文长度为 262K token。它以两个独立的检查点形式发布:NVFP4(量化感知训练)和 BF16。

快速开始

第 0 天的 Docker 镜像 vllm/vllm-openai:flint(x86_64 和 arm64,CUDA 13.0)已内置 Flint 支持:

# NVFP4 checkpoint (GGUF): config and tokenizer come from the BF16 repo
docker run --gpus all --ipc=host -p 8000:8000 \
  -v ~/.cache/huggingface:/root/.cache/huggingface \
  vllm/vllm-openai:flint \
  RecursiveSI/flint-nvfp4-gguf \
  --hf-config-path RecursiveSI/flint --tokenizer RecursiveSI/flint \
  --enable-auto-tool-choice --tool-call-parser glm47 \
  --reasoning-parser glm47 --exclude-tools-when-tool-choice-none
 
# BF16 checkpoint
docker run --gpus all --ipc=host -p 8000:8000 \
  -v ~/.cache/huggingface:/root/.cache/huggingface \
  vllm/vllm-openai:flint \
  RecursiveSI/flint \
  --enable-auto-tool-choice --tool-call-parser glm47 \
  --reasoning-parser glm47 --exclude-tools-when-tool-choice-none

Flint 支持正在合并到 vLLM 中(#62938)。使用包含该支持的 vLLM 构建版本,以相同方式提供服务:

# NVFP4 checkpoint (GGUF): config and tokenizer come from the BF16 repo
vllm serve RecursiveSI/flint-nvfp4-gguf \
  --hf-config-path RecursiveSI/flint --tokenizer RecursiveSI/flint \
  --enable-auto-tool-choice --tool-call-parser glm47 \
  --reasoning-parser glm47 --exclude-tools-when-tool-choice-none
 
# BF16 checkpoint
vllm serve RecursiveSI/flint \
  --enable-auto-tool-choice --tool-call-parser glm47 \
  --reasoning-parser glm47 --exclude-tools-when-tool-choice-none

模型架构

Flint 是一个 49 层的 pre-norm MoE,隐藏层大小为 2048。其独特之处在于,只有很少一部分会关注整个上下文。

图 1:Flint 的层堆栈及其两个子层。金色标记的是与标准 pre-norm MoE 不同的部分。全屏打开。

  • 大部分为局部注意力。35 层使用 RoPE 关注 513 token 的滑动窗口;其余 14 层关注完整上下文,不使用位置编码。只有这 14 层为整个序列保留 KV,因此缓存成本为每 token 28 KiB。
  • 学习到的注意力汇聚点、32 个查询头和 4 个 KV 头的 GQA,以及每头的 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 内核中。每个内核都使用程序化依赖启动,因此它会在前一个内核仍在运行时加载自己的权重。

图 3:低延迟解码路径上一个 MoE 层的七个内核。

NVFP4 解码总共从 4.81 毫秒降至 1.78 毫秒(2.7 倍),BF16 解码从 3.53 毫秒降至 2.34 毫秒(1.5 倍),8K token 的预填充从 207 毫秒降至 145 毫秒(1.4 倍)。现在一次前向传播运行 346 个内核,而不是 1,096 个。在端到端服务中,100K 上下文下的批量 1 解码每 token 耗时 2.06 毫秒(约 485 tokens/s),这包括前向传播加上 LM head 和采样。

使用说明

  • Flint 会输出 GLM-4.7 风格的工具调用和思考块,因此需要 glm47 解析器。当 tool_choice 为 "none" 时,--exclude-tools-when-tool-choice-none 会从提示中移除工具定义,与参考实现一致。
  • 默认采样设置为 temperature 1.0、top-p 0.95 和 top-k 20。推理会计入 max_tokens,因此对于难题至少应预留 32K。
  • Flint 内核面向单块 Blackwell GPU(TP=1,BF16 KV 缓存);其他配置会回退到 vLLM 的标准层。

来源:vLLM 官方博客 · vllm.ai