LLM - 使用 vLLM 部署 Qwen2-VL 多模态大模型 (配置 FlashAttention) 教程

欢迎关注我的CSDN:https://spike.blog.csdn.net/
本文地址:https://spike.blog.csdn.net/article/details/142528967

免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。


vLLM
vLLM 用于 大语言模型(LLM) 的推理和服务,具有多项优化技术,包括先进的服务吞吐量、高效的内存管理、连续批处理请求、优化 CUDA 内核以及支持量化技术,如GPTQ、AWQ等。FlashAttention 是先进的注意力机制优化工具,通过减少内存访问和优化计算过程,显著提高大型语言模型的推理速度。

GitHub:

  • FlashAttention: https://github.com/Dao-AILab/flash-attention
  • Transformers: https://github.com/huggingface/transformers
  • vLLM: https://github.com/vllm-project/vllm

1. 配置 vLLM

准备 Qwen2-VL 模型,包括 7B 和 72B,即:

modelscope --token [your token] download --model Qwen/Qwen2-VL-7B-Instruct
modelscope --token [your token] download --model Qwen/Qwen2-VL-72B-Instruct-GPTQ-Int4

注意:Qwen2-VL 暂时不支持 GGUF 转换,因此不能使用 Ollama 提供服务。

配置 vLLM:

pip install vllm==0.6.1 -i https://pypi.tuna.tsinghua.edu.cn/simple

参考:vLLM - Using VLMs

注意:当前(2024.9.26)最新 Transformers 版本不支持 Qwen2-VL,需要使用固定 commit 版本,参考:

pip install git+https://github.com/huggingface/transformers.git@21fac7abba2a37fae86106f87fcf9974fd1e3830

Transformers 的 Commit ID (21fac7abba2a37fae86106f87fcf9974fd1e3830) 内容,以更新 Qwen2-VL 为主,即:

commit 21fac7abba2a37fae86106f87fcf9974fd1e3830 (HEAD)
Author: Shijie <821898965@qq.com>
Date:   Fri Sep 6 00:19:30 2024 +0800
    simple align qwen2vl kv_seq_len calculation with qwen2 (#33161)
    * qwen2vl_align_kv_seqlen_to_qwen2
    * flash att test
    * [run-slow] qwen2_vl
    * [run-slow] qwen2_vl fix OOM
    * [run-slow] qwen2_vl
    * Update tests/models/qwen2_vl/test_modeling_qwen2_vl.py
    Co-authored-by: Raushan Turganbay <raushan.turganbay@alumni.nu.edu.kz>
    * Update tests/models/qwen2_vl/test_modeling_qwen2_vl.py
    Co-authored-by: Raushan Turganbay <raushan.turganbay@alumni.nu.edu.kz>
    * code quality
    ---------

vLLM 的视觉文本测试代码,如下:

  • 通过 SamplingParams 设置最大的 Tokens 数量。
  • 注意,不同的模型 Image Token 也不同,Qwen2-VL 是 <|image_pad|>,而 InternVL2-2B<image>

即:

from vllm import LLM, SamplingParams
import PIL
# from vllm.assets.image import ImageAsset
from vllm.assets.video import VideoAsset
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "1"


def main():
    # Qwen2-VL
    llm = LLM(model="llm/Qwen/Qwen2-VL-7B-Instruct/")

    # 设置最大输出 Token 数量
    sampling_params = SamplingParams(max_tokens=8172)

    # InternVL2-2B
    # llm = LLM(model="llm/InternVL2-2B/", trust_remote_code=True)
    # Refer to the HuggingFace repo for the correct format to use
    # prompt = "USER: <image>\nWhat is the content of this image?\nASSISTANT:"

    # Load the image using PIL.Image
    # image = PIL.Image.open("llm/img_test.jpg")

    # -------------------- image -------------------- #
    prompt = "USER: <|image_pad|>\nWhat is the content of this image?\nASSISTANT:"
    image = PIL.Image.open("llm/image.jpg").convert("RGB")
    outputs = llm.generate({
        "prompt": prompt,
        "multi_modal_data": {"image": image},
    }, sampling_params)
    print("[Info] Image: \n")
    for o in outputs:
        generated_text = o.outputs[0].text
        print(generated_text)
    # -------------------- image -------------------- #

    # -------------------- video -------------------- #
    prompt = "USER: <|video_pad|>\nWhat is the content of this video?\nASSISTANT:"
    video = VideoAsset(name="llm/video.mp4", num_frames=50).np_ndarrays
    outputs = llm.generate({
        "prompt": prompt,
        "multi_modal_data": {"video": video},
    }, sampling_params)
    print("[Info] Video: \n")
    for o in outputs:
        generated_text = o.outputs[0].text
        print(generated_text)
    # -------------------- video -------------------- #


if __name__ == '__main__':
    main()

Image Qwen2-VL 的输出:

The image shows a close-up of a person’s feet wearing brown high-heeled shoes with a glossy finish. The shoes have a thick sole and a small platform heel. The background features a light-colored couch with books on top, suggesting an indoor setting, possibly a living room or study. The focus is on the shoes, which are the most prominent object in the image.
这张图片展示一个人的脚穿着棕色的高跟鞋,鞋子表面有光泽。鞋子有一个厚底和一个小的厚跟。背景是一张浅色的沙发,上面放着书,暗示了室内环境,可能是客厅或书房。焦点在鞋子上,它们是图片中最突出的对象。

Img

Video Qwen2-VL 的输出:

The video portrays a person sitting on a stool near a sheer curtain adorned with a floral pattern. Throughout the video, the person in the forefront appears to be a girl across a selection of scenes. She is wearing a light-colored, cozy-looking outfit, and she is moving her feet in a fluid motion. The overall atmosphere of the video is simple and quaint.
视频描绘一个人坐在一张凳子上,靠近一扇装饰有花卉图案的透明窗帘。在整个视频中,前景中的人似乎是一个女孩,她出现在一系列场景中。她穿着一件浅色的、看起来很舒服的衣服,她的脚在流畅地移动。视频的整体氛围简单而古雅。

Video

BugFix1:

  File "miniconda3/envs/torch-llm/lib/python3.9/site-packages/vllm/transformers_utils/configs/__init__.py", line 13, in <module>
    from vllm.transformers_utils.configs.mllama import MllamaConfig
  File "miniconda3/envs/torch-llm/lib/python3.9/site-packages/vllm/transformers_utils/configs/mllama.py", line 1, in <module>
    from transformers.models.mllama import configuration_mllama as mllama_hf_config
ModuleNotFoundError: No module named 'transformers.models.mllama'

原因:降级 vLLM 版本至 0.6.1vllm/transformers_utils/configs/mllama.py0.6.2 版本加入,即:

pip install vllm==0.6.1 -i https://pypi.tuna.tsinghua.edu.cn/simple

BugFix2:

[rank0]:   File "miniconda3/envs/torch-llm/lib/python3.9/site-packages/vllm/inputs/registry.py", line 256, in process_input
[rank0]:     return processor(InputContext(model_config), inputs)
[rank0]:   File "miniconda3/envs/torch-llm/lib/python3.9/site-packages/vllm/model_executor/models/qwen2_vl.py", line 770, in input_processor_for_qwen2_vl
[rank0]:     assert len(image_indices) == len(image_inputs)
[rank0]: AssertionError

原因,参考 vllm/model_executor/models/qwen2_vl.pyhf_config.image_token_id 与当前 Prompt 的 Image Token (<image>),不一致,即:

prompt_token_ids = llm_inputs.get("prompt_token_ids", None)
if prompt_token_ids is None:
    prompt = llm_inputs["prompt"]
    prompt_token_ids = processor.tokenizer(
        prompt,
        padding=True,
        return_tensors=None,
    )["input_ids"]
print(f"[Info] decode prompt: \n{processor.decode(prompt_token_ids)}\n")
print(f"[Info] decode image_token_id (151655): {processor.decode([151655])}")

# Expand image pad tokens.
if image_inputs is not None:
    image_indices = [
        idx for idx, token in enumerate(prompt_token_ids)
        if token == hf_config.image_token_id
    ]
    print(f"[Info] hf_config.image_token_id: {hf_config.image_token_id}, prompt_token_ids: {prompt_token_ids}")
    image_inputs = make_batched_images(image_inputs)
    print(f"[Info] image_indices: {len(image_indices)} and image_inputs: {len(image_inputs)}")
    assert len(image_indices) == len(image_inputs)

经过分析,确定 Qwen2-VL 的 Image Token 是 <|image_pad|>,而不是 <image>,替换 Prompt 即可。

输出:

[Info] decode prompt: 
USER: <|image_pad|>
What is the content of this image?
ASSISTANT:
[Info] decode image_token_id (151655): <|image_pad|>
[Info] hf_config.image_token_id: 151655, prompt_token_ids: [6448, 25, 220, 151655, 198, 3838, 374, 279, 2213, 315, 419, 2168, 5267, 4939, 3846, 2821, 25]
[Info] image_indices: 1 and image_inputs: 1

2. 配置 FlashAttention

FlashAttention 可以加速大模型的推理过程,配置 FlashAttention,参考,安装依赖的 Python 包:

pip install packaging
pip install ninja

测试 ninja 包是否可用,即:

ninja --version  # 1.11.1.git.kitware.jobserver-1
echo $?  # 0

Ninja 类似于 Makefile,语法简单,但是比 Makefile 更加简洁。

不推荐 直接安装 flash-attn,建议使用源码安装,安装过程可控,请耐心等待,即:

pip install flash-attn --no-build-isolation

# log
Building wheels for collected packages: flash-attn
  Building wheel for flash-attn (setup.py) ... |

检测 Python 版本:

python --version # Python 3.9.19
nvidia-smi  # CUDA Version: 12.0

python

import torch
print(torch.__version__)  # 2.4.0+cu121
print(torch.cuda.is_available())  
exit()

建议通过直接源码进行安装,即:

git clone git@github.com:Dao-AILab/flash-attention.git
python setup.py install

整体的编译过程,包括 85 步,耐心等待,即:

Using envvar MAX_JOBS (64) as the number of workers...
[1/85] c++ -MMD -MF ...
# ...
Using miniconda3/envs/torch-llm/lib/python3.9/site-packages
Finished processing dependencies for flash-attn==2.6.3

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

02-ZYNQ linux开发环境安装,基于Petalinux2022.2和Vitis2022.2

petalinux安装 Petalinux 工具是 Xilinx 公司推出的嵌入式 Linux 开发套件&#xff0c;包括了 u-boot、Linux Kernel、device-tree、rootfs 等源码和库&#xff0c;以及 Yocto recipes&#xff0c;可以让客户很方便的生成、配置、编译及自定义 Linux 系统。Petalinux 支持 Ver…

uniapp EChars图表

1. uniapp EChars图表 &#xff08;1&#xff09;Apache ECharts 一个基于 JavaScript 的开源可视化图表库   https://echarts.apache.org/examples/zh/index.html &#xff08;1&#xff09;官网图例 &#xff08;2&#xff09;个人实现图例 1.1. 下载echart 1.1.1. 下…

docker - 迁移和备份

文章目录 1、docker commit1.1、查询 容器 docker ps1.2、docker commit zookeeper zookeeper:3.4.13 2、docker save -o2.1、宿主机 切换到 /opt 目录下2.2、将镜像保存到 宿主机/opt目录下 3、docker load -i 对某一个容器修改完毕以后&#xff0c;我们可以把最新的容器部署到…

【文心智能体 | AI大师工坊】如何使用智能体插件,完成一款旅游类智能体的开发,来体验一下我的智能体『​​​​​​​厦门CityWalk』

目录 1.1、智能体运行效果 1.2、创作灵感来源 1.3、如何制作智能体 1.4、可能会遇到的几个问题 1.5、快速调优指南 『厦门CityWalk&#x1f680;』我的优质智能体&#xff1a;https://0nxj3k.smartapps.baidu.com/?_swebfr1&_swebScene3621000000000000 在当今这个全…

Bytebase 2.22.3 - 一键回滚 PostgreSQL DML 变更

&#x1f680; 新功能 支持一键回滚 PostgreSQL DML 变更。 &#x1f384; 改进 优化 DML 事前备份和回滚体验&#xff1a; 引导用户创建 bbdataarchive 数据库。如果没有 bbdataarchive 数据库&#xff0c;无法开启备份功。用户现在可以在创建工单之后开启或关闭备份功能&a…

Python | Leetcode Python题解之第437题路径总和III

题目&#xff1a; 题解&#xff1a; class Solution:def pathSum(self, root: TreeNode, targetSum: int) -> int:prefix collections.defaultdict(int)prefix[0] 1def dfs(root, curr):if not root:return 0ret 0curr root.valret prefix[curr - targetSum]prefix[cu…

ROS学习笔记(四):使用 `ros2 run usb_cam usb_cam_node_exe` 启动 USB 摄像头

文章目录 前言1 安装 usb_cam 包2 启动 USB 摄像头3 订阅相机发布的节点信息并进行可视化3.1 使用 rqt_image_view3.2 使用 image_view3.3 使用 rviz 4 常见问题与解决方案4.1 摄像头未被识别4.2 相机显示异常4.3 如何指定不同的相机4.4 摄像头参数调整 5. 调试信息 5. 结论 前…

9.5K Star,开源在线网盘

Hi&#xff0c;骚年&#xff0c;我是大 G&#xff0c;公众号「GitHub 指北」会推荐 GitHub 上有趣有用的项目&#xff0c;一分钟 get 一个优秀的开源项目&#xff0c;挖掘开源的价值&#xff0c;欢迎关注。 随着云存储的广泛应用&#xff0c;越来越多的人和企业需要一个简单、…

用Promise实现前端并发请求

/** * 构造假请求 */ async function request(url) {return new Promise((resolve) > {setTimeout(() > {resolve(url);},// Math.random() * 500 800,1000,);}); }请求一次&#xff0c;查看耗时&#xff0c;预计应该是1s&#xff1a; async function requestOnce() {c…

docker安装Portainer CE

docker安装Portainer CE 教程 1、简介 Portainer 是一款开源的容器管理工具&#xff0c;旨在帮助用户更轻松地管理 Docker 环境。无论您是 Docker 新手还是经验丰富的开发人员&#xff0c;Portainer 都提供了直观的用户界面&#xff0c;使您能够方便地创建、部署和监控容器。…

黑马头条day5- 延迟任务精准发布文章

这个过程主要是流程负责 但是我没有仔细的过所有的流程 需要多刷几遍 今天只是照着md文档执行了一下 运行起来没差错 主要实现文章定时发布 通过schedule模块作为延迟队列的任务 通过redis实现的延迟任务 具体 实现还要在多走几遍流程 逻辑一点不清楚 没看网课 这节要多看几遍…

Redis 篇-深入了解 Redis 中的 RESP 通信协议与内存回收(过期 key 处理、内存淘汰策略)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Redis 通信协议 - RESP 协议 2.0 Redis 内存回收 2.1 Redis 内存回收 - 过期 key 处理 2.1.1 Redis 是如何知道一个 Key 是否过期呢&#xff1f; 2.1.2 是不是 TT…

GESP等级考试C++二级-数学函数

C的cmath库中有丰富的数学函数&#xff0c;通过这些函数可以进行相应的数学计算。 1 cmath库的导入 通过import指令导入cmath库&#xff0c;代码如图1所示。 图1 导入cmath库的代码 2 abs()函数 abs()函数用来获取指定数的绝对值&#xff0c;代码如图2所示。 图2 abs()函数…

X86下一文带你构建Apollo9.0运行环境(基于Ubuntu20.04避坑版)

X86下一文带你构建Apollo9.0运行环境基于Ubuntu20.04避坑版 前言准备安装基础软件1.安装Docker19.03安装Nvidia驱动安装配置Nvidia container toolkit 下载Apollo源码&#xff08;笔者下载的是releases下9.0.0版本&#xff0c;大家可以参考&#xff09;编译Apollo9.0下载资源包…

vue-cli,element-plus,axios,proxy

一、vue-cli vue-cli俗称vue脚手架&#xff0c;是vue官方提供的快速生成vue 工程化项目的工具。 1.官网&#xff1a;https://cn.vuejs.org/ 中文官网: https://cli.vuejs.org/zh/ 特点&#xff1a;基于webpack&#xff0c;功能丰富且易于扩展&#xff0c;支持创建vue2和vu…

对话总结:Scale AI的创始人兼CEO Alex Wang

AI的三大支柱 计算:主要由大公司如NVIDIA推动。算法:顶尖实验室如OpenAI主导。数据:Scale致力于推动数据进展。前沿数据的重要性 与人类智能相比较,前沿数据是AI发展的关键。互联网数据是机器与人类合作的结果。语言模型的发展 第一阶段:原始的Transformer论文和GPT的小规…

一书直接讲透自然语言处理《Getting Started with Google BERT_ Build and train》

《Getting Started with Google BERT: Build and Train》是一本面向初学者和中级读者的指南&#xff0c;旨在帮助他们理解和使用Google的BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;模型。BERT是近年来自然语言处理&#xff08;NLP&…

Linux下的git开篇第一文:git的意义

目录 1.git版本控制器 2.git gitee&&github 3.Linux中gitee的使用 &#xff08; 三板斧 git add git commit -m " " git push &#xff09; 4.git log 查看之前的修改信息 &#xff08;所有提交日志&#xff09; 5.git status 查看工作目录与本地…

透传 vs 非透传|数据传输效率与安全性的权衡及应用指南

官方原文&#xff1a;一分钟搞懂透传和非透传的区别-成都纵横指控 在当今数字化时代,数据传输已经成为各行各业的关键环节。在数据通信和物联网应用中,"透传"和"非透传"是两个常见且重要的概念。了解它们的区别,对于选择合适的通信方式至关重要。 什么是…

【java】前端RSA加密后端解密

目录 1. 说明2. 前端示例3. 后端示例3.1 pom依赖3.2 后端结构图3.3 DecryptHttpInputMessage3.4 ApiCryptoProperties3.5 TestController3.6 ApiCryptoUtil3.7 ApiDecryptParamResolver3.8 ApiDecryptRequestBodyAdvice3.9 ApiDecryptRsa3.10 ApiCryptoProperties3.11 KeyPair3…