一张 8 GB 显卡跑出 93 token/s:Strata 本地推理引擎完全解析
【免费下载链接】StrataQwen3.8-Flash-Next on any consumer hardware: one-click install for Windows / Linux. Strata inference engine, OpenAI/Anthropic API on localhost, optional image input.项目地址: https://gitcode.com/gh_mirrors/strata11/Strata
Qwen3.8-Flash-Next 有 125B 参数,按常规思路要堆服务器集群才跑得动。Strata 把它塞进"一张 8 GB 以上显存的 NVIDIA 显卡 + 64 GB 内存"的普通 PC:输出 60-95 token/s,并在本地提供 OpenAI/Anthropic 兼容的 HTTP API,Claude Code、Codex CLI 这类工具直接指过去就能用。
本文回答一个问题:一个 token 的约 53 毫秒里,每一毫秒到底花在了哪里。
架构总览:三级内存装下 125B 参数
Strata 的总设计只有一句话:按"访问频率"把模型参数切到三级存储上,让计算跟着数据走。
| 存储层 | 存放内容 | 角色 |
|---|---|---|
| GPU 显存 | 注意力/DeltaNet 混合器、路由器、共享专家、KV 缓存、MTP 草稿层,以及专家缓存 | 计算主力 |
| 系统内存 | 全部 24,576 个专家(约 23-50 GB,pinned 锁定) | CPU 池的数据源 |
| SSD | 28.8 GB n-gram 表 | 每 token 只读 16 行 |
数据流是这样的:prompt 被切成最大 8,192 token 的块做预填充,然后进入 48 层的逐层循环;每层先算注意力,路由器挑出本 token 激活的 10 个专家(MoE 意味着每层 512 个专家中只有 10 个真正参与计算),命中显存缓存的专家由 GPU 直接算,未命中的交给 CPU 池同步计算,最后组合残差写回、进入下一层。显存里"剩下的空间"全部让给专家缓存,这就是监控面板上1644 experts in VRAM、11.2/12 GB的来源——缓存规模是拿空闲显存实测出来的,不是拍脑袋定的(设计依据见 include/strata/core/expert_cache.hpp 的注释)。
专家缓存:把热专家常驻显存
结论先说:CPU 读专家字节是整个引擎最大的单项成本,专家缓存就是为了让 GPU 本地吃掉其中大部分。
为什么必须这么做?实测每 token 要从内存搬663.6 MB专家字节,即使内存跑到约 40 GB/s 也要16.2 ms,而一个 token 总共才约 53 ms;残差链是严格串行的,这 16 ms 里有96% 暴露在关键路径上。只靠 PCIe 搬运根本来不及,唯一出路是让一部分专家常驻显存。
缓存规模完全对着实测数字设计:引擎稳态下空闲显存6,414 MiB,4,105 个槽位占5,413 MiB,还剩约 1 GB 余量。装哪些专家则来自路由频率画像:tools/make_profile.py 用真实 prompt 的激活数据排序(打包版画像是 data/expert-profile.bin),交叉验证命中率0.6447(10 折留一法,置信区间 0.6110-0.6750)。一个很直观的推论:每多 1 GB 显存约多驻留 700 个专家,所以"更大的卡"比"更快的卡"更值钱。
实现上,include/strata/core/expert_cache.hpp 只管两件事:分配显存、维护驻留表并回答"(层, 专家) → 槽位或 -1"。它自己不算数——命中的专家由 GPU 在验证窗口的分组内核里直接算,未命中的才落到 CPU 池。你也能用--dump-routing trace.bin跑一遍自己的 workload 重新生成画像。
那没装进显存的 2 万多专家怎么办?这正是 CPU 专家池的活。
CPU 专家池:每颗核心满带宽读专家
这个池子的目标朴素到可以写成一句话:让每颗物理核心持续读取专家字节,因为专家内核是纯内存带宽瓶颈(DRAM-bound,算力再强也没用)。
数字支撑:6 核心实测42.55 GB/s,几乎精确地随核心数线性增长;换回标量单核循环只有 9.89 GB/s——差的那 4 倍多,全靠指令集(见 include/strata/kernels/cpu/expert.hpp 的注释)。
关键实现有三处,每处都对应一次实测:
- AVX512-VNNI:
vpdpbusd单条指令完成 4 个 int8 乘加,把 6 核算力推到约 42 GB/s 的带宽利用; - AVX512-VBMI:
vpmultishiftqb一次解包 8 个 2-bit 量化码。它的参数顺序是实测定下来的——Intel 官方指南写的是反的,照指南写会出 64 个错 43 个; - 多 token 批量点积:include/strata/kernels/cpu/iq_avx512.hpp 让同一条激活向量对多行权重复用,摊薄激活量化成本(每 token 省 480 次冗余转换)。
线程调度用"无锁扁平批次":head/done各是一个原子计数器,每个 worker 领一个任务,不碰锁(include/strata/kernels/cpu/pool.hpp)。worker 按物理核心数开——避开超线程兄弟核;主机循环独占第一颗核心轮询 CUDA 事件。Q2_0 格式还有一个专门的快速内核 src/kernels/cpu/iq_avx512.cpp,首次运行时引擎会为它生成约 40 GB 的专家重排副本。
CPU 算得再快,如果 GPU 必须停下来等它,重叠就白搭了。Strata 的解法是把 MoE 层在路由器处劈成两半。
门铃握手:MoE 层劈成两半,CPU 和 GPU 各算各的
每个 block 被拆成两段捕获图:pre跑"注意力 → 混合器 → 门控残差 → 路由",post跑"组合专家输出 → 残差写回"。pre跑完路由的瞬间,一块 mapped pinned 内存"门铃"把本层未命中的专家编号和路由权重直接写回 CPU 主机(include/strata/core/layer.hpp 中 Doorbell 结构体,约 L396-413),CPU 池随即开工;专家输出就位后post图才启动。整个过程主机零阻塞同步——一次 GPU 计算和一次 CPU 计算严格重叠。
这个握手协议里最细的两个点也全是测出来的:
- 主机等待必须同时查
cudaEventQuery而不能只读内存:驱动会批量提交命令,实测纯内存自旋 500 ms 转了 590 万次,数据一个都没到; - 门铃必须用"图中内核"写:
cudaEventRecord在图捕获里会被静默丢弃,而图中门铃内核让主机在 39.8 ms 的图内0.050 ms处就看到了交接数据。
同样的"提前搬运"思路用在长 prompt 预填充上:src/prefill/ 把 prompt 切成最大 8,192 token 的块,用量化 MMQ 内核直接做矩阵乘;当前层注意力运行时,下一层的未命中专家已经经 PCIe 流式传上显卡。GPU 侧全部内核在 src/kernels/cuda/(注意力、GDN 递归、QSA 选择式注意力、路由器、共享专家、KV 量化等),每层是一段 CUDA Graph(预先录制、可整段回放的 GPU 操作序列),避免逐算子启动开销。
投机解码与 SSD n-gram 表:token 还没生成,答案先"猜"了
解码的第二档加速是模型自带的 MTP(Multi-Token Prediction)草稿层:先猜 3 个 token,再用一次覆盖全部 48 层的校验通过,平均每步验证2.4-3.2 个 token,输出与逐 token 生成逐位一致(控制器在 include/strata/spec/controller.hpp)。当回复大量复述上下文时(代码编辑、引用文本),prompt lookup 还能从更早的副本里"抄"最多 5 个 token。
第三级存储也参与推理:28.8 GB 的 n-gram 表留在 SSD 上,src/ngram/ple_reader.cpp 走操作系统文件缓存,每 token 只读 16 行、约 1.4 KB。对比专家的 664 MB/token,这笔读取成本几乎可以忽略,却为第 1 层注入了逐层嵌入信号。
性能验证:93 token/s 是怎么测出来的
下表是官方参考机的实测输出速度(tokens/s)。参考机:RTX 5070 12 GB、Ryzen 5 7600(6 核)、64 GB DDR5-5200、Windows、引擎 0.1.26、MTP 开启、每次生成 256 token。
| 模型 | 1K | 4K | 32K | 128K | 262K |
|---|---|---|---|---|---|
| Q2_0 | 87.3 | 93.0 | 81.8 | 73.7 | 60.3 |
| IQ2_XS | 79.6 | 78.6 | 76.3 | 62.7 | 52.8 |
| IQ3_XXS | 61.9 | 61.6 | 58.5 | 49.0 | - |
| IQ3_S | 52.4 | 53.3 | 48.3 | 45.5 | - |
几个配套数字(同样来自同一份测量):
- 首 token 时间(Q2_0):4K 约 4 s,32K 约 25 s,128K 不到 2 分钟,262K 约 4.5 分钟;
- 预填充:8,192-token 分块 + 量化 MMQ 内核把 32K prompt 从 572 提到 1,290 tok/s(约翻倍);
- 显存杠杆:每多 1 GB 显存约多 700 个缓存专家,"更大的卡"比"更快的卡"收益更高;
- Coder 剪枝版:每层 512 个专家保留 256 个(激活仍是 10 个),专家只占 23 GB RAM,32 GB 内存即可运行。
数据来源:docs/DETAILS.md 的 "Speed (measured)" 章节,原始数据在 bench/results/2026-09-29-speed-0126。你的机器跑分请用 docs/BENCHMARK_PROTOCOL.md 里的协议复测。
快速上手:四步跑起本地 125B 模型
- 克隆仓库:
git clone https://gitcode.com/gh_mirrors/strata11/Strata进入目录后即可按系统选择安装方式:Linux 跑./setup.sh,Windows 双击SETUP.bat;不想从源码装的话,直接下载官方桌面应用安装包即可。
- 启动模型并跟随向导选量化档位:
strata launch向导会根据你的显存和内存自动推荐 Q2_0 / IQ2_XS 等档位并下载对应文件。
- 确认本地 API 就绪(默认地址
http://127.0.0.1:8080):
curl http://127.0.0.1:8080/health返回正常后,任意发往/v1/chat/completions的 OpenAI 格式请求都能工作。
- 把你的工具接上:
strata connect它会列出 Claude Code、Codex CLI、OpenCode 等工具的接入配置,照提示改一下 base URL 即可。装好后打开终端应用或桌面应用,就能看到上文的监控面板实时显示专家缓存与速度(界面与更多入口见 docs/INSTALL.md、docs/HOW_IT_WORKS.md)。
收尾:把每一毫秒都花在测过的地方
Strata 的设计哲学浓缩成一句话:三级内存、专家缓存、CPU 池、门铃握手和投机解码环环相扣,而每个参数都来自一次实测,没有一个是"先假设再验证"的。适合的场景很具体——你有一台消费级显卡的 PC,想让 100B 级 MoE 模型在本地以打字速度回答你,还要让现成的 AI 编程工具无缝接进来;想继续深入,docs/paper/Strata-Paper.pdf 里有全部测量、瓶颈分析和后续方向。
【免费下载链接】StrataQwen3.8-Flash-Next on any consumer hardware: one-click install for Windows / Linux. Strata inference engine, OpenAI/Anthropic API on localhost, optional image input.项目地址: https://gitcode.com/gh_mirrors/strata11/Strata
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考