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

news2024/11/10 10:25:38
  • 目录

    前言

    环境准备

    软件安装

    其它库安装启动项目

    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 asynccontextmanager

import 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

DEFAULT_CKPT_PATH = 'qwen/Qwen-VL-Chat'

@asynccontextmanager
async def lifespan(app: FastAPI):  # collects GPU memory
    yield
    if 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: str
    text: 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, tokenizer
    message = params.content
    query = 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 args


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 _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, tokenizer


if __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.coloradmin.cn/o/1907652.html

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

相关文章

关于Web开发的详细介绍

目录 一、什么是Web&#xff1f; 二、Web网站的工作流程和开发模式 &#xff08;1&#xff09;简单介绍 &#xff08;2&#xff09;工作流程 1、第一步 2、第二步 &#xff08;3&#xff09;Web网站的开发模式 1、前后端分离开发模式 ​编辑2、混合开发模式 三、开发W…

36.哀家要长脑子了!--前缀和差分

前缀和 1.一维的795. 前缀和 - AcWing题库 前缀和公式 s[i] a[1] a[2] a[3] ... a[i] 即 s[i] s[i-1] a[i] #include<iostream> using namespace std;const int N 1e5 10; int a[N], s[N];int main(){int m, n;cin >> n >> m;for(int i 1; i <…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【加解密(ArkTS)】

加解密(ArkTS) 以AES 128密钥为例&#xff0c;完成加解密。具体的场景介绍及支持的算法规格。 开发步骤 生成密钥 指定密钥别名。初始化密钥属性集。调用[generateKeyItem]生成密钥&#xff0c;具体请参考[密钥生成]。开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/l…

数据库之MQL

1&#xff0c;查询所有 mysql> select * from grade;2&#xff0c; mysql> select id,firstname,lastname from grade;3&#xff0c; mysql> select firstname,lastname from grade where id > 4;4&#xff0c; mysql> select * from grade where sex f;5&…

pandas数据分析(8)

描述性统计量和数据聚合 描述性统计量 描述性统计量通过量化数据来概括数据集。DataFrame和Series可以通过sum、mean、count等方法来获取各种描述性统计量。在默认情况下会按照axis0返回一个Series&#xff0c;也就是说会得到一个有关列的统计量&#xff1a; 如果要计算行的统…

【解决Windows11系统Windows Hello不能使用的问题】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Windows Hello是什么&#xff1f;二、使用步骤1.购买一个摄像头2.开始配置 三、异常解决1.内置管理员不能使用2.没找到合适的摄像头3.摄像头需要专用驱动4.…

CSS技巧 - 一日一例 (1):会讨好的热情按钮

题外话: 从今天开始,我准备开设一个新的专栏,专门写 使用CSS实现各种酷炫按钮的方法,本专栏目前准备写40篇左右,大概会完成如下按钮效果: 今天,我来介绍第一个按钮的实现方法:会讨好的热情按钮。为什么我给它起这样的名字呢?你看它像不像一个不停摇尾巴的小黄?当你鼠…

Java---包装类与泛型

1.包装类 1.1 包装类 在Java中&#xff0c;由于基本数据类型不是继承Object类&#xff0c;为了在泛型代码中可以支持基本数据类型&#xff0c;Java给每个基本数据类型各自提供了一个包装类。 如下图 除了char和int基本数据类型的包装类型有点特别&#xff0c;其他的都是首字…

百川工作手机实现销售管理微信监控系统

在瞬息万变的商业战场中&#xff0c;每一分效率的提升都是企业制胜的关键。传统销售管理模式已难以满足现代企业对精准、高效、合规的迫切需求。今天&#xff0c;让我们一同探索如何利用工作手机这一创新工具&#xff0c;为您的销售团队装上智能翅膀&#xff0c;开启销售管理的…

ELfK logstash filter模块常用的插件 和ELFK部署

ELK之filter模块常用插件 logstash filter模块常用的插件&#xff1a; filter&#xff1a;表示数据处理层&#xff0c;包括对数据进行格式化处理、数据类型转换、数据过滤等&#xff0c;支持正则表达式 grok 对若干个大文本字段进行再分割成一些小字段 (?<字段名…

ROS中不同文件之间的引用小结

在比较大的一些程序中&#xff0c;往往会涉及到一些不同模块的调用&#xff0c;如果这些东西放在一个.cpp文件内&#xff0c;这个文件会变的特别长&#xff0c;因此会使用多个文件互相引用。那么如何在ROS下进行这种不同文件下的引用呢&#xff0c;根据最近所学&#xff0c;简单…

【大模型LLM面试合集】大语言模型基础_Word2Vec

Word2Vec 文章来源&#xff1a;Word2Vec详解 - 知乎 (zhihu.com) 1.Word2Vec概述 Word2Vec是google在2013年推出的一个NLP工具&#xff0c;它的特点是能够将单词转化为向量来表示&#xff0c;这样词与词之间就可以定量的去度量他们之间的关系&#xff0c;挖掘词之间的联系。 …

世界商用飞机机型大全-使用Java抓取FlightAware后的答案

目录 前言 一、数据说明 1、实时航班飞机机型数据 2、网页结构分析 二、使用Java进行信息抓取 1、定义页面PageVO对象 2、爬取属性定义 3、启动信息抓取组件 三、成果分析 1、商业飞行的飞机机型的种类 2、飞机种类排名前十名 3、航班数排名后十名 4、看中国国产大飞…

解读BASE理论:高可用性与性能的完美平衡

Base概念 BASE 理论是一种处理大规模分布式系统中的数据一致性问题的思路。相比于传统的严格一致性&#xff0c;它更灵活&#xff0c;适用于那些需要高可用性和性能的系统。BASE 理论由三个部分组成&#xff1a; 基本可用&#xff08;Basically Available&#xff09; 基本可用…

《Programming from the Ground Up》阅读笔记:p19-p48

《Programming from the Ground Up》学习第2天&#xff0c;p19-p48总结&#xff0c;总计30页。 一、技术总结 1.object file p20, An object file is code that is in the machine’s language, but has not been completely put together。 之前在很多地方都看到object fi…

算法期末程序填空

1.有重复元素全排列的计数问题(部分正确 【考察知识点】有重复元素的全排列的计数 【题目描述】 共有n个小球&#xff08;1<n<20&#xff09;&#xff0c;这n个小球有k种颜色&#xff08;1<k<10&#xff09;&#xff0c;白色s1​个&#xff0c;红色s2​个&#…

大模型时代的蓝海任务,GPT4V准确率不足10%,港科大发布指代理解基准RefCOCO

谈到多模态大模型的应用场景&#xff0c;除了生成任务以外&#xff0c;应用最广泛的可能就是在图像和视频中进行目标检测。 目标检测要求从图像中识别并标注出所有感兴趣的对象&#xff0c;并给每个对象分配一个类别标签。典型的目标检测方法会生成边界框&#xff0c;标记出图…

百度、谷歌、必应收录个人博客网站

主要是给各个搜索引擎提交你的sitemap文件&#xff0c;让别人能搜到你博客的内容。 主题使用的Butterfly。 生成sitemap 安装自动生成sitemap插件。 npm install hexo-generator-sitemap --save npm install hexo-generator-baidu-sitemap --save在站点配置文件_config.yml…

LabVIEW高能质子束流密度分布测试系统

LabVIEW平台开发的高能质子束流密度分布测试系统。该系统主要应用于电子器件的抗辐射加固试验&#xff0c;旨在精确测量高能质子束的密度分布&#xff0c;以评估电子器件在辐射环境下的性能表现和耐受能力。 系统组成与设计 硬件组成&#xff1a; 法拉第杯探测器&#xff1a;…

C++ 类和对象 拷贝构造函数

一 拷贝构造函数的概念&#xff1a; 拷贝构造函数是一种特殊的构造函数&#xff0c;用于创建一个对象是另一个对象的副本。当需要用一个已存在的对象来初始化一个新对象时&#xff0c;或者将对象传递给函数或从函数返回对象时&#xff0c;会调用拷贝构造函数。 二 拷贝构造函…