File size: 5,514 Bytes
9d7391f b3e5a73 3233085 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
---
license: apache-2.0
datasets:
- KingNish/reasoning-base-20k
language:
- en
- zh
base_model:
- Qwen/Qwen2.5-1.5B
---
## Uses
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "/root/app/Reason/checkpoints"
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype="auto",
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
from typing import List, Dict
def new_apply_chat_template(history:List[Dict[str, str]], add_reasoning_generation_prompt:bool=True, add_assistant_generation_prompt:bool=False):
if add_reasoning_generation_prompt:
return "".join([f"<|im_start|>{i['role']}\n{i['content']}<|im_end|>\n" for i in history]) + "<|im_start|><|reasoning|>\n"
if add_assistant_generation_prompt:
return "".join([f"<|im_start|>{i['role']}\n{i['content']}<|im_end|>\n" for i in history]) + "<|im_start|>assistant\n"
from IPython.display import Markdown, display
device = "cuda"
history = []
history.append({"role": "system", "content": "You are a helpful assistant"})
while True:
question = input('User:' + '\n')
print(question)
print('\n')
history.append({"role": "user", "content": question})
input_text = new_apply_chat_template(
history,
add_reasoning_generation_prompt=True
)
model_inputs = tokenizer([input_text], return_tensors="pt").to(device)
if model_inputs.input_ids.size()[1]>32000:
break
generated_ids = model.generate(
model_inputs.input_ids,
max_new_tokens=3000
)
if len(generated_ids)>32000:
break
generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)]
reasoning_response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
history.append({"role": "<|reasoning|>", "content": reasoning_response})
print('reasoning:\n')
#print(response)
display(Markdown(reasoning_response))
print("------------")
print('\n')
input_text = new_apply_chat_template(
history,
add_assistant_generation_prompt=True
)
model_inputs = tokenizer([input_text], return_tensors="pt").to(device)
if model_inputs.input_ids.size()[1]>32000:
break
generated_ids = model.generate(
model_inputs.input_ids,
max_new_tokens=3000
)
if len(generated_ids)>32000:
break
generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)]
assistant_response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
history.append({"role": "assistant", "content": assistant_response})
print('assistant:\n')
display(Markdown(assistant_response))
print("------------")
print("超过模型字数上线,已退出")
在模型中加入 `<|reasoning|>` 特殊标记:
1. 训练数据格式修改
- 在 `prepare_conversation_template` 方法中,对话模板增加了 reasoning 部分
- 对话流程变成: system → user → reasoning → assistant
- 这让模型能够学习到推理过程和最终答案之间的关系
2. 模型架构变化
- 通过 `add_special_tokens` 方法添加了新的特殊标记 `<|reasoning|>`
- 扩展了模型的词表大小(通过 `resize_token_embeddings`)
- 让模型能够识别和生成这个特殊标记
3. 训练目标的改变
- 模型不仅要学习生成答案,还要学习生成推理过程
- 在 `create_answer_mask` 中,模型需要同时预测 reasoning 和 assistant 部分
4. 推理能力增强
- 模型被训练去显式地展示推理过程
- 有助于生成更可解释的答案
- 可以帮助模型形成更结构化的思维链路
让模型在回答问题时不仅给出答案,还能展示推理过程,提高模型回答的可解释性和可靠性。
与不改变词表的本质区别在于:
1. 不改词表的方式:
- `<|reasoning|>` 会被拆分成普通token序列来处理
- 模型将其视为普通文本,类似于看到 "reasoning" 这个词
- 占用更多token位置(因为被拆分)
- 没有特殊的语义表示学习
2. 添加到词表的方式:
- `<|reasoning|>` 作为单个特殊token处理
- 模型可以学习到这个标记专门的语义表示
- 只占用一个token位置
- 能够建立独特的语义空间
具体影响:
```
# 假设tokenizer编码示例
# 不加入词表:
"<|reasoning|>" -> [1234, 5678, 9012] # 被拆分成多个基础token
# 加入词表:
"<|reasoning|>" -> [32000] # 单个特殊token
```
从训练效果看:
- 加入词表能让模型更好地识别和区分推理部分的边界
- 不加入词表依然可以起到标记作用,但模型需要从上下文学习这种模式
- 加入词表的方式通常效果更好,因为给了模型更明确的语义信号
|