首页 > 其他分享 >【从零开始系列】Qwen2.5 & Llama-Factory:开源语言大模型+训练平台——(超详细、最新版)一篇文章解决:环境搭建 => 微调训练 => 本地部署

【从零开始系列】Qwen2.5 & Llama-Factory:开源语言大模型+训练平台——(超详细、最新版)一篇文章解决:环境搭建 => 微调训练 => 本地部署

时间:2025-01-13 16:03:08浏览次数:3  
标签:训练 配置文件 Qwen2.5 模型 微调 参数 model 最新版


目录

一、简介

        1.Qwen2.5:开源模型

        2. LLaMA-Factory:微调工具

二、环境搭建

        1.Python和Pytorch版本

         2.llamafactory项目克隆安装

        3.其他重要库安装

三、模型微调

        1.预训练模型下载

        2.训练数据集

        ①创建对话文本数据

        ②配置dataset_info

        3.配置文件与训练

        ①全参数配置

        ②全参数微调

        ③LoRA配置

        ④LoRA微调

四、模型部署

        1.推理环境

        2.Python代码推理


一、简介

        在开始具体操作前,先简单介绍一下本文主要使用的两个关键开源项目及其地址。

        1.Qwen2.5:开源模型

        Qwen2.5 是阿里巴巴集团Qwen团队研发的最新开源的大语言模型和多模态系列,本文主要实验的是其语言模型——Qwen/Qwen2.5 - 7B - Instruct

        Qwen2.5版本在大规模数据(18万亿tokens)上做了预训练,支持根据特定数据集进行人为偏好训练微调。Qwen2.5还支持多国语言,128K tokens上下文长度,能生成 8K tokens文本。

        Github项目地址:https://github.com/QwenLM/Qwen2.5

        模型下载huggingface国内镜像源地址:https://hf-mirror.com/Qwen


        2. LLaMA-Factory:微调工具

        LLaMA-Factory 是一个简单易用的大语言模型的训练微调平台。其搭建的高效训练框架,可以仅使用yaml配置参数文件和简单指令,就可完成对模型的微调。

        并且平台包含近百种模型,以及如(增量)预训练、(多模态)指令监督微调、奖励模型训练、PPO 训练、DPO 训练、KTO 训练、ORPO 训练等高效模型训练算法。支持FlashAttention-2等加速算法。

         Github项目地址:https://github.com/hiyouga/LLaMA-Factory

二、环境搭建

        本文逻辑顺序是,先进行微调训练模型,再进行本地部署。下图总览了整个训练所需的四个部分——环境、模型、数据、配置

        首先解决训练环境的安装,也就是 LLaMA-Factory 训练平台的配置。该部分本人花费大量时间进行实验,来处理报错和冲突,尽量按照相同的版本型号库安装。

        1.Python和Pytorch版本

        首先创建虚拟环境,定下使用的 python 和 torch 版本。根据官方文档的推荐选择。

        Pytorch指令指南地址:https://pytorch.org/get-started/previous-versions/

# 创建 python3.11 和 torch2.4.0+CUxx环境(根据本地cuda版本选择)
conda create -n llama-factory python=3.11
conda activate llama-factory

# 这里本地的cuda版本是12.4
pip install torch==2.4.0 torchvision==0.19.0 torchaudio==2.4.0 --index-url https://download.pytorch.org/whl/cu124

         2.llamafactory项目克隆安装

        然后需要将训练平台 llamafactory 从github上克隆下载下来,并且安装到刚刚创建的虚拟环境中,这是为了后续直接使用指令就可以训练微调。

        这里本机安装的是 llamafactory 0.9.2 版本。

# 克隆安装 llamafactory
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git

# 如果克隆失败也可以先下载到本地,然后在本地目录运行下面的内容
cd LLaMA-Factory
pip install -e ".[torch,metrics]"

        3.其他重要库安装

        继续还有几个训练中会用到的关键包安装,请按照下面的版本进行安装,因为如果版本不匹配很有可能会在训练中报错。下面是官方推荐的版本号可做参考,其中红框内是本文实验环境必须安装的(推荐型号可能也会出现报错,最好按后面给出的具体版本搭配)

# 具体版本号的重要库安装pip指令
pip install transformers==4.46.1 datasets==3.1.0 accelerate==0.34.0 peft==0.12.0 trl==0.9.6 deepspeed==0.15.0 flash-attn==2.7.2.post1 numpy==1.26.3 pydantic==2.10.4 typing_extensions 4.12.2

         其中的 flash-attn 库如果安装失败,可以去其对应的Github地址下载对应环境版本的wheel文件到本地后,用 pip install 加 wheel文件完整文件名安装。

        flash-attn Github地址:https://github.com/Dao-AILab/flash-attention

三、模型微调

        环境搭建好以后,还不能马上开始训练,还需要做两个准备。

        一是预训练的模型参数,这个可以在命令指令中指定,但这样是在线从huggingface上下载模型到本地,大语言模型参数量都比较大,因此这种方式存在风险,最好是先下载到本地;

        二是训练的数据集,可以使用官方提供的样例数据集,也可以自建数据集。

        最后要达成下面的“三角稳定”的训练准备工作,并且通过yaml配置文件联系各个部分,才可以安心简单的使用指令进行“炼丹”。其中绿色的训练环境上述已搭建完毕。

        1.预训练模型下载

        首先来下载训练所需的预训练模型,本文选择在通义千问 Qwen2.5 - 7B 上进行微调,可以直接在hf-mirror镜像中下载到本地,访问以下网址:https://hf-mirror.com/Qwen/Qwen2.5-7B-Instruct下载 Files and versions下的所有文件。

        单独创建一个文件夹保存下载内容,并且“记下”保存模型的绝对地址,这在之后的配置参数部分就代表你要进行微调的“模型名”。

# 模型参数信息(绝对地址)
model_name_or_path : ~/LLaMA_pretrained/Qwen2.5-7B

        如果想要微调其他Qwen或者llama的预训练模型,也是上述相同方法。可以单独创建个总文件夹LLaMA_pretrained,把所有下载模型都保存在该区域,之后要用直接导航到该目录下即可。

        下载并保存好要进行微调的模型参数后,就算完成预训练模型部分的准备工作了。继续就要准备训练数据了。

        2.训练数据集

        llamafactory平台的源码下有样例训练数据格式,先查看官方提供的训练集和说明文件,再根据规范搭建自己的数据集。同时更多信息可以直接参考源码 data 目录下的README_zh.md文件。

        官方数据集:

        在llamafactory源码的 LLaMA-Factory/data 文件夹下存放的是很多样例训练集,实际上该文件夹下主要存放的是两类文件和信息——数据集配置Json文件:dataset_info.json,和真实的具体对话文本内容的数据集Json文件:xxxx.json 。如下图所示。

        dataset_info.json 下保存的是一个字典,字典里的键对应data 下不同文本对话数据的名称,字典的值是该数据集的配置,可以看到不同的数据集如果对应不同的数据格式,其对应配置(下图蓝框内容)是不同的。


        自建数据集:

        llama-factory支持多种对话的数据集格式,具体可以参考源码 data 目录下的README_zh.md 文件,或者访问github地址:https://github.com/hiyouga/LLaMA-Factory/blob/main/data/README_zh.md

        下图是部分其支持的对话文本Json 的内容格式,每种格式又对应各自的dataset_info.json中的配置信息。

         本文选择一个最简单的自建数据例子进行测试微调——假设训练数据集中只包含两个内容:用户输入文本和模型输出文本(可以将其简单理解为一个翻译问题),特别的这里实际就是想训练一个给古文自动加标点的语言模型。

        ①创建对话文本数据

        首先创建好对话文本信息的Json数据集,这里选用最简单的AIpaca格式,且只输入必填部分。这里需要注意,如果选填的内容信息没有,一定不要在数据集中加入。如不需要系统提示词信息,那么就不要出现“system”:‘’ 的内容,不然训练会报错,不需要的信息直接忽略就好。

        ②配置dataset_info

        有了数据集以后,就要配置dataset_info.json文件了。这里可以选择新建一个配置文件然后将对话数据和配置放在一个文件夹下。

        但是最好还是将自己数据放在 LLaMA-Factory/data 下,然后在已有的dataset_info.json 内添加自建数据集的配置信息。

# dataset_info.json配置文件中添加信息
"data": { "file_name": "data.json",
              "columns": {
                    "prompt": "instruction",
                    "response": "output"}
  },

        file_name对应data目录下的数据集Json文件名,“columns”下是对话信息,这里只添加数据集中使用到的,如果要添加其他参考官方README,如下图。

         还有一点很重要的是,下图红框中数据集定义的名称——data,这个是将数据集信息传入配置文件的接口名称,先记下。

# 数据集配置参数(名称)
dataset: data

         按上述操作,创建好一个简单的对话文本信息数据集,就算完成了训练数据集部分的准备工作了,下面要进行的就是最后的训练 yaml 配置文件修改操作。

        3.配置文件与训练

        LLaMA-Factory/example 下是样例训练的 yaml 配置文件,具体如何使用这些配置文件进行指令训练可以参考 example 目录下的 README.md 文件。

        在README.md文件中,可以看到 llamafactory 支持多种训练微调模式,包括全参数Full、LoRA、QLoRA等等,本文只简单测试全参数和 lora 有监督训练(sft)微调的流程

        对应 example 下的 yaml 配置文件如下图所示。其中第一个名称是使用的模型类型(有llama3或者qwen2vl的示例选择),第二个名称代表使用的微调模式(本文记录full全参数 & lora),第三个参数代表具体的算法模式(本文统一使用 sft 有监督训练,即有真实样本对照,可以看到样例中还有如ppo等这种无监督的强化学习算法,这些暂不在本章节考虑)

        ①全参数配置

        有了上述筛选过程,可以直接定位到本文想要修改的全参数训练yaml配置文件地址——LLaMA-Factory-main / examples / train_full / qwen2vl_full_sft.yaml,打开样例配置文件,下面来看哪些是要根据实际情况需要修改的。

        下面一图总览需要修改的地方,实际主要就是三个地方要根据实际情况配置——预训练模型参数地址、数据集名称、结果参数保存地址

        ②全参数微调

        有了上述全参数训练的 yaml 配置文件之后,算是填补了准备工作的最后一角了。下面就可以方便简单的直接使用指令开始训练了。

        全参数训练指令如下。

# 全参数训练指令
FORCE_TORCHRUN=1 llamafactory-cli train examples/train_full/qwen2vl_full_sft.yaml

        ③LoRA配置

        lora是一种更加快速高效的训练方式,这里不讨论其底层原理,直接导航到对应的训练配置文件地址为 LLaMA-Factory-main / examples / train_lora / qwen2vl_lora_sft.yaml,打开样例配置文件,跟之前一样,一图总览需要修改的地方。

        和全参数一样,只不过其中一些其他参数做了变化修改,如 finetuning_type 修改为了lora。

        但是,还没有结束,LoRA 和全参数训练最大不一样的地方在于,lora训练完的 output_dir 下的参数还不能直接使用,要使用 merge_lora 指令合并结果。因此还要配置合并的配置文件,可以直接定位到 LLaMA-Factory-main / examples / merge_lora / qwen2vl_lora_sft.yaml ,合并配置文件修改内容一图总览如下。

        ④LoRA微调

        根据上述配置文件的操作,可知lora训练也是分为两步指令:LoRA微调 + 合并

        LoRA微调指令如下。

# LoRA训练
llamafactory-cli train examples/train_lora/qwen2vl_lora_sft.yaml.yaml

# LoRA结果合并
llamafactory-cli export examples/merge_lora/qwen2vl_lora_sft.yaml 

四、模型部署

        经过上述复杂的操作后,终于得到了在自建数据集上的微调模型结果,下面开始模型参数的部署到本机进行推理的操作。

        1.推理环境

        首先是推理的环境配置,当然直接用训练时的环境进行推理肯定是没问题的,但是可能存在使用性能更低的设备进行部署,或者使用CPU进行推理的问题,此时就需要重新搭建环境了。

        这里直接将配置库图放在下面,按下面的库版本进行安装是没有运行报错的。可以着重检测红框中的关键库(部署环境没有安装flash-attn库,运行可能警告,但不影响最终结果)

        2.Python代码推理

        使用下面代码,替换模型地址 model_path 和 输入文本 prompt ,就可以得到不同输入对话的模型推理回答文本了。

        这是通用的,因此官方模型参数和自己微调的参数都可以直接使用。

from transformers import AutoModelForCausalLM, AutoTokenizer

# 加载模型
def model(path):
    model_name_or_path = path
    model = AutoModelForCausalLM.from_pretrained(
        model_name_or_path,
        torch_dtype="auto",
        device_map="auto"
    )
    tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)
    return model, tokenizer

# 模型对话推理
def infer(model, tokenizer, prompt):
    device = "cuda"  # the device to load the model onto
    messages = [
        {"role": "user", "content": prompt}
    ]
    text = tokenizer.apply_chat_template(
        messages,
        tokenize=False,
        add_generation_prompt=True
    )
    model_inputs = tokenizer([text], return_tensors="pt").to(device)

    generated_ids = model.generate(
        model_inputs.input_ids,
        max_new_tokens=512
    )
    generated_ids = [
        output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
    ]
    response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
    return response


if __name__=='__main__':
    modelpath = ''  # 模型参数地址
    prompt = '你好,qwen'  # 输入文本

    model, tokenizer = model(modelpath)
    response = infer(model, tokenizer, prompt)
    print(f'用户输入:{prompt},\n模型回答:{response}')

        下面两个例子分别是微调自建数据集实现的对古文进行添加标点处理,和官方模型对话返回结果图片。

        古文标点添加模型测试结果:

        官方参数模型对话测试结果:

标签:训练,配置文件,Qwen2.5,模型,微调,参数,model,最新版
From: https://blog.csdn.net/qq_58718853/article/details/145011117

相关文章

  • 如何解决Webview和H5缓存问题,确保每次加载最新版本的资源
    WebView用于加载H5页面是常见的做法,它能够加载远程的HTML、CSS、JavaScript资源,并且让Web应用嵌入到原生App中。然而,WebView的缓存机制有时会导致用户看到的是旧版本的页面或资源,尤其是在H5发版后,iOS端用户可能仍然加载到缓存的旧页面,造成了不一致的体验。本篇文......
  • 代码随想录算法训练营第6天 | 哈希表理论基础,242.有效的字母异位词,349. 两个数组的交
    一、刷题部分1.1哈希表理论基础原文链接:代码随想录题目链接:......
  • 日常训练2025-1-13
    日常训练2025-1-13P5020[NOIP2018提高组]货币系统rating:普及+/提高https://www.luogu.com.cn/problem/P5020思路思考一下题目要干什么,原来的货币系统能够表示出一个集合,不能表示出一个集合,现在把货币数量减少之后能表示的集合和不能表示的集合不变——意味着原本的货币......
  • k8s volcano + deepspeed多机训练 + RDMA ROCE+ 用户权限安全方案
    前提:nvidia、cuda、nvidia-fabricmanager等相关的组件已经在宿主机正确安装,如果没有安装可以参考我之前发的文章GPUA800A100系列NVIDIA环境和PyTorch2.0基础环境配置【建议收藏】_a800多卡运行环境配置-CSDN博客文章浏览阅读1.1k次,点赞8次,收藏16次。Ant系列GPU支持NvLink&N......
  • 江南鹤微信hook最新版 3.9.12.15功能列表
    详询微信weixinhook主动调用登录刷新登录二维码注销登录退出微信当前登录帐号信息联系人获取好友列表获取指定好友信息获取好友简要信息_协议获取好友详细信息_协议指量获取好友信息_协议修改好友备注添加好友分享的名片同意加好友请求删除好友搜索微信用户添......
  • Cline 免费插件 + Qwen2.5 大模型,零经验也能开发“对联王”微信小程序
    小朋友即将放寒假了,意味着春节就不远了。在我们湖北老家,当我还是学生的时候,每年临近春节,写春联、贴春联和对春联是读书人一件乐事。如今,老牛同学早已不是读书人,但还是怀念那时快乐时光,因此想在春节前撸一个“对联王”微信小程序,专门用于创作春联和对春联。上次零经验的我们,借助......
  • 【牛客训练记录】牛客周赛 Round 76
    训练情况赛后反思D题被卡常了,我知道是优先队列的问题,但是一直有一个点过不去,E题疑似二分,但是我不会处理快速幂溢出的问题A题工作日每天\(3\)题,求\(x\)天一共有几周,一周有五个工作日,剩下不足\(7\)天的分类讨论。#include<bits/stdc++.h>//#defineintlonglong#de......
  • 大语言模型预训练、微调、RLHF
    转发,如有侵权,请联系删除:1.【LLM】3:从零开始训练大语言模型(预训练、微调、RLHF)2.老婆饼里没有老婆,RLHF里也没有真正的RL3.【大模型微调】一文掌握7种大模型微调的方法4.基于Qwen2.5-0.5B微调训练Ner命名实体识别任务Qwen模型应用:微调与部署实践CLUENER2020数据集......
  • 大模型分布式训练之流水线并行
    在数据并行训练中,一个明显的特点是每个GPU持有整个模型权重的副本,这就带来了冗余问题,虽然,FSDP可以缓解冗余的问题,但是对于超大规模模型来说,仅使用数据并行进行分布式训练没办法使模型的参数规模进一步提升。因此,另一种并行技术是模型并行,即模型被分割并分布在一个设备阵列上......
  • 代码随想录算法训练营第二天 | Leetcode 209、Leetcode 59、kama 44、kama 58
    Leetcode209#include"iostream"#include"vector"usingnamespacestd;intminSubArrayLen(inttarget,vector<int>&nums){intlen=INT32_MAX;intsum=0;for(intj=0,i=0;j<nums.size();j++){......