如何计算VLLM本地部署Qwen3-4B的GPU最小配置应该是多少?多人并发访问本地大模型的GPU配置应该怎么分配?

本文一定要阅读我上篇文章!!!

超详细VLLM框架部署qwen3-4B加混合推理探索!!!-CSDN博客

本文是基于上篇文章遗留下的问题进行说明的。

一、本文解决的问题

问题1:我明明只部署了qwen3-4B的模型,为什么启动VLLM推理框架后能占到显存的0.9,占了22GB显存?

问题2:VLLM框架部署Qwen3-4B的GPU最小配置应该是多少,怎么计算?

问题3:VLLM框架预留更多的GPU资源对模型推理速度影响多大?

问题4:并发处理10-20人的访问本地模型请求,GPU配置应该怎么计算,怎么分配?

二、解决问题1

问题1:我明明只部署了qwen3-4B的模型,为什么启动VLLM推理框架后能占到显存的0.9,占了22GB显存?

官网回答图片,可以知道VLLM框架是预置了0.9的显存给这个模型,但是模型实际不一定需要要那么多显存。还有最大输入的token默认值是40960,正常我们输入的长文本不需要那么大。

因此可以自定义分配GPU显存给VLLM服务,测试一下,当然你分配的显存越少,推理速度越慢。

比如我分配了0.5的显存重启VLLM服务,就可以看到分配的显存就是0.5左右。

vllm serve /root/lanyun-tmp/modle/Qwen3-4B --max-model-len 10000 --gpu-memory-utilization 0.5 

三、解决问题2

问题2:VLLM框架部署Qwen3-4B的GPU最小配置应该是多少,怎么计算?

执行完下述命令后

 vllm serve /root/lanyun-tmp/modle/Qwen3-4B --max-model-len 10000 --gpu-memory-utilization 0.5 

首先先分析配置日志

  • ​显存占用​

    • ​模型加载​​:7.552 GiB(主模型权重)。
    • ​KV缓存​​:17,440 tokens(具体显存需结合模型参数,但日志未直接给出数值)。
    • ​图捕获阶段​​:0.58 GiB(动态编译优化时的临时占用)。
    • ​总计显存​​:主模型+临时操作约为 ​​8.13 GiB左右​​(KV缓存需额外计算,但日志未明确)。
  • ​总计显存​​:主模型+临时操作约为 ​​8.13 GiB左右​

也就是说,除了自定义的KV缓存,至少8.13GB

 我们还可以自己计算KV显存,根据模型的配置文件和下述公式,得到缓存是1.37GB,也可以直接把模型配置发给deepseek叫它计算。

KV缓存总量 = batch_size × 序列长度 × 模型层数 × 2 × d_model × sizeof(float16)    

因此VLLM部署Qwen3-4B的在--max-model-len 10000GPU的情况下模型占用的GPU资源是,8.13GB+1.37GB=9.5GB

如果是默认情况--max-model-len 40960,模型占用的GPU资源是,8.13GB+5.62GB=13.75GB

小技巧,如果你不相信AI计算的结果,可以执行默认的最长输入命令。

vllm serve /root/lanyun-tmp/modle/Qwen3-4B  --gpu-memory-utilization 0.5 

发现报错

 raise ValueError( ValueError: To serve at least one request with the models's max seq len (40960), (5.62 GiB KV cache is needed, which is larger than the available KV cache memory (2.39 GiB). Based on the available memory, Try increasing `gpu_memory_utilization` or decreasing `max_model_len` when initializing the engine. 

 错误提示显示5.62 GiB KV cache is needed,而当前可用显存仅2.39 GiB。KV缓存用于存储Transformer模型中各层的键值向量。

我们就可以自己计算,10000的token所占用的应该KV缓存的GPU大小,10000/40960*5.62GB=1.37GB。说明AI计算的是正确的。

四、解决问题3

问题3:VLLM框架预留更多的GPU资源对模型推理速度影响多大?

使用下面代码进行测试分配不同的GPU,推理时间变化多少。因为每次生成的token数量不一样,所以我们主要是以tokens/s为衡量标准进行测试。

import time
from openai import OpenAI

# 初始化客户端
openai_api_key = "EMPTY"
openai_api_base = "http://localhost:8000/v1"

client = OpenAI(
    api_key=openai_api_key,
    base_url=openai_api_base,
)

# 使用高精度计时器
start_time = time.perf_counter()  # 比time.time()精度更高[3](@ref)

chat_response = client.chat.completions.create(
    model="/root/lanyun-tmp/modle/Qwen3-4B",
    messages=[
        {"role": "user", "content": "你有什么功能"},
    ],
    max_tokens=8192,
    temperature=0.7,
    top_p=0.8,
    presence_penalty=1.5,
    extra_body={
        "top_k": 20, 
        "chat_template_kwargs": {"enable_thinking": True},
    },
)

end_time = time.perf_counter()
elapsed = end_time - start_time

print("Chat response:", chat_response)
print(f"\n[性能报告] 请求耗时: {elapsed:.4f}秒")
print(f"生成token数: {chat_response.usage.completion_tokens} tokens")
print(f"每秒生成速度: {chat_response.usage.completion_tokens/elapsed:.2f} tokens/s")

情况一,设置最大10000token数量,分配0.5GPU,12.7GB给VLLM服务,除去大模型的启动占用9.5GB,还给VLLM服务预留空间为3.2GB。

vllm serve /root/lanyun-tmp/modle/Qwen3-4B --max-model-len 10000 --gpu-memory-utilization 0.5 

有思考83.71 tokens/s,无思考79.53 tokens/s

    情况二,设置最大10000token数量,分配0.8GPU,20GB给VLLM服务,除去大模型的启动占用9.5GB,还给VLLM服务预留空间为10.5GB。

    vllm serve /root/lanyun-tmp/modle/Qwen3-4B --max-model-len 10000 --gpu-memory-utilization 0.8

    有思考77.09 tokens/s,无思考 78.18 tokens/s

    通过两个情况的对比,预留给VLLM服务的GPU空间大小没有对速度有太大影响,甚至空间小一定,生成速度还更多,但是多运行几次,发现速度是差不多的。 

    五、解决问题4

    问题4:如何测试多人并发访问大模型服务,多少人是上限,生成的速度变化是怎么样的?

    我们可以创建一个并发测试的代码concurrency_test.py

    # concurrency_test.py

    import argparse

    import threading

    import time

    from queue import Queue

    # qwen3-4B_test.py

    import time

    from openai import OpenAI

    def send_request(prompt="你有什么功能", max_tokens=8192, temperature=0.7):

        """单次请求测试函数"""

        client = OpenAI(

            api_key="EMPTY",

            base_url="http://localhost:8000/v1",

        )

       

        start_time = time.perf_counter()

        try:

            response = client.chat.completions.create(

                model="/root/lanyun-tmp/modle/Qwen3-4B",

                messages=[{"role": "user", "content": prompt}],

                max_tokens=max_tokens,

                temperature=temperature,

                extra_body={"top_k": 20}

            )

            elapsed = time.perf_counter() - start_time

            return {

                "success": True,

                "time": elapsed,

                "tokens": response.usage.completion_tokens,

                "speed": response.usage.completion_tokens/elapsed,

                "response": response.choices[0].message.content

            }

        except Exception as e:

            return {

                "success": False,

                "error": str(e),

                "time": time.perf_counter() - start_time

            }

    class ConcurrentTester:

        def __init__(self, num_users):

            self.num_users = num_users

            self.results = Queue()

            self.start_barrier = threading.Barrier(num_users + 1)  # 同步所有线程同时启动

           

        def _worker(self, user_id):

            """单个用户的请求线程"""

            self.start_barrier.wait()  # 等待所有线程就绪

            result = send_request(prompt=f"测试用户{user_id}的并发请求")

            self.results.put((user_id, result))

        def run(self):

            # 创建并启动所有线程

            threads = []

            for i in range(self.num_users):

                t = threading.Thread(target=self._worker, args=(i+1,))

                t.start()

                threads.append(t)

           

            # 等待所有线程准备就绪

            self.start_barrier.wait()

            start_time = time.perf_counter()

           

            # 等待所有线程完成

            for t in threads:

                t.join()

               

            total_time = time.perf_counter() - start_time

           

            # 统计结果

            success = 0

            total_tokens = 0

            speeds = []

            errors = []

           

            while not self.results.empty():

                user_id, res = self.results.get()

                if res['success']:

                    success += 1

                    total_tokens += res['tokens']

                    speeds.append(res['speed'])

                else:

                    errors.append(f"用户{user_id}错误:{res['error']}")

           

            return {

                "total_time": total_time,

                "success_rate": success/self.num_users,

                "avg_speed": sum(speeds)/len(speeds) if speeds else 0,

                "total_tokens": total_tokens,

                "errors": errors

            }

    if __name__ == "__main__":

        parser = argparse.ArgumentParser()

        parser.add_argument("--users", type=int, required=True,

                           help="并发用户数量")

        args = parser.parse_args()

       

        tester = ConcurrentTester(args.users)

        print(f"开始{args.users}用户并发测试...")

        results = tester.run()

       

        print("\n测试报告:")

        print(f"总耗时:{results['total_time']:.2f}秒")

        print(f"成功请求:{results['success_rate']*100:.1f}%")

        print(f"平均生成速度:{results['avg_speed']:.2f}tokens/s")

        print(f"总生成token数:{results['total_tokens']}")

       

        if results['errors']:

            print("\n错误列表:")

            for err in results['errors']:

                print(f"• {err}")

    分别测试上述两个情况:

    情况一,设置最大10000token数量,分配0.5GPU,12.7GB给VLLM服务,除去大模型的启动占用9.5GB,还给VLLM服务预留空间为3.2GB。

    vllm serve /root/lanyun-tmp/modle/Qwen3-4B --max-model-len 10000 --gpu-memory-utilization 0.5 

    情况二,设置最大10000token数量,分配0.8GPU,20GB给VLLM服务,除去大模型的启动占用9.5GB,还给VLLM服务预留空间为10.5GB。

    vllm serve /root/lanyun-tmp/modle/Qwen3-4B --max-model-len 10000 --gpu-memory-utilization 0.8

     

    情况三,设置最大10000token数量,分配0.5GPU,12.7GB给VLLM服务,除去大模型的启动占用9.5GB,还给VLLM服务预留空间为3.2GB。

    vllm serve /root/lanyun-tmp/modle/Qwen3-4B --max-model-len 10000 --gpu-memory-utilization 0.5 

    终极测试500个并发请求,可以看到VLLM框架一次性是处理11个请求,然后分批次排队处理这么多的并发请求。然后越到后面处理的请求越少。

    结论,VLLM处理框架处理并发的能力是可以的,它是通过并发处理11给请求,别的请求是排队处理。所以只要模型通过VLLM部署起来,理论上它解决无上限的并发请求,就是要排队等着大模型回复。 

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

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

    相关文章

    antv/g6 图谱封装配置(二)

    继上次实现图谱后,后续发现如果要继续加入不同样式的图谱实现起来太过麻烦,因此考虑将配置项全部提取封装到js文件中,图谱组件只专注于实现各种不同的组件,其中主要封装的点就是各个节点的横坐标(x),纵坐标…

    从芯片互连到机器人革命:英伟达双线出击,NVLink开放生态+GR00T模型定义AI计算新时代

    5月19日,在台湾举办的Computex 2025上,英伟达推出新技术“NVLink Fusion”,允许非英伟达CPU和GPU,同英伟达产品以及高速GPU互连技术NVLink结合使用,加速AI芯片连接。新技术的推出旨在保持英伟达在人工智能开发和计算领…

    Qt window frame + windowTitle + windowIcon属性(3)

    文章目录 window frame属性window frame的概念1. window frame的影响2. 图片演示3. 代码演示 API接口widget.cpp(测试代码) windowTitle属性API接口问题 注意点widget.cpp(属性用法) windowIcon属性API接口啥是窗口图标玩法1. 先…

    Git 分支管理:merge、rebase、cherry-pick 的用法与规范

    Git 分支管理:merge、rebase、cherry-pick 的用法与规范 在团队开发和个人项目中,合理管理 Git 分支至关重要。merge、rebase 和 cherry-pick 是最常用的三种分支操作命令。本文将介绍它们的基本用法、适用场景及最佳实践规范,帮助大家更高效…

    VR全景制作方法都有哪些?需要注意什么?

    VR全景制作是将线下实景场景转化为具有沉浸式体验的全景图像的相关技术流程。通过图像处理和软件拼接等手段及技术,可以制作出VR全景图。后面,我们科普详细的VR全景制作方法指南,顺便介绍众趣科技在相关领域提供的支持方案。 选定拍摄地点与准…

    计算机系统结构1-3章节 期末背诵内容

    Amdahl定律: 加快某部件执行速度所能获得的系统性能加速比,受限于该部件的执行时间占系统中总执行时间的百分比。 加速比依赖于: 可改进比例:在改进前的系统中,可改进部分的执行时间在总的执行时间中所占的比例。 部件加速比:可改…

    JS实现直接下载PDF文件

    pdf文件通过a标签直接下载会打开页面,所以,请求该文件的blob文件流数据,再通过window.URL.createObjectURL转成链接,就可以直接下载了。 只需要替换url和文件名称就行,文件名的后缀记得要写上pdf,不然会变成…

    深度解析Pytest中Fixture机制与实战案例

    一、为什么我们需要Fixture? 在某次金融系统重构项目中,我们的测试团队曾遇到这样的困境:随着测试用例增长到500,使用unittest框架编写的测试代码出现了严重的维护问题——setup方法臃肿不堪,测试数据混乱&#xff0c…

    文档结构化专家:数字化转型的核心力量

    文档结构化专家:定义、职责与行业应用的全方位解析 一、文档结构化的定义与核心价值 文档结构化是将非结构化或半结构化文档(如文本、图像、表格)转换为计算机可处理的规范化数据形式的过程。其核心在于通过语义解析、信息单元划分和标准化格式(如XML/JSON),实现信息的…

    Linux系统管理与编程16番外篇:PXE自动化安装部署OpenEuler24.03LTS

    兰生幽谷,不为莫服而不芳; 君子行义,不为莫知而止休。 Preboot Execution Environment 本机服务器操作系统:CentOS7.9.2207 目标服务器安装系统:openEuler-24.03-LTS-SP1-everything-x86_64-dvd.iso 虚拟机&#xff1…

    Enhanced RTMP H.265(HEVC)技术规格解析:流媒体协议的新突破

    Enhanced RTMP H.265(HEVC)技术规格解析:流媒体协议的新突破 “每一帧画面都是时间的映射,压缩之后的灵魂,依然能栩栩如生。” 随着流媒体技术的快速发展,视频编码标准不断推陈出新。H.264/AVC虽然已经成为…

    Visual Studio Code 改成中文模式(汉化)

    1、打开工具软件(双击打开) 2、软件左边图标点开 3、在搜索框,搜索 chinese 出现的第一个 就是简体中文 4、点击第一个简体中文,右边会出来基本信息 点击 install 就可以安装了(记得联网)。 5、安装完右…

    Linux--初识文件系统fd

    01. C/系统调用文件操作 C/系统调用文件操作 02. 文件系统(ext2)结构 Linux ext2文件系统,上图为磁盘文件系统图(内核内存映像肯定有所不同),磁盘是典型的块设备,硬盘分区被划分为一个个的block。一个块的大小(有1MB,…

    算法中的数学:欧拉函数

    1.相关定义 互质:a与b的最大公约数为1 欧拉函数:在1~n中,与n互质的数的个数就是欧拉函数的值 eg: n1时,欧拉函数的值为1,因为1和1是互质的 n2是,值为2,因为1和2都是互质的 积性函数&…

    BaseDao指南

    1. BaseDao类 import java.sql.*;/*** 通用的工具类 ,负责连接数据, 执行增删改查的通用方法*/ public class BaseDao {private Connection connection;private PreparedStatement pstm;private ResultSet rs;/*** 建立数据库连接** return*/public Boolean getCon…

    SpringBoot JAR 启动原理

    文章目录 版本概述JAR 包结构MANIFEST.MF 描述文件JarLauncherArchive 接口launch 方法Handlers.register() 方法getClassPathUrls 方法createClassLoader 方法 时序图参考 版本 Java 17SpringBoot 3.2.4 概述 JAR 启动原理可以简单理解为“java -jar的启动原理” SpringBo…

    YOLO11解决方案之速度估算探索

    概述 Ultralytics提供了一系列的解决方案,利用YOLO11解决现实世界的问题,包括物体计数、模糊处理、热力图、安防系统、速度估计、物体追踪等多个方面的应用。 YOLO速度估算结合物体检测和跟踪技术,使用YOLO11 模型检测每帧中的物体&#xf…

    初识C++:模版

    本篇博客主要讲解C模版的相关内容。 目录 1.泛型编程 2.函数模板 2.1 函数模版概念 2.2 函数模版格式 2.3 函数模版的原理 2.4 函数模版的实例化 1.隐式实例化&#xff1a;让编译器根据实参推演模板参数的实际类型 2. 显式实例化&#xff1a;在函数名后的<>中指定模…

    人工智能100问☞第27问:神经网络与贝叶斯网络的关系?

    神经网络与贝叶斯网络是两种互补的智能模型:神经网络通过多层非线性变换从数据中学习复杂模式,擅长大规模特征提取和预测,而贝叶斯网络基于概率推理建模变量间的条件依赖关系,擅长处理不确定性和因果推断。两者的融合(如贝叶斯神经网络)结合了深度学习的表征能力与概率建…

    【node.js】入门基础

    个人主页&#xff1a;Guiat 归属专栏&#xff1a;node.js 文章目录 1. Node.js简介1.1 Node.js的核心特点1.2 Node.js适用场景 2. 第一个Node.js程序2.1 创建并运行Hello World2.2 创建简单的HTTP服务器 3. Node.js核心概念3.1 模块系统3.1.1 创建和导出模块3.1.2 导入和使用模…