修复 Qwen3.5系列模型在CPU后端推理长文本时质量较低,出现重复段落的问题。#4632
Conversation
本次代码修改将线性注意力计算中的浮点数精度从FP16提升到FP32以减少误差累积,从而提高模型在长时间推理时的稳定性,避免生成重复内容的问题。 GitOrigin-RevId: 5f9343d605d7b85c4790b9478186cc9f4e5bf4be
|
jingbang.yjb seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
| // ── Scalar tail (defensive; d_v < 16 remainder) ── | ||
| for (; j < dv; ++j) { | ||
| float ok = 0.0f, oq = 0.0f; | ||
| for (size_t i = 0; i < dk; ++i) { |
There was a problem hiding this comment.
性能优化建议:
将累加器从 fp16 提升到 fp32 是非常必要的精度修复,逻辑实现也没有问题。但是,原代码中包含的循环展开(每次迭代处理 8 个 dk 元素)和使用 vfmaq_laneq_f16 进行向量化加载 k 和 q 的逻辑在此修复中被全部移除,退化为纯标量的 k[i] 和 q[i] 加载与循环。考虑到 MNN 对移动端极致性能的追求,这种写法会导致明显的性能回退。
建议:在保证 fp32 累加的前提下,尝试恢复行循环的展开和 k/q 的向量化加载。例如:使用 vld1q_f16 加载 k 和 q 后转换为 float32x4_t,再配合 vfmaq_laneq_f32 进行乘加操作,以减少循环开销和标量内存访问延迟。
| } | ||
| #endif // __aarch64__ && MNN_USE_NEON | ||
|
|
||
| namespace MNN { |
There was a problem hiding this comment.
性能优化建议:
与前一个代码块类似,MNNDualMatVecFp16_Fp32Accum 和 MNNDecayRankOneUpdateFp16_Fp32Accum 中对 k、q 和 delta 的访问也是纯标量加载 (static_cast<float>(k[i]))。对于较大的 dk(如 128),标量访存会带来不必要的开销。建议同样考虑对 k, q, delta 进行向量化加载并配合 FMA lane 指令来进一步提升性能。
| FUNC_PTR_ASSIGN(gInstance->MNNDecayRankOneUpdate, MNNDecayRankOneUpdateFp16_Fp32Accum); | ||
| #if defined(__aarch64__) && defined(MNN_USE_NEON) | ||
| // Fused kernel uses NEON intrinsics directly (not extern asm), so the | ||
| // assignment must follow the same guard as the function body above. |
There was a problem hiding this comment.
跨平台兼容性 (编译问题):
新的 C++ 实现 MNNDualMatVecFp16_Fp32Accum 和 MNNDecayRankOneUpdateFp16_Fp32Accum 被放置在 #if defined(__aarch64__) && defined(MNN_USE_NEON) 宏保护内。但是在 Arm82Functions::init() 中,对它们的 FUNC_PTR_ASSIGN 却发生在宏保护块之外。
如果在未定义 __aarch64__ 或 MNN_USE_NEON 的情况下编译此代码(例如在部分跨平台编译配置中),由于这两个符号未被声明,会导致编译失败。
建议:将这两行 FUNC_PTR_ASSIGN 移动到紧随其后的 #if defined(__aarch64__) && defined(MNN_USE_NEON) 条件块内部,或者提供非 NEON 的回退实现。
本次代码修改将线性注意力计算中的浮点数精度从FP16提升到FP32以减少误差累积,从而提高模型在长时间推理时的稳定性,避免生成重复内容的问题。
GitOrigin-RevId: 5f9343d605d7b85c4790b9478186cc9f4e5bf4be
Description
Module
Type
Checklist
[Module:Type] Descriptionformat