Skip to main content
Thinking models reason before they respond. They write their reasoning into a <think>…</think> block at the start of the reply and then give the final answer:
This page shows how to run a thinking model on text and on images, how to separate the reasoning from the answer, and how to switch thinking off where a model supports it. The examples use Hugging Face Transformers and OpenAI-compatible servers. Thinking helps most on tasks with several steps, such as math, logic, documents and charts, planning, and tool use in agents. Every reasoning token is a generated token, so thinking also makes replies longer and slower (see Leave room for the reasoning).

Use thinking

Thinking is on by default for the models in the support table. Some chat templates prefill the assistant turn with <think>; others leave the model to generate the thinking tokens itself. On models with a thinking switch, the default is the same as passing enable_thinking=True. See Chat Template for how LFM3 and LFM2.5 templates handle thinking.

Text

text holds the reasoning followed by the answer. See Separate the reasoning from the answer to split them.

Images and text

LFM3-VL-2B reasons before answering image and video questions by default and supports switching thinking off. The older LFM2.5-VL models answer directly without a separate thinking mode. Use the processor to format LFM3-VL’s inputs:
MLX-VLM is the exception: mlx_vlm.generate turns thinking off unless you pass --enable-thinking. Add the flag to use thinking. See MLX.

Serve a thinking model

Start the server with a reasoning parser, so it returns the reasoning in its own field instead of mixing it into the answer. Each model page lists the parser to use. llama.cpp parses reasoning by default.

Separate the reasoning from the answer

How the reasoning comes back depends on whether a reasoning parser runs. With a parser, the server splits the output for you. The answer arrives in message.content and the reasoning in a separate field, so your application never sees the <think> tags. The name of the reasoning field differs between servers and versions, so read both:
When you stream the response, the reasoning arrives in the same field of each chunk’s delta, before the answer arrives in delta.content:
Without a parser (Transformers, MLX, and servers started without one), the reasoning and the answer arrive as one string. The text contains a closing </think> before the answer, so split on it:

Leave room for the reasoning

The token limit covers the reasoning and the answer together. Reasoning on a hard task can run to thousands of tokens, and if the limit is reached first, the model is cut off mid-thought and never gives an answer.
  • vLLM and llama.cpp: when you don’t set max_tokens, generation can run to the end of the context window, so you don’t need a limit.
  • Transformers, SGLang and other runtimes: set the limit yourself, to a generous value such as 16,384 tokens.
If a reply has reasoning but no answer, the limit was too low.

Structured output and tool calls

The reasoning comes first in every reply, also when you ask for JSON or give the model tools:
  • Structured output: with a reasoning parser, response_format (for example a JSON schema) constrains only the answer. The reasoning before it stays free text, and message.content holds just the JSON.
  • Tool calls: the model reasons first and then calls the tool. With a tool-call parser, the call arrives in message.tool_calls, and the reasoning in the reasoning field.
Without a parser, both arrive after </think> in the generated text.

Multi-turn conversations

When you add a reply to the conversation history, send the answer as content and the reasoning as reasoning_content. Keep both with each tool-call turn. The default retention rule depends on the model’s chat template:
  • LFM3-1.7B, LFM3-VL-2B, LFM2.5-8B-A1B, and LFM2.5-24B-A2B: reasoning before the latest user message is removed; reasoning from assistant turns after it stays. This preserves the reasoning across tool calls made to answer the current request.
  • LFM2.5-1.2B-Thinking: only the last assistant message’s reasoning is retained by default, including when several tool calls follow the same user request.
To keep reasoning from all assistant messages, set preserve_thinking=True. For LFM2.5-1.2B-Thinking, use this when your agent needs to retain reasoning across multiple tool-call steps:
  • Transformers: apply_chat_template(..., preserve_thinking=True)
  • vLLM and SGLang: "chat_template_kwargs": {"preserve_thinking": True} in extra_body
  • llama.cpp: the server keeps earlier reasoning by default (--reasoning-preserve). Start it with --no-reasoning-preserve to use the template’s default instead.

Switch thinking off

Some thinking models support direct answers; others have no supported thinking-off switch. LFM3-1.7B accepts the switch, but results with thinking disabled can be inconsistent, particularly on reasoning tasks, so we recommend leaving it on. The overview table shows which models support the switch.
We recommend leaving thinking on. With thinking off, a model answers faster but less accurately, especially on math, documents and other multi-step tasks. Test your task both ways before you switch it off.
To switch thinking off, set enable_thinking=False. The chat template then fills in an empty <think></think> block, so the model starts on the answer straight away. On models that always think, this setting isn’t supported.
In the image example, pass enable_thinking=False to apply_chat_template():
The empty <think></think> block is part of the prompt, so the generated text is the answer alone. Don’t pass it to split_reasoning(), which expects a closing </think>.

Thinking models

The table covers the text and vision thinking models discussed above. LFM3-Audio-2B also supports optional reasoning through an explicit assistant prefill; see Speech-to-text chat for examples. For direct answers without reasoning, the following models are options:

FAQ

Not every model has a supported thinking-off switch. Use the controls documented for your model in the support table. LFM3-1.7B accepts enable_thinking=False, but answers in that mode can be inconsistent, especially on tasks that need reasoning. We recommend leaving thinking on and testing any change on your own task. If you need direct answers, consider the non-thinking alternatives listed below the table.
Current LFM models have one thinking mode, with no effort levels and no trained thinking budget.No chat template reads a reasoning-effort value, so options such as llama.cpp’s --reasoning-effort don’t change the output. llama.cpp’s --reasoning-budget N with N greater than 0 cuts the reasoning off after N tokens. The models weren’t trained for this, so test it on your task before you rely on it.
It depends on the model and the task. Each model’s Hugging Face model card reports benchmark results with thinking on and off where the model can switch.