惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - uestc2007

AI 智能体项目的测试 磁盘挂载 LibreOffice 批量将.doc文件转换为.docx Supervisor 监控 Python 服务 容器异常或停止自动启动脚本 资源监控脚本 Docker 安全及日志管理 Docker资源控制 做项目管理需要哪些技能 项目管理的基本工作是什么 知识图谱介绍(三) 知识图谱介绍(二) 知识图谱介绍(一) 安装Kuboard管理k8s Registry&Harbor私有仓库构建 EMQX配置用户名和密码开启emqx_auth_mnesia认证方式连接 开关量、数字量、模拟量、离散量和脉冲量它们之间有什么区别? Kubernetes基础总结 Kubernetes管理应用程序、服务常用命令、集群监视
vllm方式部署Deepseek R1、Embedding、Reranker、Qwen
uestc2007 · 2026-03-24 · via 博客园 - uestc2007

一、环境准备

1、安装python环境

准备python环境,Index of /archive

bash https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-x86_64.sh
conda -V
conda create -n vllm python=3.12 -y
conda activate vllm

2、模型下载

模型地址:https://www.modelscope.cn/home

指定下载路径为:

安装ModelScope 下载工具
pip install modelscope

#DeepSeekm模型
modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Qwen-32B --local_dir /mnt/sda/model/DeepSeek-R1-Distill-Qwen-32B-AWQ/
#qwen模型
modelscope download --model Qwen/Qwen3-32B-AWQ --local_dir /mnt/sda/model/Qwen/Qwen3-32B-AWQ
#向量模型
modelscope download --model BAAI/bge-base-zh-v1.5 --local_dir /mnt/sda/model/BAAI/bge-base-zh-v1.5
#重排模型
modelscope download --model BAAI/bge-reranker-base --local_dir /opt/models/BAAI/bge-reranker-v2-m3

默认下载路径为:

下载
modelscope download --model BAAI/bge-reranker-v2-m3
默认路径
~/.cache/modelscope/hub/BAAI/bge-reranker-v2-m3/

3、安装依赖

# 然后到PyTorch 官网(https://pytorch.org/get-started/locally/)查看相符的安装命令,执行
pip install torch==2.1.2 torchvision torchaudio -i https://pypi.tuna.tsinghua.edu.cn/simple --extra-index-url https://download.pytorch.org/whl/cu118
# 安装成功后,验证PyTorch 是否正确调用 GPU
python -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0))"
# 返回类似True NVIDIA GeForce RTX 4090就代表安装成功了
 
#安装显卡状态查看工具nvitop
pip install nvitop
nvitop

4、安装vllm

#安装vllm, pip install "vllm[triton]" 命令中的[triton]代表我们要安装VLLM的可选组件triton。它是OpenAI 开源的深度学习算子编译框架,vLLM 使用它来实现高性能的「Token 并行生成机制」,使VLLM在运行时性能会得到显著提升,推荐安装
pip install vllm -i https://pypi.tuna.tsinghua.edu.cn/simple
# 验证是否安装成功
python -c "import vllm; print(vllm.__version__)" #如果打印出VLLM相关的东西,则代表安装成功了

5、vllm服务使用说明

推荐使用OpenAI API 格式服务启动。因为OpenAI API 格式几乎成为所有AI通用格式,能兼容绝大多数的服务与接口请求

vllm启动参数可参考:引擎参数 — vLLM 文档

模型启动示例

python -m vllm.entrypoints.openai.api_server --model /path/to/model --port 8000

# 模型参数详解
python -m vllm.entrypoints.openai.api_server  #启动 vLLM 的 OpenAI API 服务接口,符合 OpenAI API 格式的调用方式

--model /home/xx/model/deepseek # 模型路径,可以使用本地路径,或 huggingface 等远程路径。必填

--model-name mydeepseek # 最定义模型名称。用户或客户端需要指定模型名,所以你必须提前定义清楚它叫什么。非必填(默认为模型自己的名称)

--tokenizer /home/xx/model/deepseek # 指定分词器的位置或名称,模型文件结构规范的情况下可以不填。它的作用是防止模型文件夹结构不规范导致报错。日常不需要使用

--dtype float16 # 张量精度。支持auto(默认值。vLLM 会根据模型配置自动判断 dtype)、float32(单精度浮点数,最精确但显存占用大)、float16(半精度浮点数,推理快,占用小,当前主流推荐)等等参数。非必填(默认auto)

--port 8088 # 指定模型启动时占用的端口。最好必填

--host 0.0.0.0    # 指定模型启动时的地址,设为 0.0.0.0 允许所有 IP 访问。最好必填

--max-model-len 4068 # 最大输入 + 输出 token 长度。需模型支持。非必填。默认为模型的默认值

--gpu-memory-utilization 0.8 # 使用 GPU 显存的比例。0为最小,1为最大。(1.0=100%,0.1=%10)。调小可以保留一部分显存给系统或其他程序,防止OOM(Out Of Memory显存溢出)。非必填(默认0.9--tensor-parallel-size 2 # 用于多 GPU 并行推理。1 表示单卡运行(比如我的机器有2张显卡,就可以设置为2)。非必填(默认为1)

--swap-space 4    # 为内存不足时预留的 swap 空间(“交换空间”Swap Space)(单位 GB),在显存爆掉时能缓解崩溃。非必填(默认为4)

--disable-log-requests False # 是否禁用日志输出请求内容(保护隐私时可加)。非必填(默认为False)

--max-num-batched-tokens 4068 # 每一批请求最多允许的 token 总数。这个数越大,吞吐量高但延迟可能变大;越小,响应快但效率低。非必填(默认为自动)

--max-num-seqs 6 # 最大同时处理的请求数量,用于多并发的情况。非必填(默认为自动)

--seed 42 # 控制生成内容的一致性,设置固定值可复现生成(同样输入,生成的输出可能会不一样。但是如果设置了比如--seed 42,则会出现回答与之前完全一致的情况出现)。非必填(默认为随机)

--trust-remote-code False # 如果你从 HuggingFace 加载模型并需要运行自定义模型代码(如 LLaVA),必须加此参数。非必填(默认为False)

二、vllm启动模型

注意:我们是用VLLM 把模型部署成 openai API server 形式

vllm serve是vLLM提供的命令行工具,用于快速部署兼容OpenAl API的HTTP服务器。它是对python -m vllm.entrypoints.api_server的封装,语法更简洁。

1、vllm启动Deepseek

nohup python -m vllm.entrypoints.openai.api_server \
--model /mnt/nvme01/models/deepseek671  \
--served-model-name deepseek14 \
--dtype float16 \
--port 8000 \
--host 0.0.0.0 \
--max-model-len 4068 \
--gpu-memory-utilization 0.8 \
--tensor-parallel-size 8 \
--swap-space 8 \
--max-num-batched-tokens 4068 \
--max-num-seqs 6 &
 
nohup python -m vllm.entrypoints.openai.api_server \
  --model="/mnt/nvme01/models/DeepSeek-R1-Distill-Qwen-32B" \
  --tensor-parallel-size 4 \
  --gpu-memory-utilization 0.88 \
  --dtype half \
  --served-model-name "DeepSeek-R1-Distill-Qwen-32B" \
  --host 0.0.0.0 \
  --port 8000 --max-model-len 20480 \
  --chat-template /root/soft/deepseek_r1.jinja &

编写启动脚本vi start-deepseek.sh

#!/bin/bash
nohup /mnt/sda/python/vllm/bin/vllm serve /mnt/sda/model/Valdemardi/DeepSeek-R1-Distill-Qwen-32B-AWQ/ \
  --host 0.0.0.0 \
  --port 8000 \
  --tensor-parallel-size 2 \
  --trust-remote-code \
  --dtype float16 \
  --max-model-len 32678 \
  --quantization awq_marlin \
  --gpu-memory-utilization 0.8 \
  --served-model-name deepseek-r1:32b \
   >ds.log&

 2、vllm启动Qwen

#下载模型
modelscope download --model Qwen/Qwen3-235B-A22B --local_dir /mnt/nvme02/models/Qwen3-235B-A22B
#启动模型
nohup python -m vllm.entrypoints.openai.api_server \
  --model /mnt/nvme02/models/Qwen3-235B-A22B \
  --served-model-name qwen3 \
  --tensor_parallel_size 8 \
  --host 0.0.0.0 \
  --port 8004 \
  --gpu-memory-utilization 0.8 \
  --max-num-seqs 16 \
  --enable-expert-parallel \
  --max-model-len 4096 \
  --enable-reasoning \
  --reasoning-parser deepseek_r1 &

编写启动脚本vi start-qwen.sh

#!/bin/bash

nohup /mnt/sda/python/vllm/bin/vllm serve /mnt/sda/model/Qwen/Qwen3-32B-AWQ/ \
  --host 0.0.0.0 \
  --port 8000 \
  --tensor-parallel-size 2 \
  --trust-remote-code \
  --dtype float16 \
  --max-model-len 40960 \
  --quantization awq_marlin \
  --gpu-memory-utilization 0.7 \
  --served-model-name qwen3:32b \
  >qwen.log&

3、vllm启动Embedding模型bge-m3

CUDA_VISIBLE_DEVICES=0 nohup python -m vllm.entrypoints.openai.api_server \
  --model="/mnt/nvme01/models/bge-m3" \
  --tensor-parallel-size 1 \
  --gpu-memory-utilization 0.1 \
  --dtype half \
  --served-model-name "bge-m3" \
  --host 0.0.0.0 \
  --port 8001 --max-model-len 4096 &

编写启动脚本vi start-bge.sh

#!/bin/bash

nohup /mnt/sda/python/vllm/bin/vllm serve /mnt/sda/model/BAAI/bge-base-zh-v1.5 \
  --host 0.0.0.0 \
  --port 8001 \
  --dtype float16 \
  --tensor-parallel-size 1 \
  --gpu-memory-utilization 0.05 \
   >bge.log&

4、vllm启动Reranker模型

CUDA_VISIBLE_DEVICES=1 nohup python -m vllm.entrypoints.openai.api_server \
  --model="/mnt/nvme01/models/bge-reranker-base" \
  --tensor-parallel-size 1 \
  --gpu-memory-utilization 0.1 \
  --dtype half \
  --served-model-name "bge-reranker-base" \
  --host 0.0.0.0 \
  --port 8002 &

编写启动脚本vi start-reranker.sh

#!/bin/bash

nohup /mnt/sda/iot/python/vllm/bin/vllm serve /opt/models/BAAI/bge-reranker-v2-m3  \
  --host 0.0.0.0 \
  --port 8003 \
  --task embed  \
  --dtype float16 \
  --tensor-parallel-size 1 \
  --gpu-memory-utilization 0.1\
   >reranker.log&

参数说明: - --task embed:表示作为嵌入/重排序模型运行 - --port 8083:设置监听端口 - nohup ... &:后台运行,防止终端关闭中断服务 - 日志输出至 reranker.log

三、基准测试

方案1:使用随机生成的数据集
#运行性能基准测试    
方案1:使用随机生成的数据集
#高负载
/mnt/sda/iot/python/vllm/bin/vllm bench serve \
    --base-url http://localhost:8000 \
    --model qwen3:32b \
    --tokenizer /mnt/sda/iot/model/Qwen/Qwen3-32B-AWQ \
    --dataset-name random \
    --random-input-len 2048 \
    --random-output-len 128 \
    --num-prompts 128  \
    --max-concurrency 10

#低负载    
/mnt/sda/iot/python/vllm/bin/vllm bench serve \
    --base-url http://localhost:8000 \
    --model qwen3:32b \
    --tokenizer /mnt/sda/iot/model/Qwen/Qwen3-32B-AWQ \
    --dataset-name random \
    --random-input-len 2048 \
    --random-output-len 128 \
    --num-prompts 10 \
    --max-concurrency 1
    
方案2:使用自定义数据集文件    
/mnt/sda/iot/python/vllm/bin/vllm bench serve \
  --base-url http://localhost:8000 \
  --model qwen3:32b \
  --tokenizer /mnt/sda/iot/model/Qwen/Qwen3-32B-AWQ \
  --dataset-name custom \
  --dataset-path /mnt/sda/iot/code/vllm/test.jsonl \
  --num-prompts 128 \
  --max-concurrency 30
使用随机生成的数据集参数说明
vllm bench serve \
    --base-url http://localhost:8000 \        # 指定 vLLM 服务器的基础 URL 地址
    --model qwen3:32b \                       # 要基准测试的模型名称或路径
    --tokenizer /mnt/sda/iot/model/Qwen/Qwen3-32B-AWQ \  # tokenizer 的本地路径
    --dataset-name random \                   # 使用的数据集类型,'random' 表示随机生成文本
    --random-input-len 2048 \                 # 随机生成的输入序列长度(token 数量)
    --random-output-len 128 \                 # 随机生成的输出序列长度(token 数量)
    --num-prompts 128 \                        # 用于测试的提示(prompts)总数
    --max-concurrency 1 \                     # 最大并发请求数
    --trust-remote-code \                     # 允许执行远程代码,对自定义模型架构必需
    --dtype float16 \                         # 模型数据类型(float16, bfloat16, float32)
    --tensor-parallel-size 1 \                # 张量并行度,通常等于 GPU 数量
    --gpu-memory-utilization 0.9 \            # GPU 内存利用率(0-1),控制 vLLM 使用的 GPU 内存比例
    --quantization awq \                      # 量化方法(awq, gptq, squeezellm, none)
    --max-model-len 4096 \                    # 模型支持的最大上下文长度
    --seed 0 \                                # 随机种子,确保测试结果可重现
    --request-rate 1.0 \                      # 每秒请求数(RPS),设为 inf 表示尽可能快
    --output-file benchmark_results.json \   # 保存基准测试结果的文件路径
    --disable-tqdm \                          # 禁用进度条显示
    --profile \                               # 启用性能分析,生成详细性能报告
    --log-level info \                        # 日志级别(debug, info, warning, error)
    --warmup 5                                # 预热请求数量,在正式测试前执行

其他可选参数

  • --port 8000: 指定服务器监听端口
  • --host 0.0.0.0: 指定服务器绑定的主机地址
  • --enforce-eager: 强制使用 eager 模式,不使用 CUDA 图优化
  • --num-scheduler-steps 1: PagedAttention 调度器的步数
  • --use-v2-block-manager: 使用 v2 块管理器,提供更好的性能
  • --download-dir /path/to/cache: 指定模型下载缓存目录
  • --max-num-batched-tokens 2048: 一次批处理中最大 token 数量
  • --max-num-seqs 256: 一次批处理中最大序列数
  • --batch-size 1: 每个请求的批处理大小
方案2:使用自定义数据集文件 
方案2:使用自定义数据集文件    
/mnt/sda/iot/python/vllm/bin/vllm bench serve \
  --base-url http://localhost:8000 \
  --model qwen3:32b \
  --tokenizer /mnt/sda/iot/model/Qwen/Qwen3-32B-AWQ \
  --dataset-name custom \
  --dataset-path /mnt/sda/iot/code/vllm/test.jsonl \
  --num-prompts 128 \
  --max-concurrency 30
使用自定义数据集文件参数说明:
/mnt/sda/iot/python/vllm/bin/vllm bench serve \
  --base-url http://localhost:8000 \           # 指定API服务器地址,用于发送请求
  --model qwen3:32b \                           # 指定要测试的模型名称/标识符
  --tokenizer /mnt/sda/iot/model/Qwen/Qwen3-32B-AWQ \  # 指定tokenizer路径,用于文本编码
  --dataset-name custom \                       # 指定数据集类型,这里使用自定义数据集
  --dataset-path /mnt/sda/iot/code/vllm/test.jsonl \  # 指定自定义数据集文件路径
  --num-prompts 128 \                           # 要使用的提示数量,影响测试规模
  --max-concurrency 30 \                        # 最大并发请求数,控制负载强度
  --backend vllm \                              # 指定后端类型(vllm, openai, trt-llm等)
  --request-rate 10.0 \                         # 每秒请求数,与max-concurrency二选一使用
  --temperature 0.8 \                           # 采样温度,控制输出随机性(0.0-1.0)
  --top-p 0.95 \                                # 核心采样概率,控制输出多样性
  --max-output-len 256 \                        # 生成文本的最大长度(tokens)
  --min-output-len 64 \                         # 生成文本的最小长度(tokens)
  --trust-remote-code \                         # 允许执行远程代码,加载自定义模型时需要
  --dtype float16 \                             # 模型数据类型(float16, bfloat16, float32)
  --quantization awq \                          # 量化方法(awq, gptq, squeezellm, auto等)
  --gpu-memory-utilization 0.9 \                # GPU内存利用率(0.0-1.0),控制显存使用
  --tensor-parallel-size 4 \                    # 张量并行度,通常等于GPU数量
  --max-model-len 4096 \                        # 模型支持的最大序列长度(tokens)
  --enable-prefix-caching \                     # 启用前缀缓存,提高相同前缀请求的处理效率
  --disable-log-requests \                      # 禁用请求日志,减少日志输出
  --seed 0 \                                    # 随机种子,确保结果可重现
  --log-results \                               # 记录并保存基准测试结果
  --timeout 300                                 # 请求超时时间(秒),防止长时间阻塞

参数说明

  • 基准测试模式vllm bench serve 命令通过向已运行的服务器发送请求来测试推理性能
  • 资源平衡: 适当调整 --max-concurrency 和 --num-prompts 可帮助找到系统最佳负载点
  • 量化配置: 由于使用了AWQ量化模型,需要正确设置 --quantization awq
  • 内存管理--gpu-memory-utilization 控制显存占用,过高可能导致OOM错误
  • 输出控制--max-output-len 和 --min-output-len 影响吞吐量和延迟测试结果
  • 性能优化--enable-prefix-caching 适合测试有共享前缀的提示,可显著提升性能

测试结果:

image

 测试结果说明:

指标类别

指标名称

含义解释

基础统计

Successful requests

基准测试中成功处理的请求总数

Maximum request concurrency

测试配置中设定的最大允许并发请求数

Benchmark duration (s)

整个基准测试运行的总耗时(秒)。

Total input tokens

所有请求的输入(即提示词Prompt)中包含的 token 总数

Total generated tokens

模型生成的所有输出token总数

吞吐性能

Request throughput (req/s)

每秒处理的请求数,即请求吞吐量。计算方式为 成功请求数 / 测试总时间。本次测试为 0.12 req/s,意味着平均每秒处理约 0.12 个请求。

Output token throughput (tok/s)

每秒生成的输出 token 数,即输出吞吐量。计算方式为 总生成 token 数 / 测试总时间

Peak output token throughput (tok/s)

测试期间观察到的瞬时最高输出 token生成速率(反映短时峰值能力)。

Peak concurrent requests

测试中实际达到的最高并发请求数

Total Token throughput (tok/s)

每秒处理的总 token 数(包括输入和输出)。计算方式为 (总输入 token + 总输出 token) / 测试总时间(综合负载能力)。

Time to First Token (TTFT) —— 首 token 延迟

Mean TTFT (ms)

从发送请求到收到第一个输出token 的平均耗时(毫秒),影响用户感知响应速度。

Median TTFT (ms)

TTFT 的中位数值(50% 请求快于此值)。

P99 TTFT (ms)

TTFT 的 99 百分位值(99% 请求的首token 时间低于此值,衡量尾部延迟)。

Time Per Output Token (TPOT) —— 每个输出 token 的平均生成时间(不含首 token)

Mean TPOT (ms)

平均每个输出 token 的生成时间(不包括第一个 token)

Median TPOT (ms)

每个输出 token 生成时间的中位数

P99 TPOT (ms)

每个输出 token 生成时间的 99% 分位数

流式输出稳定性
Inter-token Latency (ITL) —— token 间延迟

Mean ITL (ms)

连续两个输出令牌之间的平均时间间隔(毫秒),衡量流式输出平滑度。

Median ITL (ms)

平均相邻 token 输出间隔时间

P99 ITL (ms)

相邻 token 输出间隔的 99% 分位数(高值可能表示生成过程卡顿)。

  1. TTFT 衡量从发送请求到收到第一个输出 token 的时间,反映模型预处理和调度开销。P99 为 760ms,说明 99% 的请求在 0.76 秒内收到首个 token,表现良好。
  2. TPOT 代表生成每个后续 token 的耗时,直接影响流式输出的平滑度。均值约 29ms,即每秒约生成 34 个 token,对于大模型而言属于正常范围,且 P99 与均值接近,说明延迟非常稳定。
  3. ITL 与 TPOT 类似,但测量的是连续两个 token 之间的时间间隔。均值和 TPOT 几乎一致,但 P99 略高(44.6ms),表明偶发性的轻微抖动。
  • TTFT vs TPOT/ITL:TTFT 反映“启动延迟”,TPOT/ITL 反映“持续生成效率”。理想服务需同时优化两者。
  • TPOT 与 ITL 关系:在稳定流式生成中,TPOT(排除首token)与 ITL 数值应高度接近(本测试中均为 ~17.8ms),差异过大可能提示调度或计算波动。
  • P99 指标意义:关注尾部延迟(P99),对用户体验和SLA保障至关重要。
  • 并发差异提示:Maximum request concurrency=1(配置上限)与 Peak concurrent requests=2.00(实测峰值)的差异,可能源于测试工具统计粒度或短暂超发,需结合系统设计分析。