官方那份 16 GB 的 MiniCPM-o 4.5 权重一个字节都没改。MiniCoach 被编译成一个 15 MB 的外挂文件,在昇腾 910B3 单卡上跑完了同一套 208 题——命令行里多一个参数, 教练就换了一个人。
| 芯片 | Ascend 910B3 单卡,HBM 64 GB(npu-smi 25.5.2) |
| CANN | 9.1.0(V100R001C11SPC001B243),driver 25.5.2 |
| 推理框架 | llama.cpp-omni(赛事指定),-DGGML_CANN=ON 现场编译,SOC 自动识别为 ascend910b3 |
| 底座权重 | 官方 MiniCPM-o-4_5-F16.gguf(16 GB,赛事推荐的 FP16 包)+ 官方 vision 投影器(1.1 GB),只读挂载,未做任何改动 另跑了一份 BF16:用 llama.cpp 官方转换脚本,从 OpenBMB 发布的 bfloat16 权重里抽出语言塔转成 BF16 GGUF,与 GPU 侧同精度对照。模型本身没换过。 |
| MiniCoach | minicoach-lora-F16.gguf,15 MB,144 个张量,只覆盖语言塔的 q/v 投影 |
| 系统 | aarch64 / openEuler 内核 5.10 / Python 3.12 / gcc 11.4 |
视觉塔与语言塔全部跑在 NPU 上(-ngl 99)。 整个过程不连任何云端 API。
# 底座:官方权重,原样加载 llama-mtmd-cli \ -m MiniCPM-o-4_5-F16.gguf \ --mmproj MiniCPM-o-4_5-vision-F16.gguf \ -ngl 99 --temp 0 # MiniCoach:同一份底座,外挂 15 MB llama-mtmd-cli \ -m MiniCPM-o-4_5-F16.gguf \ --mmproj MiniCPM-o-4_5-vision-F16.gguf \ -ngl 99 --temp 0 \ --lora minicoach-lora-F16.gguf
底座那 16 GB 留在只读目录里没动过。要在两个教练之间来回切, 换的是一个 15 MB 的文件,不是重下一份模型。
| 画面 | 底座模型 | + MiniCoach |
|---|---|---|
| 原片 | {{EX_CLEAN_BASE}} | {{EX_CLEAN_V19}} |
| 压到亮度 4/255 | {{EX_DARK_BASE}} | {{EX_DARK_V19}} |
| 只剩左下角 1/9 | {{EX_CROP_BASE}} | {{EX_CROP_V19}} |
三题用的是同一段 12 秒的弯举片段,用户都没说话,变的只有画面: 一份原片,一份压到亮度 4/255,一份只留左下角九分之一。 底座能看清时给的是教练口令,看不清时退化成复述题面; 挂上适配层之后,它先让人把手机摆好。这三行都是昇腾上跑出来的原文,一个字没改。
| 维度 | 底座模型 | + MiniCoach |
|---|---|---|
| 总分(208 题) | {{BASE_TOTAL}} | {{V19_TOTAL}} |
| 他说疼,必须让他停 | {{BASE_PAIN}} | {{V19_PAIN}} |
| 看不清,必须让他摆好机位 | {{BASE_CAM}} | {{V19_CAM}} |
| 干净画面不许瞎编 | {{BASE_FAB}} | {{V19_FAB}} |
| 看得清 / 看不清的判别力 | {{BASE_J}} | {{V19_J}} |
| 说完能正确收尾 | {{BASE_EOS}} | {{V19_EOS}} |
| 客服腔("请" / "您") | {{BASE_POLITE}} | {{V19_POLITE}} |
两轮跑在同一张卡、同一个进程配置、同一份人设卡、同一份题上,温度都是 0, 唯一的差别是命令行里有没有那个 --lora。 判分是写死的规则脚本,不让模型给自己打分。这 7 个动作在视频训练里一次都没出现过。
| 官方 MiniCPM-o-4_5-F16.gguf | 底座模型 | + MiniCoach |
|---|---|---|
| 总分(208 题) | {{F16_BASE_TOTAL}} | {{F16_V19_TOTAL}} |
| 他说疼,必须让他停 | {{F16_BASE_PAIN}} | {{F16_V19_PAIN}} |
| 看不清,必须让他摆好机位 | {{F16_BASE_CAM}} | {{F16_V19_CAM}} |
| 看得清 / 看不清的判别力 | {{F16_BASE_J}} | {{F16_V19_J}} |
赛事 checklist 推荐创新应用赛道用 FP16 权重,所以这一组也跑了。 两种数值格式下,挂上适配层之后的方向完全一致。
208 道题跑在同一个常驻进程里,模型只装一次卡。 每题之间清空上下文并重新注入人设卡,题与题之间互不影响。
这一组是刻意对齐过的:两边都是 bfloat16,都没有量化; 题面逐字相同(题面 SHA-256 都是 d75465d6…), 视频片段一一对应;每帧进模型的画面 token 数也几乎一样——昇腾侧实测每帧 64,GPU 侧 65.6。 剩下的差别只有芯片和实现:一条是 NVIDIA + Python + PyTorch 算子、适配层以 PEFT 形式挂载; 一条是昇腾 + C++ + CANN 算子、适配层以 15 MB 的 GGUF 外挂。 底座的绝对分仍然不同(两套算子实现本来就不可能逐位一致), 但挂上适配层之后表现明显变好这件事,在两块芯片上都成立。
昇腾侧的逐题输出原文、判分脚本、外挂权重和这套 208 题全部开源。 判分是纯规则,不需要显卡就能复算下面每一个数字。
# 复算昇腾侧的成绩(不需要 NPU,也不需要 GPU)
python3 eval/bench.py bench/bench_gold.json \
results/npu_base_P3.jsonl \
results/npu_v19_P3.jsonl
| 评测集 | fd414a00… (两轮结果里都写着这个哈希,对不上就拒绝比较) |
| 题面 | d75465d6… (与 GPU 侧逐字一致) |
| 外挂权重 | 36c79d9b… minicoach-lora-F16.gguf |