移植Strata技术路线到vLLM以适配R9700并让Flash Next真正带并发可用!
-
如题,R9700单卡用Strata跑qfn起来以后速度不是太理想,而且不能并发,在实战当中几乎不可用,主要的锅在孱弱的llamacpp底层,所以决定移植strata的逻辑到vllm并利用paiton的内核来追逐速度极限,目标单流3000/90,C4能到3500/160。
正在进行中,weekend project。。。
本轮:vLLM 跑通了 —— 我们的分层 MoE 已经在 vLLM 里出 token
这是整个改造的第一个端到端里程碑:
=== start test vllm (2 layers, tiered MoE) === models_http=200 after ~205s === completion === {"id":"cmpl-9c8471aec695241b","object":"text_completion", ... "choices":[{"index":0,"text":"!!!!!","finish_reason":"length" ... "usage":{"prompt_tokens":5,"total_tokens":10,...}}含义拆开说:
- vLLM 0.29 正常启动,
/v1/models返回 200; - 模型是真实主干 bf16 + 我们替换的 TieredBlock(gate/shared_expert + 3-bit 分层专家),不是替身;
- OpenAI 兼容接口完整走通,返回合法 JSON、usage、finish_reason;
- 输出
"!!!!!"是预期的:PLE 层目前是零表占位、专家路径也没做 fp8 激活量化,所以数值不对,但数据链路已经全通。
本轮修掉的 4 个问题
# 问题 处理 13 profiling 600 s 不结束 专家执行改为按专家分桶:同一个 batch 里路由到同一专家的 token 合并成一次内核调用;每层张量一次性载入内存缓存 14 输入没有旋转 forward 里加 block-diag H128(FWHT-128) 15 加载器找不到 PLE 参数 给 Stub 注册 6 个参数壳 16 IndexError: index 1 ... block_table_tensor[:, 1](Radiance 的 lazy GDN 要求 ≥2 个 block)RADIANCE_GDN_LAZY=0启动耗时约 205 s(含 vLLM 初始化、权重加载 8.9 s、profiling、warm-up),比原生慢,因为我们的专家路径还是逐专家 Python 循环。
下一步(从"跑通"到"跑对")
- 接真 PLE:把零表换成 4-bit 表(26 GB,128 片 ×
[2.5M, 80]+ 行 scale),按ngram_contextgather; - 换 48 层全模型:主干 9.3 GiB + 专家按需读,显存里放主干 + 热专家;
- 数值验收:
contract-probe的 2,356 个位置逐位对齐 logits——过了才算"改造正确"; - 再谈性能:把逐专家循环换成批量内核、加热集/冷取数,然后压 4 路并发。
现状
- 8080 每次测试后恢复(当前 200);
- 测试模型目录
/data/paiton-test22.8 GB,启动一次 3.5 分钟; - 关键结论:vLLM 的调度、KV、API 全部保留,只替换了 MoE 和 PLE 两个模块,改造面符合最初设计。
目标保持 active。
- vLLM 0.29 正常启动,
-
-
本轮:批量内核打通,输出变正确,4 路并发首次跑出真实数字
1. 把两个内核都修对了
- gu:尺度组修正为 64,20 个 tile 逐个对拍
diff 0.0; - dn:真正的错误是行块数量算错——我按 8 个块(512 行)写,实际 2560 行需要 40 个块;改成
s = tile//40, rb = tile%40、网格(n, 200)后,全量对拍diff 9.9e-5。
现在每个专家只有 2 次内核 launch(原来 15 次),一个前向的 launch 数从约 2.6 万降到约 4 千。
2. 端到端结果(一个窗口内测完)
ready=200 single (8 tokens): 20 s -> " Paris.\nThe capital of France is" ✅ 正确 4-way (4×8 tokens): 33 s 1 ' Paris. Is this statement true or false' 2 ' Paris' 3 ' Paris' 4 ' Paris' ✅ 四路都对指标 数值 单流 8 token / 20 s ≈ 0.40 tok/s(2.5 s/token) 4 路聚合 32 token / 33 s ≈ 0.97 tok/s 并发增益 2.4 倍(4 路 vs 单路) 质量 四路全部正确回答 "Paris"(PLE 仍关闭) 3. 意义
这是第一次同时拿到:正确输出 + 真实的并发加速 + 有理论依据的瓶颈定位。剩下的差距是纯性能工程,不再是"能不能"的问题:
- 每 token 2.5 秒里,大头是 1920 次 Python 循环 × 每专家 3.6 MB 的 H2D 拷贝(40 专家 × 48 层 × 3.6 MB ≈ 6.9 GB/次前向);
- 下一步做两件事就能上一个数量级:按层把活跃专家合并成一次批量内核(把 1920 次循环压到 48 次),以及层内专家驻留显存(热集),把 H2D 从 6.9 GB 降到接近 0。
4. 下一轮
- 层内批量:一次 launch 处理该层所有活跃专家(需要原子累加,接口已经验证);
- 热集驻留:把 48 层的专家按访问频率排序,前 X GB 常驻显存;
- 然后复测单流 / 4 路,目标 单流 >20 tok/s、4 路聚合 >60 tok/s;
- PLE 仍待修(独立模块)。
- gu:尺度组修正为 64,20 个 tile 逐个对拍
-
-
-
-
-
,
T terry 固定了此主题
-
-
-
@fcme打下来特团长请你吃山西菜
-
-
@fcme打下来特团长请你吃山西菜
-

-
本轮:按 Strata 逻辑把"频率热集"钉进显存,4 路从 24.7 秒降到 20 秒
实现
- 用 139 万 token 的真实路由统计算出每个专家的命中频率,生成四档热集(
/data/paiton-full/hot_set.json:2000 / 4000 / 6000 / 8000 个专家,含每层具体 id); - 启动后按层把热专家的 gu/dn 码本一次性搬进显存并常驻(不是 LRU,是频率钉死);
- 推理时热专家直接命中显存,冷专家才走原来的搬运路径;
- vLLM 的
--gpu-memory-utilization从 0.72 降到 0.60,给热集腾出空间。
实测(4000 档,7.4 GiB,理论覆盖率 34.3%)
指标 之前(LRU 2GB) 现在(频率热集 4000) 4 路 32 token 24.7 s 20.0 s 聚合吞吐 1.30 tok/s 1.60 tok/s MoE 每 block 17-19 ms 14.5-17.3 ms 质量 Paris Paris(四路全对) 这个结果说明了什么
- 热集确实有效,但只快了 23%,和"搬运只占 1.2 ms"的估算吻合:MoE 的 850 ms 里,真正搬运只占一成多,剩下全是"每个专家一次 Python 调用 + 一次内核 launch";
- 也就是说:Strata 的分层逻辑我们已经复刻了(热集常驻 + 按需取冷),但它治不了我们的主要瓶颈;
- 要再上一个量级,必须把"每层 10 个专家"合并成一次内核调用——即前面写好、但存在 0.02-0.13 数值差异的 grouped 内核。
下一轮
- 在热集已常驻的前提下,把 grouped 内核接回来(此时不需要拷贝,纯计算,最有条件跑对);
- 用"同一前向内 grouped vs 逐专家"的对照继续定位那 0.02-0.13;
- 目标:MoE 从 15 ms/block 降到 2-3 ms/block,单流进入 0.3-0.4 s/token,4 路聚合 3-4 tok/s。
- 用 139 万 token 的真实路由统计算出每个专家的命中频率,生成四档热集(
-
-
-
-
-
-
本轮:按 Strata 逻辑把"频率热集"钉进显存,4 路从 24.7 秒降到 20 秒
实现
- 用 139 万 token 的真实路由统计算出每个专家的命中频率,生成四档热集(
/data/paiton-full/hot_set.json:2000 / 4000 / 6000 / 8000 个专家,含每层具体 id); - 启动后按层把热专家的 gu/dn 码本一次性搬进显存并常驻(不是 LRU,是频率钉死);
- 推理时热专家直接命中显存,冷专家才走原来的搬运路径;
- vLLM 的
--gpu-memory-utilization从 0.72 降到 0.60,给热集腾出空间。
实测(4000 档,7.4 GiB,理论覆盖率 34.3%)
指标 之前(LRU 2GB) 现在(频率热集 4000) 4 路 32 token 24.7 s 20.0 s 聚合吞吐 1.30 tok/s 1.60 tok/s MoE 每 block 17-19 ms 14.5-17.3 ms 质量 Paris Paris(四路全对) 这个结果说明了什么
- 热集确实有效,但只快了 23%,和"搬运只占 1.2 ms"的估算吻合:MoE 的 850 ms 里,真正搬运只占一成多,剩下全是"每个专家一次 Python 调用 + 一次内核 launch";
- 也就是说:Strata 的分层逻辑我们已经复刻了(热集常驻 + 按需取冷),但它治不了我们的主要瓶颈;
- 要再上一个量级,必须把"每层 10 个专家"合并成一次内核调用——即前面写好、但存在 0.02-0.13 数值差异的 grouped 内核。
下一轮
- 在热集已常驻的前提下,把 grouped 内核接回来(此时不需要拷贝,纯计算,最有条件跑对);
- 用"同一前向内 grouped vs 逐专家"的对照继续定位那 0.02-0.13;
- 目标:MoE 从 15 ms/block 降到 2-3 ms/block,单流进入 0.3-0.4 s/token,4 路聚合 3-4 tok/s。
- 用 139 万 token 的真实路由统计算出每个专家的命中频率,生成四档热集(
版主审定:本帖设为精华,作者 +6 积分奖励,希望再接再厉!