1. 背景知识
CoT(Chain of Thought)
-
定义
根据 Google Research 的说法,思维链 (CoT) 提示是一种技术,它允许大型语言模型 (LLM) 在给出最终答案之前将问题作为一系列中间步骤来解决问题。2022 年,Google Brain 报告称,思维链提示通过诱导模型使用模仿思路的推理步骤来回答多步骤问题,从而提高推理能力。 -
优势
-
分解多步问题
Chain-of-Thought 原则上允许模型将多步问题拆解为若干中间推理步骤,从而能够根据问题的复杂度分配更多的计算资源。 -
可解释的推理路径
Chain-of-Thought 为模型的行为提供了一个可视化“窗口”,揭示模型如何得出答案,并为调试错误的推理路径提供了可能(尽管要全面刻画模型内部的所有计算过程仍是未解难题)。 -
广泛的适用性
Chain-of-Thought 推理可用于数学文字题、常识推理、符号操作等任务,并且(至少在原则上)适用于任何人类能够通过语言解决的问题。 -
无需额外训练,易于引出
只需在 few-shot 提示的示例中加入 Chain-of-Thought 序列,就能在足够大的开箱即用语言模型中轻松引出 Chain-of-Thought 推理。
-
MoE(Mixture of Experts)
-
定义
- Mixture of Experts 将一个大模型拆分为多个子模型(专家),每个专家专注于解决输入空间的不同子区域,然后通过一个门控网络(Gating Network)决定激活哪些专家来处理当前输入 。
-
架构与组件
- 专家子网络(Experts)
- 在实践中,专家是 FFN,但它们也可以是更复杂的网络,甚至是 MoE 本身,从而导致分层 MoE。
- Feed-Forward Network(FFN) 是神经网络中最基本的模块之一,其特点是信息单向流动——从输入层经过若干全连接层(及激活函数)直接到输出层,中间不包含任何循环或反馈连接。
- 门控网络(Gating Network)
用于确定将哪些token发送给哪个专家。 - 条件计算(Conditional Computation)
- 条件计算(Conditional Computation)指的是根据输入的不同,有选择性地激活网络的部分子结构,而不是对所有参数进行全量计算。通过只调度必要的模块,条件计算可在保持或提升模型容量的同时,大幅降低计算开销。
- affinity 分数反映了 token 与某个专家在特征空间上的相似度或匹配度,分数越高表示该专家越适合处理该 token 。
- 专家子网络(Experts)
-
路由机制
在使用 MoE 时,如何将令牌路由给专家是重大决策之一。- 固定 Top-K 路由
-
为每个 token 选择 affinity 分数最高的 Top-K 个专家。
-
这个策略优点在于实现简单,但容易导致专家负载不均,需要事先对专家容量进行大幅度超配(2×–8×)来避免“丢 token”
-
- 动态容量因子(Expert Choice)
- 不再让 token 选专家,而是让具有预设容量的专家去选 top-k 个 token。此方法保证了负载均衡,并允许每个 token 接收可变数量的专家。
- 在 EC 路由中,专家容量 k = (每批输入中平均每个专家处理的 token 数)×(容量因子);该因子控制了平均每个 token 可以接收多少专家。
- 固定 Top-K 路由
Dense模型
- 全连接层(Dense Layer)
在该层中,每个输出神经元都与上一层的每个神经元建立连接,等价于对输入向量做一次线性变换再加偏置后通过激活函数。 - Dense 模型(Fully‑Connected Network)
由若干全连接层堆叠而成的前馈网络(feed‑forward),信息单向流动,无循环或稀疏机制,每一步推理都会 “走” 完整个网络所有连接GeeksforGeeks。
Qwen3的推理模式
thinking mode
-
In this mode, the model will generate think content wrapped in a
<think>...</think>
block, followed by the final response. -
就是一种 Chain-of-Thought(CoT),不作为最终的答案,作为一种内部推理展示。由于模型的自回归特性,后面的输出依赖于前面的输出,CoT有助于提升模型输出的质量。
non-thinking mode
- 此模式下功能等同于Qwen2.5-Instruct models。产生的token更少,成本更低,相应的回答质量也更低一点。
thinking mode小结
- 其实就是多生成了一段以
<think>...</think>
包裹的输出。
2. 从分词器视角分析Qwen快慢思考原理
Qwen分词器的参数
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
enable_thinking=True # Switches between thinking and non-thinking modes. Default is True.
)
From deepseek :
messages
:包含多轮对话历史的列表,每个消息是一个字典,包含role
(角色,如user
、assistant
、system
)和content
(消息内容)。tokenize
:控制输出是否分词(返回 token IDs)或保持为字符串。若需直接查看格式化后的字符串(如调试模板),设为 False;若输入模型生成,通常设为 True。add_generation_prompt
:在提示末尾添加模型生成回复的起始标记(如<|assistant|>
),引导模型开始生成回复。enable_thinking
:控制模型是否启用thinking mode
(输出推理过程)或non-thinking
模式。
chat_template的组件
- 仅解释将会提到的部分:
<|im_start|>
和<|im_end|>
:标记消息的开始和结束。<think></think>
:围绕助手的思考过程。role
:标识消息发送者(system、user、assistant、tool),system是系统提示词(也可能没有),user是用户提示词(即用户的输入),assistant就是模型的回复,tool是工具调用的结果。
Hard switch & Soft switch
Hard switch
-
enable_thinking=True
By default, Qwen3 has thinking capabilities enabled, similar to QwQ-32B. This means the model will use its reasoning abilities to enhance the quality of generated responses. -
enable_thinking=False
Strictly disable the model’s thinking behavior, aligning its functionality with the previous Qwen2.5-Instruct models. This mode is particularly useful in scenarios where disabling thinking is essential for enhancing efficiency.
Soft switch
- We provide a soft switch mechanism that allows users to dynamically control the model’s behavior when
enable_thinking=True
. Specifically, you can add /think and /no_think to user prompts or system messages to switch the model’s thinking mode from turn to turn. The model will follow the most recent instruction in multi-turn conversations.
注意事项
- For API compatibility, when
enable_thinking=True
, regardless of whether the user uses/think
or/no_think
, the model will always output a block wrapped in<think>...</think>
. However, the content inside this block may be empty if thinking is disabled. Whenenable_thinking=False
, the soft switches are not valid. Regardless of any/think
or/no_think
tags input by the user, the model will not generate think content and will not include a<think>...</think>
block.
分词器的输出是什么?——即模型真正接收的输入是什么?
- 使用下面的代码进行实验
from transformers import AutoTokenizer
model_name = "Qwen/Qwen3-235B-A22B"
# Load the tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_name)
# prepare the model input
prompt = "Give me a short introduction to large language model."
messages = [
{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
enable_thinking=True # Switches between thinking and non-thinking modes. Default is True.
)
# 输出分词结果
print(text)
- 不同情况将对上述的代码模板改动两处:
prompt
:软开关 开启 / 关闭 会对应在prompt
后面加上"/think"
/"/no_think"
enable_thinking
:硬开关 开启 / 关闭 会对应enable_thinking=True
/enable_thinking=False
1、enable_thinking=True # 硬开关开启
分三种情况讨论:
1. 不启用软开关
- 分词结果
- 代码
prompt = "Give me a short introduction to large language model."
enable_thinking=True
- 结果
<|im_start|>user Give me a short introduction to large language model.<|im_end|> <|im_start|>assistant
- 代码
2. 软开关开启
- 分词结果
- 代码
prompt = "Give me a short introduction to large language model./think"
enable_thinking=True
- 结果
<|im_start|>user Give me a short introduction to large language model./think<|im_end|> <|im_start|>assistant
- 代码
3. 软开关关闭
- 分词结果
- 代码
prompt = "Give me a short introduction to large language model./no_think"
enable_thinking=True
- 结果
<|im_start|>user Give me a short introduction to large language model./no_think<|im_end|> <|im_start|>assistant
- 代码
2、enable_thinking=False # 硬开关关闭
分三种情况讨论:
1. 不启用软开关
- 分词结果
- 代码
prompt = "Give me a short introduction to large language model."
enable_thinking=False
- 结果
<|im_start|>user Give me a short introduction to large language model.<|im_end|> <|im_start|>assistant <think> </think>
- 代码
2. 软开关开启
- 分词结果
- 代码
prompt = "Give me a short introduction to large language model./think"
enable_thinking=False
- 结果
<|im_start|>user Give me a short introduction to large language model./think<|im_end|> <|im_start|>assistant <think> </think>
- 代码
3. 软开关关闭
- 分词结果
- 代码
prompt = "Give me a short introduction to large language model./no_think"
enable_thinking=False
- 结果
<|im_start|>user Give me a short introduction to large language model./no_think<|im_end|> <|im_start|>assistant <think> </think>
- 代码
原理分析
-
总结一下上述各种场景的输出
- 进行深度思考,即执行
thinking mode
- 根据官方给出的关于软硬开关的介绍,想要进入
thinking mode
必须满足:- 软硬开关同时开启
- 硬开关开启,软开关不启用(注意,启用和打开的区别,开启和关闭都属于启用,不启用不在
prompt
中指定/think
或/no_think
)
- 那么对应到分词结果为
- 软硬开关同时开启
<|im_start|>user Give me a short introduction to large language model./think<|im_end|> <|im_start|>assistant
- 硬开关开启,软开关不启用
<|im_start|>user Give me a short introduction to large language model.<|im_end|> <|im_start|>assistant
- 相同点为在
assistant
部分没有<think>...</think>
- 进行快速回答,即执行
non-thinking mode
- 根据官方给出的关于软硬开关的介绍,想要进入
non-thinking mode
必须满足:- 硬开关关闭
- 硬开关开启,软开关关闭
- 那么对应到分词结果为
- 硬开关关闭
<|im_start|>user Give me a short introduction to large language model.<|im_end|> <|im_start|>assistant <think> </think>
<|im_start|>user Give me a short introduction to large language model./think<|im_end|> <|im_start|>assistant <think> </think>
<|im_start|>user Give me a short introduction to large language model./no_think<|im_end|> <|im_start|>assistant <think> </think>
- 硬开关开启,软开关关闭
<|im_start|>user Give me a short introduction to large language model./no_think<|im_end|> <|im_start|>assistant
- 进行深度思考,即执行
-
实现原理分析
thinking mode
通过一定训练手段,使得模型在没有看到user
提示/no_think
时必须输出<think>...</think>
部分,且只看到<think>
时,生成的是推理过程,直到看到</think>
,可以开始生成最终回答。non-thinking mode
通过在assistant
部分直接输入<think>\n\n</think>\n
,截断模型的思考,使得模型直接输出最终回答。但这种情况有一个例外,就是硬开关开启、软开关关闭的情况,这种情况分词的结果没有直接加上<think>\n\n</think>\n
,推测可能在训练时,使用一定手段使模型看到/no_think
的情况下,也直接输出最终答案。
-
采取的手段
- From GPT : 可能采取的手段
-
监督微调(Supervised Fine-Tuning, SFT)
- Direct-Answer SFT
只在问答对(question → answer)数据上微调,教模型直接给出最终结论,不演示中间思路 —— 即「non-thinking mode」。 - Chain-of-Thought SFT
在包含“链式思考”(chain-of-thought)演示的问答对上微调,让模型学会复述解题的每一步 —— 即「thinking mode」。
- Direct-Answer SFT
-
指令微调(Instruction Tuning)
- 本质上也是一种 SFT,但专门收集“指令 → 响应”数据集,包含“展示推理过程”和“直接给答案”两类示例。
- 通过多样化指令,让模型学会在不同提示下自动切换输出模式:
- “请展示你的推理过程” ⇒ chain-of-thought
- “只要结论就行” ⇒ direct-answer
-
基于人类反馈的强化学习(Reinforcement Learning from Human Feedback, RLHF / RLHM)
- 优化展示偏好:用人类评分鼓励模型在需要时展示链式思考,提高透明度;在不必要时抑制冗长推理,保持简洁。
- 多策略切换:分别奖励「thinking mode」与「non-thinking mode」下的高质量输出,实现平滑切换。
-
元强化学习 / 层次化 RL(Hierarchical RL / Meta-RL)
- 研究性手段:上层策略决定“何时使用推理链”(thinking vs. non-thinking),下层策略执行具体的推理或直接回答。
-
蒸馏与蒸馏微调(Rationale Distillation)
- 用大模型生成的高质量 chain-of-thought 作为“教师示例”,蒸馏给小模型,使其在资源有限时也能输出合理思路或直接结论。
-
- 官方技术报告 (https://qwenlm.github.io/blog/qwen3/) 中提到:
To develop the hybrid model capable of both step-by-step reasoning and rapid responses, we implemented a four-stage training pipeline.-
长链式思考(CoT)冷启动
- 使用涵盖数学、编程、逻辑推理和 STEM 问题等多领域、多任务的多样化长链式思考数据对模型微调
- 让模型在无强化学习先验的情况下学会“慢慢想”,输出详细的中间推理步骤
-
基于推理的强化学习(RL)
- 在大规模算力环境下应用强化学习
- 设计基于规则的奖励函数,鼓励模型在探索(exploration)与利用(exploitation)之间取得平衡
- 提升模型推理质量与效率
-
思考模式融合
- 将“深入推理能力”(thinking mode)与“快速响应能力”(non‑thinking mode)融合于同一模型
- 使用第二阶段模型生成的长 CoT 数据,结合常见的、无需复杂推理的指令—响应对(instruction‑tuning data)一起微调
- 实现在需要时输出详细推理,简单场景下快速给出答案
-
通用强化学习
- 在 20 多个通用领域任务上继续应用强化学习
- 任务包括指令跟随(instruction following)、格式遵循(format following)、代理能力(agent capabilities)等
- 进一步提升模型通用性并校正潜在偏差或不良行为
-
- From GPT : 可能采取的手段
3. 相关问题分析
1. 两种模式使用参数量如何?
-
对于dense模型来说,无论启用什么推理模式,都不会影响模型参数的启用比例,因为这是dense的架构决定的。
-
对于MoE模型来说,不同的模式,由于前面提到的对模型输入的改变,使得模型通过门控网络可能选择使用不同的专家,但是这个操作不是不同模式导致的——MoE本来就是会为不同的token选择不同的专家。也就是说,不是因为模式不一样,所以选择了不同的专家,而是模型看到了token的不同,所以产生不同选择。而且模型也不会因为不同模式就多选或者少选专家,对每个token来说,选择的专家数量还是固定的,即每个token激活的参数量还是相同的(这里的激活指的是“要用到的”,不是实际加载到内存的。每个token激活的专家集合可能是有交集的。另外,这里不考虑有专家容量满载导致的丢弃token现象——被丢弃的token实际少激活了一个专家)。以Qwen3系列中的Qwen3-235B-A22B为例,官方的参数写的很清楚:
Qwen3-235B-A22B has the following features: Type: Causal Language Models Training Stage: Pretraining & Post-training Number of Parameters: 235B in total and 22B activated Number of Paramaters (Non-Embedding): 234B Number of Layers: 94 Number of Attention Heads (GQA): 64 for Q and 4 for KV Number of Experts: 128 Number of Activated Experts: 8 Context Length: 32,768 natively and 131,072 tokens with YaRN. For more details, including benchmark evaluation, hardware requirements, and inference performance, please refer to our blog, GitHub, and Documentation.
可以看到,总专家数为128,激活的专家数为8,激活的参数量为22B。在大多数 MoE 设计里,所有专家都是同构同规模的,这里既然激活参数是相同的,那么可以推断这里的专家设计也是同构同规模。至此,可以得出结论,不同的模式,可能通过门控网络激活了不同专家(处理每个token时都可能启用不同的专家),但是激活的专家数量是固定的,激活的参数量也是固定的。再补充一些思考,1、虽然模型不会因为不同模式就直接选择不同的专家,但是不同模式下可能导致不同token出现的频率不同,那么或许因此就导致不同模式下模型倾向于选择不同的专家集合,训练时也可能由此导致某些专家集合擅长处理某种模式。2、也可能不同模式下由于初始输入就加入了某些特定token,使得通过自注意力层之后,序列后方的token的隐藏状态就包含了这些信息,那么在通过门控网络时,自然就路由到了某个专家集合,如果这样的话,其实倒也可以说不同模式下选择了不同专家。
- 小结
两种模式,只不过是通过一定的训练手段,调整模型权重,使得模型看到特定前文token的情况下,对于下一个token的预测倾向或不倾向于某些token(比如结束符),从而在宏观的输出上造成有无深度思考部分、长或短的现象。换句话说,两种模式源于模型能力层面的调整,并非源自架构层面的设计。
2. 计算量如何?
- 每个token激活的参数量一致,但是对于Decoder来说,计算量是随token位置递增的。(此问题之前的测量中其实也存在,只不过忽视了)
- 区分激活的参数量和实际加载的参数量和产生的计算量
激活的参数量才直接影响计算量,但是激活的参数量固定,不代表计算量就固定了。比如Decoder的掩码自注意力层,参数只有QKV权重矩阵,但是后续产生的计算量是因序列长度而变化的。
4. 对强化学习和指令微调的理解
-
强化学习
- 自己的简单理解
让模型去学不具备或者不够强大的能力。 - o3的“指教”
需补充:RL 不仅是“学新能力”,也常用于“对既有能力进行对齐和优化”(如风格对齐、安全对齐),而不必完全从零开始学。
- 自己的简单理解
-
指令微调
- 自己的简单理解
在已经具备相应能力的情况下,学会什么时候使用什么能力。 - o3的“指教”
更准确地说,它还包含“教模型如何遵循指令格式”、“在多种任务间切换”以及“在面对新指令时能够泛化”,不仅仅是“调用已有能力”。
- 自己的简单理解
5. References
- https://huggingface.co/Qwen/Qwen3-235B-A22B
- https://www.51cto.com/article/815096.html?utm_source=chatgpt.com
- https://arxiv.org/pdf/2201.11903
- https://en.wikipedia.org/wiki/Prompt_engineering?utm_source=chatgpt.com#Chain-of-thought
- https://research.google/blog/mixture-of-experts-with-expert-choice-routing/?utm_source=chatgpt.com
- https://huggingface.co/blog/Kseniase/moe2?utm_source=chatgpt.com
- https://huggingface.co/blog/moe?utm_source=chatgpt.com
- https://arxiv.org/pdf/2412.19437
- https://en.wikipedia.org/wiki/Mixture_of_experts
- https://arxiv.org/pdf/2412.15115
- https://arxiv.org/abs/1511.06297
- https://arxiv.org/abs/1701.06538
- https://builtin.com/machine-learning/fully-connected-layer
- https://www.geeksforgeeks.org/what-is-fully-connected-layer-in-deep-learning/
- https://qwenlm.github.io/blog/qwen3/