Rust 从零写的 LLM 推理引擎 Kortex:20GB 显卡跑 70B 模型
开发者发布从零用 Rust 编写的 LLM 推理引擎 Kortex,在 20GB 显存显卡上以约 2 tok/s 速度运…
一位独立开发者发布了名为 Kortex 的 LLM 推理引擎,从零用 Rust 编写,定位是「核心外」(out-of-core)流式推理:在显存不足以放下模型权重时,把 NVMe → 内存 → 显存 → 计算单元视为一条统一的流式管线,让远大于显卡显存的大模型也能跑在消费级硬件上。项目同时公布了与 llama.cpp 在同一台机器、同一份 GGUF 文件下的可复现基准数据。
核心外推理的关键场景
Kortex 的目标是消费级显卡跑不动、又不甘心完全走 CPU 的「中间地带」。作者在 Radeon RX 7900 XT(20GB 显存)+ 32GB 内存 + 两块 NVMe + Windows 11 的机器上做了对照测试,llama.cpp 使用 b9860 Vulkan 后端的官方构建:
- Llama-3.1-8B(Q4_K_M,4.9GB):Kortex 89 tok/s,llama.cpp 109 tok/s,Kortex 启用投机解码后达 101 tok/s,仍略慢。
- Qwen3-30B-A3B MoE(Q4_K_M,17.3GB,显存可全放下):Kortex 解码约 160 tok/s、prefill 401 tok/s,llama.cpp 137 tok/s,Kortex 更快且输出 token 完全一致。
- Llama-3.3-70B(Q4_K_M,42.5GB):Kortex 1.95 tok/s,llama.cpp 0.21 tok/s,差距约 9 倍。
作者坦言,在能完全放进显存的小模型上,llama.cpp 经过多年 kernel 调优仍快约 8%;Kortex 的真正优势在于显存放不下的场景。llama.cpp 的部分卸载方案会把没放进显存的层放到 CPU 计算,受限于 DRAM 带宽(该机器约 12.5 GB/s),70B 模型理论上限就被锁死在 0.5 tok/s 附近;Kortex 则拒绝这种「分裂」,所有计算都留在 GPU,权重通过 PCIe 从内存和两块 NVMe 并行流式喂入,与计算重叠。
架构与实现要点
Kortex 不是 llama.cpp 的封装,GGUF 解析器、分词器、量化 kernel、GPU 后端和流式管线全部是原创代码,llama.cpp 仅作为外部测试 oracle,要求输出 token 完全一致。后端基于 wgpu + WGSL(支持 Vulkan/DX12),不依赖 CUDA、ROCm 或任何厂商 SDK,同时还有一份纯 CPU 参考实现作为正确性校验。
设计上几个关键选择:
- 驻留规划器(residency planner):按张量决定权重放在显存、内存还是 NVMe 上,运行前会打印规划;预算从 Vulkan 设备和操作系统自动探测,也可手动覆盖。
- 流式管线:被流式加载的层在一组显存槽中轮转——GPU 算第 N 层时,第 N+1 层穿过 PCIe,第 N+2 层从磁盘读取;读取使用 Win32 的
FILE_FLAG_NO_BUFFERING非缓冲直读,绕开操作系统页缓存在大工作集下的抖动。开启--mirror时,两块物理盘并发读取,读带宽可翻倍;中转内存通过 Vulkan 原生分配并导入 wgpu,实现 NVMe DMA 零拷贝直写 GPU 可视内存。 - 投机解码:用一个小草稿模型在显存中提议 K 个 token,大模型一次扫一遍权重同时验证 K+1 个位置,每轮搬运的字节不变,有效 tok/s 随接受率成倍提升;greedy 模式下与普通 greedy 解码的输出 token 完全一致,由测试强制保证。
- 端到端量化:权重在 matmul kernel 寄存器内反量化,从不物化到中间内存,每种量化格式对应一个融合的 WGSL kernel。
- MoE 快速路径:专家权重按层组织,batched prefill 走 expert-major,同一专家行被一次读入并服务所有分配到该专家的 token,长上下文走 Flash Decoding。
- GPU 侧贪心链:argmax → 嵌入 → 下一轮预测都在设备上完成,每 8 个 token 才回读一次。
当前能力与限制
目前 Kortex 已能加载 GGUF v2/v3 格式的 Llama 3.x 家族、Qwen3 dense 和 Qwen3 MoE 模型,支持 Q4_K、Q5_K、Q6_K、Q8_0 以及 F16/F32 张量,Q4_K_M 与 Q8_0 文件端到端可用;解码方式覆盖 greedy、带 seed 可复现的 top-k/top-p 采样,以及从 GGUF 读取 chat template 的对话模式(--chat)。显存/内存预算默认自动探测,可通过 --vram-budget-gb 与 --ram-cache-gb 覆盖;投机解码通过 --draft 与 --spec-k 启用。
最大的限制是平台:核心外流式路径完全基于 Win32 的非缓冲直读 I/O,目前只在 Windows 11 上验证过。VRAM 内可放下的路径走可移植的 wgpu(Vulkan/DX12),作者表示移植性较好;直读模块是唯一的 OS 相关部分,Linux 移植已在路线图上,但当下仍是一个 Windows 项目。
基准可复现性
为了避免被质疑「自吹」,作者给出了完整的 llama.cpp 复现命令,例如 8B 与 30B MoE 用 -ngl 99 全量卸载、70B 在 20GB 上最大可放 30 层用 -ngl 30、上下文 2048、温度 0、生成 200/24 个 token。作者明确邀请读者在相近硬件上跑出不同数字时直接提 issue,强调这套对比追求可复现,而不是为了好看。
