自学内容网 自学内容网

基于LLama_factory的Qwen2.5大模型的微调笔记

LLama-facroty

  1. 根据git上步骤安装即可,要求的软硬件都装上。
    llama-factory
  2. 运行llama-factory:
    export GRADIO_SERVER_PORT=6006    # 可以修改端口号。
    export GRADIO_SERVER_NAME=*.*.*.* # 可以修改服务地址
    或者可以通过修改interface.py文件的run_web_ui()函数
    llamafactory-cli webui  # 运行llama-factory
    运行成功可以看到一个URL,点击即可跳转到页面端
    

Qwen2.5 模型下载。

huggingface 下载方式

qwen2.5模型地址
huggingface地址
modelscope地址

  1. 安装依赖
    pip install -U huggingface_hub
  2. 模型下载
    export HF_HUB_ENABLE_HF_TRANSFER=0
    export HF_ENDPOINT=https://hf-mirror.com
    huggingface-cli download --resume-download --local-dir-use-symlinks False Qwen/Qwen2.5-7B-Instruct --local-dir /your_model_save_path

Modelscope 下载方式

  1. 安装依赖
    pip install modelscope
  2. 使用Python脚本
from modelscope import snapshot_download

cache_directory = '/your_model_save_path'
model_dir = snapshot_download('Qwen/Qwen2.5-7B-Instruct', cache_dir=cache_directory)

执行脚本即可

数据集准备

  • llama-factory 支持 alpaca 格式和 sharegpt
    格式的数据集,具体要求可以看llama-factory数据集格式要求
  • 我这里采用的是sharegpt格式的数据集,比如我做一个信息抽取。
[
{
        "conversations": [
            {
                "from": "human",
                "value": "(这里替换成你的prompt)"
            },
            {
                "from": "gpt",
                "value": "(这里是你的标注的输出)"
            }
        ],
        "system": "你是一个信息抽取助手。你的任务是从给定的文本中提取特定的信息,并以结构化的格式呈现。提取的信息应准确、简洁且与查询相关。",
        "tools": ""
    },
    {
    ...
    }
]
  • 在你的数据集存放位置的同级目录下,一定要有一个dataset_info.json,这个里面是你自定义数据集的描述,可以包括你的多个数据集,供llama-factory识别。如果你采用的是sharegpt格式,dataset_info.json 格式如下。file_name字段填写你的数据路径。
{
  "my_dataset1": {
    "file_name": "/data/llama_factory/info_extract.json",
    "formatting": "sharegpt",
    "columns": {
      "messages": "conversations",
      "system": "system",
      "tools": "tools"
    },
    "tags": {
      "role_tag": "from",
      "content_tag": "value",
      "user_tag": "human",
      "assistant_tag": "gpt"
    }
  },
  "my_dataset2": {
    "file_name":"/data/llama_factory/info_extract2.json",
    "formatting": "sharegpt",
    "columns": {
      "messages": "conversations",
      "system": "system",
      "tools": "tools"
    },
    "tags": {
      "role_tag": "from",
      "content_tag": "value",
      "user_tag": "human",
      "assistant_tag": "gpt"
    }
  }
 }

模型微调

模型训练

  1. 我这里选择的LORA-SFT
    图中模型名称选择你微调的模型类别
    模型路径填写你下载的离线模型路径。
    微调方法选择 lora
    训练阶段 设置train 里面参数即可。
    训练方式选择SFT
    数据路径选择你数据集路径,选择之后,在数据集里面就可以选择你训练的数据集了。
    其它参数根据自己需求和资源进行调整。
    微调的时候 检查点路径不填写

在这里插入图片描述
点击开始训练,模型就开始训练,可以观察损失变化。
模型的输出目录在你的 llama-factory 项目下的saves文件夹中。
在这里插入图片描述

模型验证及推理

模型验证 - 点击evaluate&predict。
首先在 检查点路径选择你保存的某个checkpoint
然后添加你的验证集路径,选择验证集,点击开始。
到输出目录即可查看结果。
在这里插入图片描述
模型推理 - 点击chat。
首先在 检查点路径选择你保存的某个checkpoint。
然后选择推理引擎、数据类型,点击加载模型即可对话。
在这里插入图片描述

模型导出

模型导出-点击export
选择你验证过的最好的checkpoint.
设置相应的参数,
导出量化模型,需要填写一个量化数据集路径(验证集)。
导出设备如果是GPU 选择auto
导出的模型是已经merge后的模型。直接加载使用即可。

部署推理

vllm 推理

from transformers import AutoTokenizer
from vllm import LLM, SamplingParams


class VLLMInfer:
    def __init__(self, model_path):
        self.model_path = model_path
        self.llm, self.tokenizer = self.vllm_load_model()

    def vllm_load_model(self):
        tokenizer = AutoTokenizer.from_pretrained(self.model_path)
        llm = LLM(model=model_path,
                  gpu_memory_utilization=0.9,
                  trust_remote_code=True,
                  tensor_parallel_size=2  # GPU数量
                  )
        return llm, tokenizer
   
    # 批次
    def inference(self, prompts, system):
        texts = []
        for prompt in prompts:
            messages = [
                {"role": "system", "content": system},
                {"role": "user", "content": prompt}
            ]
            text = self.tokenizer.apply_chat_template(
                messages,
                tokenize=False,
                add_generation_prompt=True
            )
            texts.append(text)
        sampling_params = SamplingParams(temperature=0.1,
                                         top_p=0.7,
                                         repetition_penalty=1.0,
                                         max_tokens=200,
                                         )
        outputs = self.llm.generate(texts, sampling_params)

        result_list = []
        for output in outputs:
            generated_text = output.outputs[0].text
            result_list.append(generated_text.replace("\n", "").replace("<|im_end|>", '').replace("json", ""))
        return result_list


if __name__ == '__main__':
    model_path = "your_model_path"
    qwen_chat = VLLMInfer(model_path)
    system = "你是一个智能的助手."
    test_texts = ['', '']
    result = qwen_chat.inference(test_texts, system)
    print(result)

Sglang 推理

from transformers import AutoTokenizer
import sglang as sgl
import time


class SgLangInfer:
    def __init__(self, model_path):
        self.model_path = model_path
        self.llm, self.tokenizer = self.load_model()

    def load_model(self):
        tokenizer = AutoTokenizer.from_pretrained(
            self.model_path,
            trust_remote_code=True,
            clean_up_tokenization_spaces=False
        )

        llm = sgl.Engine(
            model_path=self.model_path,
            mem_fraction_static=0.85,
            tp_size=2,
            max_total_tokens=9000,
            enable_p2p_check=True  # 解决4090 p2p之间通信传输问题
        )

        return llm, tokenizer

    def inference(self, prompts, system):
        texts = []
        for prompt in prompts:
            messages = [
                {"role": "system", "content": system},
                {"role": "user", "content": prompt}
            ]
            text = self.tokenizer.apply_chat_template(
                messages,
                tokenize=False,
                add_generation_prompt=True
            )
            texts.append(text)
        sampling_params = {"temperature": 0,
                           "top_p": 1,
                           "repetition_penalty": 1.0, 
                           "max_new_tokens": 200}
        result_list = []
        response = self.llm.generate(texts, sampling_params)
        # print(f"response:{response}")

        for res in response:
            result_list.append(res['text'])

        return result_list

原文地址:https://blog.csdn.net/sinat_24330297/article/details/143937176

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!