本地多卡(3090)部署通义千问Qwen2-72B大模型提速实践:从龟速到够用

最近在做文本风格转化,涉及千万token级别的文本。想用大模型转写,在线的模型一来涉及数据隐私,二来又不想先垫钱再找报销。本地的7-9B小模型又感觉效果有限,正好实验室给俺配了4卡3090的机子,反正也就是做个推理,也不训练不微调,就想试试本地72B大模型能不能跑起来。

先上结论:

  • 模型:Qwen-72B-Chat-Int4
  • 使用2张3090 24G就能跑起来,但是上下文长度在一千汉字左右就会爆显存OOM
  • 使用4张3090 24G也可以跑,上下文长度可以拓展到万字级别
  • 速度:短上下文约10字/s,勉强够用:

下面讲讲怎么做的:

 首先,有博主做了双卡3090部署Qwen2-72B-Int4的教程:

大模型笔记之-Qwen72B-chat-int4部署 |使用双卡3090成功运行_运行qwen-72b-CSDN博客

笔者也是看着该教程跑起来的,但是完全按照该教程会出现很多的问题:比如刚跑起来的时候,推理速度非常慢,大约1token/s,官方文档里面同样模型用A100能做到11.32token/s,完全没道理的。

1. 下载模型

从魔搭社区下载,不需要梯子

from modelscope.hub.snapshot_download import snapshot_download

model_dir = snapshot_download('qwen/Qwen-72B-Chat-Int4')

# 在当前目录下创建一个名为model_dir的txt文件,里面包含model_dir变量的内容
with open('model_dir.txt', 'w') as f:
    f.write(model_dir)

2. 配置环境

2.1. 基础conda环境

conda安装:

python==3.10

pytorch==2.1.0

pytorch-cuda==12.1

笔者cuda driver版本(通过nvidia-smi查看)是12.0,使用cuda runtime版本(通过nvcc -V查看)也应为12.0/12.1,否则后面源码编译flash-attention时会报ptxas版本错误:(以前都是runtime<=driver就行了,现在终于碰见一种情况必须==了)

ptxas *.ptx, line 9; Fatal : Unsupported .version 8.0; current version is ‘7.8’ ptxas fatal

由于conda里面 cuda toolkit / cuda runtime 没有 12.0版本(conda search cudatoolkit最高11.8),所以还得源码编译,但是实验室的服务器咱也没有root权限,所以参考这篇文章中修改路径的做法:不用sudo权限安装cuda10.1_非sudo用户安装cuda-CSDN博客

所以在这里你需要保证你有与cuda driver版本的cuda runtime(即保证使用nvidia-smi查到的版本和nvcc -V查到的版本一致或基本一致)

2.2. Qwen pip依赖

接着就是安装Qwen需要的pip依赖,首先下载Qwen git仓库

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

安装pip依赖:

#1.切换至项目目录下
cd Qwen

#2.安装项目依赖
pip install -r requirements.txt
#使用镜像源加速 pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/

#3.使用web_demo.py 还需要安装web依赖
pip install -r requirements_web_demo.txt

2.3. 安装量化模块Auto-GPTQ

因为我们用Int4量化版本,所以需要安装Auto-GPTQ量化包。在官方指南中,直接使用了pip安装,事后笔者发现这样安装会出现严重问题(事实上,这样子做可能会让推理速度降至1/10,而且还很难排查),在此我们先给出完美方案(参考Auto-GPTQ源码编译):

git clone https://github.com/PanQiWei/AutoGPTQ.git && cd AutoGPTQ
pip install numpy gekko pandas
# 有点小久
pip install -vvv --no-build-isolation -e .

2.4. 安装flash-attention(可选)

flash-attention据悉可以加速模型加载和推理,笔者自己感觉没什么区别。

注意要安装的话需要将cuda runtime(nvcc -V)和cuda driver(nvidia-smi)的版本对齐。

git clone https://github.com/Dao-AILab/flash-attention
cd flash-attention && pip install .
# 下方安装可选,安装可能比较缓慢。
# pip install csrc/layer_norm
# 如果flash-attn版本高于2.1.1,下方无需安装。
# pip install csrc/rotary

3. 运行

Qwen git repo中cli_demo和web_demo均可运行

3.1. 修改DEFAULT_CKPT_PATH

修改DEFAULT_CKPT_PATH为前文1.中model_dir(cli_demo 19行,web_demo 18行)

3.2. 修改device_map为多卡配置

(cli_demo 52行,web_demo 48行):

 2卡参考大模型笔记之-Qwen72B-chat-int4部署 |使用双卡3090成功运行_运行qwen-72b-CSDN博客

4卡:

# 偏向于少分配给卡0,因为在推理时卡0需要承担高负载
device_map = {'transformer.wte': 0, 'transformer.drop': 0, 'transformer.rotary_emb': 0, 'transformer.h.0': 0,
                      'transformer.h.1': 0, 'transformer.h.2': 0, 'transformer.h.3': 0, 'transformer.h.4': 0,
                      'transformer.h.5': 0, 'transformer.h.6': 0, 'transformer.h.7': 0, 'transformer.h.8': 0,
                      'transformer.h.9': 1, 'transformer.h.10': 1, 'transformer.h.11': 1, 'transformer.h.12': 1,
                      'transformer.h.13': 1, 'transformer.h.14': 1, 'transformer.h.15': 1, 'transformer.h.16': 1,
                      'transformer.h.17': 1, 'transformer.h.18': 1, 'transformer.h.19': 1, 'transformer.h.20': 1,
                      'transformer.h.21': 1, 'transformer.h.22': 1, 'transformer.h.23': 1, 'transformer.h.24': 1,
                      'transformer.h.25': 1, 'transformer.h.26': 1, 'transformer.h.27': 1, 'transformer.h.28': 1,
                      'transformer.h.29': 1, 'transformer.h.30': 1, 'transformer.h.31': 1, 'transformer.h.32': 1,
                      'transformer.h.33': 1, 'transformer.h.34': 1, 'transformer.h.35': 1, 'transformer.h.36': 2,
                      'transformer.h.37': 2, 'transformer.h.38': 2, 'transformer.h.39': 2, 'transformer.h.40': 2,
                      'transformer.h.41': 2, 'transformer.h.42': 2, 'transformer.h.43': 2, 'transformer.h.44': 2,
                      'transformer.h.45': 2, 'transformer.h.46': 2, 'transformer.h.47': 2, 'transformer.h.48': 2,
                      'transformer.h.49': 2, 'transformer.h.50': 2, 'transformer.h.51': 2, 'transformer.h.52': 2,
                      'transformer.h.53': 2, 'transformer.h.54': 2, 'transformer.h.55': 2, 'transformer.h.56': 2,
                      'transformer.h.57': 2, 'transformer.h.58': 2, 'transformer.h.59': 2, 'transformer.h.60': 2,
                      'transformer.h.61': 3, 'transformer.h.62': 3, 'transformer.h.63': 3, 'transformer.h.64': 3,
                      'transformer.h.65': 3, 'transformer.h.66': 3, 'transformer.h.67': 3, 'transformer.h.68': 3,
                      'transformer.h.69': 3, 'transformer.h.70': 3, 'transformer.h.71': 3, 'transformer.h.72': 3,
                      'transformer.h.73': 3, 'transformer.h.74': 3, 'transformer.h.75': 3, 'transformer.h.76': 3,
                      'transformer.h.77': 3, 'transformer.h.78': 3, 'transformer.h.79': 3, 'transformer.ln_f': 3,
                      'lm_head': 3}

# 也可以用这个
device_map = 'balanced_low_0'

静态负载:

3.3. 修改模型加载方式为AutoGPTQ

web_demo 50-55行

cli_demo 54-59行

model = AutoGPTQForCausalLM.from_quantized(
        args.checkpoint_path,
        device_map=device_map,
        trust_remote_code=True,
        resume_download=True,
        # use_marlin=True,
    ).eval()

如果用的是gptq v7.0,会让你用use_marlin:

INFO - You passed a model that is compatible with the Marlin int4*fp16 GPTQ kernel but use_marlin is False. We recommend using `use_marlin=True` to use the optimized Marlin kernels for inference. Example: `model = AutoGPTQForCausalLM.from_quantized(..., use_marlin=True)`.

但是不知道为什么,用了就报错,所以我注释掉了。

加载模型速度对比:


# 从加载模型至允许query约500s
model = AutoGPTQForCausalLM.from_quantized(
        args.checkpoint_path,
        device_map=device_map,
        trust_remote_code=True,
        resume_download=True,
        use_marlin=False,
    ).eval()

# 从加载模型至允许query约600s
model = AutoModelForCausalLM.from_pretrained(
        args.checkpoint_path,
        device_map=device_map,
        trust_remote_code=True,
        resume_download=True,
        use_flash_attn=True
    ).eval()

可以看出加载模型GPTQ快20%,官方文档说GPTQ推理速度也快20%。笔者没实测,但显然和上面的观察结果一致。

3.4. 修改web_demo中的服务器地址

33行,改IP为0.0.0.0,否则局域网无法访问

parser.add_argument("--server-name", type=str, default="0.0.0.0",
                        help="Demo server name.")

4. 关于我是如何发现问题并把推理速度提升10倍的

最初按照官方文档做完之后,双卡/四卡3090推理速度在1token/s左右,是官方1张A100速度的10%,完全不符合逻辑。本来打算放弃了,突然看到官方文档里有一句话说用AutoGPTQ加载能快20%,于是我就试了试AutoGPTQForCausalLM而不是AutoModelForCausalLM加载模型

model = AutoGPTQForCausalLM.from_quantized()

但是其中给了我警告(AutoModelForCausalLM没有给过这个警告):

意思是我的auto-gptq包没装好,其中的Exllamav2没有安装,这会导致推理显著变慢。

于是我按着gptq主页:AutoGPTQ/AutoGPTQ: An easy-to-use LLMs quantization package with user-friendly apis, based on GPTQ algorithm. (github.com)的教程从源码编译装好了,速度就拉满了。

现在3090多卡速度(10token/s)和官方单张A100速度(10token/s)接近,可以看出其实卡间通讯其实并不是瓶颈。

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

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

相关文章

Python falsk 接口挂载 步骤

Python falsk 接口挂载 步骤 1.首先要有自己独立的python环境&#xff0c;因为如果和别人共用环境的话&#xff0c;会有依赖包冲突的情况 2.找到python.exe的安装路径 3.CMD切换到该路径下 4.执行指令activate,进入到专属的python环境 5.然后执行指令 pip freeze > re.tet…

CentOS 7遗忘了root密码怎么办?

正文共&#xff1a;666 字 12 图&#xff0c;预估阅读时间&#xff1a;1 分钟 说来也巧&#xff0c;突然发现使用KVM在部署CentOS时&#xff08;笔记本电脑安装CentOS系统&#xff09;&#xff0c;会有一个神奇的现象&#xff0c;还不是偶然出现的&#xff0c;在最近的三四次部…

【ComfyUI节点】扰动注意力引导Perturbed Attention Guidance

扰动注意力引导 Perturbed Attention Guidance GitHub - KU-CVLAB/Perturbed-Attention-Guidance: Official implementation of "Perturbed-Attention Guidance" 按照官方介绍&#xff0c;扰动注意力指导显著提高了扩散模型的样本质量&#xff0c;而无需外部条件&am…

测试用例编写与管理流程

hello&#xff0c;大家好&#xff0c;我是一名测试开发工程师&#xff0c;至今已在自动化测试领域深耕9个年头&#xff0c;现已将本人实战多年的多终端自动化测试框架【wyTest】开源啦&#xff0c;在接下来的一个月里&#xff0c;我将免费指导大家使用wyTest&#xff0c;请大家…

14-Django项目--文件上传-Excel

目录 前端 路由 视图函数 前端 <div class"modal-body"><form method"post" enctype"multipart/form-data" action"/pretty/asset/">{% csrf_token %}<input type"file" name"excel"><bu…

Leetcode3194. 最小元素和最大元素的最小平均值

Every day a Leetcode 题目来源&#xff1a;3194. 最小元素和最大元素的最小平均值 解法1&#xff1a;排序遍历 将数组 nums 排序后&#xff0c;利用双指针计算每一对 (minElement maxElement) / 2&#xff0c;最小值即为答案。 代码&#xff1a; /** lc appleetcode.cn …

Spring源码十七:Bean实例化入口探索

上一篇Spring源码十六&#xff1a;Bean名称转化我们讨论doGetBean的第一个方法transformedBeanName方法&#xff0c;了解Spring是如何处理特殊的beanName&#xff08;带&符号前缀&#xff09;与Spring的别名机制。今天我们继续往方法下面看&#xff1a; doGetBean 这个方法…

AI 大模型系统实战

AI 大模型是什么&#xff1f; 维基百科对基础模型的定义是这样的&#xff0c;基础模型是一种大型机器学习模型&#xff0c;通常在大量数据上进行大规模训练&#xff08;通过自监督学习或半监督学习&#xff09;&#xff0c;以使它可以适应各类下游任务。因此&#xff0c;它需要…

数学系C++ 类与对象 STL(九)

目录 目录 面向对象&#xff1a;py&#xff0c;c艹&#xff0c;Java都是,但c是面向过程 特征&#xff1a; 对象 内敛成员函数【是啥】&#xff1a; 构造函数和析构函数 构造函数 复制构造函数/拷贝构造函数&#xff1a; 【……】 实参与形参的传递方式&#xff1a;值…

【Java】了解异常

初始异常 我们平时应该已经接触过一些 “异常” 了&#xff0c;这里列举一些例子。 算术异常&#xff1a; 数组下标越界异常&#xff1a; 访问空指针异常&#xff1a; 所谓异常指的就是程序在 运行时 出现错误时通知调用者的一种机制。 异常的基本用法 捕获异常 try{ 有可能…

知识的向量表示

1、one-hot表示&#xff0c;空间太大 2、bag词袋模型&#xff0c;无法表示词的语义 3、词的语义由什么决定&#xff1f;词由他的上下文决定&#xff1f;分布式语义 4、CBow&#xff0c;通过前面几个词和后面几个词&#xff0c;预测中间几个词 5、skip-gram&#xff0c;通过…

【Python】已解决:(MongoDB安装报错)‘mongo’ 不是内部或外部命令,也不是可运行的程序

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例及解决方案五、注意事项 已解决&#xff1a;&#xff08;MongoDB安装报错&#xff09;‘mongo’ 不是内部或外部命令,也不是可运行的程序 一、分析问题背景 在安装和配置MongoDB时&#xff0c;有…

数据库逆向工程工具reverse_sql

reverse_sql 是一个用于解析和转换 MySQL 二进制日志&#xff08;binlog&#xff09;的工具。它可以将二进制日志文件中记录的数据库更改操作&#xff08;如插入、更新、删除&#xff09;转换为反向的 SQL 语句&#xff0c;以便对系统或人为产生的误操作进行数据回滚和恢复。 *…

Python28-9 XGBoost算法

XGBoost&#xff08;eXtreme Gradient Boosting&#xff0c;其正确拼写应该是 "Extreme Gradient Boosting"&#xff0c;而XGBoost 的作者在命名时故意使用了不规范的拼写&#xff0c;将“eXtreme”中的“X”大写&#xff0c;以突出其极限性能和效率&#xff09;是一…

【open3d专栏】利用PCA计算狭长点云的主方向

在点云处理中&#xff0c;PCA通常用于识别数据集中的主要方向&#xff0c;从而帮助理解数据的几何结构。 使用工具&#xff1a;python&#xff0c;open3d库 目的&#xff1a;计算狭长型点云的主方向 # -*- coding: utf-8 -*- """ Created on Sun Jul 7 11:50…

SpringMVC源码解析(一):web容器启动流程

SpringMVC源码系列文章 SpringMVC源码解析(一)&#xff1a;web容器启动流程 目录 一、SpringMVC全注解配置1、pom文件2、web容器初始化类(代替web.xml)3、SpringMVC配置类(代替springmvc.xml)4、测试Controller 二、SpringServletContainerInitializer1、web容器初始化入口2、…

RNN 交叉熵

RNN善于处理时序 序列数据 简单RNN 展开就是 LSTM 遗忘门f_t决定上期记忆保留多少 隐藏层 在神经网络中&#xff0c;隐藏层指的是除了输入层和输出层之外的层&#xff0c;它们的输出不会直接用于网络的最终输出&#xff0c;而是作为中间步骤用于提取和转换数据。因此&#x…

LabVIEW光谱测试系统

在现代光通信系统中&#xff0c;光谱分析是不可或缺的工具。开发了一种基于LabVIEW的高分辨率光谱测试系统&#xff0c;通过对可调谐激光器、可编程光滤波器和数据采集系统的控制&#xff0c;实现了高效、高精度的光谱测量。 项目背景 随着光通信技术的迅速发展&#xff0c;对…

Filter和Listener

1. Filter 过滤器 1 过滤器简介 Filter过滤器是JavaWeb的三大组件&#xff08;Servlet程序、Listener监听器、Filter过滤器&#xff09;之一 Filter作用&#xff1a;拦截请求、过滤响应 是javaee的规范也是接口 拦截请求常见的应用有 权限检查日记操作事务管理 2 Filter …

刷题之多数元素(leetcode)

多数元素 哈希表解法&#xff1a; class Solution { public:/*int majorityElement(vector<int>& nums) {//map记录元素出现的次数&#xff0c;遍历map&#xff0c;求出出现次数最多的元素unordered_map<int,int>map;for(int i0;i<nums.size();i){map[nu…