Lora微调Deepseek-llm-7B-chat

一、单机多卡训练

  • 方法一:把AutoModelForCausalLM.from_pretrained的参数device_map改为"auto",可自动把模型和数据分配到多个GPU上
  • 方法二:也可以使用 Accelerate​,其是一个分布式训练工具包,提供底层的分布式训练基础。它更倾向于与##手动训练##循环配合使用,而不是与高级抽象如 Trainer 配合使用。

二、把数据转换为模型可以处理的格式

  1. 基础知识
    输入模型的数据需要进行处理,一般模型都会有聊天模版,可以用apply_chat_template函数直接处理或者手动处理。处理后的输出包括:
     - input_ids:是输入序列token的id列表,用于模型输入
     -attention_mask: 用于指示模型在处理输入序列时应关注哪些标记。
     -labels(训练时候需要): 是目标序列的标记 ID 列表。不需要计算损失的标签需要被设置为 -100。

    注意:由于我们模型的目的是预测下一个token,因此某一位值labels的实际值是该位置的下一位input_id。但是由于某些datacollator例如DataCollatorForLanguageModeling自动让labels向右位移一位,所以不需要手动位移。

  2. tokenizer.apply_chat_template函数
    用于将对话格式的聊天数据转换为模型可以处理的输入格式,对于不同的模型,输出格式会有所不同。

    • 参数说明
      messages: 对话列表,每个元素是一个字典,包含 role (system/user/assistant) 和 content (文本内容)
      tokenize: 是否直接进行tokenize (默认True,返回token IDs;False则返回格式化后的字符串)
      add_generation_prompt: 是否添加提示词表示需要模型生成回复 (默认False),推理时候要设置为True
      return_tensors: 返回的张量格式 (“pt” for PyTorch, “tf” for TensorFlow)
      truncation=True:当输入文本长度超过 max_length 时,自动截断超出的部分
      max_length:设置文本最大长度
      padding:设置padding方式,可选 max_length,False,longest

    • 注意
       1.该函数输出的attention_mask填充部分为0,其余部分为1。
       2.这个函数并不输出labels,训练时候若需要,要手动设置

    • 不同模型示例
      deepseek-ai/deepseek-llm-67b-chat

      <|begin▁of▁sentence|>你是一个乐于助人的助手。
      User: 你好,你叫什么名字?
      Assistant: 我是DeepSeek助手,很高兴为您服务!<|end▁of▁sentence|
      

      Qwen/Qwen1.5-7B-Chat:

      <|im_start|>system
      你是一个乐于助人的助手。<|im_end|>
      <|im_start|>user
      你好,你叫什么名字?<|im_end|>
      <|im_start|>assistant
      我是DeepSeek助手,很高兴为您服务!<|im_end|>
      

  3. 处理指令对话数据

    1. 单轮对话数据

      1. 直接用apply_chat_template函数,然后创建一个labels,因为我们不需要学习assistant回答之外的内容,因此可以创建一个与input_id一样的数组,然后把system和user内容的labels设为-100,其余值不变,最后输出三者。
      2. 手动设置。
        按照模型的对话模板手动设置三者,此时要在对话末尾注意添加eos_token。EOS的label要设置为-100,mask为1(因为我们需要关注EOS的生成,否则无法学习到何时生成EOS),EOS的input_id为tokenizer.eos_token_id,很多模型的EOS和PAD的id一样。
        例如:
        input_ids, attention_mask, labels = [], [], []
        instruction = tokenizer(f"User: {example['instruction']+example['input']}\n\n", add_special_tokens=False)  # add_special_tokens 不在开头加 special_tokens
        response = tokenizer(f"Assistant: {example['output']}", add_special_tokens=False)
        input_ids = instruction["input_ids"] + response["input_ids"] + [tokenizer.pad_token_id]
        attention_mask = instruction["attention_mask"] + response["attention_mask"] + [1] 
        labels = [-100] * len(instruction["input_ids"]) + response["input_ids"] + [tokenizer.pad_token_id]
        
    2. 多轮对话数据

      1. 与单轮对话类似
      2. 与单轮对话不同的是,我们不止要在对话末尾添加EOS,而是要在每次助手回复的内容后加上EOS,否则模型不会学习停止回答。

  4. DataCollator
    DataCollator 的主要作用是在训练前对一批(batch)样本进行处理,确保它们具有相同的格式和长度,以便能够组成一个有效的张量(tensor)输入模型。一般在在训练时被调用。
    在这里介绍几个常见的DataCollator

    1. DataCollatorForLanguageModeling

      1. 作用:专门用于语言建模任务,包括:
      • 因果语言建模:预测下一个token(如GPT系列)
      • 掩码语言建模:预测被掩盖的token(如BERT系列)

      1. 关键参数
        tokenizer: 必需的分词器实例
        mlm:是否使用掩码语言建模,False 表示使用因果语言建模。
          当 mlm=False(因果LM)时:label会和input_ids一样,即使你自己设置了labels也会覆盖。自动将labels向左移动一位,并对最后一个token进行掩码;
          当 mlm=True(掩码LM)时:会随机选择15%的token进行掩盖(80%用[MASK],10%用随机token,10%保持不变)
        mlm_probability:当 mlm=True 时,token被掩盖的概率(默认0.15)
        pad_to_multiple_of:将序列长度填充到该值的倍数(有助于某些硬件加速)
        return_tensors:返回的张量类型,通常是 "pt"(PyTorch)
        padding:padding的方式,新版取消了,默认padding到序列最长。如需要设置padding方式,需要配合DataCollatorWithPadding
        注意:如果数据有column,记得remove_columns=['xxxx'],否则会报错

    2. DataCollatorForSeq2Seq

      1. 作用:专门用于序列到序列的任务,如翻译、摘要、对话生成,微调就用这个。作用是让每一个batch内的input_ids和labels都长度对齐
      2. 关键参数
        tokenizer: 必需的分词器实例
        model:可选的模型实例(用于自动获取decoder_start_token_id等)
        padding:是否进行填充(默认为True)
        max_length:最大序列长度
        pad_to_multiple_of:填充到的倍数
        label_pad_token_id:用于填充labels的token ID(默认为-100)
        return_tensors:返回的张量类型
    3. 还有DataCollatorForTokenClassification、DataCollatorForWholeWordMask、DataCollatorForSeq2Seq、DataCollatorWithPadding等

posted @ 2025-08-27 17:38  IAMM!  阅读(25)  评论(0)    收藏  举报