通义千问Qwen-VL-Chat大模型本地训练(二)

目录

前言

环境准备

软件安装

数据准备

模型训练

        模型名称修改

        数据集修改

        模型参数修改

        数据读取编码修改

        output_dir修改

模型调用

 验证

小结


前言

        人工智能大模型是一种能够利用大数据和神经网络来模拟人类思维和创造力的人工智能算法。它利用海量的数据和深度学习技术来理解、生成和预测新内容,通常情况下有数十亿乃至数百亿个参数,可以在不同的领域和任务中表现出智能拟人的效果。

        现在大模型火的不行,项目中如果没有大模型好像都缺少点啥?没办法要跟着时代进步,最近研究了一下开源的通义千问大模型,翻阅了大量文档,记录一下使用心得。我使用的是通义千问Qwen-VL-Chat多模态模型。LLM模型可以通过Ollama下载官网最新推出的Qwen2模型,网上教程很多比较简单,但我们怎么可能仅仅只用聊天,必须得上多模态,Ollama的多模态模型很少,并且尝试过效果都不好,最后盯上modelScope上的Qwen-VL-Chat多模态,官网提供了modelScope和transformers两种途径获取模型,训练需要用到transformers,梯子已经架好。

        

环境准备

       硬件:  本人使用的是window10系统,电脑为工作站内存,显存不需要考虑,正常情况下16G内存,6G显存能跑低7亿参数的模型。

        软件: Anconda、Pytorch、Python、cuda(有GPU的考虑)主要用到这3个,其它包稍后说明。版本之间要按照官网上的说明来寻找适合的版本。我使用的版本如下:

        Anconda:23.3.1;

        Pytorch:2.0.1;

        Python:3.10;

        cuda:11.7;

软件安装

        详细环境安装请看通义千问Qwen-VL-Chat大模型本地部署(一);

数据准备

[{"id": "identity_0","conversations": [{"from": "user","value": "你好"},{"from": "assistant","value": "我是Qwen-VL,一个支持视觉输入的大模型。"}]},{"id": "identity_1","conversations": [{"from": "user","value": "Picture 1: <img>https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg</img>\n图中的狗是什么品种?"},{"from": "assistant","value": "图中是一只拉布拉多犬。"},{"from": "user","value": "框出图中的格子衬衫"},{"from": "assistant","value": "<ref>格子衬衫</ref><box>(588,499),(725,789)</box>"}]},{ "id": "identity_2","conversations": [{"from": "user","value": "Picture 1: <img>assets/mm_tutorial/Chongqing.jpeg</img>\nPicture 2: <img>assets/mm_tutorial/Beijing.jpeg</img>\n图中都是哪"},{"from": "assistant","value": "第一张图片是重庆的城市天际线,第二张图片是北京的天际线。"}]}
]

         数据格式如上,文件喂.json格式。<img>标签为图片地址标签,<box>标签为左上角,右下角坐标,用于标出矩形框,<ref>引用文本标签。

模型训练

        这里面踩了不少坑,网上一大堆linux环境训练的教学,找个windows环境的训练找不到,身边也没有linux系统,头铁只能硬搞finetune.py脚本。finetune.py是windows系统执行训练的脚本,直接运行报错,问题不少下面列举我遇到的问题以及解决方式:

        模型名称修改

        将代码模型名称改成

class ModelArguments:model_name_or_path: Optional[str] = field(default="QWen/QWen-VL-Chat")

        数据集修改

@dataclass
class DataArguments:data_path: str = field(default="自己的训练数据集位置", metadata={"help": "Path to the training data."})eval_data_path: str = field(default="自己的验证集位置", metadata={"help": "Path to the evaluation data."})lazy_preprocess: bool = False

        模型参数修改

@dataclass
class TrainingArguments(transformers.TrainingArguments):cache_dir: Optional[str] = field(default=None)optim: str = field(default="adamw_torch")model_max_length: int = field(default=1024, # 这里根据自己硬件内存适当调整我的内存是150G 改成1024跑起来会占掉120G左右metadata={"help": "Maximum sequence length. Sequences will be right padded (and possibly truncated)."},)use_lora: bool = True # 使用lora参数 将false 改成truefix_vit: bool = True

         model_max_length根据自己计算机内存适当调整,我们需要使用lora参数。

        数据读取编码修改

def make_supervised_data_module(tokenizer: transformers.PreTrainedTokenizer, data_args, max_len,
) -> Dict:"""Make dataset and collator for supervised fine-tuning."""dataset_cls = (LazySupervisedDataset if data_args.lazy_preprocess else SupervisedDataset)rank0_print("Loading data...")# 使用UTF-8加载train_json = json.load(open(data_args.data_path, "r", encoding='utf-8'))train_dataset = dataset_cls(train_json, tokenizer=tokenizer, max_len=max_len)# 使用UTF-8加载if data_args.eval_data_path:eval_json = json.load(open(data_args.eval_data_path, "r", encoding='utf-8'))eval_dataset = dataset_cls(eval_json, tokenizer=tokenizer, max_len=max_len)else:eval_dataset = Nonereturn dict(train_dataset=train_dataset, eval_dataset=eval_dataset)

        这里要在open()中添加encoding='utf-8',不然文件读取会编码集错误。

        output_dir修改

        在运行finetune.py文件的时候会报output_dir找不到的错误,如果使用pycharm运行需要修改如下设置:

        edit添加运行指令 --output_dir 模型输出路径,点OK;

        命令行方式启动:

python finetune.py --output_dir 输出文件地址

        至此需要修改的内容都结束了,如果运行提示内存不足那么需要修改模型参数model_max_length到合适值。我使用的内存为150G,model_max_length=1024运行会占120G左右。这里用到transformers的版本是项目中自带版本不需要升级到最新版。上一篇中如果要使用transformers需要升级最新版。

模型调用

        训练结束后会在设置的输出目录中看到保存的微调模型。接下来就是调用,我们还继续使用上一篇中的http_api.py调用。代码如下:

        代码中添加了model_name_or_path = "H:/ali-qwen/Qwen-VL/output_dir"为上一步模型训练的输出地址,通过peft的PeftModel在模型加载的时候使用如下方式将我们自己训练的模型参数添加到预训练模型中。并且将modelscope相关加载方式换成了transformers的。

model = PeftModel.from_pretrained(model, model_id=model_name_or_path)
from argparse import ArgumentParser
from contextlib import asynccontextmanagerimport torch
import uvicorn
from fastapi import FastAPI, Response
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, Field
# from modelscope import (
#     AutoModelForCausalLM, AutoTokenizer, GenerationConfig
# )
from sse_starlette.sse import EventSourceResponse
from transformers import AutoTokenizer, AutoModelForCausalLM
from transformers.generation import GenerationConfig
from peft import PeftModelDEFAULT_CKPT_PATH = 'QWen/QWen-VL-Chat'
model_name_or_path = "H:/ali-qwen/Qwen-VL/output_dir"@asynccontextmanager
async def lifespan(app: FastAPI):  # collects GPU memoryyieldif torch.cuda.is_available():torch.cuda.empty_cache()torch.cuda.ipc_collect()app = FastAPI()app.add_middleware(CORSMiddleware,allow_origins=["*"],allow_credentials=True,allow_methods=["*"],allow_headers=["*"],
)class RequestParams(BaseModel):image: strtext: str@app.post("/v1/chat/demo")
async def _launch_demo(params: RequestParams, resp: Response):# 设置响应头部信息resp.headers["Content-Type"] = "text/event-stream"resp.headers["Cache-Control"] = "no-cache"global model, tokenizermessage = params.textquery = tokenizer.from_list_format([{'image': 'C:/Users/LENOVO/Desktop/f0d17c6f301f675ac8cbe600da4a8e1.png'},{'text': '这是什么'},])return EventSourceResponse(stream_generate_text(query))async def stream_generate_text(message):for response in model.chat_stream(tokenizer, message, history=[]):yield _parse_text(response)# 设置模型参数
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="0.0.0.0",help="Demo server name.")args = parser.parse_args()return argsdef _parse_text(text):lines = text.split("\n")lines = [line for line in lines if line != ""]count = 0for i, line in enumerate(lines):if "```" in line:count += 1items = 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>" + linetext = "".join(lines)return text# 加载模型
def _load_model_tokenizer(args):#, revision='master',tokenizer = AutoTokenizer.from_pretrained(args.checkpoint_path, trust_remote_code=True, resume_download=True)if args.cpu_only:device_map = "cpu"else:device_map = "cuda"# revision='master',model = AutoModelForCausalLM.from_pretrained(args.checkpoint_path,device_map=device_map,trust_remote_code=True,resume_download=True,).eval()# , revision='master',model.generation_config = GenerationConfig.from_pretrained(args.checkpoint_path, trust_remote_code=True, resume_download=True)# 添加自定义训练模型节点model = PeftModel.from_pretrained(model, model_id=model_name_or_path)return model, tokenizerif __name__ == "__main__":args = _get_args()# 加载qwen-vl-chat合并后的新模型model, tokenizer = _load_model_tokenizer(args)uvicorn.run(app, host=args.server_name, port=args.server_port, workers=1)

 验证

        我将自定义的图片添加到数据集中;

        验证图片如下:

         在没有训练情况下模型回答如下:

        经过训练后情况如下:

        从结果来看只是去掉了关于键盘的描述部分,多次询问结果都一样,官网解释为当模型不清楚问题具体想要时会以介绍图片的形式回答问题,我们只是侧重于这张图片的关于烟的描述,训练后模型不再介绍关于这张图片其它之外的内容。说明对于这张图片以及我们喂给模型的数据它已经学习过了。 

小结

        本文介绍了开源Qwen-VL-Chat多模态本地训练功能,供小白参考,欢迎大佬指点问题。

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

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

相关文章

中职网络安全B模块Cenots6.8数据库

任务环境说明&#xff1a; ✓ 服务器场景&#xff1a;CentOS6.8&#xff08;开放链接&#xff09; ✓ 用户名&#xff1a;root&#xff1b;密码&#xff1a;123456 进入虚拟机操作系统&#xff1a;CentOS 6.8&#xff0c;登陆数据库&#xff08;用户名&#xff1a;root&#x…

【C++深度探索】全面解析多态性机制(二)

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;C从入门至进阶 这里将会不定期更新有关C/C的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 前言 我…

Debezium日常分享系列之:Debezium 3.0.0.Alpha1 Released

Debezium日常分享系列之&#xff1a;Debezium 3.0.0.Alpha1 Released 一、重大改变Java 和 Maven 要求已更改 二、新的特征和提高MongoDB 三、更多内容 Debezium 3 的第一个预发布版本 3.0.0.Alpha1。这个版本虽然比正常的预版本要小&#xff0c;但高度关注几个关键点&#xff…

《财经日报》︱揭秘随身WiFi市场乱象与格行的破局之路 格行如何树立行业清流新标杆? 随身WiFi真的靠谱吗?

在移动互联网高速发展的今天&#xff0c;随身WiFi以其便捷性和高性价比迅速成为市场宠儿。然而&#xff0c;随着行业的迅速扩张&#xff0c;一系列乱象与套路也逐渐浮出水面&#xff1a;从虚假宣传到限速虚量&#xff0c;随身WiFi行业中的种种套路让消费者防不胜防。商家利用信…

c语言题目之求两个整数的二进制位数的不同个数

文章目录 一、题目二、分析三、代码实现 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、题目 二、分析 首先看到这道题我们是求两个整数的二进制位不同位的个数&#xff0c;在操作符中我们详细学到到了按位操作符相关的内容&#xff0c;首先看到要…

三相感应电机建模仿真(5):考虑铁耗时静止dq坐标系的数学模型及其仿真模型

1.概述 2.考虑铁耗时的三相感应电机数学模型 3.考虑铁耗时的三相感应电机仿真模型 4.仿真实例 5.总结 6.参考文献 1.概述 电机的铁心损耗主要包括涡流损耗和磁滞损耗,这些损耗以热的形式消耗能量,减少了电动机的有效输出功率,对电机效率产生影响;铁心损耗会导致电机内…

【教程】Vue2中使用svg矢量图

1.npm导包 npm i svg-sprite-loader --save2.创建目录放入svg文件&#xff0c;创建SvgIcon.js 3.SvgIcon.js const req require.context(./svg, false, /\.svg$/) const requireAll requireContext > requireContext.keys().map(requireContext) requireAll(req)4.vue.c…

【前端】零基础学会编写CSS

一、什么是CSS CSS (Cascading Style Sheets&#xff0c;层叠样式表&#xff09;是一种是一种用来为结构化文档&#xff08;如 HTML 文档&#xff09;添加样式&#xff08;字体、间距和颜色等&#xff09;的计算机语言&#xff0c;能够对网页中元素位置的排版进行像素级别的精…

【数据结构取经之路】二叉搜索树的实现

目录 前言 二叉搜索树 概念 性质 二叉搜索树的实现 结点的定义 插入 查找 删除 二叉搜索树完整代码 前言 首先&#xff0c;二叉搜索树是一种数据结构&#xff0c;了解二叉搜素树有助于理解map和set的特性。 二叉搜索树 概念 二叉搜索树又称二叉排序树&#xff0c…

【Caffeine】⭐️SpringBoot 项目整合 Caffeine 实现本地缓存

目录 &#x1f378;前言 &#x1f37b;一、Caffeine &#x1f37a;二、项目实践 2.1 环境准备 2.2 项目搭建 2.3 接口测试 ​&#x1f49e;️三、章末 &#x1f378;前言 小伙伴们大家好&#xff0c;缓存是提升系统性能的一个不可或缺的工具&#xff0c;通过缓存可以避免大…

java基础之接口

接口和抽象类很像&#xff0c;接口是把行为给抽象化&#xff0c;可以理解成一个抽象类抽象到极致的情况下&#xff0c;形成的类&#xff0c;也就是一个抽象类有且只有抽象方法的时候&#xff0c;就可以用接口来写。 一、抽象类与接口在书写上的异同 这是一个抽象类 public abst…

五、 计算机网络(考点篇)

1 网络概述和模型 计算机网络是计算机技术与通信技术相结合的产物&#xff0c;它实现了远程通信、远程信息处理和资源共享。计算机网络的功能&#xff1a;数据通信、资源共享、管理集中化、实现分布式处理、负载均衡。 网络性能指标&#xff1a;速率、带宽(频带宽度或传送线路…

什么是人力资源管理审计

企业管理者可以通过会计审计了解公司的财务状况&#xff0c;对企业同样重要的人力状况如何要怎样了解呢&#xff1f;要怎样提高人力资源部门的运行能力&#xff1f;如何实施各种人力资源功能&#xff1f; 相对与财务、会计审计而言&#xff0c;人力资源审计在我国管理层中还是一…

驱动电机液冷冷却系统

1.自然冷却 自然冷却也可以看作是被动散热&#xff0c;它是依靠驱动电机自身的硬件结构&#xff0c;把热量从里经由金属材料向外散热&#xff0c;所以也就不会造成太多的成本支出&#xff0c;但是整体的散热效果并不太好。 考虑到低成本的原因&#xff0c;自然冷却就不能加装…

【简历】重庆某一本大学:JAVA简历指导,中厂通过率较低

注&#xff1a;为保证用户信息安全&#xff0c;姓名和学校等信息已经进行同层次变更&#xff0c;内容部分细节也进行了部分隐藏 简历说明 这是一份重庆某一本大学Java同学的简历。那么因为学校是一个一本的学校&#xff0c;就先要确定就业层次在中厂或者大厂&#xff0c;但是…

串联式 VS 并联式电源连接拓扑

https://download.csdn.net/download/qq_42605300/89538758https://download.csdn.net/download/qq_42605300/89538758串联式电源连接拓扑&#xff1a; 缺点&#xff1a;公共阻抗耦合&#xff0c;引入更多共模干扰。 并联式(星型)电源连接拓扑&#xff1a; 缺点&#xff1a;接地…

【Python】基础语法(顺序语句、条件语句、循环语句)

一、顺序语句 默认情况下&#xff0c;Python 的代码执行顺序是按照从上到下的顺序&#xff0c;依次执行的。 编程是一件明确无歧义的事情&#xff0c;安排好任务的顺序&#xff0c;计算机才能够正确的进行执行。 二、条件语句 1、什么是条件语句 条件语句能够表达 “如果...&…

架构师机器学习操作 (MLOps) 指南

MLOps 是机器学习操作的缩写&#xff0c;是一组实践和工具&#xff0c;旨在满足工程师构建模型并将其投入生产的特定需求。一些组织从一些自主开发的工具开始&#xff0c;这些工具在每次实验后对数据集进行版本控制&#xff0c;并在每个训练周期后对检查点模型进行版本控制。另…

【qt】 QGridLayout布局管理器怎么用?

QGridLayout是 Qt 中的一个布局管理器&#xff0c;用于在窗口或对话框中创建网格布局。它将控件按照行和列的方式进行排列&#xff0c;使得界面更加整齐和有序。 可以用setSpacing()来设置各个主键之间的间距. 可以设置各组件之间的间隙和与窗口边界的边距. 用addWidget()来添…