Hacker News 中文摘要

RSS订阅

Janas: Run LLMs larger than RAM by streaming experts from SSD

贾纳斯(janas)目前处于实验性状态,支持 Linux 和 Windows x86-64 平台,以纯 C 语言编写,可通过 CPU 或 GPU 运行比内存更大的大语言模型。在 32 GB 内存的笔记本上,它让 48 GB 的通义千问3-Next-80B(Qwen3-Next-80B)模型生成速度达到 37 tok/s,不使用草稿时为 24 tok/s,骆马.cpp(llama.cpp)为 2.8 tok/s;读取速度为 62 tok/s,对比后者的 16 tok/s。在 Q4KM 量化下比较全部 13 个模型,贾纳斯均快于骆马.cpp。

正文

状态:实验性

平台:Linux | Windows x86-64

在一台 32 GB 内存的笔记本上,Qwen3-Next-80B(48 GB 模型)跑出 37 tok/s,不用草稿为 24,而 llama.cpp 只有 2.8;读取提示词时,62 tok/s 对 16。 Janas-LLM 在同一台笔记本上比 llama.cpp 快,比较了每一个模型(Debian 13 Linux,Intel Core Ultra 9 185H,其集成 Arc GPU,32 GB,NVMe SSD;2026 年 10 月 9–11 日;整机见 下文):

Image 3: LinkedIn

| 模型 | 读取 1,024 tokens:Janas-LLM | llama.cpp | 生成:Janas-LLM | llama.cpp | | --- | --- | --- | --- | --- | | Qwen3-Next-80B-A3B(48.4 GB,超过内存) | 62 tok/s | 16 tok/s | 24 tok/s | 2.8 tok/s | | Qwen3-Coder-Next(48.4 GB,超过内存) | 66 tok/s | 14 tok/s | 22 tok/s | 2.2 tok/s | | Qwen3.6-35B-A3B | 104 tok/s | 79 tok/s | 19 tok/s | 12 tok/s | | Qwen3-30B-A3B | 135 tok/s | 122 tok/s | 32 tok/s | 15 tok/s | | Gemma-4-26B-A4B-it | 84 tok/s | 76 tok/s | 18 tok/s | 12 tok/s | | Gemma-4-12B-it | 65 tok/s | 46 tok/s | 9.9 tok/s | 7.1 tok/s | | Qwen3.5-9B | 111 tok/s | 78 tok/s | 14 tok/s | 8.7 tok/s | | Gemma-4-E4B-it | 122 tok/s | 109 tok/s | 20 tok/s | 15 tok/s | | Qwen3-4B | 193 tok/s | 164 tok/s | 27 tok/s | 18 tok/s | | Gemma-4-E2B-it | 191 tok/s | 150 tok/s | 38 tok/s | 19 tok/s | | Qwen3.5-2B | 441 tok/s | 323 tok/s | 52 tok/s | 28 tok/s | | Qwen3.5-0.8B | 799 tok/s | 519 tok/s | 109 tok/s | 32 tok/s | | Qwen3-0.6B | 939 tok/s | 670 tok/s | 130 tok/s | 45 tok/s |

Image 4: Substack

同样模型、但由其他发布者制作(量化目录与前文并列):

| 模型 | 读取 1,024 tokens:Janas-LLM | llama.cpp | 生成:Janas-LLM | llama.cpp | | --- | --- | --- | --- | --- | | Qwen3-30B-A3B,bartowski 的 Q4KM(importance matrix) | 131 tok/s | 122 tok/s | 32 tok/s | 16 tok/s | | Qwen3-30B-A3B,unsloth 的 UD-Q3KXL(3 bits) | 100 tok/s | 112 tok/s | 36 tok/s | 11 tok/s | | Qwen3-4B,bartowski 的 Q4KM(importance matrix) | 191 tok/s | 160 tok/s | 26 tok/s | 18 tok/s |

一个例外:3-bit 的 Qwen3-30B 读取提示词比 llama.cpp 慢,因为它的 Q3_K 权重还不能进入 GPU 的快速提示路径;但它生成速度是后者的三倍。

测量方法以及带草稿时的速度见 What works now。在另一台机器上数字会不同:janas-bench 会测量你自己的机器。

试用于 Linux x86-64(Ubuntu 22.04、Debian 12 及更高版本):

curl -LO https://github.com/prabanta-dev/janas/releases/latest/download/janas-linux-x8664.tar.gz tar xf janas-linux-x8664.tar.gz && cd janas ./janas-chat # 它认识的模型:选一个,会下载并校验

或在 Windows 上 10(1903 或更高版本)和 11,x86-64:下载 janas-windows-x86_64.zip,解压,然后在 janas 文件夹的终端中运行 .\janas-chat。在同一台笔记本的 Windows 11(2026 年 10 月 12 日)下,Janas-LLM 的生成速度与 Linux 上相同(Qwen3-4B 25.6 tok/s,Qwen3-30B-A3B 34.2),读取提示词时混合模型(Qwen3-30B-A3B)也是 132 tok/s;稠密模型(Qwen3-4B)则在 Intel 自己的 Windows 驱动下达到 346 tok/s,是 Linux 上 193 的 1.8 倍,因为它的整个块都能进入 GPU。

模型已转换好,来自 Hugging Face;从源码构建见 Getting started。

Janas 是一个用 C 语言编写的人工智能工具家族,除 C 标准库外没有依赖。它的第一个组件 Janas-LLM 能在普通计算机上运行大型混合专家(MoE)语言模型,有无 GPU 均可:权重留在磁盘上,每个 token 需要的专家从 NVMe SSD 流式读取,而反复用到的专家则留在内存里。一个 800 亿参数的模型能在 32 GB RAM 的笔记本上跑起来并回答问题。

⚠️ 请先阅读

这是一个实验,不是产品。

| | | | --- | --- | | 阶段 | 早期开发。公开 API 和命令行会不经通知就变更,而且一周改过好几次。模型文件是例外:发布在 Hugging Face 上的 .jns 文件(格式版本 2)将被 Janas-LLM 的每一个后续版本读取。 | | 稳定性 | 未经验证。 引擎故意对机器施压:它会用专家缓存填满空闲内存,并以 O_DIRECT 全速读取磁盘。在一台余量不足的机器上,桌面可能被挤进 swap,变得缓慢或无响应。使用 GPU 曾有一次导致驱动重置,连桌面一起挂掉。 | | 数据 | 它只在 ~/.cache/janas(学到的机器信息,以及读过的系统消息,以免重复读取)和你指定的转换模型存放位置写入。它不会动它读取的模型文件。 | | 硬件 | 只在一台机器(见下文)上开发和运行。在其他任何机器上均未测试:可能更慢,可能拒绝模型,可能行为异常。 |

如果出问题,Ctrl-C 停止当前回答,Ctrl-D 退出聊天;--cache <GiB> 对其占用内存设硬限制,JANAS_GPU=0 则完全不使用 GPU。

它成长的机器

本仓库的一切都在以下机器上编写和测量:

  • Linux Debian 13(trixie),x86-64,内核 6.12.107;GPU 驱动 Mesa 26.1.6(Vulkan);用 GCC 14.2 构建
  • Intel Core Ultra 9 185H(6 个性能核,8 个能效核,2 个低功耗核;AVX2、FMA、F16C、AVX-VNNI;集成 Arc GPU)
  • 32 GB DDR5 RAM
  • 1 TB NVMe SSD(读取约 5.7 GB/s)

Windows 构建在同一台笔记本的 Windows 11(build 26300)上运行,使用 Intel 自己的图形驱动:测试在那里通过,速度如何见上文的“或在 Windows 上”。

引擎所做的一切都根据它测到的数据来选择,因此另一台机器会做出不同选择——这部分本来就是可移植的。从未尝试过的是其余情况:其他 CPU(尤其是没有 AVX-VNNI 的,或 AMD)、独立 GPU、更慢的磁盘、更多或更少的内存。如果你在别处运行它,janas-bench 的报告是你最有用的反馈(见 Helping it run on more hardware)。

目前可用的功能

Janas-LLM 目前按模型和特性支持什么:docs/features.md。

在上述机器且没有其他程序运行时,janas-bench 报告如下(2026 年 10 月 10 日测量,使用引擎自当天起默认采用的快速提示):

| 模型 | 读取提示词 | 生成回复 | 聊天中带草稿 | | --- | --- | --- | --- | | Qwen3.5-2B(稠密,1.3 GB) | 395 tok/s | 50 tok/s | 67 tok/s | | Qwen3-4B(稠密,2.5 GB) | 220 tok/s | 28 tok/s | 见下文 --draft | | Qwen3.5-9B(稠密,5.7 GB) | 103 tok/s | 14 tok/s | 24 tok/s | | Qwen3-30B-A3B(18.6 GB) | 133 tok/s | 34 tok/s | — | | Qwen3.6-35B-A3B(22.3 GB) | 86 tok/s | 25 tok/s | 34 tok/s | | Qwen3-Next-80B-A3B(48.4 GB) | 64 tok/s | 22 tok/s | 37 tok/s | | Gemma-4-E2B-it(3.1 GB) | 211 tok/s | 38 tok/s | 52 tok/s | | Gemma-4-E4B-it(5.0 GB) | 133 tok/s | 20 tok/s | 32 tok/s | | Gemma-4-12B-it(稠密,7.1 GB) | 71 tok/s | 10 tok/s | 14 tok/s | | Gemma-4-26B-A4B-it(18.3 GB) | 90 tok/s | 18 tok/s | 26 tok/s |

每个数字都是三轮的平均值,不是最好一轮,取引擎自己为每类 pass 选择的配置——也就是聊天运行的配置:先 256 token 的提示词,再生成 64 token。这里集成 GPU 读取每一个提示词(即下文的快速提示),引擎最终选定的线程是:对提示词和单个 token,几乎所有模型都用性能核的 12 线程;对少数几个 token 同时处理,则用所有可用核(性能核和能效核,不包括低功耗核)。在另一台机器上引擎可能选其他线程:每类 pass 的最初几轮会尝试每一个核,一个线程对应一个性能核以及性能核的线程,保留最快的,之后偶尔再试其他的,这样一台会预热的机器可能改变结论(在 i9-14900HX 上,每个线程的回复速度都不到 16 个性能核的一半)。几轮以交替顺序运行,使机器预热和缓存填充对每个设置的影响相同。预计不同运行间有百分之几的波动,第一次运行(缓存仍在填充时)会比这些数字低一些。关闭 GPU(JANAS_GPU=0)时,Qwen3-4B 读取同一提示词为 85 tok/s,生成为 27。

最后一列是草稿:先猜后续 token,再由模型校验,相当于以更高速度产出同样的文本——完整说明见 --mtp:Qwen3.5、Qwen3.6 和 Qwen3-Next 用自己的预测块,Gemma 4 用它的助手(它自带的一个小草稿模型)。它是在聊天回复上测的:一个普通英文问题(“explain how bread is made at home”),取回答的 64 个 token,采样方式与聊天时相同。草稿有多大用取决于文本:在 Qwen 模型和 Gemma 两个较大的模型上,草稿存活率为 74–89%,在 Gemma 的 E2B 和 E4B 上为 63–72%;在意大利语散文上,Qwen3.5-2B 只保留约三分之一,几乎没有提升。这里一轮 64 token 噪声较大,不同运行间有约十分之一的波动。Qwen3-30B-A3B 没有这种块,稠密的 Qwen3 也没有;稠密的 Qwen3.5 在其原始 checkpoint 里有,由 hf2jns_mtp 转换(MODELS.md)。

这一列在 2026 年 9 月 26 日之前是错的,而且偏高:它测的是块去续写一个自我重复的段落,模型会照抄,块几乎每次都能猜中——Qwen3.5-2B 是 107 tok/s,Qwen3.5-9B 是 26。当时的 MoE 数字(29 和 30)恰好比今天的低;细节见 ChangeLog。

本页顶部与 llama.cpp 的比较是这样测的:llama.cpp(2026 年 9 月 18 日的 2b18470 构建)用它的 Vulkan 后端跑在同一集成 GPU 上,全部放上去(llama-bench -p 1024 -n 16 -ngl 99 -t 12;最大模型另见下文),对抗 janas-bench --prompt 1024 --gen 16,用同样的文件、在同样的几天(2026 年 10 月 9–11 日;llama.cpp 用最佳配置,Janas-LLM 用自己的选择;10 月 11 日每方三轮,llama-bench -r 3 和 janas-bench --rounds 3,针对 Qwen3-0.6B、Qwen3.5-0.8B、Qwen3.6-35B-A3B 以及来自其他发布者的模型;Qwen3-Coder-Next 视作 Qwen3-Next-80B,见下文)。

对于 Qwen3-Next-80B-A3B,其文件大于这台笔记本的 30 GB,llama.cpp 用通常构建时,只要 GPU 参与就会内存耗尽,即使把专家留在 CPU 上(-ngl 99 -ncmoe 48)也一样:它的 CPU 后端会把权重复制进自己的内存去 repack,而 Vulkan 后端把那些留给 CPU 的权重复制进系统无法回收的缓冲区。它用一个不做 repack 的构建(GGML_CPU_REPACK=OFF)再加两个选项 --no-host 1 -lm mmap 来跑,这两个选项把专家留在文件里、通过页缓存读取:用 GPU 读取为 16 tok/s,纯 CPU 生成为 2.8 tok/s(用 GPU 为 2.0);这就是表中它的两个数字。Janas-LLM 跑同一模型时不带自己的额外选项,最常用的专家放在约 19 GB 的缓存里,其余从磁盘读。Janas-LLM 的数字各为一轮;两侧的生成列都不带草稿。两个工具测量方式不完全相同(llama-bench 在写之前没有提示词;janas-bench 是在 1,024 token 之后),而且只有一台机器。llama.cpp 自己的 CPU 后端在这台笔记本上读取时比它的 Vulkan 后端更差(Qwen3-4B 在 20 线程上为 70 tok/s),生成时两者相当。

先在空闲机器上试用。 专家缓存会占用打开模型时空闲的内存,剩下的模型在回答时从磁盘读取,因此其他正在运行的程序都会分走一部分。它是温和降级而不是崩溃:在开着浏览器和编辑器的情况下测,同一模型保持约四分之三的速度,但等磁盘的时间是五倍。不过你首先应看到机器真实的速度,而且任何要发给别人的测量都必须在机器独占时进行。

文档

  • INSTALL.md — 构建所需、如何准备模型,以及首次运行
  • ChangeLog.md — 变更内容,最新在上
  • MODELS.md — 转换后模型的许可,以及可再分发的内容
  • CONTRIBUTING.md — 如何贡献,以及 sign-off 要求
  • src/services — Janas 的服务,每个服务在 janas-chat 和其他 MCP 客户端中都有对应页面
  • docs/features.md — Janas-LLM 目前按模型和特性支持什么
  • docs/models.md — 获取模型:janas-get,或转换 GGUF 文件
  • docs/chat.md — 使用 janas-chat、它的服务以及来自 MCP 服务器的工具
  • docs/library.md — 从程序中调用,C 或 FreeBASIC
  • docs/serving.md — 把模型提供给 MCP 客户端(janas-mcp)和通过 HTTP(janas-server)
  • docs/code-completion.md — 在 VSCodium 和 VS Code 中通过 janas-server 补全代码
  • docs/tools.md — 转换器、检查器和基准测试
  • docs/hardware.md — 测量你的机器,并帮助它支持更多硬件
  • AUTHORS — 谁写了它,以及它借鉴了谁
  • LICENSE — GNU GPL,第 3 版或更高版本

开始使用

sudo apt install build-essential # Debian/Ubuntu sudo apt install libvulkan-dev glslang-tools vulkan-tools # 可选,GPU sudo pacman -S vulkan-headers glslang vulkan-tools # 同上,Arch

./build.sh # 全部输出到 bin/x86_64-linux/ ./build.sh release test # 并运行测试

获取模型

用 janas-get 下载已转换的模型,或自己转换 GGUF 文件,以及哪些文件经过校验:docs/models.md。

使用聊天

janas-chat:它的选项和命令、草稿、Janas 的服务、来自 MCP 服务器的工具,以及如何观察长提示词被读取:docs/chat.md。

补全代码

janas-server 用代码模型(如 Qwen3-Coder-30B-A3B)在编辑器的光标处补全代码:支持 OpenAI 的带 suffix 的 /v1/completions,以及 llama.cpp 的 /infill(llama.vscode 用的就是这个)。每次按键发送的窗口被固定住不移动,因此一次按键只读取它改动的部分:在笔记本上,一个补全建议耗时 1.5–2.2 秒,而如果窗口滑动一行,重新读取要 17 秒。如何在 VSCodium 和 VS Code 中用 llama.vscode 或 Continue 配置,以及测得的数据:docs/code-completion.md。

从程序中调用

从 C、FreeBASIC 和 BASIC MODERN 使用该库,以及从程序中使用 MCP 服务器:docs/library.md。

Janas 作为 MCP 服务器

janas-mcp:把模型作为工具提供给 Claude Code、编辑器和其他 MCP 客户端:docs/serving.md。

通过 HTTP 使用

janas-server:遵循 OpenAI 的 HTTP API,以及一个可从浏览器试用的聊天页面:docs/serving.md。

测量你的机器

janas-bench:它测量什么,以及留下的报告:docs/hardware.md。

工具

随程序一起构建的转换器、检查器和基准测试:docs/tools.md。

帮助它支持更多硬件

最需要哪些机器、尝试 Janas 并生成报告的那一条命令,以及要发送什么:docs/hardware.md。

致谢

它建立在他人工作的基础上,并对此作了说明:

  • 它运行的模型属于各自的作者:阿里云 Qwen 团队的 Qwen3、Qwen3.5、Qwen3.6 和 Qwen3-Next,Google 的 Gemma 4;GGUF 量化来自 Qwen、bartowski 和 unsloth(MODELS.md 列出了所有来源)。
  • llama.cpp 和 ggml 是引擎校验所参照的基准(logits、token、速度);Janas 中没有它们的任何代码。唯一取自 ggml 的是定义某种格式的数据:IQ3_S 网格,位于 src/llm/iq3s_grid.h,遵循 ggml 的 MIT 许可。
  • The Unicode Character Database 为分词器提供表(tools/gen_unicode),OpenAI 的 OpenAPI specification 为 janas-server 提供路由表(tools/openapi_routes)。
  • GNU libmicrohttpd、yyjson 和 Mbed TLS 被编译进下文提到的程序中。
  • 在自己机器上试用并报告所见的人(在本仓库的 issue 中):他们的报告不止一次改变了引擎(它选择的线程、提示词的进度、GPU 的诊断)。

许可

版权所有 © 2026 Maurizio "camauri" Cammalleri。

Janas 是自由软件,采用 GNU 通用公共许可证第 3 版或更高版本——见 LICENSE。每个源文件都带有 SPDX 行。

janas-server(且仅它)编译进两个第三方库,其源码未改动地放在 src/third_party/ 中,并附有许可和来源:GNU libmicrohttpd 1.0.10(LGPL 2.1 或更高,或无 HTTPS 的 eCos 许可,如此处构建所示)和 yyjson 0.13.0(MIT)。libjanas_mcp 及使用它的程序带有 Mbed TLS 4.2.0 with TF-PSA-Crypto(Apache-2.0 或 GPL-2.0-or-later),用于 https:// MCP 服务器。libjanas_llm 没有。

模型不受此许可覆盖。 转换后的 .jns 文件是模型的衍生品,而非 Janas 的衍生品,并保持其作者授予的许可;MODELS.md 说明了本项目会再分发和不会再分发什么,以及在传递转换模型前应检查什么。

贡献

CONTRIBUTING.md。简短版:一台这里没人拥有的机器上的测量,比大多数补丁更有价值,而且每个提交都需要一行 Signed-off-by(git commit -s)。

评论

整体气氛是欢迎中带着强烈挑剔。支持者认为对普通本地模型用户来说 62 tokens/秒已经够用,更多开源实现也令人兴奋;分歧主轴则在于它是否只是重复 llama.cpp 已有能力或等同于 swap、所用模型是否已被 Strata 等更好实现超越,以及本地推理时机器还能否正常做日常任务。

认为速度对普通本地模型已经够用,甚至可能带来质变

  • 对不是运行 gas town 的普通用户,62 tokens/秒似乎足够;有人此前本地只能跑到约 8 tokens/秒,因此这可能带来明显改善,不过其个人当前瓶颈在任务规划且刚入手云端套餐,短期内未必回归本地。也有人对这类开源应用持续感到兴奋。(较多人) > “对不想跑 gas town、只想用本地模型的普通人来说,62 tokens/秒似乎已经够用。”(@3eb7988a1663)

认为所用模型过时,已有 Strata 等更好实现,纯属浪费时间

  • 所用模型太旧,社区已有人在更新的 Qwen3.8 系列上做同类工作;Strata 等项目早就实现了同样的流式加载,再做一个是浪费时间。(较多人) > “Qwen 3?现在是哪一年?这完全是浪费时间,Strata 早就用 Qwen3.8-Flash-Next 做了这个。”(@suprjami)

认为类似项目已经很多,并非新东西,需要指南或整合

  • 从 SSD 流式加载专家权重的项目近期大量出现,llama.cpp 多年前就有类似能力,反复被重新实现,本质上和 swap 差不多;因此更需要一个总览指南,并把各家优点合并成终极项目。(较多人) > “年轻人刚发现 swap 吗?”(@aboardRat4)

担心本地推理会拖垮机器,影响日常使用与稳定性

  • 能放进 RAM 只是第一步,真正实用还得看运行时能否同时用浏览器、看视频或 VS Code;一旦 GPU 显存溢出带崩桌面,日常任务就无从谈起。(较多人)

有价值的补充

  • 未来若出现与 NVMe 集成的小型商用加速器,就能突破典型 NVMe 四通道带宽限制;由于要靠更大容量堆叠来达到所需带宽,所有模型几乎都像已加载,从而可以极快地切换不同模型。
  • GPU 显存分配必须给桌面显示预留空间,并在分配前做检查;否则 LLM 试图把过大权重(例如把 24GB bf16 权重塞进 16GB GPU)加载进去时会 OOM,并直接带走显示输出。即便加了保护,仍可能有错误漏网。
  • 编写这类专用推理引擎工作量很大,不可能两天靠 vibe code(凭感觉写代码)完成;作者正参考 DwarfStar4 和 Strata,为 gfx1201 写 gemma4 专用引擎。