通义千问Qwen-VL-Chat大模型本地部署(一)

  • 目录

    前言

    环境准备

    软件安装

    其它库安装启动项目

    FASTAPI

    小结


前言

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

        现在大模型火的不行,项目中如果没有大模型好像都缺少点啥?没办法要跟着时代进步,最近研究了一下开源的通义千问大模型,翻阅了大量文档,记录一下使用心得。我使用的是通义千问Qwen-VL-Chat多模态模型。LLM模型可以通过Ollama下载官网最新推出的Qwen2模型,网上教程很多比较简单,但我们怎么可能仅仅只用聊天,必须得上多模态,Ollama的多模态模型很少,并且尝试过效果都不好,最后盯上modelScope上的Qwen-VL-Chat多模态,官网提供了modelScope和transformers两种途径获取模型,本人都尝试了下最终选择了modelScope,官网也推荐使用modelScope,第一modelScope不需要搭梯子,第二下载Qwen-VL-Chat源码后运行transformers会报错,源码中transformers版本为4.32.0,需要升级到更高版本才能正常运行,modelScope不需要进行其它包的升级。

        

环境准备

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

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

        Anconda:23.3.1;

        Pytorch:2.0.1;

        Python:3.10;

        cuda:11.7;

软件安装

        开源项目最大的麻烦就是环境问题,安装错误会报一堆问题,还无从查找。网上有很多使用docker安装的,这里我使用的是conda安装的Python虚拟环境。

        Anconda下载:清华大学开源软件镜像站点;

        网上搜一下conda和python3.10版本对应名称下载,安装的话除了指定安装位置外其它的都是next就好了,conda内置了python版本无需再安装一次python。

安装程序结束后需要配置conda的环境变量。

        在系统变量的path中添加以下五个自己安装的conda的对应文件夹位置的变量然后 win+r 输入cmd 查看是否安装成功。

        下载Qwen-VL-Chat源码: 

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

         下载完成后打开命令管理行创建conda虚拟环境;

# 创建虚拟环境
conda create qwen-vl

        进入到虚拟环境;

# 进入虚拟环境
conda activate qwen-vl

        安装Pytorch;

        Pytorch官网:pytorch官网;   

        找到2.0.1版本对应的安装命令,windows中前两个是GPU的命令,最后一个是CPU的命令。根据自己硬件复制命令执行。

# 在qwen-vl空间下安装pytorch
conda install pytorch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 pytorch-cuda=11.7 -c pytorch -c nvidia

        需要安装cuda的去英伟达官网直接下载自己电脑支持的cuda版本即可。

其它库安装启动项目

# 进入qwen-vl空间下
conda activate qwen-vl# 进入到qwen-vl安装目录下
cd qwen-vl安装目录# 初始化依赖
pip install requirements.txt# 安装modelscope
pip install modelscope -U# 安装gradio
pip install gradio# 运行web_demo 0.0.0.0设置其它主机访问,
# 也可以在pycharm里面打开项目web_demo_mm.py
# 文件编辑server-name设置default为0.0.0.0
python web_demo_mm.py --server-name 0.0.0.0

        启动成功访问:http://127.0.0.1:8000 ;

FASTAPI

        Qwen-VL-Chat提供了openai_api.py web接口,想要运行接口需要安装一些依赖;

# 进入qwen-vl虚拟空间,进入项目根路径
conda activate qwen-vl
cd 。。。项目路径# 安装依赖
pip install requiredments_openai_api.txt

        运行 penai_api.py需要transformers,文章开头提到了要运行还需要升级transformers到最近版本。

# 升级transformers
pip install transformers -U# 运行api
python openai_api.py --server-name 0.0.0.0

        访问:http://127.0.0.1:8000/docs ;

        我试了几次都调用失败,于是自己写了一个api接口调用成功。(缺少啥依赖直接pip install 包名安装即可)

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 EventSourceResponseDEFAULT_CKPT_PATH = 'qwen/Qwen-VL-Chat'@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.contentquery = tokenizer.from_list_format([{'image': 'C:/Users/LENOVO/Desktop/kn.jpeg'},{'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):tokenizer = AutoTokenizer.from_pretrained(args.checkpoint_path, trust_remote_code=True, resume_download=True, revision='master',)if args.cpu_only:device_map = "cpu"else:device_map = "cuda"model = AutoModelForCausalLM.from_pretrained(args.checkpoint_path,device_map=device_map,trust_remote_code=True,resume_download=True,revision='master',).eval()model.generation_config = GenerationConfig.from_pretrained(args.checkpoint_path, trust_remote_code=True, resume_download=True, revision='master',)return model, tokenizerif __name__ == "__main__":args = _get_args()model, tokenizer = _load_model_tokenizer(args)uvicorn.run(app, host=args.server_name, port=args.server_port, workers=1)

        我将多余的请求参数都去掉只保留text、image字段 。通过postman测试可以访问到结果。接口只是简单测了一下,并没有完全封装,如果用java-web的方式调用还需要实现图片上传功能,并返回图片的服务器地址,封装成代码中query 的数据格式访问即可实现离线本地化接口调用。

小结

        本文介绍了开源Qwen-VL-Chat多模态环境搭建,以及运行demo和api功能展示,供小白参考。后续会写如何本地化训练多模态模型。

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

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

相关文章

什么?这动物图片可以上国家地理?

stable difussion中大部分的模型都是关于人的,今天交给大家一些不一样的:如何生成动物图片。在这篇文章中我们将会学到如何生成逼真的动物&#xff0c;可爱的动物&#xff0c;还有幻想中的动物。 准备工作 当然前提是你需要一个SD的软件&#xff0c;你可以用本地的SD webUI或…

[Spring] SpringBoot基本配置与快速上手

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

企业如何做好数据防泄密丨十个措施杜绝泄密事件

在当今数字化时代&#xff0c;信息泄露对企业构成了前所未有的威胁。企业的创新成果、专利技术和商业机密是其竞争力的核心。防止泄密可以确保这些关键资产不被非法复制或盗用。 客户数据是企业的宝贵资源。保护客户隐私不被泄露&#xff0c;不仅是法律要求&#xff0c;更是赢…

两位软件工程师创业,开发出一款软件质量保证自主AI代理,融资总额超3000万美元

编译整理&#xff5c;TesterHome社区 来源&#xff5c;TechCrunch 随着生成式人工智能&#xff08;generative AI&#xff09;的出现&#xff0c;人工智能应用正在改变和重塑各行各业&#xff0c;并改变人们的工作方式。软件开发也不例外。 总部位于旧金山和东京的初创公司Aut…

自动化立体仓库设计步骤:7步

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 完整版文件和更多学习资料&#xff0c;请球友到知识星球【智能仓储物流技术研习社】自行下载 这份文件是关于自动化立体仓库设计步骤的详细指南&#xff0c;其核心内容包括以下几个阶…

孟德尔随机化与痛风4

写在前面 今天阅读的文献是多种暴露与某结局的孟德尔随机化&#xff0c;算是以量取胜了。 The effect of metabolism-related lifestyle and clinical risk factors on digestive system cancers in East Asian populations: a two-sample Mendelian randomization analysis …

淘宝商品评论电商API接口:帮你轻松挑选优质商品

随着互联网的快速发展&#xff0c;电子商务应运而生&#xff0c;并在短时间内取得了巨大的成功。其中&#xff0c;淘宝作为我国最大的在线购物平台之一&#xff0c;每天都有数以亿计的商品交易发生。然而&#xff0c;面对海量的商品信息&#xff0c;如何挑选出优质商品成为了一…

800 元打造家庭版 SOC 安全运营中心

今天,我们开始一系列新的文章,将从独特而全面的角度探索网络安全世界,结合安全双方:红队和蓝队。 这种方法通常称为“紫队”,集成了进攻和防御技术,以提供对威胁和安全解决方案的全面了解。 在本系列的第一篇文章中,我们将指导您完成以 100 欧元约800元左右的预算创建…

无人机在交通管理方面的应用与潜力

随着智能化和数字化技术的发展&#xff0c;无人机已经成为智慧交通管理体系中的重要一环。无人机能够搭载各种专业设备&#xff0c;如超清摄像头、红外热成像摄像头、目标跟踪器等&#xff0c;从而完成多任务的数据采集和快速机动的任务执行。这些数据通过无线传输实时回传&…

LVS+Nginx高可用集群--基础篇(二)

1.虚拟主机-使用nginx为静态资源提供服务 静态资源服务器&#xff1a;主要包括两类资源&#xff0c;网页&#xff1b;图片&#xff0c;音频等&#xff1b; 也可以通过别名设置静态资源路径。 配置代码&#xff1a; server {listen 88;server_name localhost;locatio…

Kudu分区策略

Kudu表的分区策略主要有三种&#xff1a;范围分区&#xff08;Partition By Range&#xff09;、哈希分区&#xff08;Partition By Hash&#xff09;和高级分区&#xff08;Partition By Hash And Range&#xff09;。这些策略都要求分区字段必须包含在主键中。 范围分区&…

数据安全治理:从库级权限申请到表级权限申请

背景 随着数据安全意识的提高&#xff0c;企业越来越重视数据治理和权限管理。传统数仓大多对库级别进行读写授权&#xff0c;仅对人工标记的敏感库进行表级别授权&#xff0c;但由于敏感等级是由人为标记&#xff0c;错误率较高&#xff0c;故期望将权限申请流程细化到表级申…

树莓派_Pytorch学习笔记20:初步认识深度学习框架

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: ​ Python 版本3.7.3&#xff1a; ​ 本文很水&#xff0c;就介绍一下我以后的学习使用P…

【线程同步-1】

三大不安全案例 1、车站买票 package syn; ​ //不安全的买票 //线程不安全&#xff0c;有负数 public class UnsafeBuyTicket {public static void main(String[] args) {BuyTicket buyTicket new BuyTicket();new Thread(buyTicket,"xiaoming").start();new Thr…

STM32-按键及传感器模块

本内容是基于江协科技STM32视频整理而得。 1. 按键及传感器模块 1.1 按键简介 按键&#xff1a;常见的输入设备&#xff0c;按下导通&#xff0c;松手断开&#xff1b; 按键抖动&#xff1a;由于按键内部使用的是机械式弹簧片来进行通断的&#xff0c;所以在按下和松手的瞬间…

【代码随想录】【算法训练营】【第63天】 [卡码53]寻宝

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 63&#xff0c;周二&#xff0c;ding~ 题目详情 [卡码53] 寻宝 题目描述 卡码53 寻宝 解题思路 前提&#xff1a; 思路&#xff1a; 重点&#xff1a; 代码实现 C语言 prim算法 kruskal…

百望股份于港交所上市 用户量突破2300万

7月9日&#xff0c;百望股份&#xff08;股份代码&#xff1a;6657.HK&#xff09;正式于港交所上市&#xff0c;以32港元价格开盘&#xff0c;成为“电子发票第一股”。 招股书披露&#xff0c;百望股份成立于2015年&#xff0c;作为一家专注于企业数字化解决方案的提供商&…

C++ | Leetcode C++题解之第221题最大正方形

题目&#xff1a; 题解&#xff1a; class Solution { public:int maximalSquare(vector<vector<char>>& matrix) {if (matrix.size() 0 || matrix[0].size() 0) {return 0;}int maxSide 0;int rows matrix.size(), columns matrix[0].size();vector<…

在Mac上一键安装Mysql(解决所有安装问题)

重点强调安装mysql成功的关键在于安装的版本不能是最新&#xff01;&#xff01; 目录 一&#xff1a;下载mysql数据库安装部分到此结束 二&#xff1a;配置mysql数据库三&#xff1a;启动mysql数据库四&#xff1a;各类奇葩问题总结 一&#xff1a;下载mysql数据库 1.进入MyS…

214.贪心算法:K次取反后最大化的数组和(力扣)

class Solution { public:int largestSumAfterKNegations(vector<int>& nums, int k) {int sum 0;// 进行k次取反操作while (k > 0){// 对数组进行排序sort(nums.begin(), nums.end());// 将最小的元素取反nums[0] -nums[0];// 减少k的值k--;}// 计算数组的总和…