端侧部署小型 MoE 模型要先认清总参数与激活参数的差别。以 LFM2.5-24B-A2B 为例,模型共 240 亿参数,每个 token 只激活约 20 亿,架构上是 40 层、每层 MoE 块 64 个专家、top-4 路由,混合门控短卷积与 GQA,上下文窗口 131072 tokens,词表 128K。稀疏激活压低的是单次前向的计算量,显存占用和内存带宽仍由总参数决定。适合想在本地跑智能体、又不愿把数据送出去的开发者。
稀疏激活省的是算力,不是显存
MoE 把每层的专家网络拆成很多份,路由只挑少数几个参与计算。240 亿总参数、20 亿激活意味着权重表要完整装下 240 亿,每次前向只读其中约 20 亿。省下的是乘加次数。权重体积一点没少。同尺寸稠密模型每个 token 都要把全部权重过一遍,差距就出在这里。
端侧瓶颈为什么落在内存带宽
生成每个 token 都要把激活到的权重从内存搬到计算单元。带宽决定速度上限,容量决定能否装下。可以先用 T ≈ B ÷ (A × b) 估个量级上限,B 是有效内存带宽,A 是激活参数量,b 是每参数字节数。这是估算方法,真实结果还会被缓存命中率和调度开销拉低。按这个式子反推,想跑到每秒几十个 token,带宽和激活参数量的组合只剩那么几档。
本地运行时怎么选
- 走 llama.cpp 一路,用 GGUF 权重,跨平台最省事,CPU 和多种加速后端都能跑。
- 苹果芯片上选 MLX,能吃满统一内存的带宽。
- 需要在服务端做高并发批处理,选 vLLM 或 SGLang 这类方案。
- 要覆盖多种加速器,考虑 ONNX 这条路径。
选定之后把权重格式和运行时版本绑在一起,别混用不同来源的量化文件。
量化格式怎么选
先按可用内存筛掉装不下的格式,再拿任务集比对质量。别只看困惑度。
- 4 bit 量化,体积约为 16 bit 的四分之一,多数任务上精度损失可接受,端侧首选。
- 5 bit 和 6 bit,精度更稳,内存与带宽压力相应变大。
- 8 bit 接近原始精度,端侧设备通常装不下。
上下文长度和 KV cache 怎么估
KV cache 字节数 ≈ 2 × 层数 × KV 头数 × 头维度 × 序列长度 × 每元素字节数。以 40 层为例,上下文拉到 131072 时这一项会迅速超过权重本身。这是估算方法,实际占用还跟运行时的内存分配策略有关。
- 先定任务真正需要的上下文长度,别默认开满。
- 按上面的算式算一遍 KV cache,跟权重体积相加,看是否超出可用内存。
- 超了就降上下文,或者开 KV cache 量化,两者都会影响质量。
- 改完之后重跑任务集,确认没有明显退化。
首 token 延迟和生成吞吐怎么测
测之前把输入输出长度固定下来。各跑多轮取中位数。单次结果不算数。
- 用运行时自带的计时输出,把预填充和逐 token 生成两段分开记录。
- 分别记下首 token 延迟、生成速度和内存峰值三个数。
- 换几档上下文长度重测,看速度曲线的拐点落在哪里。
跑不起来时,先查模型文件与运行时版本是否匹配,再看上下文参数有没有超过训练窗口,最后确认是不是内存不足触发了换页。
内存峰值与持续推理的热限制
短时跑分好看不代表长时间稳定。端侧设备的持续功耗预算有限,长时间推理会降频。压测时把内存峰值和降频后的速度一起记下来,只看前几十秒会偏乐观。
哪些场景不适合放在端侧
知识密集的问答、需要检索大量长文档、要求高并发的服务端负载,这些放端侧都不划算。模型更擅长工具调用与指令跟随,知识面相对薄,配检索更合适。
常见问题
240 亿参数的模型手机能跑吗? 看量化后的体积和可用内存。4 bit 之后仍需不小的内存预算,先算容量再决定。
上下文开满是不是更好? 不一定。KV cache 会吃掉内存并拖慢速度,按任务实际需要的长度设置。