【大语言模型+Lora微调】10条对话微调Qwen-7B-Chat并进行推理 (聊天助手)

news2024/11/20 20:41:59

代码:https://github.com/QwenLM/Qwen/tree/main
国内源安装说明:https://modelscope.cn/models/qwen/Qwen-7B-Chat/summary
通义千问:https://tongyi.aliyun.com/qianwen

在这里插入图片描述

一、环境搭建

下载源码

git clone https://github.com/QwenLM/Qwen.git

conda+pytorch (根据自己显卡驱动选择)

去pytorch官网 https://pytorch.org/get-started/previous-versions/

conda create -n qwenLM python=3.10 
conda activate qwenLM 
conda install pytorch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 pytorch-cuda=11.8 -c pytorch -c nvidia

其他依赖

pip install transformers==4.32.0 accelerate tiktoken einops scipy transformers_stream_generator==0.0.4 peft deepspeed

UI相关依赖

cd Qwen
pip install -r requirements_web_demo.txt

可供选择(安不上不影响推理和训练)

git clone https://github.com/Dao-AILab/flash-attention
cd flash-attention && pip install .

二、模型下载与推理

2.1 运行 test_down.py

#模型下载
from modelscope import snapshot_download
model_dir = snapshot_download('Qwen/Qwen-7B-Chat')

在这里插入图片描述

2.2 下载完成后

~/.cache/modelscope/hub/Qwen/Qwen-7B-Chat

在这里插入图片描述

2.2 推理

–server-name 如果不写,只能本机打开,0.0.0.0输入ip可以。。
CUDA_VISIBLE_DEVICES=0 表示选择显卡0,多显卡才用,单点卡不用输入
-c表示的是模型的地址
–server-port 也可指定端口 ,默认是8000,可改为其他

CUDA_VISIBLE_DEVICES=0 python web_demo.py  -c ~/.cache/modelscope/hub/qwen/Qwen-7B-Chat --server-name 0.0.0.0

在这里插入图片描述

三、微调-训练lora (见官网)

3.1 数据集示意:test_zhj_11.json (局部非完整)


[  {
    "id": "000000000",
       "conversations": [
           {
               "from": "user",
               "value": "你好"
           },
           {
               "from": "assistant",
               "value": "我是曾小蛙的助手,支持xx游戏相关问答。"
           }
        ]
    },       
   {
       "id": "000000001",
       "conversations": [
           {
               "from": "user",
               "value": "镇魂街游戏中,合击技是做什么用的?"
           },
           {
               "from": "assistant",
               "value": "合击技是由寄灵人与守护灵搭配使用的技能,可以在战斗中释放强大效果。"
           }
       ]
   },
   {
       "id": "000000002",
       "conversations": [
           {
               "from": "user",
               "value": "灵海之境"
           },
           {
               "from": "assistant",
               "value": "灵海之境是玩家养成寄灵人和守护灵,提升他们能力的系统。"
           }
       ]
   },
   {
       "id": "000000003",
       "conversations": [
           {
               "from": "user",
               "value": "共鸣神石是用来做什么的?"
           },
           {
               "from": "assistant",
               "value": "共鸣神石可以提升对应元素的寄灵人和守护灵的能力等级。"
           }
       ]
   },
   {
       "id": "000000004",
       "conversations": [
           {
               "from": "user",
               "value": "游戏中的竞技场?"
           },
           {
               "from": "assistant",
               "value": "竞技场是玩家们进行PVP战斗,争夺排名的场所。"
           }
       ]
   },
   {
       "id": "000000005",
       "conversations": [
           {
               "from": "user",
               "value": "游戏中,蓬莱宝库有什么特别之处?"
           },
           {
               "from": "assistant",
               "value": "蓬莱宝库是探索活动,玩家可以通过解决事件获取奖励,并挑战更高层的内容。"
           }
       ]
   },
   {
       "id": "000000006",
       "conversations": [
           {
               "from": "user",
               "value": "五灵宝珠"
           },
           {
               "from": "assistant",
               "value": "五灵宝珠用于提升角色的五行属性,角色品质到橙色后可使用。"
           }
       ]
   },
   {
       "id": "000000007",
       "conversations": [
           {
               "from": "user",
               "value": "千机黑刹是什么?"
           },
           {
               "from": "assistant",
               "value": "千机黑刹是游戏中的挑战副本之一。玩家需要挑战守卫和收集强化buff来提升自己的阵容实力,并挑战首领【镇狱童子】,根据造成的伤害获得排名和奖励。"
           }
       ]
   },
   {
       "id": "000000008",
       "conversations": [
           {
               "from": "user",
               "value": "星河罗盘有何作用?"
           },
           {
               "from": "assistant",
               "value": "星河罗盘是游戏中的一个资源收集系统。通过收集星辉作为资源,玩家可以提升星河罗盘等级,从而获得对应职业属性的加持,提升角色实力。"
           }
       ]
   },
   {
       "id": "000000009",
       "conversations": [
           {
               "from": "user",
               "value": "地狱道?"
           },
           {
               "from": "assistant",
               "value": "地狱道是一个任务系统,玩家完成任务可以激活特权,提升地狱道等级后可以获得更多加成,并且每日可领取与等级相应的奖励。"
           }
       ]
   },
   {
       "id": "000000010",
       "conversations": [
           {
               "from": "user",
               "value": "贪字营?"
           },
           {
               "from": "assistant",
               "value": "贪字营是游戏中的悬赏任务系统,玩家可以接受任务并派遣符合条件的寄灵人和守护灵上阵,完成任务后可以获得丰富的奖励。"
           }
       ]
   }
]


3.2 单卡 训练lora 脚本(直接放入命令端)

num_train_epochs 默认为 5
output_dir 训练后lora保存
data_path 数据集json的路径
model_name_or_path 使用绝对路径
gradient_accumulation_steps 数据少时 ,要改为1(默认为8),否则loss训练不下去

CUDA_VISIBLE_DEVICES=1 python finetune.py \
  --model_name_or_path "your_dir/modelscope/hub/Qwen/Qwen-7B-Chat" \
  --data_path "./datasets/test_zhj_11.json"\
  --bf16 True \
  --output_dir output_qwen/test1 \
  --num_train_epochs 5 \
  --per_device_train_batch_size 2 \
  --per_device_eval_batch_size 1 \
  --gradient_accumulation_steps 1 \
  --evaluation_strategy "no" \
  --save_strategy "steps" \
  --save_steps 1000 \
  --save_total_limit 10 \
  --learning_rate 3e-4 \
  --weight_decay 0.1 \
  --adam_beta2 0.95 \
  --warmup_ratio 0.01 \
  --lr_scheduler_type "cosine" \
  --logging_steps 1 \
  --report_to "none" \
  --model_max_length 512 \
  --lazy_preprocess True \
  --gradient_checkpointing \
  --use_lora

训练过程

在这里插入图片描述

训练后的lora模型(未融合)

在这里插入图片描述

3.3 加载lora (未合并 合并见官网)

官网加载示意 (部分代码)

from peft import AutoPeftModelForCausalLM

model = AutoPeftModelForCausalLM.from_pretrained(
    path_to_adapter, # path to the output directory
    device_map="auto",
    trust_remote_code=True
).eval()

修改 web_demo.py 为web_demo_lora.py (代码见附录)

下面代码DEFAULT_CKPT_PATH 改为自己主模型的绝对路径,非lora

# Copyright (c) Alibaba Cloud.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.

"""A simple web interactive chat demo based on gradio."""
import os
from argparse import ArgumentParser

import gradio as gr
import mdtex2html

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.generation import GenerationConfig


DEFAULT_CKPT_PATH = 'Qwen/Qwen-7B-Chat'
from peft import AutoPeftModelForCausalLM


def _get_args():
    parser = ArgumentParser()
    parser.add_argument("-c", "--checkpoint-path", type=str, default=DEFAULT_CKPT_PATH,
                        help="Checkpoint name or path, default to %(default)r")
    parser.add_argument("--cpu-only", action="store_true", help="Run demo with CPU only")

    parser.add_argument("--share", action="store_true", default=False,
                        help="Create a publicly shareable link for the interface.")
    parser.add_argument("--inbrowser", action="store_true", default=False,
                        help="Automatically launch the interface in a new tab on the default browser.")
    parser.add_argument("--server-port", type=int, default=8000,
                        help="Demo server port.")
    parser.add_argument("--server-name", type=str, default="127.0.0.1",
                        help="Demo server name.")

    args = parser.parse_args()
    return args


def _load_model_tokenizer(args):
    tokenizer = AutoTokenizer.from_pretrained(
        args.checkpoint_path, trust_remote_code=True, resume_download=True,
    )

    if args.cpu_only:
        device_map = "cpu"
    else:
        device_map = "auto"

    model = AutoPeftModelForCausalLM.from_pretrained(
         args.checkpoint_path, # path to the output directory
        device_map=device_map,
        trust_remote_code=True,
    ).eval()

    config = GenerationConfig.from_pretrained(
        DEFAULT_CKPT_PATH , trust_remote_code=True, resume_download=True,
    )

    return model, tokenizer, config


def postprocess(self, y):
    if y is None:
        return []
    for i, (message, response) in enumerate(y):
        y[i] = (
            None if message is None else mdtex2html.convert(message),
            None if response is None else mdtex2html.convert(response),
        )
    return y


gr.Chatbot.postprocess = postprocess


def _parse_text(text):
    lines = text.split("\n")
    lines = [line for line in lines if line != ""]
    count = 0
    for i, line in enumerate(lines):
        if "```" in line:
            count += 1
            items = line.split("`")
            if count % 2 == 1:
                lines[i] = f'<pre><code class="language-{items[-1]}">'
            else:
                lines[i] = f"<br></code></pre>"
        else:
            if i > 0:
                if count % 2 == 1:
                    line = line.replace("`", r"\`")
                    line = line.replace("<", "&lt;")
                    line = line.replace(">", "&gt;")
                    line = line.replace(" ", "&nbsp;")
                    line = line.replace("*", "&ast;")
                    line = line.replace("_", "&lowbar;")
                    line = line.replace("-", "&#45;")
                    line = line.replace(".", "&#46;")
                    line = line.replace("!", "&#33;")
                    line = line.replace("(", "&#40;")
                    line = line.replace(")", "&#41;")
                    line = line.replace("$", "&#36;")
                lines[i] = "<br>" + line
    text = "".join(lines)
    return text


def _gc():
    import gc
    gc.collect()
    if torch.cuda.is_available():
        torch.cuda.empty_cache()


def _launch_demo(args, model, tokenizer, config):

    def predict(_query, _chatbot, _task_history):
        print(f"User: {_parse_text(_query)}")
        _chatbot.append((_parse_text(_query), ""))
        full_response = ""

        for response in model.chat_stream(tokenizer, _query, history=_task_history, generation_config=config):
            _chatbot[-1] = (_parse_text(_query), _parse_text(response))

            yield _chatbot
            full_response = _parse_text(response)

        print(f"History: {_task_history}")
        _task_history.append((_query, full_response))
        print(f"Qwen-Chat: {_parse_text(full_response)}")

    def regenerate(_chatbot, _task_history):
        if not _task_history:
            yield _chatbot
            return
        item = _task_history.pop(-1)
        _chatbot.pop(-1)
        yield from predict(item[0], _chatbot, _task_history)

    def reset_user_input():
        return gr.update(value="")

    def reset_state(_chatbot, _task_history):
        _task_history.clear()
        _chatbot.clear()
        _gc()
        return _chatbot

    with gr.Blocks() as demo:
        gr.Markdown("""\
<p align="center"><img src="https://qianwen-res.oss-cn-beijing.aliyuncs.com/logo_qwen.jpg" style="height: 80px"/><p>""")
        gr.Markdown("""<center><font size=8>Qwen-Chat Bot</center>""")
        gr.Markdown(
            """\
<center><font size=3>This WebUI is based on Qwen-Chat, developed by Alibaba Cloud. \
(本WebUI基于Qwen-Chat打造,实现聊天机器人功能。)</center>""")
        gr.Markdown("""\
<center><font size=4>
Qwen-7B <a href="https://modelscope.cn/models/qwen/Qwen-7B/summary">🤖 </a> | 
<a href="https://huggingface.co/Qwen/Qwen-7B">🤗</a>&nbsp | 
Qwen-7B-Chat <a href="https://modelscope.cn/models/qwen/Qwen-7B-Chat/summary">🤖 </a> | 
<a href="https://huggingface.co/Qwen/Qwen-7B-Chat">🤗</a>&nbsp | 
Qwen-14B <a href="https://modelscope.cn/models/qwen/Qwen-14B/summary">🤖 </a> | 
<a href="https://huggingface.co/Qwen/Qwen-14B">🤗</a>&nbsp | 
Qwen-14B-Chat <a href="https://modelscope.cn/models/qwen/Qwen-14B-Chat/summary">🤖 </a> | 
<a href="https://huggingface.co/Qwen/Qwen-14B-Chat">🤗</a>&nbsp | 
&nbsp<a href="https://github.com/QwenLM/Qwen">Github</a></center>""")

        chatbot = gr.Chatbot(label='Qwen-Chat', elem_classes="control-height")
        query = gr.Textbox(lines=2, label='Input')
        task_history = gr.State([])

        with gr.Row():
            empty_btn = gr.Button("🧹 Clear History (清除历史)")
            submit_btn = gr.Button("🚀 Submit (发送)")
            regen_btn = gr.Button("🤔️ Regenerate (重试)")

        submit_btn.click(predict, [query, chatbot, task_history], [chatbot], show_progress=True)
        submit_btn.click(reset_user_input, [], [query])
        empty_btn.click(reset_state, [chatbot, task_history], outputs=[chatbot], show_progress=True)
        regen_btn.click(regenerate, [chatbot, task_history], [chatbot], show_progress=True)

        gr.Markdown("""\
<font size=2>Note: This demo is governed by the original license of Qwen. \
We strongly advise users not to knowingly generate or allow others to knowingly generate harmful content, \
including hate speech, violence, pornography, deception, etc. \
(注:本演示受Qwen的许可协议限制。我们强烈建议,用户不应传播及不应允许他人传播以下内容,\
包括但不限于仇恨言论、暴力、色情、欺诈相关的有害信息。)""")

    demo.queue().launch(
        share=args.share,
        inbrowser=args.inbrowser,
        server_port=args.server_port,
        server_name=args.server_name,
    )


def main():
    args = _get_args()

    model, tokenizer, config = _load_model_tokenizer(args)

    _launch_demo(args, model, tokenizer, config)


if __name__ == '__main__':
    main()

运行命令

CUDA_VISIBLE_DEVICES=0  python web_demo_lora.py    --server-name 0.0.0.0   -c ./output_qwen/test1   --server-port 8088

结果

我是曾小蛙的小助手
在这里插入图片描述

文章目录

  • 一、环境搭建
    • 下载源码
    • conda+pytorch (根据自己显卡驱动选择)
    • 其他依赖
      • UI相关依赖
      • 可供选择(安不上不影响推理和训练)
  • 二、模型下载与推理
    • 2.1 运行 test_down.py
    • 2.2 下载完成后
    • 2.2 推理
  • 三、微调-训练lora (见官网)
    • 3.1 数据集示意:**test_zhj_11.json** (局部非完整)
    • 3.2 单卡 训练lora 脚本(直接放入命令端)
      • 训练过程
      • 训练后的lora模型(未融合)
    • 3.3 加载lora (未合并 合并见官网)
      • 官网加载示意 (部分代码)
      • 修改 web_demo.py 为web_demo_lora.py (代码见附录)
      • 运行命令
      • 结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1609633.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浏览器渲染流程中的 9 个面试点

记得 08 年以前&#xff0c;打开网页的时候一个页面卡死整个浏览器凉凉。 这是因为当时浏览器是单进程架构&#xff0c;一个页面或者插件卡死&#xff0c;整个浏览器都会崩溃&#xff0c;非常影响用户体验。 经过了一代代工程师的设计&#xff0c;现代浏览器改成了多进程架构&…

C++:继承作业题

1. 关于以下菱形继承说法不正确的是&#xff08; &#xff09; &#xfeff;class B {public: int b;};class C1: public B {public: int c1;};class C2: public B {public: int c2;};class D : public C1, public C2 {public: int d;};A.D总共占了20个字节B.B中的内容总共在D…

2024物理学、电子电路与通信工程国际学术会议(ICPECCE2024)

2024物理学、电子电路与通信工程国际学术会议(ICPECCE2024) 会议简介 2024国际物理、电子电路与通信工程学术会议&#xff08;ICPECCE2024&#xff09;将在深圳隆重举行。本次会议旨在汇聚全球物理、电子电路、通信工程等领域的专家学者&#xff0c;共同探讨最新研究成果和…

《从零开始的Java世界》05异常处理

《从零开始的Java世界》系列主要讲解Javase部分&#xff0c;从最简单的程序设计到面向对象编程&#xff0c;再到异常处理、常用API的使用&#xff0c;最后到注解、反射&#xff0c;涵盖Java基础所需的所有知识点。学习者应该从学会如何使用&#xff0c;到知道其实现原理全方位式…

洛谷 P1131 [ZJOI2007] 时态同步

思路&#xff1a;树形DP 这道题总的来说有点贪心的味道&#xff0c;贪心在我们需要把这个时间点加到哪一条边上。 借用一下一位洛谷大佬的图&#xff1a; 其实这样看出来&#xff0c;如果说越靠近根的那条边加长&#xff0c;其实价值最小&#xff0c;所以我们需要尽量向靠近根…

AbstractQueuedSynchronizer 源码解析

AbstractQueuedSynchronizer 源码解析 文章目录 AbstractQueuedSynchronizer 源码解析一、CAS二、字段分析三、内部类 Node1、CLH 队列2、源码分析 四、内部类 ConditionObject1、字段分析2、方法分析1、await2、signal 五、方法分析1、独占式下的 AQS1、acquire 独占式获取资源…

14.基础乐理-音级、基本音级、变化音级

音级&#xff1a; 乐音体系中的每一个音&#xff0c;都叫 音级。 基本音级&#xff1a; 基本音级是 CDEFGAB 它们七个&#xff0c;在钢琴上使用白键展示的&#xff0c;没有任何升降号、没有任何重升重降号的。 变化音级&#xff1a; 除了 CDEFGAB 这七个音&#xff0c;都叫变化…

面向对象练习坦克大兵游戏

游戏玩家&#xff08;名称&#xff0c;生命值&#xff0c;等级&#xff09;&#xff0c;坦克&#xff0c;大兵类&#xff0c;玩家之间可以相互攻击&#xff0c;大兵拥有武器&#xff0c;用枪弹和反坦克炮弹&#xff0c;造成攻击不同&#xff0c;坦克攻击值固定&#xff0c;请设…

logisim 图解超前进位加法器原理解释

鄙人是视频作者&#xff0c;文件在视频简介的网盘链接。 找规律图解超前进位加法器与原理解释_哔哩哔哩_bilibili 一句话就是“把能导致进位到这个位置的情况全都穷举一遍。” 穷举情况看图中算式。 视频讲解比较啰嗦。

JavaFX--基础简介(1)

一、介绍 中文官网&#xff1a;JavaFX中文官方网站OpenJFX 是一个开源项目,用于桌面、移动端和嵌入式系统的下一代客户端应用程序平台。openjfx.cn是OpenJFX(JavaFX)的标准中文翻译网站&#xff0c;致力于方便开发者阅读官方文档和教程。https://openjfx.cn/ JavaFX 是一个开…

【一文配置好Python开发环境】Python创建虚拟环境,一键更换国内镜像源

一、使用Python自带的venv创建虚拟环境 首先&#xff0c;确保你的Python安装中包含了venv模块。你可以在命令行中运行以下命令来检查&#xff1a; python -m venv --help进入代码目录&#xff0c;创建一个新的虚拟环境。在命令行中运行以下命令&#xff1a; python -m venv …

Llama 3王者归来,可与GPT-4分庭抗礼,开源模型即将追上闭源模型了?

“有史以来最强大的开源大模型”Llama 3引爆AI圈&#xff0c;马斯克点赞&#xff0c;英伟达高级科学家Jim Fan直言&#xff0c;Llama 3将成为AI大模型发展历程的“分水岭”&#xff0c;AI顶尖专家吴恩达称Llama3是他收到的最好的礼物。 4月18日&#xff0c;AI圈再迎重磅消息&a…

ubuntu22.04下编译ffmpeg和ffplay

Ubuntu22.04 下编译安装 ffmpeg 和 ffplay 一、下载源码包 1.1 官方下载链接&#xff1a;Download FFmpeg 可以手动下载&#xff0c;也可以命令行下载&#xff1a; wget http://www.ffmpeg.org/releases/ffmpeg-7.0.tar.xz 1.2 下载完解压 tar -xvf ffmpeg-7.0.tar.xz…

X-314智能合约:金融创新的强大引擎

&#x1f4a5;火爆到烫手的X-314智能合约&#x1f525; X-314智能合约是基于以太坊区块链开发的&#xff0c;具有高度可定制性和灵活性。 ave开单独板块&#xff1b;详细资料已经准备好&#xff1b;对web3感兴趣的大佬货&#xff1b;多交流多指导&#x1f91d; ​X-314智能合…

新质生产力如何点燃乡村振兴之火?(2010-2022年)

数据来源&#xff1a;主要来源于《中国国统计年鉴》、《中国能源统计年鉴》、《中国农村统计年鉴》、《中国人口和就业统计年鉴》、《中国城乡建设统计年鉴》以及各省份统计年鉴。时间范围&#xff1a;2010-2022年数据范围&#xff1a;各省、市、自治区数据指标&#xff1a; 本…

web网站搭建实验

综合练习&#xff1a;请给openlab搭建web网站 网站需求&#xff1a; 1.基于域名www.openlab.com可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料 和缴费网站&#xff0c;基于&#xff0c;www.openlab.com/data网站…

贪吃蛇游戏源码(VS编译环境)

贪吃蛇游戏源码&#xff08;VS编译环境&#xff09; &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C语言&#x1f353; &#x1f33c;文章目录&#x1f33c; 1. Snake.h 头文件 2. Snake.c 源文件 3. Test.c 头文件 1. Snake.h 头…

云安全问题频发,我们能做什么

随着云计算技术的快速发展&#xff0c;云服务已广泛应用于各行各业&#xff0c;为企业提供了高效、灵活和可扩展的算力资源与服务。然而&#xff0c;向云迁移的最大挑战是需要改造企业现有的安全和网络架构&#xff0c;云安全作为保障云计算环境安全稳定运行的重要性愈加突显。…

[Java基础揉碎]泛型

目录 泛型的理解和好处 使用传统方法的问题分析 使用泛型 泛型介绍 泛型的语法 泛型的声明 泛型的注意事项和细节 自定义泛型类 ​编辑 自定义泛型接口 自定义泛型方法 泛型的继承和通配符 泛型的理解和好处 看一个需求 1)请编写程序&#xff0c;在ArrayList 中&a…

在IDEA中解决SSM项目修改图片不能回显问题

1.问题描述 图片成功上传之后&#xff0c;件夹中已经显示图片了&#xff0c;但是访问图片资源会出现404错误&#xff0c;再重新启动服务器之后&#xff0c;发现这个错误又消失了&#xff0c;图片又能正常显示&#xff0c;但是必须重启Tomcat才有效。 2.解决方法如下&#xff…