进一步微调 Peft/LoRA 微调的 CausalLM 模型

Jul*_*ard 5 huggingface-transformers text-generation large-language-model peft

我有点不确定如何继续讨论上述主题。

\n

基线是通过 Huggingface\xe2\x80\x99s 库创建的模型,作为 AutoModelForCausalLM 模型、PEFT 和 LoRA 方法,并随后合并权重。

\n

我现在想进一步微调模型而不丢失其原始属性 - 在这种情况下通过指令微调/前缀调整。

\n

我的方法如下:

\n
model = AutoModelForCausalLM.from_pretrained(\n        model_id,\n        use_cache=False if gradient_checkpointing else True\n        device_map="auto",\n        load_in_8bit=True,\n    )\n\nmodel = create_peft_config(model)\n\noutput_dir = "/tmp"\ntraining_args = TrainingArguments(\n        output_dir=output_dir,\n        overwrite_output_dir=True,\n        per_device_train_batch_size=per_device_train_batch_size,\n        per_device_eval_batch_size=per_device_train_batch_size,\n        bf16=bf16,\n        learning_rate=lr,\n        num_train_epochs=epochs,\n        gradient_checkpointing=gradient_checkpointing,\n        gradient_accumulation_steps=2,\n        logging_dir=f"{output_dir}/logs",\n        logging_strategy="steps",\n        logging_steps=10,\n        optim="adafactor",\n        save_strategy="epoch",\n        save_total_limit=3,\n        evaluation_strategy="epoch",\n        load_best_model_at_end=False,\n        no_cuda=False,\n        auto_find_batch_size=True\n)\n\ntrainer = Trainer(\n        model=model,\n        args=training_args,\n        train_dataset=dataset_train,\n        compute_metrics=compute_metrics,\n        preprocess_logits_for_metrics=preprocess_logits_for_metrics,\n        eval_dataset=dataset_eval,\n        data_collator=default_data_collator\n)\n\ntrainer.train()\n\ntrainer.model.save_pretrained(output_dir)\n\ndel model\ndel trainer\n\npeft_config = PeftConfig.from_pretrained(output_dir)\nmodel = AutoModelForCausalLM.from_pretrained(\n        peft_config.base_model_name_or_path,\n        load_in_8bit=False,\n        return_dict=True,\n        device_map="auto",\n        torch_dtype=torch.float16,\n        low_cpu_mem_usage=True,\n)\nmodel = PeftModel.from_pretrained(\n        model,\n        output_dir,\n        torch_dtype=torch.float16,\n        device_map="auto",\n)\nmodel.eval()\nos.makedirs("lora", exist_ok=True)\n\nmerged_model = model.merge_and_unload()\nmerged_model.save_pretrained('lora')\n\ntokenizer = AutoTokenizer.from_pretrained(model_id)\ntokenizer.save_pretrained('lora')\n
Run Code Online (Sandbox Code Playgroud)\n

原则上,我使用合并的权重加载原始模型,同样使用 PEFT 和 LoRA 对新数据进行微调,然后再次将权重合并到基本模型中。

\n

这是一种明智的方法,还是有什么建议,例如,我这样做甚至可能会严重损害原始功能?如果有什么反对的话,更好的方法是什么?

\n

提前致以亲切的问候和感谢

\n

在对大约 15000 个指令对进行 3 个 epoch 的训练后,正确创建模型,应用权重,然后可以加载。

\n

不幸的是,您可以清楚地看到该模型已经失去了其原有的功能。之前有效的提示功能失效了。您可以看到模型尝试正确地处理提示,但不是定性的。

\n

thi*_*not 1

原始文档缺少如何加载模型 https://huggingface.co/blog/4bit-transformers-bitsandbytes

    trainer.model.save_pretrained('./bits')
    ...
    tokenizer = AutoTokenizer.from_pretrained(model_id)
    #model_id = '/root/.cache/huggingface/hub/models--EleutherAI--gpt-neo-1.3B/snapshots/0f35a20339a9e208bc061570981180cfb87c9572'

    peft_config = PeftConfig.from_pretrained('bits')
    model = AutoModelForCausalLM.from_pretrained(
            peft_config.base_model_name_or_path,
            quantization_config=bnb_config, device_map={"":0}
            #load_in_8bit=False,
            #return_dict=True,
            #device_map="auto",
            #torch_dtype=torch.float16,
            #low_cpu_mem_usage=True,
    )
Run Code Online (Sandbox Code Playgroud)

但是,如果您使用 peftmodel,这里也有一些步骤 https://github.com/huggingface/blog/blob/main/peft.md

    peft_config = LoraConfig(task_type=TaskType.SEQ_2_SEQ_LM, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1)
    
      model = AutoModelForSeq2SeqLM.from_pretrained(model_name_or_path)
    + model = get_peft_model(model, peft_config)
    + model.print_trainable_parameters()
Run Code Online (Sandbox Code Playgroud)