Qwen2.5-1.5B-O1 / README.md
Laurie's picture
Update README.md
3233085 verified
metadata
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
  • 这让模型能够学习到推理过程和最终答案之间的关系
  1. 模型架构变化
  • 通过 add_special_tokens 方法添加了新的特殊标记 <|reasoning|>
  • 扩展了模型的词表大小(通过 resize_token_embeddings)
  • 让模型能够识别和生成这个特殊标记
  1. 训练目标的改变
  • 模型不仅要学习生成答案,还要学习生成推理过程
  • create_answer_mask 中,模型需要同时预测 reasoning 和 assistant 部分
  1. 推理能力增强
  • 模型被训练去显式地展示推理过程
  • 有助于生成更可解释的答案
  • 可以帮助模型形成更结构化的思维链路

让模型在回答问题时不仅给出答案,还能展示推理过程,提高模型回答的可解释性和可靠性。

与不改变词表的本质区别在于:

  1. 不改词表的方式:
  • <|reasoning|> 会被拆分成普通token序列来处理
  • 模型将其视为普通文本,类似于看到 "reasoning" 这个词
  • 占用更多token位置(因为被拆分)
  • 没有特殊的语义表示学习
  1. 添加到词表的方式:
  • <|reasoning|> 作为单个特殊token处理
  • 模型可以学习到这个标记专门的语义表示
  • 只占用一个token位置
  • 能够建立独特的语义空间

具体影响:

# 假设tokenizer编码示例
# 不加入词表:
"<|reasoning|>" -> [1234, 5678, 9012]  # 被拆分成多个基础token

# 加入词表:
"<|reasoning|>" -> [32000]  # 单个特殊token

从训练效果看:

  • 加入词表能让模型更好地识别和区分推理部分的边界
  • 不加入词表依然可以起到标记作用,但模型需要从上下文学习这种模式
  • 加入词表的方式通常效果更好,因为给了模型更明确的语义信号