Janas 引擎让 32GB 笔记本跑 48GB MoE 模型,37 tok/s 超越 llama.cpp

C语言推理引擎Janas用O_DIRECT流式读取专家权重,让32GB笔记本以37 tok/s运行48GB MoE模型。
Janas 是一个用 C 语言编写的语言模型推理引擎,声称能在 32GB 内存笔记本上以 37 tok/s 运行 48.4GB 的 Qwen3-Next-80B,而 llama.cpp 仅 2.8 tok/s。其核心思路是绕开操作系统页缓存,用 O_DIRECT 从 NVMe SSD 直接流式读取 MoE 专家权重,避免缺页风暴;同时通过热专家内存缓存、GPU 辅助 prompt 处理和投机解码进一步提升速度。作者自测 13 个模型全面超过 llama.cpp,但其数据均为单机自测、未经独立验证。项目仍是实验性质,命令行接口频繁变动,仅支持作者的模型目录,AMD、独显和慢速磁盘完全未测试。文章建议:模型能放进内存就用 llama.cpp,超过内存且有高速 NVMe 时 Janas 才有意义。
本地大模型玩家最熟悉的场景莫过于此:好不容易找到心仪的 MoE 模型,一看文件 48GB,再看看自己的 32GB 内存,默默关掉标签页。就算硬着头皮加载,换来的也只是每秒 3 个 token 的龟速和硬盘灯长亮。
本周登上 Hacker News 首页的 Janas 项目声称打破这堵墙。这是一个用 C 语言编写的语言模型推理引擎,作者 Maurizio Cammalleri 给出的核心数据相当抓眼球:在 32GB 内存的笔记本上运行 48.4GB 的 Qwen3-Next-80B,达到 37 tok/s。同一台机器、同一个模型跑 llama.cpp 只有 2.8 tok/s。
需要先说明:所有数据均来自项目公开的基准测试、README 和 Hacker News 讨论帖。作者自己的测量而非独立第三方验证,请带着这个前提阅读。

为什么超过内存的模型会卡成幻灯片
一个自然的疑问是:操作系统不是自带内存映射机制吗?模型文件放在 SSD 上,系统可以按需分页加载,llama.cpp 就是这么用 mmap 干的。
问题出在工作集超过物理内存之后。内存映射文件并不知道模型的哪些部分重要,每次缺页都要走内核的页缓存流程。当内存耗尽,内核开始驱逐你马上要用的页面。研究者把这种现象称为"缺页风暴":模型大小达到内存的两倍左右时,mmap 方案就会崩溃,操作系统在盲目地调度页面,推理则卡在磁盘 I/O 上动弹不得。
MoE 架构从另一个角度放大了这个问题,同时也暗示了解法。一个 MoE 模型包含多个独立的"专家"前馈网络块,每生成一个 token 只路由到其中少数几个专家,通常是 256 个中的 8 个。绝大部分参数在任意时刻都处于闲置状态。真正的瓶颈是:如何每个 token 都快速读取到正确的那部分参数。
页缓存(Page Cache) 是操作系统用空闲物理内存缓存磁盘文件内容的机制。程序读取文件时,内核先把数据读入页缓存,再从缓存复制给程序,下次读同一文件可直接命中缓存,无需磁盘 I/O。这在内存充裕时能极大提升性能,但缓存是"机会主义"的:一旦其他进程需要物理内存,内核就会驱逐页缓存中的页面。对于超过物理内存的大模型,页缓存几乎永远命中不了——刚读进来的权重页面随即被驱逐,程序再次访问时又触发磁盘读取,反复颠簸。
O_DIRECT 是 Linux 提供的一个文件打开标志,它告诉内核绕过页缓存,直接把数据从磁盘传输到用户空间缓冲区。这牺牲了缓存的加速作用,但换来了两点关键好处:一是内存使用完全由程序自己掌控,内核不会因为页缓存争抢而盲目驱逐有用的页面;二是避免了"数据先拷进页缓存、再拷给程序"的双重拷贝开销。Janas 正是用 O_DIRECT 按需读取专家权重,让内存只保留自己主动缓存的热专家,从而避免系统层面的缺页风暴。代价是每次读取都必须对齐到块大小,且完全依赖 SSD 的随机读取性能。
Janas 的核心设计思路
Janas 的设计之所以相对可信,是因为它的原理本身足够简洁:
权重留在磁盘上。 引擎从不加载整个模型。它把转换后的 .jns 文件放在 NVMe SSD 上,用 O_DIRECT 读取专家权重,完全绕过页缓存,操作系统不会发生颠簸。
热专家进内存缓存。 运行过程中引擎会追踪哪些专家被反复调用,将高频专家保留在内存缓存中。启动时探测本机硬件,据此自动决定缓存大小和线程数。
GPU 只处理 prompt,不碰整个模型。 在集成 GPU 的机器上,Janas 用 GPU 做 prompt 处理(并行度最受益的环节),token 生成阶段则从 SSD 流式读取专家权重。可以用 JANAS_GPU=0 强制纯 CPU 模式。
草稿 token 隐藏延迟。 引擎支持投机解码:小型草稿模型猜出接下来几个 token,大模型一次验证。在 Qwen3-Next-80B 上,这让写入速度从 24 提升到 37 tok/s,文本内容完全一致,只是生成得更快。
在作者的测试机上(Debian 13,Intel Core Ultra 9 185H,32GB DDR5,1TB NVMe 读取约 5.7 GB/s),Qwen3-Next-80B 读取 1024 token 的 prompt 速度为 62 tok/s,不开启草稿时写入 24 tok/s。同为 48.4GB 的 Qwen3-Coder-Next 则为读取 66、写入 22。
投机解码(Speculative Decoding) 是一种在不改变输出分布的前提下加速大模型生成的技术。其原理是:用一个体积小得多的"草稿模型"快速生成接下来若干 token 的候选序列,再让大模型一次性并行验证这些候选 token 是否与它自己会生成的 token 一致。因为大模型验证一批 token 只需一次前向传播,而正常生成同样多的 token 需要多次前向传播,所以当草稿命中率高时,就能显著减少大模型的调用次数。
关键在于,验证过程在数学上保证了最终输出与大模型单独生成完全一致——被拒绝的候选 token 会被丢弃并从拒绝位置重新采样。因此投机解码是"无损"加速,只影响速度不影响质量。在 Janas 场景中,大模型的瓶颈是每个 token 都要从 SSD 流式读取专家权重,投机解码让一次读取能验证多个 token,直接降低了每 token 的磁盘 I/O 开销,这正是文中写入速度从 24 提升到 37 tok/s 而文本内容不变的原因。
逐模型的基准测试对比
作者声称 Janas 在全部 13 个对比模型上都超过了 llama.cpp,测试条件相同笔记本、Q4_K_M 量化。这些是作者自测数据,参考时需打折扣。
超出内存的大模型是最有说服力的场景。Qwen3-Next-80B-A3B(48.4GB,大于物理内存)在 Janas 上读取 62 tok/s、写入 24 tok/s,llama.cpp 分别为 16 和 2.8,写入速度差距约 8.5 倍。Qwen3-Coder-Next(48.4GB)写入 22 vs 2.2。
能放进内存的模型上差距缩小但仍然存在。Qwen3.6-35B-A3B(22.3GB)读取 104 vs 79,写入 19 vs 12;Qwen3-30B-A3B(18.6GB)写入 32 vs 15;Gemma-4-26B-A4B-it(18.3GB)写入 18 vs 12。即使小到 Qwen3-0.6B,Janas 读取也有 939 tok/s vs 670。
一个值得注意的细节:对于超大模型,llama.cpp 不是简单地变慢,而是直接崩溃了。标准构建一旦启用 GPU 就内存溢出,因为其 CPU 后端会复制权重做重排,Vulkan 后端也会把 CPU 侧的权重复制到系统无法回收的缓冲区。那个 2.8 tok/s 的数据需要特殊编译版本加额外参数才能跑出来。Janas 运行同一个模型不需要任何特殊配置。
Hacker News 上的质疑者提出了一个合理观点:llama.cpp 多年来一直支持基于 mmap 的磁盘流式加载,Strata 和 flash-moe 等项目也在做类似的事。如果这些数据在其他机器上站得住脚,Janas 的差异在于它主动探测硬件并管理哪些专家驻留内存,而非把页面调入决策交给内核。作者也明确表示未测试硬件上的表现未知,janas-bench 报告正是为了回答这个问题而设计的。
Q4_K_M 是 llama.cpp 社区广泛使用的量化格式名称。GGUF 模型文件支持多种量化等级,字母"Q"代表量化(Quantization),数字"4"表示权重被压缩到约 4 比特。后缀 "K" 指采用 k-quant 混合量化方案——对模型不同层或不同张量使用不同的量化精度,以在压缩率和精度之间取得更好平衡;"M" 则是该方案下的中等档位(Medium)。Q4_K_M 因在 4 比特量化的体积优势与接近原始模型的输出质量之间取得较好折中,成为本地部署 MoE 模型的默认选择。
理解这一点对看待文中的对比很重要:Janas 与 llama.cpp 的基准测试都基于 Q4_K_M,意味着两者的模型文件体积和数值精度相同,差异只来自推理引擎的调度策略而非量化本身。此外,量化后的权重在磁盘上以块为单位存储,这也解释了为什么 O_DIRECT 读取和专家缓存管理对性能影响如此之大——引擎需要高效地把这些压缩块从 SSD 搬运到内存并解压使用。
上手指南与注意事项
Linux x86-64 机器(Ubuntu 22.04、Debian 12 及以上)上从 README 快速安装:
curl -LO https://github.com/prabanta-dev/janas/releases/latest/download/janas-linux-x86_64.tar.gz
tar xf janas-linux-x86_64.tar.gz && cd janas
./janas-chat
从目录中选择模型,下载并校验后即可使用。Windows 10(1903+)和 11 有 zip 版本,作者报告 Windows 11 上写入速度与 Linux 持平,稠密模型读取 prompt 快 1.8 倍(整块通过 Intel 驱动发送到 GPU)。
几个实用参数:--cache <GiB> 给 Janas 的内存占用设硬上限,默认它会用空闲内存填满专家缓存;JANAS_GPU=0 完全禁用 GPU(README 坦诚提到 GPU 路径曾导致驱动重置,桌面直接崩溃);janas-bench 测量你的机器并生成报告,这是目前对项目最有价值的反馈形式。首次测试建议关掉浏览器——开着浏览器和编辑器时,同一模型大约保持四分之三的速度,但磁盘等待时间翻了五倍。
必须正视的限制
这个项目本质上是一个实验,不是产品。命令行接口每周可能改动数次,只有 .jns 模型文件格式承诺稳定。所有开发和测试都在单台 Intel 笔记本加集成 Arc GPU 上完成,AMD CPU、独立显卡和较慢的磁盘完全是未测试领域。全内存缓存加全速 O_DIRECT 读取对机器压力很大,没有余量的系统可能被推入 swap。
模型可用性是更实际的约束。你需要转换好的 .jns 文件,目前只有作者在 Hugging Face 上的 Qwen 和 Gemma 目录,或者自己从 GGUF 格式转换。草稿加速效果取决于文本类型,英文散文上草稿命中率 74-89%,但意大利语散文上某个模型只有约三分之一。README 也坦承早期版本的基准测试有美化成分,已做修正。
决策清单
模型能放进内存,继续用 llama.cpp。它成熟、通用,小模型上的差距虽然真实但意义不大。模型超过内存且你有高速 NVMe SSD,Janas 正是为这个场景设计的,80B 模型上 24-37 tok/s 让它从好奇心变成了可用工具。需要稳定性或特定模型,llama.cpp 的生态和工具链积累是数年之功,Janas 没有任何稳定性保证。只是想要好答案且有网络,付费 API 在每 token 质量上仍然胜过所有本地方案。
更大的启示是:"太大跑不动"的定义正在从内存容量转向 SSD 带宽。NVMe 每秒 5-7 GB/s 的流式读取能力,已经超过了 token 生成器消费专家权重的速度。如果这个趋势成立,本地模型的实际上限将取决于磁盘而非内存,而升级磁盘比升级内存便宜得多。",
相关推荐

OpenAI与Shield合作:Astra智能体如何革新IT故障修复
OpenAI与Shield合作推出Astra智能体,可自动登录电脑和遗留系统,实时修复IT故障,比传统模型快35%到40%,仅在需要人类判断时引入人工。

iPhone Duo续航实测:一天一充跑不掉,大屏是耗电元凶
iPhone Duo续航实测:重度使用一天需至少充电一次,6.5小时亮屏约剩30%电量。大屏展开频率是耗电关键,MagSafe电池背夹可救场,长期衰减同样值得关注。

Kimi K3.1 Pro开源发布:2.8万亿参数逼近Opus
Moonshot发布开源MoE模型Kimi K3.1 Pro,2.8万亿总参数、1040亿激活参数,Terminal Bench 4.0仅落后Opus 5.5不到1分,单任务成本约三分之一,API价格减半,开源权重11月4日开放。