Qwen1.5-72B/110B并发性能测试:vLLM与私有化封装对比及ChatGLM2/3-6B部署结论

vLLM 推理框架—Qwen1.5并发性能测试

Qwen1.5系列

prompt_200prompt_200 = """总结提炼以下文字50字左右:在数字化时代,信息的获取和处理变得尤为重要。作为一款智能助手,我致力于帮助用户高效地处理和理解各种信息。无论是文本、表格还是演示文档,我都能够迅速阅读和分析,提供精准的信息反馈。 在这个过程中,我始终遵循用户的需求,努力提供丰富、详尽且有帮助的回答。同时,我也严格遵守法律法规,确保服务的安全性和合规性,坚决不涉及不当内容。我深知,作为智能助手,我的任务是为用户提供支持和便利。"""
prompt_512prompt_512 = """总结提炼以下文字120字左右:在这个信息爆炸的时代,人们对于获取信息的途径和方式有着更高的要求。随着科技的不断进步,人工智能技术已经成为了我们日常生活中不可或缺的一部分。作为一款由月之暗面科技有限公司开发的智能助手,我被赋予了强大的功能和独特的优势,旨在为用户提供更加便捷、高效的信息服务。 首先,我能够处理和理解多种格式的文件,包括TXT、PDF、Word文档、PPT幻灯片和Excel电子表格等。这意味着用户可以轻松地将他们需要的信息以文件的形式发送给我,而我则能够迅速地阅读和分析这些内容,从而为用户提供他们所需的信息。无论是进行数据分析、提取关键信息还是解答具体问题,我都能够提供准确且及时的反馈。 此外,我还具备访问互联网的能力,这让我能够获取最新的信息和数据,以便为用户提供最准确的答案。无论是时事新闻、科技动态还是学术研究,我都能够通过搜索功能,快速地找到相关的信息,并结合用户的问题给出详尽的回答。 我始终遵循着用户的指令,尽我所能地去完成用户的指令。我理解到,用户的需求是多样化的,因此我始终致力于提供丰富、详尽且有帮助的回答。同时,我也意识到,作为一个智能助手,我必须遵守相关的法律法规和社会道德标准。"""
prompt_2000prompt_2000 = """大模型,全称为大规模预训练模型,是人工智能领域中的一种重要技术,尤其在自然语言处理(NLP)和计算机视觉(CV)等方向有着广泛的应用。大模型的出现,极大地推动了AI技术的发展,使得机器能够更好地理解和生成人类语言,甚至在某些任务上超越了人类的表现。下面,我将从大模型的定义、发展历程、工作原理、应用领域以及未来趋势等方面进行详细介绍。

一、大模型的定义

大模型,顾名思义,是指模型参数量非常大的机器学习模型。这些模型通常由数十亿甚至数百亿个参数组成,远超传统的人工智能模型。这些参数是在大量的无标注数据上通过预训练得到的,目的是学习到数据中的通用知识和模式,以便在后续的特定任务上进行微调,从而达到更好的性能。

二、大模型的发展历程

  1. 早期阶段:在深度学习兴起之前,人工智能模型的规模相对较小,如SVM、决策树等。随着深度学习的出现,模型的规模开始增大,如AlexNet、VGG、ResNet等在计算机视觉领域的模型,以及RNN、LSTM等在自然语言处理领域的模型。

  2. 预训练模型阶段:2018年,Google推出了BERT(Bidirectional Encoder Representations from Transformers),这是一个基于Transformer架构的预训练模型,其规模已经达到了数亿参数。BERT的出现,开启了预训练模型的新篇章,它在多项NLP任务上取得了显著的性能提升。

  3. 大规模预训练模型阶段:2020年,OpenAI发布了GPT-3(Generative Pre-training Transformer 3),模型参数量达到了1750亿,这是当时最大的预训练模型。随后,阿里云的Qwen、百度的ERNIE、华为的鹏城-盘古、阿里云的M6等国内大厂也纷纷推出自己的大模型,参数量不断刷新纪录。

三、大模型的工作原理

大模型的核心是Transformer架构,这是一种自注意力机制,可以并行处理输入序列,解决了RNN等模型的序列依赖问题,大大提高了训练效率。在预训练阶段,大模型通过无监督学习的方式,如 masked language modeling 和 next sentence prediction 等任务,学习语言的内在规律和模式。在微调阶段,根据具体任务,如文本分类、问答系统、机器翻译等,对预训练模型进行针对性的训练,使其适应特定场景。

四、大模型的应用领域

  1. 自然语言处理:大模型在文本生成、问答系统、情感分析、机器翻译、对话系统等领域有广泛应用。例如,GPT-3可以生成连贯、有逻辑的文本,甚至可以进行简单的编程。

  2. 计算机视觉:大模型也可以应用于图像识别、目标检测、图像生成等任务,如ViT(Vision Transformer)就是将Transformer应用于CV领域的成功案例。

  3. 跨模态学习:大模型可以同时理解文本和图像信息,实现跨模态的交互和理解,如CLIP(Contrastive Language-Image Pre-training)模型。

  4. 其他领域:大模型还可以应用于语音识别、推荐系统、生物信息学、物理模拟等多个领域。

五、大模型的挑战与未来趋势

尽管大模型带来了显著的性能提升,但也面临着一些挑战,如计算资源需求巨大、训练和推理效率低、泛化能力有限、可解释性差等。因此,未来的趋势可能会是:

  1. 模型压缩与量化:通过模型剪枝、知识蒸馏等方法,减少模型大小,提高推理效率。

  2. 能效优化:研发更高效的硬件和算法,降低大模型的能耗。

  3. 强化学习与元学习:通过强化学习和元学习,使模型能更快地适应新任务,提高泛化能力。

  4. 可解释性研究:提高模型的可解释性,增强人机交互的信任度。

  5. 多模态与跨模态学习:结合不同类型的输入信息,提升模型的理解和生成能力。

总的来说,大模型是人工智能发展的重要里程碑,它不仅推动了技术的进步,也为我们的生活带来了诸多便利。随着技术的不断迭代和优化,我们有理由相信,大模型将在未来发挥更大的作用,为人类社会创造更多的价值。”””

Qwen1.5-72B-Chat

4卡,vllm,4096最大长度

启动方式

1
CUDA_VISIBLE_DEVICES=1,2,3,4 python -m vllm.entrypoints.openai.api_server --served-model-name Qwen1.5-72B-Chat --port 8991  --model /models/Qwen1.5-72B-Chat --tensor-parallel-size 4 --max-model-len 4096 --gpu-memory-utilization 0.75

4卡,4096最大长度,vllm,2000输入,512输出,并发分别为1,40,256

1、测试结果(2000输入,512输出,1并发),时间单位/秒,22.8 tokens/s

  • 前五个请求的第一个token返回时间:0.574028
  • response_start_time_average: 0.574028
  • 前五个请求的最后一个token返回时间:13.375516
  • response_end_time_average: 13.375516

2、测试结果(2000输入,512输出,40并发),时间单位/秒

  • 前五个请求的第一个token返回时间:1.063959, 1.082008, 2.742584, 2.750586, 2.76558
  • response_start_time_average: 11.415306750000001
  • 前五个请求的最后一个token返回时间:46.19368, 47.478858, 47.488864, 47.599811, 50.408245
  • response_end_time_average: 58.81113555

3、测试结果(2000输入,512输出,256并发),时间单位/秒

  • 前五个请求的第一个token返回时间:0.978002, 1.022001, 2.725005, 2.777001, 2.788007
  • response_start_time_average: 176.60942325390624
  • 前五个请求的最后一个token返回时间:42.569945, 43.109365, 43.950199, 44.987483, 47.045394
  • response_end_time_average: 225.57635427734368

4卡,vllm,32768最大长度

启动方式

1
CUDA_VISIBLE_DEVICES=1,2,3,4 python -m vllm.entrypoints.openai.api_server --served-model-name Qwen1.5-72B-Chat --port 8991  --model /models/Qwen1.5-72B-Chat --tensor-parallel-size 4 --max-model-len 32768 --gpu-memory-utilization 0.75

4卡,32768最大长度,vllm,2000输入,512输出,并发分别为1,40,256

1、测试结果(2000输入,512输出,1并发),时间单位/秒,22.2 tokens/s

  • 前五个请求的第一个token返回时间:0.599894
  • response_start_time_average: 0.599894
  • 前五个请求的最后一个token返回时间:14.133368
  • response_end_time_average: 14.133368

2、测试结果(2000输入,512输出,40并发),时间单位/秒,前三条速度很快

  • 前五个请求的第一个token返回时间:1.450993, 1.457002, 1.462003, 14.920011, 14.921026
  • response_start_time_average: 18.555341225
  • 前五个请求的最后一个token返回时间:43.130326, 43.76127, 44.728032, 45.359908, 45.954806
  • response_end_time_average: 58.34559765

3、测试结果(2000输入,512输出,256并发),时间单位/秒,前一条速度很快

  • 前五个请求的第一个token返回时间:0.570004, 14.766113, 14.812125, 14.818117, 14.825118
  • response_start_time_average: 185.39021865234378
  • 前五个请求的最后一个token返回时间:39.982682, 40.008683, 41.408154, 41.464129, 41.47612
  • response_end_time_average: 230.58626417968762

结论:官方vllm的max_model_len不影响单并发、256并发,40并发耗时提升约50%。


4卡,私有化封装,4096最大长度

启动方式

1
CUDA_VISIBLE_DEVICES=1,2,3,4 python ./service/foundation_model/qwen_chat.py --port 8991  --model /models/Qwen1.5-72B-Chat --tensor_parallel_size 4 --max_model_len 4096 --gpu_memory_utilization 0.75

4卡,4096最大长度,vllm,2000输入,512输出,并发分别为1,40,256

1、测试结果(2000输入,512输出,1并发),时间单位/秒,24.2 tokens/s

  • 第一个请求的第一个token返回时间:0.882857
  • response_start_time_average: 0.882857
  • 第一个请求的最后一个token返回时间:13.175237
  • response_end_time_average: 13.175237

2、测试结果(2000输入,512输出,40并发),时间单位/秒

  • 前五个请求的第一个token返回时间:15.693883, 15.658891, 15.636887, 15.717891, 15.641887
  • response_start_time_average: 22.158714125000003
  • 前五个请求的最后一个token返回时间:38.990434, 42.371323, 48.083964, 49.15638, 50.4055
  • response_end_time_average: 69.001847975

3、测试结果(2000输入,512输出,256并发),时间单位/秒

  • 前五个请求的第一个token返回时间:15.8075, 15.815497, 15.804504, 15.800505, 15.841502
  • response_start_time_average: 243.73916464062512
  • 前五个请求的最后一个token返回时间:39.602129, 44.075711, 50.699566, 51.167524, 52.672676
  • response_end_time_average: 302.3232604140626

4卡,私有化封装,32768最大长度

启动方式

1
CUDA_VISIBLE_DEVICES=1,2,3,4 python ./service/foundation_model/qwen_chat.py --port 8991  --model /models/Qwen1.5-72B-Chat --tensor_parallel_size 4 --max_model_len 32768 --gpu_memory_utilization 0.75

4卡,32768最大长度,vllm,2000输入,512输出,并发分别为1,40,256

1、测试结果(2000输入,512输出,1并发),时间单位/秒

  • 第一个请求的第一个token返回时间:0.922553
  • response_start_time_average: 0.922553
  • 第一个请求的最后一个token返回时间:13.325315
  • response_end_time_average: 13.325315

2、测试结果(2000输入,512输出,40并发)

  • 前五个请求的第一个token返回时间:15.799517, 15.808511, 15.864479, 15.889488, 15.886475
  • response_start_time_average: 22.247778274999995
  • 前五个请求的最后一个token返回时间:42.416026, 43.562881, 47.233508, 50.159447, 51.210282
  • response_end_time_average: 68.37788262499998

3、测试结果(2000输入,512输出,256并发)

  • 前五个请求的第一个token返回时间:15.854161, 15.808154, 15.794163, 15.827147, 15.81914
  • response_start_time_average: 247.9474947460937
  • 前五个请求的最后一个token返回时间:39.903629, 39.911628, 44.407305, 45.926388, 48.999993
  • response_end_time_average: 307.88330739843764

结论:私有化封装的max_model_len不影响模型第一个token时间和总返回时间

Qwen1.5-110B-Chat

4卡,vllm,4096最大长度

启动方式

1
CUDA_VISIBLE_DEVICES=1,2,3,4 python -m vllm.entrypoints.openai.api_server --served-model-name Qwen1.5-110B-Chat --port 8991  --model /models/Qwen1.5-110B-Chat --tensor-parallel-size 4 --max-model-len 4096 --gpu-memory-utilization 0.77

4卡,4096最大长度,vllm,2000输入,512输出,并发分别为1,40,256

1、测试结果(2000输入,512输出,1并发),时间单位/秒, 19.2 tokens/s

  • 前五个请求的第一个token返回时间:0.74063
  • response_start_time_average: 0.74063
  • 前五个请求的最后一个token返回时间:11.913654
  • response_end_time_average: 11.913654

2、测试结果(2000输入,512输出,40并发),时间单位/秒

  • 前五个请求的第一个token返回时间:1.199546, 1.208588, 3.15569, 3.185673, 3.198662
  • response_start_time_average: 11.030676525
  • 前五个请求的最后一个token返回时间:32.920417, 32.989418, 33.024932, 33.081456, 33.1034
  • response_end_time_average: 38.37808929999999

3、测试结果(2000输入,512输出,256并发),时间单位/秒

  • 前五个请求的第一个token返回时间:1.654987, 1.66899, 1.673998, 3.627005, 3.637012
  • response_start_time_average: 102.93876760546877
  • 前五个请求的最后一个token返回时间:56.828779, 57.16778, 57.170783, 57.268787, 57.28578
  • response_end_time_average: 163.7370169765626

4卡,vllm,32768最大长度

启动方式

1
CUDA_VISIBLE_DEVICES=1,2,3,4 python -m vllm.entrypoints.openai.api_server --served-model-name Qwen1.5-110B-Chat --port 8991  --model /models/Qwen1.5-110B-Chat --tensor-parallel-size 4 --max-model-len 32768 --gpu-memory-utilization 0.77

4卡,32768最大长度,vllm,2000输入,512输出,并发分别为1,40,256

1、测试结果(2000输入,512输出,1并发),时间单位/秒, 19.2 tokens/s

  • 前五个请求的第一个token返回时间:0.619865
  • response_start_time_average: 0.619865
  • 前五个请求的最后一个token返回时间:11.570689
  • response_end_time_average: 11.570689

2、测试结果(2000输入,512输出,40并发),时间单位/秒

  • 前五个请求的第一个token返回时间:2.586619, 2.592628, 2.628583, 2.638603, 2.64161
  • response_start_time_average: 17.967369324999996
  • 前五个请求的最后一个token返回时间:33.563753, 33.593744, 33.645755, 35.529838, 36.181372
  • response_end_time_average: 43.930624974999986

3、测试结果(2000输入,512输出,256并发),时间单位/秒

  • 前五个请求的第一个token返回时间:1.643004, 1.650005, 1.656999, 19.021139, 19.027133
  • response_start_time_average: 138.04490729687504
  • 前五个请求的最后一个token返回时间:33.551216, 34.284966, 34.350958, 35.618316, 35.664315
  • response_end_time_average: 176.71878233984376

结论:官方vllm的max_model_len不影响单并发、256并发,40并发耗时提升约50%。


4卡,私有化封装,4096最大长度

启动方式

1
CUDA_VISIBLE_DEVICES=1,2,3,4 python ./service/foundation_model/qwen_chat.py --port 8991  --model /models/Qwen1.5-110B-Chat --tensor_parallel_size 4 --max_model_len 4096 --gpu_memory_utilization 0.77

4卡,4096最大长度,vllm,2000输入,512输出,并发分别为1,40,256

1、测试结果(2000输入,512输出,1并发),时间单位/秒,18.1 tokens/s

  • 第一个请求的第一个token返回时间:0.960181
  • response_start_time_average: 0.960181
  • 第一个请求的最后一个token返回时间:12.841381
  • response_end_time_average: 12.841381

2、测试结果(2000输入,512输出,40并发),时间单位/秒

  • 前五个请求的第一个token返回时间:20.951468, 20.975463, 20.944461, 20.919458, 20.95246
  • response_start_time_average: 20.96528225
  • 前五个请求的最后一个token返回时间:50.763612, 50.841614, 51.566975, 52.587483, 52.943488
  • response_end_time_average: 59.514841925000006

3、测试结果(2000输入,512输出,256并发),时间单位/秒

  • 前五个请求的第一个token返回时间:41.775744, 41.709742, 41.854731, 41.972718
  • response_start_time_average: 161.60969656250018
  • 前五个请求的最后一个token返回时间:75.101425, 80.340986, 85.438611, 85.318608, 85.582627
  • response_end_time_average: 253.64892319531225

4卡,私有化封装,32768最大长度

启动方式

1
CUDA_VISIBLE_DEVICES=1,2,3,4 python ./service/foundation_model/qwen_chat.py --port 8991  --model /models/Qwen1.5-110B-Chat --tensor_parallel_size 4 --max_model_len 32768 --gpu_memory_utilization 0.77

4卡,32768最大长度,vllm,2000输入,512输出,并发分别为1,40,256

1、测试结果(2000输入,512输出,1并发),时间单位/秒,18.4 tokens/s

  • 第一个请求的第一个token返回时间:1.003635
  • response_start_time_average: 1.003635
  • 第一个请求的最后一个token返回时间:14.044728
  • response_end_time_average: 14.044728

2、测试结果(2000输入,512输出,40并发)

  • 前五个请求的第一个token返回时间:21.403267, 21.374292, 21.389297, 21.437257, 21.37728
  • response_start_time_average: 21.403976375000003
  • 前五个请求的最后一个token返回时间:42.717535, 48.127041, 51.04268, 51.058684, 53.334163
  • response_end_time_average: 62.728350625

3、测试结果(2000输入,512输出,256并发)

  • 前五个请求的第一个token返回时间:21.36488, 21.360869, 21.444868, 21.343875, 21.427845
  • response_start_time_average: 206.9659326757812
  • 前五个请求的最后一个token返回时间:48.675407, 50.051908, 50.1279, 51.756788, 54.681915
  • response_end_time_average: 264.7068086835935

结论:私有化封装的max_model_len不影响模型第一个token时间和总返回时间

ChatGLM

ChatGLM2-6B

1卡,HF,8192最大长度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# -*- coding: utf-8 -*-
# @Time : 2023/9/6
# @Author : gkm0120
# @File : test_glm2_api.py
# @Software: PyCharm
import json
import os
import sys

import uvicorn
from fastapi import FastAPI
from loguru import logger
from torch.cuda import empty_cache, ipc_collect, is_available
from transformers import AutoTokenizer, AutoModel

project_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
sys.path.insert(0, project_path)

from config.message import ChatRequest
from config.paths import chatglm2_6b_model_path
from utils.time_util import time_it
from utils.multi_gpus_util import load_model_on_gpus


def load_model(model_path):
"""
多GPU策略加载模型
:param model_path:
:return:
"""
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
if is_available():
logger.info("loading chat model on GPU")
model = load_model_on_gpus(model_path, num_gpus=3)
logger.info("GPU加载模型完毕")
else:
logger.info("loading chat model on CPU")
model = AutoModel.from_pretrained(model_path, trust_remote_code=True).float()
logger.info("CPU加载模型完毕")
model.eval()
return tokenizer, model


class Chat:
@time_it
def __init__(self):
pass

@time_it
def answer(self, conversation, tokenizer, model, history, temperature, max_length, top_p):
"""
:param top_p: 解码阶段的解码策略。根据候选项可能性得分之和达到阈值p,来选择候选项的个数
:param max_length: 生成文本token最大长度
:param temperature: 模型预测的字符概率。temperature 越大,则新的概率分布越均匀,随机性也就越大
:param history: 历史记录
:param conversation: 用户查询语句query
:param tokenizer: 分词器。如chatglm2-6b使用SentencePiece方法
:param model: 语言模型,如chatglm2-6b
:return:
"""
response, history = model.chat(tokenizer,
conversation,
temperature=temperature,
max_length=max_length,
top_p=top_p,
history=history)
# 释放显存
empty_cache()
ipc_collect()
return response

@time_it
def answer_generator(self, conversation, history, tokenizer, model):
"""
:param conversation:
:param history:
:param tokenizer:
:param model:
:return:
"""
streams = model.stream_chat(tokenizer,
conversation,
history=history)
return streams


# 初始化fastapi
chat_app = FastAPI()

# 初始化云谷小智
# os.environ['CUDA_VISIBLE_DEVICES'] = '3,4,5'
zoomlion_tokenizer, zoomlion_model = load_model(chatglm2_6b_model_path)
zoomlion_chat = Chat()

logger.info(zoomlion_chat.answer(conversation="你是谁啊",
tokenizer=zoomlion_tokenizer,
model=zoomlion_model,
history=[],
temperature=0.8,
max_length=8192,
top_p=0.8))


@chat_app.post("/chat/")
def chat(request: ChatRequest):
ans = None
state = True
try:
request = json.loads(request.json())
prompt = request.get("prompt")
temperature = request.get("temperature")
history = request.get("history")
max_length = request.get("max_length")
top_p = request.get("top_p")
logger.info("Receive message: {} ".format(prompt))

ans = zoomlion_chat.answer(conversation=prompt,
tokenizer=zoomlion_tokenizer,
model=zoomlion_model,
history=history,
temperature=temperature,
max_length=max_length,
top_p=top_p)
logger.info("Sending message: {}".format(ans))
except Exception as e:
state = False
logger.error(e)
return {
"state": state,
"response": ans
}


def start_chat_service(args):
"""
:param args:
:return:
"""
uvicorn.run("test_glm2_api:chat_app",
host=args.host,
port=int(args.port),
workers=int(args.workers),
debug=True)


if __name__ == "__main__":
"""
nohup python test_glm2_api.py &
"""
# "不要使用test_glm2_api:chat_app,否则源文件会再执行一遍"
# http://10.103.190.9:9001/chat
uvicorn.run(app="test_glm2_api:chat_app",
host="0.0.0.0",
port=9001,
workers=2)

1卡,vllm,8192最大长度

chatglm2-6b 100个请求并发测试(调用接口)
测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import concurrent.futures
import json
from datetime import datetime

import requests

# 目标 POST 接口的 URL
url = "http://10.103.190.9:9001/chat"
# 要发送的 POST 数据
data = json.dumps({
"prompt": "晚上睡不着应该怎么办",
"temperature": 0.8,
"history": [],
"max_length": 8192,
"top_p": 0.8
})

headers = {
'Content-Type': 'application/json'
}


# 定义一个函数,用于发送 POST 请求
def send_post_request(url, data):
try:
response = requests.post(url, headers=headers, data=data)
print(response.text)
# 如果需要,你可以在这里处理响应内容
# 例如,打印响应状态码:print(response.status_code)
except Exception as e:
# 处理请求过程中的异常
print(f"Exception: {e}")


# 定义一个函数,用于执行并发任务
def run_concurrent_requests(num_requests):
start_time = datetime.now()
with concurrent.futures.ThreadPoolExecutor() as executor:
# 启动并发任务
futures = [executor.submit(send_post_request, url, data) for _ in range(num_requests)]
# 等待所有任务完成
concurrent.futures.wait(futures)

end_time = datetime.now()
print("end_time - start_time: {}".format(end_time - start_time))


if __name__ == "__main__":
# 指定并发请求数量
num_concurrent_requests = 100
# 运行并发请求
run_concurrent_requests(num_concurrent_requests)

测试结果:发送100个请求后,1236秒后请求全部结束,后台日志截图如下:

测试结果日志

chatglm2-6b 100个请求并发测试(vllm部署)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from datetime import datetime
from vllm import LLM, SamplingParams


def build_prompt(prompt_):
return "[Round 1]\n\n问:{}\n\n答:".format(prompt_)


prompts = [
"晚上睡不着应该怎么办"
] * 100
prompts = [build_prompt(item) for item in prompts]
# edit this model_url
model_url = '/mnt/lustre/share/test_train/young/knowledge_extraction/models/chatglm2-6b'

sampling_params = SamplingParams(temperature=0.8, top_p=0.95, max_tokens=8192)

llm = LLM(model=model_url,
tensor_parallel_size=1,
trust_remote_control=True,
dtype="float16",
gpu_memory_utilization=0.6)
start_time = datetime.now()
outputs = llm.generate(prompts, sampling_params)

# Print the outputs.
for output in outputs:
prompt = output.prompt
generated_text = output.outputs[0].text
# print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
end_time = datetime.now()
print("end_time - start_time: {}".format(end_time - start_time))

100个请求耗时37秒左右

vllm测试结果

测试结论:并发性能提升(类比):1236/37 = 33.41倍

ChatGLM3-6B

1卡,HF,8192最大长度

chatglm3-6b接口调用方式与chatglm2-6b保持一致

1卡,vllm,8192最大长度

vllm部署方式如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from datetime import datetime
from vllm import LLM, SamplingParams

prompts = ["""<|system|>
You are ChatGLM3, a large language model trained by Zhipu.AI. Follow the user's instructions carefully. Respond using markdown.
<|user|>
晚上睡不着应该怎么办
<|assistant|>
"""]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95, max_tokens=512)

llm = LLM(model="/mnt/lustre/data/chatglm3-6b",
tensor_parallel_size=1,
trust_remote_code=True,
dtype="float16",
gpu_memory_utilization=0.4)
output_ = llm.generate(prompts, sampling_params)

prompts = prompts * 500
start_time = datetime.now()
outputs = llm.generate(prompts, sampling_params)

# Print the outputs.
for output in outputs:
prompt = output.prompt
generated_text = output.outputs[0].text
# print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
print(f"Generated text: {generated_text!r}")
end_time = datetime.now()
print("end_time - start_time: {}".format(end_time - start_time))

100个请求耗时39秒左右

本文结束 感谢您的阅读