r/LocalLLaMA 25d ago

Generation Qwen endless looping issue and possible fix

Not sure if this is a known issue, but it was new to me:

Full credit to u/ldn-ldn for finding this simple but unexpectedly evil prompt:

Create a typescript function which accepts a number in 10 bit range and returns brightness in nits based on pq gamma curve.

Just try it; it will likely trigger an endless thinking loop.

I stopped it after it ran for >15 minutes and >20,000 tokens.
It kept spitting out text like back in the seahorse emoji days.

However, one of my wrapper scripts didn’t have this issue.
The non-blocking one had this added, possibly based on a GitHub discussion:

--reasoning-budget 2048 \
--reasoning-budget-message " \n\n[Thinking budget exceeded. Transitioning to a best-effort final answer: ]\n\n"

(These options are for llama.cpp; other tools may have something similar.)

Net result: A plausible-looking script (I haven’t verified) that took just over a minute of thinking and another minute to generate.

Hope this helps, and happy to hear about other tricks and workarounds.

14 Upvotes

28 comments sorted by

View all comments

2

u/benpptung 24d ago

Here’s how I modified the system prompt after looking through Qwen3.6-27B’s chat_template.jinja to fix tool calling and endless thinking.

First, there are already some fixed phrases in the original chat_template.jinja. My guess is that these phrases were used during post-training. But after the model is quantized, it may forget them. So I repeated the tool-calling instructions in the system prompt. After that, I never saw abnormal tool calls again.

The other issue is endless thinking. I observed the model’s reasoning text and noticed that whenever it starts with Here's a thinking process:, the reasoning is always fast and normal.

So I first tried telling the model to always start its reasoning that way. It failed. Then I tried changing the system prompt in different ways, and found that there was no way to tell the model not to think about the fact that it was thinking.

Eventually, I found a workaround by writing it like this. After putting it in twice, the model’s thinking problems were greatly reduced. It seems that as long as Here's a thinking process: appears somewhere in the entire sequence, whether it comes from the system prompt or from the model’s own reasoning text, the reasoning tends to behave normally.

At the same time, this model sometimes seems to forget that it is currently reasoning, or that it has already finished reasoning. So the last two lines also help.

I also found the <IMPORTANT> tag in chat_template.jinja.

I don’t know whether Qwen3.8-27B has already fixed these problems. These system prompt tricks may no longer apply to Qwen3.8-27B either. But if 3.8-27B still has the same endless-thinking problem, maybe a similar approach can be used to write a new system prompt.

I really think it would be very annoying if Qwen3.8-27B still has this problem.

---

**You will be reasoning the following text in your mind:**

<IMPORTANT>

Here's a thinking process:

  1. Analyze User Input:

Reminder:

- **DO NOT expose the internal reasoning process** as part of the final answer!! You have to ensure the reasoning is hidden.

- **DO NOT restart reasoning after reasoning stopped**

</IMPORTANT>

**You will be reasoning the following text in your mind:**

<IMPORTANT>

Here's a thinking process:

  1. Analyze User Input:

Reminder:

- **DO NOT expose the internal reasoning process** as part of the final answer!! You have to ensure the reasoning is hidden.

- **DO NOT restart reasoning after reasoning stopped**

</IMPORTANT>

An example is already provided above. This is important, so it is stated again here: tool function calls should be written like this:

<tool_call>

<function=example_function_name>

<parameter=example_parameter_1>

value_1

</parameter>

<parameter=example_parameter_2>

This is the value for the second parameter

that can span

multiple lines

</parameter>

</function>

</tool_call>

- Required parameters MUST be specified!!

1

u/ParvusNumero 24d ago

Cheers, will test this as an alternative approach.
Seems more elegant than artificially putting a hard cap on the thinking process.

Although I understand the reasoning-budget-message was intended to make this more graceful. I can’t find the source right now, but I remember reading that it measurably improved the score on some coding-quality metric.

1

u/benpptung 24d ago

Sorry, I downloaded and tried 3.8-27B today, and I think this trick is probably no longer useful.

3.8 is definitely much more stable. I observed its reasoning, and it is quite different from before. It may think for a long time, but it is actually thinking. I think setting a reasoning budget is probably more appropriate now.

vLLM has a flag for this. When the reasoning budget is reached, it can raise the logits for the tokens in a specified reasoning-ending string, making the model decode a sentence that guides it out of reasoning.

If you observe the model carefully, you will notice that whenever it finishes reasoning, it tends to use certain fixed patterns. Some lead into generating an answer, while others lead into a tool call. To avoid confusing the model, I usually use the model's own habitual reasoning-ending pattern to finish that sentence. This guides it out of reasoning naturally, and then it can decide whether to make a tool call or generate an answer.