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

Qwen2.5大模型微调记录

LLama-facroty

  1. 根据git上步骤安装即可,要求的软硬件都装上。
    llama-factory

  2. 运行llama-factory:

    python在这里插入代码片 复制代码
    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脚本
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格式的数据集,比如我做一个信息抽取。
python 复制代码
[	
	{
        "conversations": [
            {
                "from": "human",
                "value": "(这里替换成你的prompt)"
            },
            {
                "from": "gpt",
                "value": "(这里是你的标注的输出)"
            }
        ],
        "system": "你是一个信息抽取助手。你的任务是从给定的文本中提取特定的信息,并以结构化的格式呈现。提取的信息应准确、简洁且与查询相关。",
        "tools": ""
    },
    {
    	...
    }
]
  • 在你的数据集存放位置的同级目录下,一定要有一个dataset_info.json,这个里面是你自定义数据集的描述,可以包括你的多个数据集,供llama-factory识别。如果你采用的是sharegpt格式,dataset_info.json 格式如下。file_name字段填写你的数据路径。
python 复制代码
{
  "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 推理

python 复制代码
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 推理

python 复制代码
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
相关推荐
小小逆向1 分钟前
[SWPUCTF 2021 新生赛]老鼠走迷宫
笔记
俸涛努力学前端1 小时前
ajax (一)
开发语言·前端·javascript·笔记·ajax
慕卿扬1 小时前
基于python的机器学习(四)—— 聚类(一)
笔记·python·学习·机器学习·聚类
家有狸花2 小时前
Node.js笔记(二):Socket.io
笔记·node.js
静能生慧2 小时前
大模型-微调与对齐-非强化学习的对齐方法
人工智能·深度学习·机器学习·大模型
Power20246663 小时前
NLP论文速读(MPO)|通过混合偏好优化提高多模态大型语言模型的推理能力
人工智能·深度学习·语言模型·自然语言处理·自动化·nlp
Leweslyh3 小时前
线性代数公式速记手册
笔记·学习·线性代数
豚豚糯4 小时前
栈和队列——考研笔记
数据结构·笔记·考研
杳戢4 小时前
技术美术百人计划 | 《2.1 色彩空间介绍》笔记
笔记·unity·游戏引擎·图形渲染·技术美术