如何用自我一致性方法对多条推理路径投票得出最终答案
【免费下载链接】llm-cookbook面向开发者的 LLM 入门教程,吴恩达大模型系列课程中文版项目地址: https://gitcode.com/GitHub_Trending/ll/llm-cookbook
用大语言模型做复杂推理时,单条思维链(Chain-of-Thought,CoT)推理路径可能在中间某一步出错,导致最终答案不准确——llm-cookbook 中“选修-Advanced Prompting”教程的示例就展示了直接提问甚至零样本思维链都会产生错误推理的“幻觉”情况。自我一致性(Self-Consistency)方法针对的就是这个问题:对同一个问题采样生成多条不同的 CoT 推理路径,再对各条路径的最终答案做多数投票,得到最终答案。
本文以 2. 思维链和自我一致性.ipynb 第 2.3 节的代码实现为依据,走通一次完整的自我一致性流程:初始化 OpenAI 客户端 → 调整采样参数生成 3 条推理路径 → 读取结果并按最一致的答案投票得出最终答案。
方法原理:自我一致性的三个步骤
教程将自我一致性描述为一种替代思维链提示中“朴素贪婪解码”的解码策略,包括三个步骤(教程引述自 Google 在 ICLR 2023 发表的论文Self-Consistency Improves Chain of Thought Reasoning in Language Models):
- 使用思维链提示的大语言模型;
- 通过从语言模型的解码器中采样,生成不同的推理路径集合,取代 CoT 提示中的“贪心解码”;
- 边缘化推理路径,并通过选择最终答案集中最一致的答案进行聚合。
也就是说,自我一致性扩展了思维链的构建:它生成多个思维链而非一个,并通过多数投票选择最终答案。其依据是:一个复杂的推理问题通常可以通过多种不同的思维方式得出同一个正确答案。
准备:环境、依赖与客户端初始化
教程说明的实验环境是Anaconda + Python 3.8.10,Python 版本要求 Python 3.7+;模型使用gpt-3.5-turbo-0125。所需的第三方依赖库是openai,安装命令:
pip install openai==1.10.0按教程代码创建客户端。代码中的OPENAI_API_KEY需要替换为你自己的 API Key(教程代码同时支持从环境变量OPENAI_API_KEY读取);BASE_URL默认为官方 API 地址,如果使用代理请求则按教程注释替换为你的代理 URL:
import os from openai import OpenAI # 从环境变量中获取 OpenAI API Key 或者直接赋值 OPENAI_API_KEY = os.environ['OPENAI_API_KEY'] OPENAI_API_KEY = "sk-...你的 OpenAI API Key" # 如果您使用的是官方 API,就直接用 https://api.openai.com/v1 就行。 # 如果您使用的不是官方 API,而是通过代理进行请求,请设置您的代理 URL。 BASE_URL = "https://api.openai.com/v1" # 实例化 OpenAI 对象 # 传入参数:OpenAI API Key(必需)、Base URL 和最大重试次数 client = OpenAI(api_key=OPENAI_API_KEY, base_url=BASE_URL, max_retries=3)采样多条推理路径:设置 n 与 temperature
教程先给出了两个关键参数的说明:
n:整数或 Null,可选项,默认为 1,表示为每条输入信息生成多少个聊天完成选项;temperature:实数值或 Null,可选项,默认为 1,取值介于 0 和 2 之间。0.8 等较高值会使输出更加随机,0.2 等较低值会使输出更加集中和确定。
自我一致性需要多条“不尽相同”的推理路径,教程将n设为 3、temperature设为 0.80:
# 改造一下获得 Completions 的函数 设置参数 n=3,temperature=0.80,实现生成多个不尽相同的思维链 def get_completions(system_instruction, llm_prompt, model_endpoint): response = client.chat.completions.create(model=model_endpoint, messages=[{"role": "system", "content": system_instruction}, {"role": "user", "content": llm_prompt} ], n=3, temperature=0.80, seed=42, presence_penalty=0, frequency_penalty=0, max_tokens=1024 ) return response.choices, response.usage执行 Few-shot CoT 提示,生成 3 条推理路径
提示词采用少样本思维链形式:前面给出若干带完整推理步骤的问答示例,最后留出待解问题的A:。教程的示例是一道算术题(鸭子下蛋问题),完整执行代码如下:
llm = "gpt-3.5-turbo-0125" system_instruction = "您是世界知识专家。" # Few-shot 思维链提示过程 prompt = f"""问:罗杰有 5 个网球。他又买了 2 罐网球。每罐有 3 个网球。他现在有多少个网球? 答:罗杰开始有 5 个球。每罐有 3 个网球,两罐共有 6 个网球。5 + 6 = 11。答案是 11。 问:森林中开始有 15 棵树。林业工人今天将在林中种树。完成后,将有 21 棵树。林业工人今天种了多少棵树? 答:我们从 15 棵树开始。后来我们有 21 棵树。差异必须是他们种树的数量。因此,他们必须种了 21 - 15 = 6 棵树。答案是 6。 问:杰克有 23 美元。他以每个 3 美元的价格买了 5 个小蛋糕。他还剩下多少钱? 答:他以每个 3 美元的价格买了 5 个小蛋糕,总共花费了 3 * 5 = 15 美元。所以,他还剩下 23 - 15 = 8 美元。答案是 8 美元。 问:当我 6 岁时,我的妹妹的年龄是我的一半。现在我已经 24 岁了,那么我的妹妹现在的年龄是多少? 答:当你 6 岁时,你妹妹的年龄是 6 / 2 = 3 岁。现在你 24 岁,所以你妹妹的年龄是 24 - (6 - 3) = 21 岁。 问:李莉的鸭子每天下 16 个蛋。她每天早餐吃 3 个,每天用 4 个给朋友烤松饼。剩下的蛋她以每个 2 美元的价格出售。她每天能赚多少钱? 答: """ result_Chinese, tokens_count = get_completions(system_instruction, prompt, llm) for response_num, con in enumerate(result_Chinese, start=1): result = con.message.content.strip() print(f"思维链-中文-{response_num}:\n{result}\n")注意返回值是response.choices列表:n=3时一次调用得到 3 条互不相同的推理路径,循环依次打印。教程中还给出了一道结构相同、问题语言为英文的对照示例,执行方式一致,可选做对照。
读取输出并投票得出最终答案
运行后按路径编号依次查看每条推理链的结尾答案,再按教程定义的聚合规则投票:选择最终答案集中最一致(出现次数最多)的答案作为最终答案。
教程文档中的示例结果如下(文档示例,实际运行输出可能不同):
- 思维链-中文-1:
每天剩下 16 - 3 - 4 = 9 个蛋。……她每天能赚 9 * 2 = 18 美元。答案是 18 美元。 - 思维链-中文-2:
剩下的蛋数量为 16 - 3 - 4 = 9 个。……所以她每天能赚 18 美元。 - 思维链-中文-3:
……每天剩下 16 - 3 - 4 = 9 个蛋。……李莉每天能赚 18 美元。
3 条路径的最终答案都是 18 美元,多数投票的结果即18 美元。
需要说明的是,教程笔记本在这一节只提供了采样与打印多条推理路径的代码,投票聚合是按教程对方法的描述人工比对各路径结尾答案完成的,仓库中没有给出程序化投票的代码片段。
适用边界与下一步
- 教程文档示例只展示了 3 条路径恰好收敛到同一答案的情形;对于路径答案不一致时如何处理,教程未给出进一步规则,只能依据“选择最一致的答案”这一聚合定义判断。
- 教程总结部分的结论是:即使原始的思维链无效,自我一致性也能改善结果,并且该方法在算术、常识和符号推理任务上通常具有良好的性能。
- 示例代码固定使用
gpt-3.5-turbo-0125模型与seed=42,教程未给出其他模型或参数组合下的效果对比。
本教程其余章节(提示优化工具、ReAct、情绪激励提示等)的完整内容清单可参见 1. 简介 Introduction.md。
【免费下载链接】llm-cookbook面向开发者的 LLM 入门教程,吴恩达大模型系列课程中文版项目地址: https://gitcode.com/GitHub_Trending/ll/llm-cookbook
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考