Ling-3.0-tiny-RKNN / docs /MTP_LATEST_20261002.md
Sariel00's picture
Keep MTP opt-in: default-off build, isolated experimental package and measurements
3706f1c verified
|
Raw History Blame Contribute Delete
9.1 kB

最新混合量化模型与 MTP 组合测试

2026-10-02,在 NanoPi M6 / RK3588 / 16GB(10.1.20.33)测试。 结论:最新主模型与 MTP 可以一起加载并连续前向,未改变本组主模型生成 token;但预测命中偏低,尚未证明投机解码收益。

实验开关(默认关闭)

LING3_EXPERIMENTAL_MTP=OFF 是 CMake 默认值。关闭时,MTP 层、状态、 前向函数、实验 API 和 mtp-benchmark 命令均不编译;正常推理只运行原主干, 不初始化 MTP 权重和 KV。追加了 MTP 的模型文件不会自动激活它。

开启编译也不会把 MTP 加入终端或 OpenAI API 对话流程。Decoder 构造函数 不再自动加载 sidecar,只有实验探针显式调用 EnableMtp() 才会初始化。 现有正常生成、KV 复用和服务流程没有调用此接口。

以下性能和内存数据为之前显式运行实验探针的记录,不代表默认构建开销。 实验模型保留在 models/local-experimental/mtp/,不进入正式 v6 发布包。 本地及板端的独立 MTP 编译目录、旧实验二进制已清理;源码、模型和测试记录 保留,可按下方命令重新构建。当前源码复现实验时必须单独开启编译开关;默认二进制的 帮助信息不包含 mtp-benchmark,测试脚本会在锁频前提示编译开关未开启。

版本与口径

主干使用本工作区 models/local-final/v6-board-test/ling3-tiny-w4.l3r, SHA256 为 80f0086247328fe77b2f939df460b4955287b6f75f6aaada85512c56e652f435。 它是混合 W4A8/W8A8 包,包含 91 个 BF16 源线性权重张量,在运行时走 W8A8; 不是上一轮 minimind-o/Ling3RKNN 的旧 W4 实验主干。

MTP 来自 inclusionAI/Ling-3.0-tiny-base 的 layer 24,使用此前已转换的 W4A8 资产。仅追加 798 个 MTP 张量,原主干 18,029 个张量保留原数据并逐项 验证 SHA256;不重新量化主模型。MTP 使用主模型的共享 W8A8 输出头。

组合包:models/local-experimental/mtp/ling3-tiny-v6-mtp-experimental.l3r, 5,188,395,008 bytes,约 4.832 GiB。 SHA256 为 edfc670a0d27d9e5db1a49e18584adb1f47af1120b2060cfa5042ec9332ce8a9。 正式 v6 模型和便携发布二进制未替换。

使用本工作区根目录源码的实验 HasMtp / EvalMtp 与 mtp-benchmark, 在板端重新编译。该源码与 README 中 2026-09-22 的 engine/source/ 历史性能测试版本不同,不把新旧结果视为同成本优化对比。

两个模型均初始化 32K 容量,实际输入为 128、44、42、39 token, 输出均为 64 token;这是短请求测试,不是 32K 实际输入测试。每题在同一个 驻留进程中预热一次,再测三轮;切换题目时重置对话状态,保留权重和 RKNN context。固定中文性能题、故事题、办公题、解释题均关闭 thinking,贪心解码。

CPU 大核 2.304/2.352 GHz、NPU 1 GHz、DMC 2.4 GHz,固定最高频率。 启用专家预加载、三核平衡调度、共享输入、SIMD/vector math。 MLA attention 使用 CPU,GDN 使用 FP32 CPU 路径;线性层和专家矩阵使用 NPU。 采样未发现降频,最高温度 58.23°C;推理进程未使用 swap,测试后频率已恢复。

连续速度与内存

速度取预热后三轮合计解码时间,均计入首 token 后的 63 次计算。

项目 最新主模型 加载 MTP、只运行主模型 主模型逐步追加 MTP
四题合计解码速度 18.69 token/s 18.71 token/s 15.54 token/s
固定 128/64 题速度 18.43 token/s 18.56 token/s 15.34 token/s
主模型每步平均 53.35 ms 53.32 ms 53.54 ms
MTP 每步平均 — — 10.54 ms
MTP 层 / 输出头 — — 2.03 / 8.51 ms
预热后进程 RSS 6,516~6,524 MiB 7,012~7,021 MiB 7,012~7,021 MiB
进程峰值 RSS 6,952 MiB 7,021 MiB 7,021 MiB

RSS 约从 6.37 GiB 增至 6.86 GiB,同题稳定态增量约 497 MiB。 MTP 增加一个 MLA 层,32K BF16 KV 本体增加 320 MiB;其他增量包括专家与 投影权重、RKNN context 和工作内存。共享输出头没有另复制一整套权重。 峰值还包含构造期间临时映射,不能直接用两次冷启动峰值差计算 MTP 的内存增量。 RSS 包含 NPU 共享映射,是进程统计,不等于整个系统内存差值。

输出头约占 MTP 前向时间的 **81%**。上一轮旧 W4 主干的 MTP 为 6.85 ms、 输出头 4.76 ms;最新模型使用共享 W8A8 输出头,不能沿用旧包的成本估算。

本探针逐 token 填满 MTP 缓存:固定 128-token 题的主模型填充约 6.8 秒, 追加 MTP 后约 8.1 秒。这不是正式批量 prefill 的 TTFT,不能与 README 的 753 ms 直接比较。

预测与主模型一致性

问题 输入 token MTP 下一 token Top1 命中
固定工作安排性能题 128 3/63,4.76%
中文故事 44 6/63,9.52%
项目会议议程 42 3/63,4.76%
长上下文原理解释 39 5/63,7.94%
四条不同序列合计 — 17/252,6.75%

每题三轮相同,重复轮次用于测速度,不能当作更多独立质量样本。 加入 MTP 后每轮主模型 Top1 均为 64/64 一致;四题的生成 token hash 也与不含 MTP 的原模型一致。这只证明本组生成序列一致,没有完整 logits 数值等价认证,也不是通用问答正确率。

目前测的是使用真实主干 hidden 和正确历史的单步 NEXTN;不是连续预测 四个候选后的实际投机接受率。主模型批量验证、接受前缀提交、拒绝回滚及 MTP 会话状态恢复尚未实现。直接顺序追加 MTP 会降低速度,当前命中表现 也不足以支持“预测四个、接受两个”的假设。

下一步应先对照桌面参考定位预测偏差,包括 MTP 量化损失、主干与 sidecar 兼容性、位置和缓存对齐。已核对上游 HF 实现确实传入主模型最终归一化后的 hidden;不应在没有数值对照时擅自去掉这一归一化。先修预测质量,再做完整 投机验证和输出头优化。

使用与复现

在 RK3588 上显式开启实验编译,使用独立构建目录:

cmake -S . -B build-mtp -DCMAKE_BUILD_TYPE=Release \
  -DLING3_WITH_RKNN=ON -DRKNN_ROOT=./vendor/rknpu2 \
  -DLING3_EXPERIMENTAL_MTP=ON
cmake --build build-mtp -j4 --target ling3-rknn

普通发布使用 README 中的默认 OFF 配置。CLI 参数示例如下,依赖匹配的 RKNN/ICU 用户态运行库;定量复现请使用后面的脚本设置优化环境。正式便携 二进制尚未加入这个实验 CLI。模型头中的 4096 是原包默认容量,本测试显式 传入 32768 初始化,不代表实际输入被限制在 4096。

./build-mtp/ling3-rknn mtp-benchmark \
  models/local-experimental/mtp/ling3-tiny-v6-mtp-experimental.l3r \
  128 64 3 32768 tests/data/mtp_probe_questions.txt

tools/mtp_resident_benchmark.py 会设置优化环境、临时锁频、采样 CPU/NPU、 内存及温度,正常结束和 SIGINT/SIGTERM 时恢复原设置:

sudo python3 tools/mtp_resident_benchmark.py \
  ./build-mtp/ling3-rknn \
  models/local-experimental/mtp/ling3-tiny-v6-mtp-experimental.l3r \
  --runtime /path/to/rknn/lib --output ./results/mtp-combined-new \
  --context 32768 --seqlen 128 --tokens 64 --rounds 3 \
  --cases tests/data/mtp_probe_questions.txt

对照时将模型路径换成 models/local-final/v6-board-test/ling3-tiny-w4.l3r, 使用新的输出目录。脚本拒绝覆盖旧结果,一次只运行一个模型进程。

tools/append_mtp_package.py 可从含量化 MTP 张量的 .l3r 追加 layer 24, 不要求原始主模型或重新量化主干:

python3 tools/append_mtp_package.py \
  --base models/local-final/v6-board-test/ling3-tiny-w4.l3r \
  --mtp-package /path/to/package-containing-layer24.l3r \
  --output ./work/ling3-tiny-v6-mtp-new.l3r

MTP 缓存目前要求连续填满。跳过前缀、重复提交同一个位置、只恢复主模型 缓存后直接调用 MTP 都会被接口检查拒绝;不能把主模型状态复用直接视为 MTP 状态复用。

主机侧 8 项机制测试通过,包含新增的 MTP 精度族分类检查。板端两组测试 均 exit 0,本地生成的组合模型 SHA256 与板端一致。

整理实验开关后,主机侧默认 OFF 与显式 ON 两种构建分别通过全部 8 项测试;检查默认静态库不含 EnableMtp、HasMtp、EvalMtp 导出符号, 默认 CLI 不含 mtp-benchmark,禁用的实验命令不会打开模型文件。此轮没有 重跑板端性能测试,上面的数值仍是此前保存的实测记录。

结果摘要与 合包审计 保存在工作区。完整前向日志、频率元数据和占用采样保留在同目录的 baseline-32k/、combined-32k/,以及板端 /home/serial/ling3-latest-mtp-20261002/results/。