Strata:125B MoE 与百万上下文--本地部署大模型(5)
2026年10月13日 · 3146 字 · 7 分钟
上一篇记录了 27B 在 170HX 单卡上的部署演进。这一篇讲讲目前的形态:170HX 与 2080 Ti 组成异构搭档,跑 125B 的 MoE 模型,上下文拉到百万级。
当前阵容
| CMP 170HX | RTX 2080 Ti 22GB | |
|---|---|---|
| 显存 | 40GB HBM2e | 22GB GDDR6 |
| 显存带宽 | 约 1.5 TB/s | 616 GB/s |
| 计算架构 | sm_80(GA100) | sm_75(TU102) |
| PCIe | Gen2 x4(硬上限) | Gen3 x16 |
| 功耗墙 | 150W | 200W |
合计 62GB 显存、350W 功耗。与双 2080 Ti 的"同代同质"路线(44GB、400W+)相比,这套异构组合的显存多出四成,HBM 带宽则完全不在一个量级。
两张卡插在同一台主机上:华南金牌 X99-TF 主板、Xeon E5-2696 v3、128GB 四通道 DDR3 内存(1866MT/s,平台详情见第一篇)。后文 Strata 方案里"冷门专家驻内存"的设计,靠的就是这 128GB。
Strata:让 125B 跑在 62GB 上
这个方案本身来得颇有戏剧性:国庆期间在小红书上刷到了 Strata 的介绍,出门在外碰不到机器,只能看着心痒;回到机器旁第一时间部署尝试,结果相当惊人。
当前的主力模型是 Qwen3.8-Flash-Next——125B 的混合架构 MoE,每步仅激活约 6B 参数(另有 51B 的 n-gram 嵌入参数与 4B 的 MTP 草稿头),量化后权重约 94GB(Unsloth UD-IQ4_XS),单纯靠显存无论如何装不下。
量化版本的选择
Unsloth 为 Flash-Next 提供了从 BF16(约 354GB)到 IQ1(约 72GB)的完整梯度,魔塔上能直接下载的主要有三档:
| 量化 | 大小 | 说明 |
|---|---|---|
| UD-Q4_K_XL | 约 111GB | llama.cpp 时期在用的一档,最接近原版质量;但 Strata 对它只标记 experimental,且 111GB 的内存占用对 121GB 内存偏紧 |
| UD-IQ4_XS | 约 94GB | 最终选择。Strata 官方支持最好的 4-bit 量化,质量介于 IQ3_S 与 Q4_K_XL 之间,94GB 对 121GB 内存很从容 |
| UD-Q3_K_XL | 约 90GB | 比 IQ4_XS 略小略快,质量略低 |
选型权衡了三点:Strata 的支持度、质量档位(4-bit 优于 3-bit)、内存余量。还有一条隐含前提:这台机器的瓶颈从来不在内存,更小的量化省不出什么——62GB 显存全部留给专家缓存才重要。另外 Strata 官方最推荐的其实是 ISTA-DASLab 的 i-quant 系列(如 IQ3_S,约 70GB),但魔塔上没有镜像,下载不便,只能作罢。
实际下载为三个分卷合计约 93.7GB,外加视觉编码器 mmproj(0.9GB)与 Q8_0 的 MTP 草稿层(2.8GB)。
这个模型在这台机器上并不是第一次跑。Strata 之前,llama.cpp 时期的部署记录是:9 月 5 日双 2080 Ti 上 decode 约 17 t/s、prefill 约 100 t/s(16 个专家层上卡,其余走内存);9 月 10 日 170HX 加入后压榨到极限——32 个专家层上卡,decode 22 t/s、prefill 158 t/s,但代价是上下文只能开 32K。瓶颈很清晰:CPU 计算的专家层拖住了整体。这个成绩只能算"能跑",离可用尚远。
让它在这台机器上成立的是 Strata,一个基于 llama.cpp/ggml 改造的 MoE 专家分流引擎,思路是:
- 热点专家进显存:双卡合计缓存 21634/24576 个热点专家,覆盖 99.6% 的路由命中;
- 冷门专家驻内存:128GB 的四通道 DDR3 在这里派上用场,未命中显存的专家按需从内存读取;
- 层按算力自动拆分:170HX(70 SM)分到前 30 层,2080 Ti(68 SM)分到后 18 层加输出头;
- 绕开 PCIe 瓶颈:170HX 的上行只有 1.6 GB/s,引擎探测后自动把 PCIe 传输占比压到 0.04,几乎全部流量走显存本地。
再叠加官方的 MTP 投机草稿(实测接受率 61%~84%),最终成绩:decode 74~100 t/s——是此前 llama.cpp 跑同一模型(约 19 t/s)的 4 到 5 倍。agent 场景(代码 + 工具调用)落在最快的 85~100 区间,为什么是这个区间,后文「不同内容,不同速度」一节有实测。
百万上下文,而且几乎不衰减
通过 YaRN×4 把原生 262K 上下文扩展到 104 万 token,KV 缓存以 int8 量化并 streaming 到内存(实测约 14.4GB,不占显存,两卡显存占用不变)。1M 配置下的完整实测(JSON 生成任务):
| 上下文 | decode | MTP 接受率 | 增量 prefill |
|---|---|---|---|
| 10K | 99.6 t/s | 93% | 750 t/s |
| 50K | 91.4 t/s | 92% | 1209 t/s |
| 100K | 81.4 t/s | 86% | 1197 t/s |
| 200K | 85.4 t/s | 88% | 1210 t/s |
| 400K | 82.8 t/s | 89% | 1093 t/s |
| 700K | 80.2 t/s | 93% | 862 t/s |
两个结论值得单独写:
- decode 衰减很小且早触底:10K→700K 只慢 19%,且 100K 之后就稳定在 80~85 区间不再下降——DeltaNet 混合注意力 + KV streaming 的设计让长上下文几乎无感。对比上一篇 27B vLLM 方案在 200K 以上降到 50~80 t/s,差距明显;
- YaRN×4 对短上下文无副作用:10K 时 decode 99.6 t/s,与未缩放的 262K 配置(101 t/s)基本一致——扩展上下文没有付出日常速度的代价。
其余实测:一份 272K token 的文档完整读入约 211 秒;埋针测试把 PINEAPPLE-7391 埋在约 270K 处(故意超过 262K 训练上限以验证 YaRN×4),准确命中;同会话第二轮复用 KV 后,decode 仍有 88.2 t/s(JSON,接受率 94%)。
顺带一提:第三篇里双 2080 Ti 跑 27B 的方案放到今天也能用,但 27B 与 125B 的模型能力差距、以及长上下文表现,是两代方案之间真正的分水岭。
不同内容,不同速度
投机解码的速度很看内容:草稿模型猜得越准,decode 越快。为此专门测过两轮。
第一轮在 262K 配置下,六类内容各发一条(短上下文):
| 内容类型 | decode | MTP 接受率 |
|---|---|---|
| 结构化输出(JSON) | 101.2 t/s | 87% |
| 数学推理 | 99.2 t/s | 85% |
| 中英翻译 | 89.3 t/s | 70% |
| 代码生成 | 86.9 t/s | 69% |
| 中文散文 | 77.1 t/s | 60% |
| 英文写作 | 74.7 t/s | 57% |
规律很直观:内容越可预测,接受率越高。整体波动只有 ±15%,不存在某类内容特别慢的短板。
第二轮更有意思:换到 1M 配置,挑了 16 个话题,包括一些故意刁钻的冷门领域:
- 快档:表格数据 91.8(83%)、菜谱 88.3(73%)、医学常识 85.6(71%)
- 中档:梵文语法 82.8、蜉蝣分类 80.7、拓扑证明 80.7、Python 80.0、混合语言 80.8
- 慢档:有机合成 76.4、手抄本颜料 75.6、拜占庭税制 69.9(58%)、文言文 68.3(56%)、虚构自我介绍 64.4(56%)
最慢的不是冷门知识,而是虚构自我介绍——创意内容的下一个 token 天然不可预测;梵文语法、蜉蝣分类这类"冷门但结构严谨"的内容,接受率反而有 70% 以上。最慢也有 64 t/s,只比最快低 30%。
跑起来之后
- 服务注册为 systemd 单元开机自启,启动前置任务按 PCI 地址设好两张卡的功耗墙;
- 视觉输入已开启(mmproj 编码器本地编译,图像 prompt 编码 108 t/s);
- 针对 agent 反复全量重读对话的问题,开启了 24GB / 8 槽的会话缓存,双对话交替命中率 98.9%——这类细节对日常体验的影响不亚于模型本身。
服务暴露的是 OpenAI 兼容接口,凡是支持自定义模型的客户端都能直接接入。以 Qoder 为例,在模型管理里把 Strata 的地址添加为自定义模型,就能在模型列表里直接选用:

Qoder 的模型选择界面:qwen3.8-flash-next 以 OpenAI Compatible 的方式接入。
命令行这边用的是 opencode——终端里的 AI 编程 agent,通过 @ai-sdk/openai-compatible 插件可以接任意 OpenAI 兼容端点。配置写在 ~/.config/opencode/opencode.jsonc:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"strata": {
"npm": "@ai-sdk/openai-compatible",
"name": "Strata Qwen3.8-Flash-Next",
"options": { "baseURL": "http://127.0.0.1:8080/v1" },
"models": {
"flash-next": {
"name": "Qwen3.8-Flash-Next UD-IQ4_XS (Strata)",
"modalities": { "input": ["text", "image"], "output": ["text"] },
"limit": { "context": 1048576, "output": 32768 }
}
}
}
},
"model": "strata/flash-next"
}
其中 limit.context 值得如实填写:标成 1M,agent 才敢放心地读大文件、攒长上下文;output 给到 32768,是因为长回答曾被默认的 8192 掐断过。这台机器上的 opencode 配置文件本身就是一部部署史:8 月第一次接入的是 llama.cpp 时代的 27B,9 月加了 vLLM 的 provider,10 月 Strata 上线当天就切了过来,如今默认模型就是上面的 strata/flash-next。

opencode 实际使用界面:底部状态栏显示当前模型为 Strata 的 flash-next,以及本次会话的上下文用量(7.9K,占 1M 上限的 1%)。
小结
回头看,Strata 之所以能成为这条路的终点,是因为它恰好踩中了 MoE 模型的特点:125B 的参数量听着吓人,但每步只激活约 6B,真正需要显存带宽伺候的权重并不多。热点专家进显存、冷门专家驻内存、KV 缓存 streaming 到 DDR3——它把"显存不够"这个死结,拆成了"显存放热点、内存放长尾"的工程问题。62GB 显存加 128GB 内存的旧平台,因此跑起了百万上下文下的 125B 模型。