Skip to content
懒人吧
Go back

小模型原地打转:模型为什么会陷入反复循环以及如何解决

编辑页面

小模型原地打转:为什么模型会陷入”反复循环”以及如何解决

引言

使用小模型(7B/9B/13B)的时候,你有没有遇到过这种情况:

用户:请写一个 Python 函数计算斐波那契数列
模型:我来写一个 Python 函数计算斐波那契数列
模型:首先我们需要定义函数
模型:让我再想想,我们可以用递归
模型:或者用循环更高效
模型:好的,我来写一个 Python 函数
模型:这个函数应该接受参数 n
模型:首先我们需要定义函数
...(陷入循环,重复上述内容)

小模型在处理复杂任务时,容易出现”反复循环”的问题。 这不是模型”傻了”,而是有明确的技术原因。

一、什么是”反复循环”

典型表现

  1. 内容重复:反复说同一段话,每次都略有变化但整体循环
  2. 无法收尾:生成了几百个 token 还在”考虑”,迟迟不给最终答案
  3. 自我否定:先给出一个方案,然后否定,再给另一个,再否定
  4. 忘记上下文:说了后面的忘了前面的,导致逻辑无法推进

在高、低参数模型中的表现差异

对比项大模型(35B+)小模型(7B-14B)
循环发生率较高
复杂任务能稳定推进容易卡住
自我修正修正后继续推进修正后可能循环
上下文利用充分利用上下文容易”走失”

二、根本原因分析

原因一:注意力机制的”局部锁定”

小模型的注意力头数量有限,当上下文变长时,注意力分布倾向于聚焦在最近的 token 上,导致模型”忘记”了较早的输出内容,从而无意识地重复之前的内容。

正常的注意力分布:
[我][要][写][一][个][函][数][...][def][fib][(][n][)]
  ↑  ↑  ↑  ↑  ↑  ↑  ↑      ↑  ↑   ↑   ↑   ↑
  分散关注,能看到全局

循环时的注意力分布:
[我][要][写][一][个][函][数][...][def][fib][(][n][)]
                          ↑↑↑↑↑↑↑↑↑↑
                    只盯着最近的内容,忘了前面已经写过了

原因二:模型容量不足

用一个比喻:

原因三:概率采样的”随机游走”

模型生成 token 本质是概率采样。小模型的概率分布更”扁平”——即在多个可能的 token 之间概率接近,容易在不同选项之间来回切换:

在生成某个步骤时:
  - "递归实现" 概率 35%
  - "循环实现" 概率 32%
  - "用数学公式" 概率 28%
  → 模型在不同方案间反复横跳

大模型的概率分布更”尖锐”:

  - "循环实现" 概率 72%  ← 明确的选择
  - "递归实现" 概率 18%
  - "用数学公式" 概率 10%
  → 迅速确定方向,继续推进

原因四:缺乏”闭环能力”

复杂任务需要模型具备 “规划-执行-检查-完成” 的闭环能力。小模型的规划能力弱,容易在”执行”环节迷失方向。

三、实际案例:我们在 9B 模型上的观察

在之前部署的体验中,9B 级别模型在处理以下任务时容易出现循环:

任务类型循环表现
写代码(多函数)写到第二个函数时忘记第一个函数的逻辑
多步骤推理推理到第三步时忘了第一步的结论
长文本总结总结到后半部分内容开始重复前半部分的表述
工具调用(Function Calling)反复调用同一个工具,说”让我再查一下”

而切换到 35B A3B 模型 后,同样的问题明显减少——不是因为架构变好了,而是总参数量的增加提供了更大的”工作记忆容量”

四、解决方法

方法一:调低温度(Temperature)

最直接有效的方法:

# 循环时——降低温度,让输出更"确定"
temperature = 0.3  # 从默认的 0.7-0.8 降低

原理:低温让高概率 token 更突出,减少在不同选项间的摇摆。

方法二:增加重复惩罚(Repetition Penalty)

# 在 llama.cpp 中
llama-server \
  --repeat-penalty 1.15 \  # 默认 1.0,适当提高
  --frequency-penalty 0.1 \
  --presence-penalty 0.1

方法三:缩短上下文窗口

小模型不适合超长上下文。如果发现循环,尝试:

给模型减负,让它专注在当前任务上。

方法四:优化提示词(Prompt Engineering)

让小模型”提前规划”:

❌ 不好的提示词:
"写一个计算器程序。"

✅ 好的提示词(引导模型按步骤推进):
"请按以下步骤写一个计算器程序:
1. 先定义加减乘除四个函数
2. 再写主菜单循环
3. 最后组装成完整程序
在完成步骤 1 之前不要跳到步骤 2。"

明确的步骤引导能有效防止模型”走丢”。

方法五:使用大模型验证/修正

在 Agent 架构中,可以用小模型生成初稿,大模型做最终验证:

小模型(9B)→ 生成初稿(快,可能有循环)
大模型(35B)→ 检查并修正(慢,但稳定)

这也是我们最终使用 35B A3B 配合 9B Agent 的思路。

五、不同场景的推荐配置

场景推荐模型温度重复惩罚上下文
简单问答小模型(7-9B)0.71.08K
代码生成中/大模型(14-35B)0.31.1516K
长文总结大模型(35B+)0.51.132K+
多轮对话中/大模型0.61.0516K
工具调用中/大模型0.31.18K

六、总结

小模型循环的根本原因是”容量不足”——总参数限制了工作记忆和规划能力。

解决手段效果难度
降低温度⭐⭐⭐低(改参数)
增加重复惩罚⭐⭐⭐低(改参数)
缩短上下文⭐⭐
优化提示词⭐⭐⭐⭐
大模型验证⭐⭐⭐⭐⭐高(需双模型)
换更大的模型⭐⭐⭐⭐⭐⭐终极方案

如果条件允许,35B A3B 这样的 MoE 模型是解决循环问题的最佳选择——既保持小模型的速度(仅激活 3B),又拥有大模型的容量(总参数 35B)。


编辑页面
Share this post on:

Previous Post
反常识:为什么有些 7B 模型比 9B 模型更吃显存?(全面分析)
Next Post
按卡索骥:如何根据自己的显卡找到合适的模型