0.前言
之前在使用ollama+qwen2.5:7b在搭建了一个基于CPU的测试大模型,使用起来感觉太过一般,allert-webhook做告警分析,单条就高达48s。正所谓要知道小龙虾的味道,就要亲口尝一尝,于是在云上租了一台GPU服务器,准备再次安装qwen2.5:7b大模型,并且使用VLLM做推理引擎,实测GPU服务器推理的效果,那么话不多说我们马上开始。
1.服务器准备
在网上找了下提供GPU服务器的云厂商,综合考虑后在AutoDL上租用了一台配置如下的服务器:
镜像 PyTorch 2.8.0 Python 3.12(ubuntu22.04) CUDA 12.8
GPU vGPU-32GB(32GB) * 1
CPU 16 vCPU Intel(R) Xeon(R) Platinum 8352V CPU @ 2.10GHz
内存 62GB
因为是测试qwen2.5:7b大模型,以上配置完全够用,如果大家还想测试别的大模型,可以根据需要租用。
注意:据我观察服务器是运行在容器当中的,追求极简,里面有许多依赖需要自行安装。
2.ollama和vLLM比较
在开始实验之前我们要先了解一下什么是ollama,什么是vLLM,二者之间有何区别。
2.1 ollama简介
Ollama 本质是 llama.cpp 的一层友好封装。它把模型下载、量化、运行时管理全包了,一句 ollama run qwen2.5:7b 就能在笔记本上跑起来。它对硬件极其宽容:纯 CPU 能跑(虽然慢),有 Metal / ROCm / CUDA 就自动加速。代价是——它的首要目标是「能跑、好用」,不是「跑得多快、扛多少并发」。
2.2 vLLM简介
vLLM 是伯克利搞的生产级推理引擎,招牌是 PagedAttention——把 KV Cache 当操作系统虚拟内存那样分页管理,几乎消灭显存碎片。它的默认假设是「你有 GPU,且要服务很多并发请求」。单请求延迟可能和别家差不多,但在高并发下吞吐能甩开一大截。
3.vLLM部署
既然是vLLM实验,当然要先部署vLLM引擎了,不过在那之前还得部署qwen2.5:7b大模型。
3.1 qwen2.5:7b部署
在GPU服务器上这次我们不用ollama部署大模型了,用更为传统的方法:modelscope,具体部署方式如下:
(1)安装modelscope命令
pip install modelscope -i https://pypi.tuna.tsinghua.edu.cn/simple
(2)部署大模型
modelscope download --model Qwen/Qwen2.5-7B-Instruct --local_dir /root/autodl-tmp/models/Qwen2.5-7B-Instruct
qwen2.5:7b大约有15GB,安装过程需要一点时间,可以喝杯咖啡耐心等待。 (3)模型检查
du -sh autodl-tmp/models/Qwen2.5-7B-Instruct/
输出信息如下:
15G autodl-tmp/models/Qwen2.5-7B-Instruct/
可以看到大模型安装成功,目录为autodl-tmp/models/Qwen2.5-7B-Instruct/ 到此,大模型安装完成。
3.2 vLLM引擎部署
vLLM是基于python开发,是一个比较重的python模块,推荐单独开通一个虚拟环境进行测试。 (1)创建环境
python3 -m venv vllm-env
(2)切到虚拟环境
source vllm-env/bin/activate
(3)安装vLLM模块
pip install vllm -i https://pypi.tuna.tsinghua.edu.cn/simple
(4)测试vLLM版本
python -c "import vllm; print(vllm.__version__)"
输出如下信息:
0.26.0
说明安装完成,vLLM版本是0.26.0。
4.vLLM测试
通过上述操作,我们已经成功部署了大模型和vLLM推理引擎,接下来就来看下推理引擎的功能和性能吧。
4.1 启动vLLM
首先需要启动vLLM引擎,命令如下:
python -m vllm.entrypoints.openai.api_server --model autodl-tmp/models/Qwen2.5-7B-Instruct/ --port 8000 --host 0.0.0.0
(APIServer pid=7362) INFO 08-14 16:27:02 [api_utils.py:345]
(APIServer pid=7362) INFO 08-14 16:27:02 [api_utils.py:345] █ █ █▄ ▄█
(APIServer pid=7362) INFO 08-14 16:27:02 [api_utils.py:345] ▄▄ ▄█ █ █ █ ▀▄▀ █ version 0.26.0
(APIServer pid=7362) INFO 08-14 16:27:02 [api_utils.py:345] █▄█▀ █ █ █ █ model autodl-tmp/models/Qwen2.5-7B-Instruct/
(APIServer pid=7362) INFO 08-14 16:27:02 [api_utils.py:345] ▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀ ▀
(APIServer pid=7362) INFO 08-14 16:27:02 [api_utils.py:345]
(APIServer pid=7362) INFO 08-14 16:27:02 [api_utils.py:273] non-default args: {'host': '0.0.0.0', 'model': 'autodl-tmp/models/Qwen2.5-7B-Instruct/'}
(APIServer pid=7362) INFO 08-14 16:27:02 [model.py:623] Resolved architecture: Qwen2ForCausalLM
(APIServer pid=7362) INFO 08-14 16:27:02 [model.py:1788] Using max model len 32768
(APIServer pid=7362) INFO 08-14 16:27:02 [vllm.py:1109] Asynchronous scheduling is enabled.
(APIServer pid=7362) INFO 08-14 16:27:02 [kernel.py:295] Final IR op priority after setting platform defaults: IrOpPriorityConfig(rms_norm=['native'], fused_add_rms_norm=['native']
..............
(APIServer pid=7362) INFO 08-14 16:27:41 [api_server.py:677] Starting vLLM server on http://0.0.0.0:8000
..............
看到"Starting vLLM server on http://0.0.0.0:8000" 字样,说明vLLM启动成功,就可以开始推理测试了。
4.2 调用vLLM
直接使用curl命令,就可以调用vLLM了,具体命令如下:
curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"autodl-tmp/models/Qwen2.5-7B-Instruct/","messages":[{"role":"user","content":"hello"}],"max_tokens":50}'
输出信息如下:
{"id":"chatcmpl-9d6d829005f1cd8d","object":"chat.completion","created":1786703191,"model":"autodl-tmp/models/Qwen2.5-7B-Instruct/","choices":[{"index":0,"message":{"role":"assistant","content":"Hello! How can I assist you today?","refusal":null,"annotations":null,"audio":null,"function_call":null,"reasoning":null},"logprobs":null,"finish_reason":"stop","stop_reason":null,"token_ids":null,"routed_experts":null}],"service_tier":null,"system_fingerprint":"vllm-0.26.0-cb087445","usage":{"prompt_tokens":30,"total_tokens":40,"completion_tokens":10,"prompt_tokens_details":null},"prompt_logprobs":null,"prompt_token_ids":null,"prompt_text":null,"kv_transfer_params":null,"ec_transfer_params":null,"metrics":null}
重点信息可以看"message"里面的"content":"Hello! How can I assist you today?",这个就是大模型的回复,收到正确的回答,说明vLLM部署成功,切可以正常访问,并且vLLM调用大模型也是正常的。
4.3 性能测试
vLLM已经可以正常访问了,接下来我们开始性能测试,准备两个脚本: (1)脚本1:
vim test1.sh
# 纯 shell 命令
echo "=== 单请求 ==="
for i in 1; do
curl -s http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"/root/autodl-tmp/models/Qwen2.5-7B-Instruct","messages":[{"role":"user","content":"Pod OOMKilled原因"}],"max_tokens":100}' \
-o /dev/null -w "%{time_total}\n"
done
echo "=== 并发3 ==="
for i in 1 2 3; do
curl -s http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"/root/autodl-tmp/models/Qwen2.5-7B-Instruct","messages":[{"role":"user","content":"Pod OOMKilled原因,50字"}],"max_tokens":100}' \
-o /dev/null -w "%{time_total}\n" &
done
wait
echo "=== 完毕 ==="
(2)脚本2:
vim test2.sh
# 纯 shell 版并发测试,零依赖
test_one() {
local t1 t2
t1=$(date +%s%N)
curl -s http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"/root/autodl-tmp/models/Qwen2.5-7B-Instruct","messages":[{"role":"user","content":"Pod OOMKilled原因,50字"}],"max_tokens":100}' \
-o /dev/null -w "%{time_total}\n"
}
echo "=== 并发10 ==="
for i in 1 2 3 4 5 6 7 8 9 10; do test_one & done
wait
echo "=== 完毕 ==="
阅读脚本可以看到是脚本功能是测试1并发,3并发,10并发 vLLM的执行时间。 (3)执行脚本1:
bash test1.sh
=== 单请求 ===
0.003869
=== 并发3 ===
0.004547
0.006266
0.006926
=== 完毕 ===
(4)执行脚本2:
bash test2.sh
=== 并发10 ===
0.007212
0.009932
0.012733
0.015430
0.018167
0.020891
0.023631
0.025152
0.026013
0.026142
=== 完毕 ===
可以看到单次请求和并发请求响应时间几乎一样,vLLM性能确实是杠杠的,基于原理我也在研究中,等我研究透彻也可以和大家分享探讨。
5.总结
经过一段时间的折腾,今天的测试就到此结束了,可以看到基于GPU服务器,千问2.5 7B大模型,再配合vLLM推理引擎,可以很好地测试大模型的性能,但其实现实生活中我们并不会直接把vLLM推理引擎给到模型训练师用,而是通过推理网关,目前推理网关正在开发优化中,等开发完成也会分享给大家,今天的测试就到这里了。
