GitHub - coder543/minnow: 快速的 LLaDA2.2 推理服务器

Reddit r/LocalLLaMA 工具

摘要

Minnow 是一个用于 LLaDA2.2 模型的高性能 Rust 推理服务器,提供通过量化、GPU加速的优化推理,以及相比标准 Transformers 实现的显著速度提升。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/09/09 03:23

coder543/minnow

来源: https://github.com/coder543/minnow

minnow

Minnow 是一个基于 Rust 构建的推理服务器,专为 LLaDA2.2-mini 和 LLaDA2.2-flash 模型设计。它支持 OpenAI 聊天补全、流式传输、工具调用、对话前缀缓存、连续批处理,并可选择启用 llama-server 的 Web 界面。

LLaDA 通过优化 32 个 token 的块来生成内容。Minnow 会缓存已确认的块,并在优化过程中仅重新计算当前块。完成的块会以预填充进度、有效 token 速率和优化统计信息的形式流式传输给客户端。

实测性能

DGX Spark (GB10)
LLaDA2.2-mini,单次请求,CUDA 13。Minnow 使用分块 FlashAttention、BF16 密集层和 512 MiB 工作区缓存;上游 Transformers 5.2.0 参考实现使用 BF16 和 SDPA。
速率单位为 token/秒

实现方式 / 专家执行4,096-token 预填充LHC 解码React TypeScript 解码
Transformers BF16 / SDPA5,80812.739.5
Minnow BF1610,00048.8131.6
Minnow INT8 / BF16 激活值9,55273.1232.5
Minnow INT4 / BF16 激活值10,567102.2273.1
Minnow INT4 / INT8 激活值12,919105.6272.0
Minnow NVFP4 / 原生 FP4 tensor cores15,50995.0279.8

这些测试使用相同的提示、贪心设置,并限制输出为 512 个 token。解码统计的是有效文本 token 数量,包含所有优化过程,并在预热后对三次运行取平均值。预填充使用相同的输入 token,不包括加载和词汇表头部。禁用请求间的前缀复用;minnow 仍在每个响应内复用已确认的 K/V。响应和优化次数在不同实现和精度之间有所不同;React 在每一行中都达到了输出上限。这些是吞吐量测量,并非声称答案质量相同。详见 Spark 设置和示例

RTX 3090 (24 GiB)
LLaDA2.2-mini,单次请求,CUDA 13,GPU 功率限制 420 W,BF16 密集层,FlashAttention,512 MiB 工作区缓存。
以下速率单位为 token/秒

专家执行4,096-token 预填充LHC 解码React TypeScript 解码
INT8 / BF16 激活值13,094210667
INT4 / INT8 激活值15,667238697
NVFP4 / BF16 tensor-core 回退11,578133300

预填充对十个样本取平均值,不包括加载和词汇表头部。解码对每个提示的四次预热运行取平均值,使用默认贪心扩散设置和 512 个 token 输出上限;它统计生成的文本 token 数,不包括预填充。不同的量化方式会产生不同的响应和优化次数,因此解码速率取决于提示和数值精度。这里的 INT4 使用了 --int8-expert-activations 参数。详见 RTX 3090 完整测量和验证

BF16 Transformers 参考实现未在此 GPU 上进行基准测试:其权重本身就需要约 30.3 GiB,在考虑激活值或 K/V 之前就已超过 24 GiB 显存。逐层参考检查可以适配,但无法衡量端到端的生成速度。

要求

  • Linux 和 Rust。CPU 构建无需安装 CUDA。
  • GPU 加速需要:Git、CUDA 13 或更高版本(nvcc 需在 PATH 中,或设置 NVCC),以及支持 BF16 的 NVIDIA GPU(Ampere 或更新)。NVFP4 在 SM120/121(RTX Blackwell 或 GB10)上使用原生 FP4 tensor cores,在其他 Ampere 或更新的 GPU 上使用 BF16 tensor-core 回退。
  • 本地模型检查点需位于支持直接 I/O(O_DIRECT)的文件系统上。仅路由专家被量化;注意力、共享专家、嵌入和输出头部保留其源精度。mini 模型近似权重大小:BF16 约 30.3 GiB,INT8 约 16.3 GiB,INT4 约 9.1 GiB,NVFP4 约 9.8 GiB。需为 K/V、激活值和 CUDA 工作区分配额外内存。详见 内存配置

构建和运行

从 Hugging Face 下载 LLaDA2.2-mini (https://huggingface.co/inclusionAI/LLaDA2.2-mini) 或 LLaDA2.2-flash (https://huggingface.co/inclusionAI/LLaDA2.2-flash),包括其配置、分词器和聊天模板。使用 --model 明确传递检查点位置;没有预设的安装目录。

预转换的 BF16、INT8、INT4 和 NVFP4 容器可用于 mini (https://huggingface.co/coder543/LLaDA2.2-mini-minnow) 和 flash (https://huggingface.co/coder543/LLaDA2.2-flash-minnow):

hf download coder543/LLaDA2.2-mini-minnow \
    llada2.2-mini-int4.mnw \
    --local-dir models
cargo build --release --features cuda
# 在终端生成回复。
target/release/minnow --model models/LLaDA2.2-mini \
    generate 'What is the LHC?' --max-tokens 1024
# 启动兼容 OpenAI 的聊天补全 API 服务器。
target/release/minnow --model models/LLaDA2.2-mini serve --listen 127.0.0.1:8080

首次 CUDA 构建会通过 CudaForge 获取固定的 CUTLASS 头文件;后续构建会重用其缓存。第三方通知位于 vendor/flash-attention/。服务和检查点转换不需要 Python。

对于仅 CPU 构建:

cargo build --release
target/release/minnow --model models/mini-int8.mnw --device cpu serve

--device auto(默认)在 CUDA 可用时选择 CUDA,否则选择 CPU。--dtype auto 在 CUDA 上使用 BF16,在 CPU 上使用 FP32。CUDA 构建仍需要其链接的 NVIDIA 库才能启动;在没有这些库的系统上使用 CPU 构建。CPU 执行支持浮点、INT4、INT8 和 NVFP4 检查点,具有相同的 API、缓存和流式传输行为,但比 CUDA 慢得多。量化专家保持压缩状态;CPU 一次展开一个选定的专家进行 GEMM 计算。未量化权重在 CPU 上使用 FP32,因此需为其分配两倍于 BF16 的存储空间,外加专家临时空间、K/V 和激活值。CPU 和 CUDA 结果可能因浮点舍入而有所不同。设置 RAYON_NUM_THREADS 以限制 CPU 并行度。Candle 的 Apple Metal 后端尚未集成到 minnow 中。此构建不支持 AMD/Intel GPU 加速;这些系统可以使用 CPU 路径。

量化

转换产生一个独立的 .mnw 文件,包含权重、分词器、配置和聊天模板。它流式传输源数据,不会将完整模型加载到内存中。不会覆盖现有的目标文件。源文件可以是 safetensors 目录或浮点 .mnw 文件。转换默认使用多达八个 CPU 工作线程,重叠直接读取、专家量化和有序写入。使用 convert --workers N 设置工作线程数(1-64)。内存受每个工作线程的专家临时空间和每个工作线程一个排队结果的限制;大型未量化张量会流式传输。工作线程数不会改变检查点字节数。

# Blackwell:原生 FP4 tensor cores 用于预填充和解码。
target/release/minnow --model models/LLaDA2.2-mini \
    convert models/mini-nvfp4.mnw --experts nvfp4
# Ampere 及更新架构:INT8 权重,BF16 激活值。
target/release/minnow --model models/LLaDA2.2-mini \
    convert models/mini-int8.mnw --experts int8
# 从独立的 BF16 检查点直接量化。
target/release/minnow --model models/llada2.2-mini-bf16.mnw \
    convert models/llada2.2-mini-int4.mnw --experts int4
target/release/minnow --model models/mini-nvfp4.mnw serve

NVFP4 使用 E2M1 权重和激活值,每 16 个值使用 E4M3 缩放因子,以及 FP32 累加。INT4 和 INT8 使用每组 128 个权重并带 FP16 缩放因子,默认解量化到 BF16 tensor-core 寄存器中。所有量化都会改变模型数值精度;吞吐量结果并非答案质量相同的证明。从浮点权重进行转换。--tensor-rules 允许按层或投影混合精度。使用 minnow --model models/mini-int8.mnw validate 可独立于加载来验证检查点校验和。详见 格式和转换

--int8-expert-activations 使具有 INT4/INT8 权重的实例在 SM80 及更新架构上选择 W4A8/W8A8 整数 tensor cores。它动态量化每组激活值,在 INT32 中累加,然后在 FP32 中应用缩放因子。这再次改变了数值精度;它独立于检查点存储,且不会改变默认的 GB10 路径。详见 RTX 3090 测量

INT4、INT8 和 NVFP4 默认使用融合的门控/上采样/SiLU 内核和 GPU 路由处理 32 token 的解码块。--host-routing--unfused-activation 提供了用于比较的路径。分块 FlashAttention 通过将注意力分数保持在芯片上来改进长提示预填充,并且是支持的 CUDA 形状上的默认选项。--materialized-attention 选择之前的注意力路径以进行数值或性能比较。两者之间的浮点舍入不同,可能会改变生成的响应。详见 NVFP4 测量INT8 测量与 CPU 回退

API 和 Web 界面

curl http://127.0.0.1:8080/v1/chat/completions \
    -H 'Content-Type: application/json' \
    -d '{"messages":[{"role":"user","content":"What is the LHC?"}],"max_tokens":1024,"stream":true}'

服务器支持聊天补全和文本补全、函数工具、工具结果历史记录、采样控制、停止字符串、用量统计、/v1/models/health,以及 llama-server 兼容的 /props 和时间元数据。尚不支持 Responses API 和会话恢复。

要使用 llama-server 的 Web 界面,请从你的 llama.cpp 检出构建 UI 并传递其输出目录。Minnow 直接提供这些文件;它不捆绑或复制 UI。UI 是可选的,无需 Docker 或单独的代理。

target/release/minnow --model models/mini-nvfp4.mnw serve \
    --ui-dir ../llama.cpp/build/tools/ui/dist

thresholdediting_thresholdmax_post_steps 可以按请求设置,或通过 serve --threshold--editing-threshold--max-post-steps 设置。默认情况下暴露完整的模型上下文。--max-context--parallel--cache-slots--cache-max-mib 控制请求和缓存容量。在该上下文中,响应没有默认的输出 token 上限。使用 --max-tokens 或请求的 token 限制来设置明确的输出预算。详见 API、缓存和 UI 配置

开发和性能

cargo test --release
cargo test --release --features cuda
cargo test --release --features cuda --lib -- --ignored --test-threads=1
cargo clippy --all-targets --features cuda -- -D warnings

被忽略的测试需要兼容的 CUDA 硬件(SM80 或更新)。测试涵盖模型/参考一致性、缓存提交、解码、容器完整性以及针对独立数值预言机的 CUDA 内核。

逐点、归一化和路由内核默认针对 compute_80MINNOW_CUDA_ARCH 可覆盖其 PTX 目标。分块 FlashAttention 使用 compute_80;Candle 和 cuBLAS 单独构建。原生 NVFP4 构建为一个单独的 compute_120f 模块。其回退和可选的整数内核使用单独的 compute_80 模块,独立于 MINNOW_CUDA_ARCH 进行选择。

相似文章

构建一个媲美 Llama.cpp 的 Rust 推理引擎

Hacker News Top

Ferrox 是一个纯 Rust 推理引擎,可加载 GGUF 模型,并在 CPU、Metal 或 CUDA 上运行本地 LLM,提供 CLI 和兼容 OpenAI 的服务器。它的目标是在不使用任何绑定、从零编写的情况下,达到与 llama.cpp 相当的性能。

当你没有数据中心GPU时

Reddit r/LocalLLaMA

LiquidAI 发布了 LFM2.5-230M,一个 230M 参数的语言模型,专为在有限硬件上运行而设计,支持 transformers、vLLM 和 SGLang。