修了三个bug,把Qwen 3.5在Mac Studio上跑成了日常主力
Andryo Marzuki 的桌面上摆着一台 Mac Studio M3 Ultra,96GB 统一内存。他原本把 DS4 Flash 当主力,可一旦上下文超过五万个 token,预填充就要等上三五分钟。那感觉不像在聊天,像在提交批处理作业。
于是他把目光转向阿里巴巴的 Qwen 3.5 122B。这是个 MoE 模型,激活参数只有约 100 亿,理论上很适合 Apple Silicon。但真正跑起来才发现,瓶颈不在模型,而在自己那一套推理栈里。
五万 token 之后它变成了一台批处理任务

长上下文是日常工作的常态。代码库、长文档、多轮对话,token 数轻松破五万。起初每轮预填充都要重算 KV,等待时间从秒变成分钟。
作者用 qMLX 来服务模型,这是 rapid-mlx 的一个分支,专门给 Qwen 做混合注意力优化。可优化再激进,也架不住缓存被反复打碎。每一次新请求,都像把刚砌好的墙推倒重来。
他把问题拆成三个可疑点,一个一个修。
Bug 一系统提示词里藏了个时间戳

第一个 bug 藏在系统提示词里。每一轮对话,系统消息都会被注入一个唯一的 message ID。这个 ID 让提示词永远做不到字节级一致。
KV cache 的复用非常苛刻:前缀必须完全一样。一个变动的 ID,意味着每次都要重新计算前缀。作者把它从缓存前缀里剔除,预填充立刻回归正常。
Bug 二从未发生过的回复

第二个 bug 更隐蔽。当用户在中途打断模型输出时,已经流式生成的回复会被直接丢弃。历史记录里不存在这段文本,但 KV cache 里却残留了它的影子。
下一次请求进来,缓存和对话历史对不上,模型开始凭空编造、输出混乱。他把中断时的已生成内容先写回历史再退出,KV 和文本终于对齐。
Bug 三检查点里的毒

第三个 bug 在 MLX 检查点里。每隔 256 个 token 就会写入一个完整检查点,但这个检查点缺少必要的 token key。它还挤占了有效检查点的位置。
restore 时读到这种无效条目,缓存恢复失败,只能从头算。他给这些”毒”检查点降低优先级,并在恢复期间禁止写入垃圾检查点。
修完后,13k 到 54k token 的预填充从几分钟降到秒级;32k 重复提示在磁盘缓存加持下只要 0.64 秒。Qwen 3.5 在他这台消费级 Mac 上,成了真正的日常主力。
来源:mrzk.io | Hacker News
