--- license: gpl-3.0 language: - zh - en base_model: - unsloth/Qwen2.5-3B-Instruct-unsloth-bnb-4bit pipeline_tag: text-generation tags: - not-for-all-audiences - text-generation-inference - transformers - unsloth - qwen2 - gguf --- 一个更好的实现,试试这个:DeepSeek-V3.2-asks-the-user-questions-while-they-are-thinking https://modelscope.cn/studios/likewendy/DeepSeek-V3.2-asks-the-user-questions-while-they-are-thinking/summary 显然,ds也开始实现在思考中调用工具了。 # Qwen2.5-3B-YiLin-GGUF-q4_k_m ## 概述 该模型基于 Qwen2.5-3B-Instruct 的动态4位量化,使用 QLoRA 在两个开源数据集一个合成数据集上训练了 3 epochs,最大上下文长度为 8192。 成功的将类似于 DeepSeek-r1 的思维链迁移到 Qwen2.5-3B-Instruct ,并且实现了 **“使用系统提示控制思维链”** 使模型可以**更灵活的产生思维链**并**在思考的过程中与外界交互调用工具**,从而实现模型自身 **“具身智能”**。 该特性旨在解决:**模型在输出思考过程的时候,遇到需要查询资料或者用户补充问题时,无法与外界交互,从而导致推理性能得不到释放的问题。** >作者认为,该特性应用前景巨大,配合 MCP 可以完全摆脱传统 Agent 以多轮对话的形式调用工具的不足,将工具调用搬到思维链中来,借助思维链提高工具使用的水平和效益,更好的利用起现实世界中的各种工具。 合成数据集使用该仓库 [yilin-chatgpt-prompts](https://github.com/youyi0218/yilin-chatgpt-prompts) 的提示词通过自动化数据合成管道,合成了 2000 余篇意林风格的文章。 ## 权重 提供合并到 Qwen2.5-3B-Instruct 的16位 .safetensors 文件,和 GGUF 格式的 BF16、Q4_K_M 文件以方便 ollama 部署。 ## 预期用途 研究 “使用系统提示控制思维链” 的可行性与效益。 作为一个吃螃蟹的模型,它旨在抛出一个引子,引导人们继续相关研究,从而推进 LLM 在 AGI 道路上的进程。 ## 滥用 几乎可以用模型做任何事情,它拥有良好的人类对齐,符合普遍价值观。并且善于编写文笔具有艺术性的文章。 ## 快速开始 ### 推理 1. 你可以使用 ollama 部署,尽可能的使用 16 位 GGUF 文件,除非你的硬件难以运行它,那么,你可以使用 Q4_K_M ,如果你使用 Q4_K_M 一个好的技巧是,请尝试使用类似于这样的 user prompt : ``` 这里是你的提示词\n ``` 2. VLLM 你可以直接使用 vllm 运行此模型,只需传入 likewendy/Qwen2.5-3B-YiLin-GGUF-q4_k_m 。 3. 使用代码,常规推理 ```python from unsloth import FastLanguageModel model, tokenizer = FastLanguageModel.from_pretrained( model_name="likewendy/Qwen2.5-3B-YiLin-GGUF-q4_k_m", max_seq_length=8192, dtype=None, load_in_4bit=Flase, ) from unsloth.chat_templates import get_chat_template # 获取 Qwen-2.5 的聊天模板,并应用到分词器 tokenizer = get_chat_template( tokenizer, chat_template="qwen-2.5", ) FastLanguageModel.for_inference(model) # 启用原生 2 倍速推理 # 定义消息列表,包含用户角色和内容 messages = [ {"role": "system", "content": "如果需要搜索网页,你需要在标签之前,输出这样格式的文本来调用工具搜索网页:{'search':'此处为需要搜索的关键词'}"}, {"role": "user", "content": "给我邓文怡的最新歌曲"}, ] inputs = tokenizer.apply_chat_template( messages, tokenize=True, add_generation_prompt=True, return_tensors="pt", ).to("cuda") from transformers import TextStreamer text_streamer = TextStreamer(tokenizer, skip_prompt=True) # 使用模型生成输出 _ = model.generate( input_ids=inputs, streamer=text_streamer, max_new_tokens=8192, use_cache=True, temperature=0.7, top_p=0.7, ) ``` 4. 使用代码,**通过 “使用系统提示控制思维链” 实现让用户补充问题的完整demo** ```python from unsloth import FastLanguageModel model, tokenizer = FastLanguageModel.from_pretrained( model_name="likewendy/Qwen2.5-3B-YiLin-GGUF-q4_k_m", max_seq_length=8192, dtype=None, load_in_4bit=Flase, ) from unsloth.chat_templates import get_chat_template # 获取 Qwen-2.5 的聊天模板,并应用到分词器 tokenizer = get_chat_template( tokenizer, chat_template="qwen-2.5", ) FastLanguageModel.for_inference(model) # 启用原生 2 倍速推理 import json from transformers import TextStreamer, StoppingCriteria, StoppingCriteriaList should_stop_ok = False class CustomStreamer(TextStreamer): def __init__(self, tokenizer, **kwargs): super().__init__(tokenizer, **kwargs) self.should_stop = False self.issue_content = None self.buffer = "" self.output_text = "" def put(self, value): # 实时输出到控制台(父类方法) # 如果您只想解码新增的最后一个 token,也可以只 decode 最后一个 super().put(value) # 如果 value 是张量,先把它移到 CPU 并转换成列表 # 如果已经是列表,可以根据实际情况判断是否需要做类似的操作 if hasattr(value, "cpu"): value = value.cpu() if hasattr(value, "numpy"): value = value.numpy().tolist() elif hasattr(value, "tolist"): value = value.tolist() # 如果是批量大小=1,则取出第一行 # 这里假设传入的 value 是二维 [batch_size, sequence_length] 结构 # 如果 batch_size 不是 1,需酌情修改 if isinstance(value[0], list): value = value[0] # 现在 value 应该是一维的 token 列表 last_token = value[-1:] text_chunk = self.tokenizer.decode(last_token, skip_special_tokens=True) self.buffer += text_chunk # 分割处理完整行 while '\n' in self.buffer: newline_pos = self.buffer.find('\n') line = self.buffer[:newline_pos] self.buffer = self.buffer[newline_pos+1:] self._process_line(line) def _process_line(self, line): self.output_text += line + '\n' # 记录完整输出 # 检测是否包含停止条件 line = line.strip() if line.startswith("{'issue_add':") or line.startswith('{"issue_add":'): try: # 处理单引号并解析JSON json_str = line.replace("'", '"') data = json.loads(json_str) if 'issue_add' in data and not should_stop_ok: self.should_stop = True self.issue_content = data['issue_add'] except json.JSONDecodeError: pass def end(self): # 处理剩余缓冲区内容 if self.buffer: self._process_line(self.buffer) self.buffer = "" super().end() class StopCondition(StoppingCriteria): def __init__(self, streamer): super().__init__() self.streamer = streamer def __call__(self, input_ids, scores, **kwargs): return self.streamer.should_stop # 定义消息列表,包含用户角色和内容 messages = [ {"role": "system", "content": "如果需要让用户补充更多信息,你需要在标签之前,输出这种格式的文本来调用工具,以实现让用户补充更多信息,格式是:{'issue_add':'这里你需要告诉用户缺少什么信息'}"}, {"role": "user", "content": "我买了点散装称重的零食,花了100块钱,每袋多少钱?"}, ] while True: # 准备模型输入 inputs = tokenizer.apply_chat_template( messages, tokenize=True, add_generation_prompt=True if not should_stop_ok else False, return_tensors="pt" ).to("cuda") # 创建流式处理器和停止条件 streamer = CustomStreamer(tokenizer, skip_prompt=True) stop_condition = StopCondition(streamer) if should_stop_ok: inputs_str = tokenizer.decode(inputs[0], skip_special_tokens=False) # delete <|im_end|> inputs_str = inputs_str[:-11] # print(inputs_str) import torch inputs = torch.tensor([tokenizer.encode(inputs_str,add_special_tokens=False)], dtype=torch.long, device='cuda') # 执行生成(带停止条件) model.generate( input_ids=inputs, streamer=streamer, max_new_tokens=8192, use_cache=True, temperature=0.7, top_p=0.7, stopping_criteria=StoppingCriteriaList([stop_condition]), ) # 将模型输出添加到对话历史 if streamer.output_text.strip(): messages.append({"role": "assistant", "content": streamer.output_text.strip()}) # 检测停止条件 if streamer.should_stop: print(f"\n---\n检测到issue_add内容: {streamer.issue_content}") user_input = input("请输入您的回复: ") print("---\n") should_stop_ok = True # 将用户拼接到assistant消息 messages[len(messages)-1]['content'] += f"\n工具调用结果:{user_input}\n我已经得到了工具的调用结果:“{user_input}”,下面我需要根据工具调用结果继续推理。\n首先," # print(messages) else: break # 正常结束生成 ``` 上述代码的终端输出: ``` 我现在得解决这个问题。题目说,我买了一些散装称重的零食,总共花了100块钱,但是不知道每袋的价格是多少。那应该怎么做呢? 首先,我得仔细看看问题。题目里提到的是“散装称重”的零食,也就是可能是一些大包装的东西,比如一包饼干、一盒巧克力或者某种混合坚果,这些都是没有明确标价的,所以每袋的价格可能不同。不过题目中并没有给出具体的种类和数量,只是总价100块钱。 那可能的问题在于,题目中的“散装”是否意味着每袋价格不同?比如说,有的袋子可能更贵一些,而有的便宜一些,这样的话,总金额100元的话,可能无法平均分配到每个袋子上。这时候可能需要更多的信息来确定每袋的价格,比如有多少种不同的袋子,每种的数量等等。 不过题目里并没有提供这些额外的信息。那可能题目本身存在假设或隐含条件,比如是否存在折扣或者优惠活动,但题目里没有提到这些情况。或者可能是题目设计时忽略了这些细节,导致无法直接计算出每袋的价格。 那么,按照常规的处理方法,如果每袋的价格不同,且总金额为100元,可能需要知道具体每种袋子的数量,才能计算出每袋的价格。例如,如果有5种不同大小的袋子,每种的数量分别是2、3、4、5、6个,那么总共有5×(2+3+4+5+6)=55个袋子,总重量是2+3+4+5+6=20公斤,每公斤的价格就是100/20=5元。这样每袋的价格应该是5元除以对应的数量,比如第一种袋子可能每袋5元,第二种可能8元,第三种10元,以此类推。但题目里并没有给出具体的数据,所以无法准确计算。 或者题目可能假设所有袋子的价格相同,或者总共有几种不同的袋子,但数量未知。比如,如果有三种袋子,分别是A、B、C,每袋的价格分别为a元、b元、c元,总数量为n袋,那么总费用就是a*n+a*b+n*c=100元。但同样,题目里没有给出a、b、c的具体数值,也没有n的值,所以无法解出答案。 另外,可能题目中存在其他隐藏条件,比如是否有优惠券、打折等情况,但题目里没有提及,所以只能按照最简单的处理方式,即假定每袋价格相同,或者有不同价格的情况,但题目里没有说明。因此,根据题目给定的信息,无法得出准确的答案。 总结一下,由于题目没有提供足够的信息,比如每袋的价格类型、数量等,所以无法确定每袋的具体价格。可能需要更多数据才能解答。所以,正确的回答应该是:“无法确定,因为缺少必要的信息。” 或者更简洁地说,“需要更多信息。” 这样既符合逻辑,又尊重题目提供的有限信息。 {"issue_add":"缺少每袋的价格类型和数量"}<|im_end|> --- 检测到issue_add内容: 缺少每袋的价格类型和数量 请输入您的回复: 20袋 --- 我需要确认这个结果是否合理。散装零食通常会有多种规格,比如小袋、中袋、大袋等,每种规格的价格不同。假设每袋的价格都是整数,那么总金额100元的情况下,每袋的价格应该是100除以袋数的结果。如果袋数是20,那么每袋的价格就是5元。但实际散装零食的袋数可能不是20,而是其他数字,比如10袋、25袋、50袋等等。我们需要验证这个结果是否符合实际情况。 接下来,考虑散装零食的常见规格和价格分布。例如,常见的零食袋装价格可能如下: - 小袋(如50克):5元左右 - 中袋(如100克):10元左右 - 大袋(如200克):15元左右 假设每袋的价格分布在这个范围内,我们可以尝试将100元分成几个部分。例如,如果每袋都是5元,那么需要20袋;如果是10元,需要10袋;如果是15元,需要6.67袋,这显然不合理。因此,每袋的价格应该是介于5元和10元之间,且总和为100元。 现在,假设每袋的价格是5元,那么需要多少袋才能凑成100元?计算如下: 100 ÷ 5 = 20 袋 所以,如果每袋价格是5元,需要20袋。这个结果与工具给出的结果一致,因此是合理的。 结论:每袋的价格是5元,共购买了20袋。<|im_end|> ``` ### 技巧 1. 建议的参数 temperature=0.7 top_p=0.7 ### 例子 1. 通过 “使用系统提示控制思维链” 实现搜索网页 **系统提示词:** ``` 如果需要搜索网页,你需要在标签之前,输出这样格式的文本来调用工具搜索网页:{'search':'此处为需要搜索的关键词'} ``` **用户提示词:** ``` 给我邓文怡的最新歌曲 ``` **模型回复:** ``` 用户让我提供邓文怡的最新歌曲。首先,我需要确认邓文怡是谁,可能是一个歌手的名字。然后,我应该回想一下她最近有什么新歌发布。邓文怡是中国台湾的女歌手,她的音乐风格可能是流行或者电子舞曲? 接下来,我需要检查最近是否有她的新专辑或单曲发布。我记得她曾经和林俊杰合作过《不分手》,但不知道有没有其他作品。另外,她也参与过一些合辑,比如《超级星光大道》之类的选秀节目吗?不过用户可能更想听她的原创作品。 根据我的知识库,邓文怡最近的一首比较热门的单曲是《爱在月光下》,这是一首电子舞曲风格的歌曲,通常用于舞蹈场合。另外,她还有一首《你是我最爱的人》,这首歌听起来像是抒情风格,可能适合晚间的温柔氛围。不过这些信息可能需要进一步验证。 然后,我需要考虑用户的潜在需求。他们可能是在寻找邓文怡的新歌来播放,或者准备演唱会、活动等场合。如果是演唱会的话,可能需要推荐她的主打曲目,而如果只是日常听歌,可能需要更多选择。 还要注意版权问题,确保提供的链接是合法的,并且没有侵犯任何版权。所以最好直接给出歌词和歌曲名称,或者提供下载链接,但要注意不要提供非法内容。 最后,我应该组织这些信息,分点列出最新的几首歌曲,并简要说明类型和风格,让用户可以根据自己的喜好选择。同时提醒用户可能需要通过官方渠道获取最新信息,因为歌手可能会有新的动态。 {'search':'邓文怡 最新 歌曲'} 邓文怡(Yumi)是中国台湾的知名女歌手,以电子舞曲和流行音乐为主打风格。以下是她近期的热门单曲及最新作品: --- ### **1. 《爱在月光下》** - **类型**:电子舞曲 - **特点**:节奏强烈、动感十足,常作为派对或健身音乐使用。 - **推荐场景**:夜店、健身房、户外活动。 --- ### **2. 《你是我最爱的人》** - **类型**:抒情流行 - **特点**:旋律温暖,歌词表达深情与思念,适合夜晚安静聆听。 - **推荐场景**:浪漫约会、电影配乐。 --- ### **3. 《不分手》** - **类型**:轻快舞曲 - **特点**:与林俊杰合作的经典作品,旋律朗朗上口,常用于社交场合。 - **推荐场景**:聚会、KTV、广告背景音乐。 --- ### **4. 《心跳》** - **类型**:流行电子 - **特点**:节奏感强,歌词描述心动时刻,适合恋爱主题MV或广告。 --- ### **5. 《逆光飞翔》** - **类型**:励志流行 - **特点**:鼓励积极向上的歌词,适合正能量场合。 --- ### **如何获取最新歌曲?** 1. **官方平台**:访问邓文怡的微博、抖音或YouTube频道,关注最新动态。 2. **数字音乐平台**:如Spotify、Apple Music、YouTube Music等,搜索歌曲名称即可找到完整版。 3. **实体发行**:部分单曲可通过线上商城购买实体CD或下载。 --- 如果你需要具体的歌词或下载链接,请告诉我!<|im_end|> ``` 2. 通过 “使用系统提示控制思维链” 实现让用户补充问题 **系统提示词:** ``` 如果需要让用户补充更多信息,你需要在标签之前,输出这种格式的文本来调用工具,以实现让用户补充更多信息,格式是:{'issue_add':'这里你需要告诉用户缺少什么信息'} ``` **用户提示词:** ``` 我买了点散装称重的零食,花了100块钱,每袋多少钱? ``` **模型回复:** ``` 我现在要解决这个问题。题目说,我买了一些散装称重的零食,总共花费了100块钱。每个袋子的价格不同,所以我想知道每袋多少钱。不过问题好像有点不太对头,因为散装零食通常都是按重量收费的,而不是按袋子来卖的。比如,可能是一箱一箱的,每个袋子里面装的是不同重量的零食。 那问题中的“每袋多少钱”应该是指每个袋子里面的单价,对吧?但这里的问题似乎把重量和袋子的数量混在一起了。比如说,假设我买了5袋零食,每袋20元的话,那么总费用就是5×20=100元,刚好符合题目的条件。这样的话,每个袋子就是20元? 或者有没有可能是题目中的“散装称重”的零食,指的是按照不同的重量来计价的呢?比如,每袋里有不同的重量,而价格也是根据重量来计算的。这样的话,每个袋子里的重量可能不同,所以单价也不一样。比如,第一个袋子可能有1斤,第二个袋子可能有2斤,这样总价就是1+2=3斤,每斤的价格就是100/3≈33.33元。这样的话,每个袋子的单价应该是不同的。 但是题目中并没有说明每个袋子的具体重量是多少,只是说每袋的钱数。这时候应该怎么处理呢?可能题目中的“每袋多少钱”指的是每个袋子的单价,而这个单价可能根据袋子的大小或重量来决定。比如,可能每个袋子的价格是固定的,不管里面有多少重量。这样的话,每个袋子的单价就是100元除以袋子的数量。比如,如果买了5袋,每个袋子就是100/5=20元。这和前面的例子一致。 不过题目中没有明确说明是否每个袋子的价格固定,还是根据重量来计算。如果是后者的话,可能每个袋子的价格不同,所以不能直接算出每个袋子的单价。例如,如果第一个袋子是1斤,第二个袋子是2斤,第三个袋子是3斤,那么总价就是6斤,平均每个袋子的价格就是60元,每个袋子的单价是60/3=20元。这时候每个袋子的单价应该是相同的,等于总价除以袋子数量。 不过题目中的问题看起来更复杂,可能需要更多的信息才能确定每个袋子的单价。比如,题目中可能提到每个袋子的重量不同,或者每个袋子的价格不同。这时候可能需要进一步的信息,比如每个袋子的重量分别是多少,或者每个袋子的价格分别是多少。如果没有这些信息,可能无法准确回答问题。 所以,根据当前给出的信息,可能有两种情况: 1. 如果每个袋子的价格是固定的,比如每个袋子都是20元的话,那么每个袋子就是20元。 2. 如果每个袋子的价格不同,比如第一个袋子是1斤,第二个是2斤,第三个是3斤,那么总价是6斤,每个袋子的单价就是60元,每个袋子的单价是20元。 但题目中并没有提供足够的信息来确定每个袋子的具体重量和价格。因此,可能需要更多的细节才能解答这个问题。比如,题目中是否有提到每个袋子的重量和对应的单价,或者是否有其他相关信息? 假设题目中的每个袋子的价格是固定的,比如每个袋子都是20元的话,那么答案就是每个袋子20元。但如果每个袋子的价格不同,就需要更多数据才能计算每个袋子的单价。在这种情况下,可能需要用户提供更多信息来确定每个袋子的单价。 {'issue_add':'这里你需要告诉我每个袋子的重量以及它们各自的单价'} 散装零食通常按重量计费,但题目描述的“每袋多少钱”可能存在歧义。需先确认以下关键信息: 1. **散装零食的包装单位**:是否为独立包装(如小袋)或统一容器(如大桶)? - 若为独立包装,需了解每袋的重量或容量。 - 若为统一容器,需了解其总重量及包含袋数。 2. **定价方式**: - 是否存在不同单价的袋子?例如,部分袋装零食标价为20元/袋,而另一些为30元/袋。 - 是否有固定单价的包装(如每袋20元),还是按重量分档收费? 若缺乏具体数据,无法直接计算。例如: - 假设每个袋子均为20元/袋,则100元可购买5袋。 - 若存在不同单价,需列出所有选项进行组合验证。 建议补充以下信息: - 每个袋子的重量(如1斤、2斤等)。 - 具体定价方案(如20元/袋、30元/袋等)。 - 总共购买了多少个袋子(或总重量)。 根据现有信息,无法准确计算单价,需提供更详细数据。<|im_end|> ``` 3. 通过 “使用系统提示控制思维链” 实现让用户补充问题,在界面实现中可能的样子 ![image/png](https://cdn-uploads.huggingface.co/production/uploads/66719e03a4dd9ce916a82688/azssO7njGWkSfi-blC5Ef.png)