思维链技术(Chain-of-Thought, CoT)

思维链(Chain-of-Thought, CoT)是一种通过模拟人类逐步推理过程来提升大型语言模型(LLM)复杂任务表现的技术。其核心思想是让模型在生成最终答案前,先输出中间推理步骤,从而增强逻辑性和可解释性。

1. 基础示例:数学问题求解

  • 问题: “罗杰有5个网球,他又买了两盒网球,每盒有3个网球。他现在有多少网球?”
  • 传统Prompting(直接输出答案):模型可能直接输出错误答案(如"27"),因为缺乏中间计算步骤

CoT Prompting(分步推理):

问:罗杰有5个网球,他又买了两盒网球,每盒有3个网球。他现在有多少网球?  
答:罗杰一开始有5个网球,2盒3个网球,一共是2*3=6个网球,5+6=11。答案是11。

2.复杂推理:符号操作任务
问题
“将单词 ‘hello’ 的最后一个字母与 ‘world’ 的最后一个字母拼接起来。”

CoT Prompting:

1. 'hello'的最后一个字母是'o'2. 'world'的最后一个字母是'd'3. 拼接'o''d'得到'od'。  
最终答案:od

3. 零样本思维链(Zero-shot CoT)
无需示例,仅通过指令触发推理:
问题
“若A=B+2,B=3*C,C=5,求A的值。”

指令
“让我们一步一步思考:”
模型自动生成:

1. 计算C=52. 计算B=3*5=153. 计算A=15+2=17。  
答案:17

代码示例:
准备数据

import json
import os
from typing import List, Dict, Any# 创建CoT训练数据集
def create_cot_dataset():"""创建包含思维链(CoT)示例的数据集"""cot_examples = [{"instruction": "解决以下数学问题,请一步一步思考。","input": "罗杰有5个网球,他又买了两盒网球,每盒有3个网球。他现在有多少网球?","output": "让我一步一步思考:\n1. 罗杰一开始有5个网球\n2. 他买了两盒网球,每盒有3个网球\n3. 两盒网球总共有2×3=6个网球\n4. 罗杰现在总共有5+6=11个网球\n因此,罗杰现在有11个网球。"},{"instruction": "解决以下数学问题,请一步一步思考。","input": "一个商店以每个15元的价格卖了8个苹果,又以每个10元的价格卖了12个橘子。商店总共赚了多少钱?","output": "让我一步一步思考:\n1. 苹果的收入:8个 × 15元 = 120元\n2. 橘子的收入:12个 × 10元 = 120元\n3. 总收入 = 苹果收入 + 橘子收入 = 120元 + 120元 = 240元\n因此,商店总共赚了240元。"},{"instruction": "解决以下逻辑问题,请一步一步思考。","input": "如果所有的A都是B,所有的B都是C,那么所有的A都是C吗?","output": "让我一步一步思考:\n1. 已知条件:所有的A都是B,所有的B都是C\n2. 对于任何一个A,它一定是B(根据条件1)\n3. 由于它是B,而所有的B都是C(根据条件2),所以这个A也一定是C\n4. 因此,所有的A都是C\n所以,结论\"所有的A都是C\"是正确的。",},{"instruction": "解决以下符号操作问题,请一步一步思考。","input": "将单词'hello'的最后一个字母与'world'的最后一个字母拼接起来。","output": "让我一步一步思考:\n1. 'hello'的最后一个字母是'o'\n2. 'world'的最后一个字母是'd'\n3. 将这两个字母拼接起来,得到'od'\n因此,答案是'od'。"},{"instruction": "解决以下代数问题,请一步一步思考。","input": "若A=B+2,B=3*C,C=5,求A的值。","output": "让我一步一步思考:\n1. 已知C=5\n2. 计算B:B=3*C=3*5=15\n3. 计算A:A=B+2=15+2=17\n因此,A的值是17。"}]# 添加更多复杂的CoT示例more_examples = [{"instruction": "解决以下概率问题,请一步一步思考。","input": "一个袋子里有3个红球和5个蓝球。如果随机抽取两个球,求抽到的两个球都是红球的概率。","output": "让我一步一步思考:\n1. 袋子里总共有3+5=8个球\n2. 第一次抽取红球的概率是3/8\n3. 在第一次抽到红球的情况下,第二次抽取红球的概率是2/7(因为还剩2个红球和5个蓝球)\n4. 两次都抽到红球的概率是(3/8)×(2/7)=6/56=3/28\n因此,抽到的两个球都是红球的概率是3/28。"},{"instruction": "解决以下物理问题,请一步一步思考。","input": "一辆汽车以60千米/小时的速度行驶了2小时,然后以80千米/小时的速度行驶了1小时。求汽车的平均速度。","output": "让我一步一步思考:\n1. 第一阶段:速度60千米/小时,时间2小时,距离=60×2=120千米\n2. 第二阶段:速度80千米/小时,时间1小时,距离=80×1=80千米\n3. 总距离=120+80=200千米\n4. 总时间=2+1=3小时\n5. 平均速度=总距离/总时间=200/3≈66.67千米/小时\n因此,汽车的平均速度约为66.67千米/小时。"}]cot_examples.extend(more_examples)# 保存数据集os.makedirs("d:\\Trae\\develop\\try\\data", exist_ok=True)with open("d:\\Trae\\develop\\try\\data\\cot_dataset.json", "w", encoding="utf-8") as f:json.dump(cot_examples, f, ensure_ascii=False, indent=2)print(f"已创建CoT数据集,包含{len(cot_examples)}个示例")return cot_examplesif __name__ == "__main__":create_cot_dataset()

lora微调

import os
import json
import torch
from transformers import (AutoModelForCausalLM,AutoTokenizer,Trainer,TrainingArguments
)
from datasets import Dataset
from peft import (LoraConfig,get_peft_model,prepare_model_for_kbit_training,TaskType
)def load_cot_dataset(file_path: str):"""加载CoT数据集"""with open(file_path, "r", encoding="utf-8") as f:data = json.load(f)return datadef prepare_dataset_for_lora(examples, tokenizer, max_length: int = 512):"""准备用于LoRA训练的数据集"""formatted_examples = []for example in examples:# 格式化为指令微调格式formatted_text = f"指令: {example['instruction']}\n问题: {example['input']}\n回答: {example['output']}"formatted_examples.append({"text": formatted_text})# 创建数据集dataset = Dataset.from_list(formatted_examples)# 对数据集进行分词处理def tokenize_function(examples):return tokenizer(examples["text"],padding="max_length",truncation=True,max_length=max_length,return_tensors="pt")tokenized_dataset = dataset.map(tokenize_function,batched=True,remove_columns=["text"])# 划分训练集和验证集tokenized_dataset = tokenized_dataset.train_test_split(test_size=0.1)return tokenized_datasetdef train_cot_with_lora():"""使用LoRA方法微调模型以学习CoT推理"""# 加载预训练模型和分词器model_name = "THUDM/chatglm3-6b"  # 可以替换为其他中文模型print(f"加载模型: {model_name}")tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)model = AutoModelForCausalLM.from_pretrained(model_name,trust_remote_code=True,torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,load_in_8bit=True if torch.cuda.is_available() else False)# 准备模型进行LoRA微调if torch.cuda.is_available():model = prepare_model_for_kbit_training(model)# 配置LoRAlora_config = LoraConfig(task_type=TaskType.CAUSAL_LM,r=8,  # LoRA的秩lora_alpha=32,lora_dropout=0.1,target_modules=["query_key_value"],  # 根据模型架构调整bias="none",)# 应用LoRA配置model = get_peft_model(model, lora_config)print(f"可训练参数数量: {model.print_trainable_parameters()}")# 加载CoT数据集cot_examples = load_cot_dataset("d:\\Trae\\develop\\try\\data\\cot_dataset.json")print(f"加载了{len(cot_examples)}个CoT示例")# 准备训练数据集tokenized_dataset = prepare_dataset_for_lora(cot_examples, tokenizer)# 设置训练参数training_args = TrainingArguments(output_dir="d:\\Trae\\develop\\try\\cot_lora_model",overwrite_output_dir=True,num_train_epochs=3,per_device_train_batch_size=4,  # 使用LoRA可以用更大的批量per_device_eval_batch_size=4,gradient_accumulation_steps=4,evaluation_strategy="steps",eval_steps=50,save_strategy="steps",save_steps=50,save_total_limit=3,learning_rate=1e-4,weight_decay=0.01,warmup_steps=50,logging_dir="d:\\Trae\\develop\\try\\logs",logging_steps=10,fp16=torch.cuda.is_available(),report_to="none",)# 创建训练器trainer = Trainer(model=model,args=training_args,train_dataset=tokenized_dataset["train"],eval_dataset=tokenized_dataset["test"],)# 开始训练print("开始LoRA训练...")trainer.train()# 保存模型model.save_pretrained("d:\\Trae\\develop\\try\\cot_lora_model\\final")tokenizer.save_pretrained("d:\\Trae\\develop\\try\\cot_lora_model\\final")print("LoRA训练完成,模型已保存")if __name__ == "__main__":train_cot_with_lora()

推理

import torch
from transformers import AutoModelForCausalLM, AutoTokenizerdef load_cot_model(model_path: str):"""加载训练好的CoT模型"""tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)model = AutoModelForCausalLM.from_pretrained(model_path,trust_remote_code=True,torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32)return model, tokenizerdef generate_cot_response(model, tokenizer, instruction: str, problem: str, max_length: int = 1024):"""使用CoT模型生成包含推理步骤的回答"""# 构建输入提示prompt = f"指令: {instruction}\n问题: {problem}\n回答:"# 生成回答inputs = tokenizer(prompt, return_tensors="pt").to(model.device)outputs = model.generate(inputs.input_ids,max_length=max_length,temperature=0.7,top_p=0.9,do_sample=True,num_return_sequences=1)# 解码回答response = tokenizer.decode(outputs[0], skip_special_tokens=True)# 提取回答部分response = response.split("回答:")[1].strip() if "回答:" in response else responsereturn responsedef test_cot_model():"""测试CoT模型的推理能力"""# 加载模型model_path = "d:\\Trae\\develop\\try\\cot_model\\final"model, tokenizer = load_cot_model(model_path)model.to("cuda" if torch.cuda.is_available() else "cpu")model.eval()# 测试问题test_problems = [{"instruction": "解决以下数学问题,请一步一步思考。","problem": "小明有12个苹果,他给了小红3个,又给了小李2个,然后自己吃了1个。小明还剩下多少个苹果?"},{"instruction": "解决以下逻辑问题,请一步一步思考。","problem": "如果今天不是周一,那么明天不是周二。今天是周三,那么明天是周几?"},{"instruction": "解决以下代数问题,请一步一步思考。","problem": "若x+y=10且xy=21,求x²+y²的值。"}]# 对每个问题生成回答for i, test in enumerate(test_problems):print(f"\n测试 {i+1}:")print(f"指令: {test['instruction']}")print(f"问题: {test['problem']}")response = generate_cot_response(model, tokenizer, test['instruction'], test['problem'])print(f"回答:\n{response}")print("-" * 50)if __name__ == "__main__":test_cot_model()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/899462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷粒微服务高级篇学习笔记整理---异步线程池

多线程回顾 多线程实现的4种方式 1. 继承 Thread 类 通过继承 Thread 类并重写 run() 方法实现多线程。 public class MyThread extends Thread {Overridepublic void run() {System.out.println("线程运行: " Thread.currentThread().getName());} }// 使用 pub…

Windows学习笔记(4)关于MITRE

基本术语 APT(威胁组,高级持续威胁) TTP(攻击目的技术过程,战术技术和程序) ATT&CK框架 网站 https://attack.mitre.org/ CAR知识库 MITRE Engage MITRE D3FEND 网址 https://d3fend.mitre.org/

Go 语言规范学习(2)

文章目录 VariablesTypesBoolean typesNumeric typesString typesArray typesSlice typesStruct typesPointer typesFunction typesInterface typesBasic interfacesEmbedded interfacesGeneral interfaces【泛型接口】Implementing an interface【实现一个接口】 Map typesCha…

创意 Python 爱心代码分享

创意 Python 爱心代码分享 在编程中,用代码表达创意和情感是一种非常有趣的方式。本文将分享几段用 Python 编写的爱心代码,涵盖简单到复杂的实现方式,适合初学者和进阶开发者。 1. 简单爱心图案 代码实现 print("\n".join([&qu…

NLP高频面试题(二十四)——RAG相关内容简介

检索增强生成(Retrieval-Augmented Generation,简称 RAG)是一种将信息检索与生成模型相结合的技术,旨在提升大型语言模型的响应准确性、相关性和时效性。通过在生成过程中引入外部知识,RAG 能够有效弥补 LLM 在知识局限…

Share01-WinCC文件越用越大?

为什么你们的经典WinCC项目在客户电脑上运行的越来越慢?为什么查询一个历史曲线慢的要死?为什么重启一下电脑画面都要怀疑人生?具体原因可能多种多样,但是极大可能是您的数据管理设置欠佳,那么闲话少叙,和小…

练习题:111

目录 Python题目 题目 题目分析 需求理解 关键知识点 实现思路分析 代码实现 代码解释 指定文件路径和名称: 定义要写入的内容: 打开文件并写入内容: 异常处理: 输出提示信息: 运行思路 结束语 Python题…

2025_0327_生活记录

昨晚正在玩手机,凌晨一点二十一分左右手机突然响起来,通知地震波将在5秒后到达海淀区。看着倒计时的数字不断减小,橙色预警页面不断闪动,床猛地摇了几下。那一刻,我的记忆被拉回了2008年。 上大学之前我在成都生活了1…

基于改进粒子群算法的多目标分布式电源选址定容规划(附带Matlab代码)

通过分析分布式电源对配电网的影响,以有功功率损耗、电压质量及分布式电源总容量为优化目标,基于模糊理论建立了分布式电源在配电网中选址定容的多目标优化模型,并提出了一种改进粒子群算法进行求解。在算例仿真中,基于IEEE-14标准…

雨云云应用测评!内测持续进行中!

大家好,时隔一个月,我们又见面了! 最近,雨云推出了新型云应用(RCA,Rainyun Cloud Application)。 通过云应用,你可以快速创建可以外部访问的应用,采用全新的面板和dock…

【研究方向】联邦|自然语言

联邦学习 Federated Learning,FL 分布式学习方案。 通过多个参与方(client) 联邦计算 Federated Computing 联邦计算(Federated Learning)是一种分布式 机器学习 方法,旨在解决数据隐私保护与数据孤岛问题。 图联邦 Graph Neural Networks,GNNs 图联…

【算法day25】 最长有效括号——给你一个只包含 ‘(‘ 和 ‘)‘ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。

32. 最长有效括号 给你一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。 https://leetcode.cn/problems/longest-valid-parentheses/ 2.方法二:栈 class Solution { public:int longestValid…

C++编程学习笔记:函数相关特性、引用与编译流程

目录 一、函数的缺省参数 (一)全缺省参数 (二)半缺省参数 二、函数重载 (一)参数类型不同 (二)参数个数不同 (三)参数类型顺序不同 三、引用相关问题…

RPCGC阅读

24年的MM 创新 现有点云压缩工作主要集中在保真度优化上。 而在实际应用中,压缩的目的是促进机器分析。例如,在自动驾驶中,有损压缩会显着丢失户外场景的详细信息。在三维重建中,压缩过程也会导致场景数据中语义信息(Contour)的…

泛目录优化:无极泛目录优化网站,技术解析与风险控制指南

无极泛目录优化网站精简版 一、核心功能 无限层级目录:支持动态创建 5 级以上子目录,形成内容矩阵AI 内容生成:集成 GPT-4 接口,日均生产 10 万 原创度 70% 以上的页面SEO 智能检测:自动优化 TDK、URL 结构、图片属…

归档重做日志archived log (明显) 比redo log重做日志文件小

归档重做日志 (明显) 比重做日志文件小。 (文档 ID 1356604.1) 日志切换将由于以下原因发生: 1. 由于在重做日志文件已满之前强制创建存档而记录和设计的行为 SQL> alter system switch logfile;SQL> alter system archive log current;RMAN> backup ar…

645.错误的集合

import java.util.HashMap; import java.util.Map;/*** program: Test* description: 645 错误的集合* author: gyf* create: 2025-03-23 10:22**/ public class Test {public static void main(String[] args) {}public static int[] findErrorNums(int[] nums) {int[] arr n…

力扣刷题494. 目标和

494. 目标和 - 力扣(LeetCode) 方法一,暴力dfs 直接进行深搜查找出所有的情况,缺点严重超时,只能过20个案例 留一下超时的 class Solution {//首先定义全局变量int[] abs { 1, -1 }; //用来记录当前遍历的数的正…

一周学会Flask3 Python Web开发-SQLAlchemy数据迁移migrate

锋哥原创的Flask3 Python Web开发 Flask3视频教程: 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 模型类(表)不是一成不变的,当你添加了新的模型类,或是在模型类中添加了新的字段,甚至是修改…

Python练习之抽奖界面

前言 一、代码整体架构分析 1、数据层 (Model) 2、控制层 (Controller) 3、视图层 (View) 二、核心功能实现详解 1、 文件导入功能 1.1、实现逻辑 1.2、代码涉及知识点讲解 1.2.1、wildcard 1.2.2、wx.FileDialog 1.2.3、dlg.ShowModal() 2、抽奖动画控制 1.1、…