Chain of Thought(CoT,思维链)已经存在了一段时间,技术上它是一种高级提示工程方法。CoT 旨在迫使 LLM 进行推理。
自 OpenAI 在 2024 年 9 月发布 o1 模型预览后,CoT 的热度再次攀升。
目前除了 OpenAI 没有人完全知道 o1 是如何工作的,也不清楚它是否为一个组合系统、使用了哪些数据进行微调、是否使用了强化学习,或者是否有多个模型协同工作。
或许一个模型负责规划,另一个负责推理,第三个模型进行评分。但我们知道它们使用了某种逐步推理的方式。
围绕这一话题,已经有了大量的开放性研究,值得深入探索。
Medium 上有一篇付费文章介绍了这些研究,帮助我们了解了可以使用的技术。作者也会测试不同的技术,看看是否能够实现真正的改进。
研究概述
在过去两年中,许多论文相继发布:
https://github.com/ilsilfverskiold/Awesome-LLM-Resources-List?tab=readme-ov-file#research-papers-on-chain-of-thought-prompting
这些论文中提到的推理技术,如下图所示。
大多数研究直接来自 DeepMind 或普林斯顿大学,感谢他们开源了这么多工作。
“Chain of Thought(CoT,思维链)”这一术语最早由 DeepMind 在 2022 年提出,主要用于提示工程。最新的论文则探索了“带蒙特卡罗搜索的思维树(Tree of Thoughts)”以及“不依赖提示的CoT”。
在本文中,我们将讨论简单的 CoT、CoT 链、贪婪解码(Greedy Decoding)、CoT-SC、解码 CoT,以及带蒙特卡罗树搜索的思维树(ToT)。
我们还将使用我们自己的数据集用来测试采用这些推理技术后,能实现的改进效果。
LLM 的基准评分
为了理解如何提升 LLM 的结果,首先需要建立一些基准评分。
当一个模型被发布时,通常会附带评估指标。常见的评估指标有 MMLU(语言理解)、BigBench(推理)、HellaSwag(常识推理)等。
然而,需要注意的是,部分数据集已经过时,可能存在一定程度的污染。
我们可以去 Hugging Face 看一下最新(截至 2025 年 1 月 21 日)的 LLM 评测排行榜,该排行榜基于更新的数据集进行评估,可以清楚地看到大多数模型在这些新数据集上的得分远低于在原始数据集上的表现。
https://huggingface.co/spaces/open-llm-leaderboard/open_llm_leaderboard#/
了解模型评估方法以及根据何种标准评估模型,值得深入研究。拥有一个内部的私有数据集进行测试可能是个不错的主意。
在这项研究中,作者从多个数据集中提取了约 350 个问题,并结合一些在线流行的问题,评估了最多 11 个不同的模型。
作者需要了解这些数据集的内容以及 LLM 生成的答案。因此,作者编写了自己的脚本,循环处理问题,并对每个问题为 LLM 的回答打上 0 或 1 的评分。
尽管如此,从结果中我们并不能得出太多结论。由于所用问题来自 BigBench、MMLU、Putnam 等数据集,还有一些流行问题如“草莓里有多少个‘r’”,我们无法确定这些问题是否已受到污染,且数据集本身规模较小。
不过,我们可以明显看到,较大的模型表现更好。
接下来,值得关注的是,是否通过应用促使模型推理和“思考”再回答问题的方法,能够提升这些评分。
CoT
CoT 提示最早由 DeepMind 的 Brain 团队在 2022 年发布的论文《Chain-of-Thought Prompting Elicits Reasoning in Large Language Models》中提出。
这篇论文的研究重点是如何通过提示策略激活模型固有的推理能力,迫使模型在解决问题时进行推理。
当时,人们只是通过正确的提示方式,要求模型“逐步思考”,可以采用 zero-shot 或few-shot 的方法。
如今,我们可以通过在提示的末尾简单添加“让我们一步步思考”,来使用这一方法进行各种模型( Claude、ChatGPT 等)的推理。如果你想尝试 few-shot learning,可以在提示中给出一些示例。
DeepMind 报告称,通过正确的提示使用 CoT 技术,模型的表现得到了显著提高。
此后,许多研究论文在这些技术的基础上进行了扩展,发展出了越来越先进的方法。
构建推理链
在提示工程社区中,许多人都在尝试使用 CoT 风格的技术。我收集了大多数相关的开源库,方便大家查找。
https://github.com/ilsilfverskiold/Awesome-LLM-Resources-List?tab=readme-ov-file#cot-implementations
其中,Benjamin Klieger 最近的一个应用引起了关注,他通过使用 Groq 和 Llama 3.1 70B 模型,进一步拆解思维过程,构建了一个提示式应用来引导链式思维。
https://github.com/bklieger-groq/g1
其核心思想是让 LLM 将思维拆解成多个链条,模型会继续思考,直到对答案有足够的信心。
系统会为每个链生成独立的 LLM 调用,而不是将整个思维过程放在一次回答中。
以提问“草莓里有多少个‘r’”(How many R’s are in Strawberry?)为例,模型会为每个思维环节设置标题,并决定是否需要继续思考,直到得出最终答案。
这种方法仍然属于 CoT 风格的技术,因为它是线性的,但比单纯要求模型“逐步思考”要复杂一些。
作者使用了 Klieger 的部分代码,构建了一个脚本,循环遍历 LLM 的基础问题,测试这种方法能带来多少改善。作者还将该脚本适配到 Claude 和 Grok 上,评估这一策略的效果。
测试结果显示,Llama 3.1 70B 在前三个类别中表现出了最佳的提升。而 Grok 在流行问题上的表现较差(Haiku 也是如此)。
Putnam 数据集包含高级数学,只有极少数 LLM 能处理得很好,因此当 Claude Sonnet 3.5 在使用 CoT 链时,以 68.75% 的准确率超越了o1-preview(63%),我感到非常惊讶。
Sonnet 在高级数学方面通过使用 CoT 技术,总体提升了 81%。
需要注意的是,虽然作者使用的是一个非常小的数据集,这只是为了了解模型在哪些方面表现良好,以及是否能够改善评分,然而,只有在更大数据集上测试才能得出更可靠的结论。
此外,我还观察到,当较小的模型在简单问题上开始过度分析时,结果会更差。这在 Grok-Beta 和 Haiku 处理流行的“简单”问题时尤其明显。
对于非数学类的简单问题,CoT 可能不会带来相同的提升效果。
我们还必须记住,虽然我们可以推动模型在其能力范围内发挥,但很少能够让它超越自身的能力。如果模型不知道答案,它就不知道。
推理的微调
在继续之前,我想提一下微调的部分。
一个非常有趣的研究方向是尝试对较小的模型进行 CoT 数据集的微调,以提升它们的准确性,使其接近 1-2 倍更大模型的表现。
我找到了多个相关资源,但遗憾的是,从基础模型进行微调后,我并未发现足够显著的提升,难以支撑深入分析。
下面是我找到的开源模型和 CoT 数据集。
https://github.com/ilsilfverskiold/Awesome-LLM-Resources-List/edit/main/README.md#models
这并不是说 CoT 微调不行,而是目前需要构建更好的、文档化完善的模型。
如果你有兴趣自己尝试微调,可以查看这些资源,肯定还有更多的相关资料可以挖掘。
替代生成技术
我们之前讨论的是 CoT 技术,但还有其他方法可以优化语言模型的输出准确性,而不需要依赖提示。
这些方法涉及到我们在调用 LLM 时常常忽略的采样设置,比如 temperature(温度)、top_p 和 do_sample,这些参数可以控制输出的行为。
尽管我们在商业 API 中并不总能访问所有这些设置,但 temperature 是可以调节的。在技术上,temperature 意味着我们可以通过调整 logits 的大小,增加低概率 token 被选中的机会。
对于新接触 LLM 的人来说,这可能有些令人困惑,但实际上并不像听起来那么复杂。
temperature 越高,token 的概率分布就越平坦,这意味着模型更可能选择那些看起来“更不安全”的词语,这通常被称为随机性或创造力。
假设 mat 在开始时具有最高的初始 logit,但随着 temperature 的升高,我们看到它开始缩小,从而降低了概率。对于具有较低数字的初始 logit,情况则相反。
top_p 参数(并非所有商业 API 都能访问)可以根据设定的值来限制或扩展 token 池。低 score 会将 token 池限制为高概率 token,而高 score 则允许更多 token 进入候选池。
将高 temperature 与高 top_p 结合使用会生成更多创新和创意的输出,因为更多 token 会成为候选项。
do_sample 参数决定模型是否使用采样来生成下一个 token。这在商业模型 API 中通常无法设置。如果 do_sample 设置为 True,模型将从候选池中进行采样,并且具有更大的自由度(这是所有 API 的默认行为)。如果设置为 False,模型将只选择最高概率的 token,并完全忽略 temperature 和 top_p 的设置。
我们可以通过将 do_sample 设置为 True 来强制模型生成更确定性的输出,即每个阶段都选择最高概率的 token,这种方法被称为“贪婪解码”(Greedy Decoding)。
在使用 do_sample 参数进行贪婪解码时,我对 Llama 3 8B(指令版)模型进行测试,看看这种方法能否改善基础问题的表现。
测试结果表明,MMLU 和 Big-Bench 上有所提升,但在高级数学问题上几乎没有改善。
由于商业 API 通常无法访问 do_sample 参数,如果没有模型的访问权限,你可以尝试将 temperature 设为 0,模仿这种行为,但这并不保证一定有效。
你可能会问,既然贪婪解码能够带来小幅提升,为什么不总是使用它?
如果我们忽视输出的创造力需求,你会发现较弱的 LLM 在面对难题时容易陷入重复循环,比如说“颜色是蓝色蓝色蓝色蓝色”,这时“蓝色”可能是最高概率的 token,因此会不断重复。
高级 CoT
到目前为止,我们讨论的都是线性技术,即模型在单一线程或链条中生成输出。
然而,在第一篇 CoT 论文发布后不久,DeepMind 引入了更先进的技术——带自一致性的思维链(CoT-SC)。
这种技术创建多个推理路径,并使用某种方法来选择最一致的答案(或路径)。
DeepMind 报告称,使用此方法,在算术推理方面能够实现 1% 到 8% 的提升。
2024 年推出的另一种方法与此相似,依然使用多个推理路径,但不需要任何提示。
这种方法与之前提到的贪婪解码有些相似,但不仅仅是强制选择最可能的 token,还会分析整个响应的置信度得分。
系统首先启动 k 个初始的 top token,然后从每个 token 生成不同的推理路径。一旦答案生成后,系统会根据不同路径中各个 token 的概率(logits)计算置信度得分。
最终,模型返回具有最高概率的答案或路径。
这种方法被称为“解码CoT”(Decoding CoT),也是由 DeepMind 提出的,其核心思想是观察模型在返回答案时的内部置信度。
但是,如果模型没有足够的知识来回答问题,会发生什么呢?就像 CoT-SC 一样,这种方法在很大程度上依赖于模型是否在一开始就知道正确答案。
尽管如此,这并不意味着我们不应该测试它。
对于这些技术,很多人都在开源不同的实现,解码CoT 也不例外。
因此,我很容易设置了一个系统,测试这些方法,并将其与较小的开源模型Llama 3 8B 进行比较。
感谢 Codelion 开源他的实现,使得我能够轻松复制和测试。
https://github.com/codelion/optillm
从上面的结果可以看到,与其他方法(如熵方法或单纯的贪婪解码)相比,解码CoT在此特定模型中的表现最好。
在技术部分,我们将创建一个 API,展示如何使用这个解码 CoT 系统,让你了解它是如何工作的。
更新的技术
随着研究的不断进展,推理方法已从简单的 CoT 发展到了在更高风险领域中的应用。
我现在不会详细讨论这些策略,因为那是另一个话题,但我想特别提到的是“思维树(Tree of Thoughts,ToT)”技术,尤其是它与蒙特卡洛搜索(MCTS)相结合的应用。
ToT 是由普林斯顿大学和 DeepMind 于 2023 年底提出的,它通常是在基于树形推理的前一种方法的基础上进一步发展而来的。
与 CoT-SC 不同,ToT 在生成多个推理路径后进行动态评估,而不是在生成完所有路径后再评估。
可以将其想象成四个人一起解决问题,在每个步骤中,他们提出自己的想法并集体评估哪些想法最有前景。如果某个人的推理出现问题,他们将退出,剩下的人继续处理解决方案。
最终,那些推理正确的人将能给出答案。
这种方法允许模型在推理过程中动态地剔除看起来无效的路径,集中精力在更有前景的线程上,从而节省资源。
但可能会有人质疑,系统如何判断哪个路径是正确的,哪个是错误的?这一点由模型自己来决定。
这也是 MCTS 等扩展技术的出现原因,它提供了更为公正的评估机制。MCTS 允许回溯,这意味着它可以根据新信息重新审视并改进早期的决策,而简单的 ToT 只会向前推进。
在四个人解决问题的例子中,MCTS 允许有些人提出的想法不理想,但他们仍然可以在游戏中停留更长时间。评估方法将会不同。
MCTS 可以模拟多条未来路径,评估它们的潜力,并通过回溯来改进早期的决策。它引入了外部度量(奖励),而不是完全依赖模型。
例如,像UCB(上置信界)这样的统计方法,使用奖励来决定进一步探索哪些想法或回顾哪些想法。
MCTS 比简单的 ToT 更为复杂,可能值得单独写一篇文章来深入探讨。
CoT 的经济学
到目前为止,你可能会认为,既然有了一些改进,为什么不总是使用更高级的 CoT 形式呢?
首先,要考虑的是成本(以及思考时间的消耗)。
对于我应用于不同模型的思维链,我计算了平均推理步骤数。
根据这些数据,你会发现每个问题的成本平均会高出最多 8 倍。例如,对于 Sonnet,在处理高级数学问题时表现最佳,每 500 个问题的费用高达 15 美元。
这可能看起来不多,但如果你每天都使用该系统来为客户服务或团队生成答案,每月的费用可能会达到数百甚至数千美元。
在某些情况下,使用高级推理方法是有意义的,但并非总是如此。
另外,也许可以通过为 CoT 进行微调,从而消除生成多个调用的需求,但目前我还没有看到任何一个开源模型做得很好。
这里存在一些权衡。我们希望增加思考时间,以便模型有足够的时间进行有效推理,但这样做的代价是增加了用户的等待时间和成本。
构建智能系统
2024 年 9 月,发布了一篇名为《To CoT or not to CoT?》的论文,指出应用 CoT 的改进大多集中在数学和复杂推理领域。
https://arxiv.org/abs/2409.12183
我们也观察到这一点,对于简单问题,应用思维链带来的改善有限。
当我们应用这些思维链时,需要等待更长的响应时间。值得吗?不过,需要注意的是,所有这些策略对于简单任务来说可能是过度的。
这也是你在使用 OpenAI 的 o1 模型时,处理大多数问题时感到沮丧的原因——通常一个简单的答案就足够了。
但如果你在构建一个需要确保答案正确的系统,那么应用某种形式的 CoT 或解码技术可能会是一个不错的选择。
可以考虑使用一个模型,根据问题的难度设定初步步骤,然后分析它是否有信心能够回答这个问题。接着,模型通过思维链进行推理,最后使用另一个模型来评估答案的准确性。
最后
当然,比我在这里介绍的框架更多,但我展示的是我认为对理解非常有趣的框架。这些内容可以让你了解我们在这个领域的进展,同时不会让信息过于复杂。
大多数 AI 工程师都熟悉这些框架,但遗憾的是,这些研究没有更快地普及到公众。
理解如何实现 CoT 应该是构建 LLM 应用程序时的基础之一,即使你最终决定不使用它们。
技术实现
我们将使用开源模型 Llama 3.1 8B 实现一个 Decoding CoT 系统。
Decoding CoT 的方法来源于 2024 年发布的论文《Chain-of-Thought Reasoning Without Prompting》:
https://arxiv.org/abs/2402.10200
实现代码来自Codelion:
https://github.com/codelion/optillm
我对其进行了扩展,使得系统能够根据问题的难度来决定生成推理路径的数量(k)。
我们将使用提供15小时的免费配额的无服务器 LLM 服务平台 Beam:
http://www.beam.cloud/
脚本位于:
https://github.com/ilsilfverskiold/decoding-cot-beam
如果你更愿意使用 Colab 进行测试,你也可以在此运行脚本:
https://colab.research.google.com/drive/1jUWFn7J7mcRY4dXA4I4Vk_DyEl7Ewyqy?usp=sharing
最终结果应该是一个 API 端点,允许我们提问,系统会评估问题的难度,然后执行 Decoding CoT 并返回类似如下的答案。
你将看到 LLM 的请求数量以及系统对问题的分类方式。你还会注意到系统非常慢,因为它会生成多个答案来评估。
但是,如果我们使用 Groq 8B 模型,我们会发现它不能完全正确回答问题。
关于最终答案,我想指出的是,像这样的较小模型只能在某种程度上给出正确答案。遗憾的是,使用更大的模型会需要更多的工作,因为我们需要将其存储在某个地方,这可能会比较昂贵。
GitHub 源码:
https://github.com/ilsilfverskiold/Awesome-LLM-Resources-List/tree/main/helpers/scripts/beam
原文:
https://towardsdatascience.com/advanced-prompt-engineering-chain-of-thought-cot-8d8b090bf699