Skip to content

修复 Qwen3.5系列模型在CPU后端推理长文本时质量较低,出现重复段落的问题。#4632

Open
v0jiuqi wants to merge 1 commit into
masterfrom
sync/20260716-1637
Open

修复 Qwen3.5系列模型在CPU后端推理长文本时质量较低,出现重复段落的问题。#4632
v0jiuqi wants to merge 1 commit into
masterfrom
sync/20260716-1637

Conversation

@v0jiuqi

@v0jiuqi v0jiuqi commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

本次代码修改将线性注意力计算中的浮点数精度从FP16提升到FP32以减少误差累积,从而提高模型在长时间推理时的稳定性,避免生成重复内容的问题。

GitOrigin-RevId: 5f9343d605d7b85c4790b9478186cc9f4e5bf4be

Description

Module

Type

  • Feature
  • Bugfix
  • Perf
  • Refact
  • Style
  • Doc
  • Test
  • Chore

Checklist

  • Commit message follows [Module:Type] Description format
  • Code compiles without errors
  • Tested on relevant platform(s)
  • No unrelated format or style changes included

本次代码修改将线性注意力计算中的浮点数精度从FP16提升到FP32以减少误差累积,从而提高模型在长时间推理时的稳定性,避免生成重复内容的问题。

GitOrigin-RevId: 5f9343d605d7b85c4790b9478186cc9f4e5bf4be
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


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.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 来自 MNN 助手的智能建议

// ── 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) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

性能优化建议:
将累加器从 fp16 提升到 fp32 是非常必要的精度修复,逻辑实现也没有问题。但是,原代码中包含的循环展开(每次迭代处理 8 个 dk 元素)和使用 vfmaq_laneq_f16 进行向量化加载 kq 的逻辑在此修复中被全部移除,退化为纯标量的 k[i]q[i] 加载与循环。考虑到 MNN 对移动端极致性能的追求,这种写法会导致明显的性能回退。
建议:在保证 fp32 累加的前提下,尝试恢复行循环的展开和 k/q 的向量化加载。例如:使用 vld1q_f16 加载 kq 后转换为 float32x4_t,再配合 vfmaq_laneq_f32 进行乘加操作,以减少循环开销和标量内存访问延迟。

}
#endif // __aarch64__ && MNN_USE_NEON

namespace MNN {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

性能优化建议:
与前一个代码块类似,MNNDualMatVecFp16_Fp32AccumMNNDecayRankOneUpdateFp16_Fp32Accum 中对 kqdelta 的访问也是纯标量加载 (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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

跨平台兼容性 (编译问题):
新的 C++ 实现 MNNDualMatVecFp16_Fp32AccumMNNDecayRankOneUpdateFp16_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 的回退实现。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants