如何計算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
    繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81985.shtml
    英文地址,請注明出處:http://en.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 導入和使用模…