公司网络是有严格限制,所有涉及境外服务器的网站都无法访问,包括docker等镜像源。本教程,是在提前下载或构建好资源,通过上传到服务器后,做离线部署。
途径很多,比如github、huggface、modelscope等,就不多说了。
国内建议:https://modelscope.cn/search?search=Qwen2.5-VL
这个脚本,不管是在什么环境部署都一样,主要关注的是VLLM版本。不同版本参数会有差异。
#!/bin/bash
echo "###########start vl by vllm...##########"
export GLOO_SOCKET_IFNAME="enp210s0f0"
export CUDA_VISIBLE_DEVICES="1,2"
export VLLM_LOGGING_LEVEL="DEBUG"
export VLLM_ATTENTION_BACKEND="FLASH_ATTN"
vllm serve /model/Qwen2.5-VL-7B-Instruct \
--gpu-memory-utilization 0.8 \
--dtype auto \
--host 0.0.0.0 \
--port 7860 \
--tensor-parallel-size 2 \
--kv-cache-dtype fp8 \
--max-model-len 10000 \
--limit-mm-per-prompt mage=4,video=1 \
--api-key yourkey \
脚本注释如下:
我们用的7B的模型,理论上24G显存卡就够了,可是单卡或多卡依然报显存不足。核心原因是gpu_memory_utilization设置太大了,导致给kv缓存的不够预分配。所以要配合max_model_len一起设置,显存利用率设置低一些,那上下文长度就能大一些。
显存不足的根本原因举例:
• 日志显示总GPU内存为23.50GiB,已使用率95%(约22.32GiB可用)。
• 模型权重占用15.63GiB,KV缓存预留5.95GiB,理论上总和为21.58GiB,但实际初始化时仍出现显存溢出。
• 可能原因:KV缓存预估不准确、图捕获(cudagraph)过程额外占用内存,或模型加载存在内存碎片。
关键错误日志:
ERROR 03-14 02:13:07 engine.py:389] CUDA error: out of memory
RuntimeError: CUDA error: out of memory
这表明在初始化KV缓存或捕获CUDA图时,显存分配失败。
降低GPU内存利用率
修改启动参数,减少显存占用:
--gpu_memory_utilization 0.8 # 从0.95降至0.8,释放更多显存
减少KV缓存大小
通过以下参数降低KV缓存需求:
--max_num_seqs 128 # 减少并发序列数
--max_model_len 2048 # 减少模型上下文长度(需平衡性能与需求)
关闭图捕获(Cudagraph)
在显存紧张时,禁用图捕获以降低内存占用:
--enforce_eager=True # 强制启用Eager模式,禁用Cudagraph
优化模型加载
确保模型路径正确且无损坏,尝试重新下载或加载模型:
--download_dir /path/to/cache # 指定缓存目录,避免重复下载
调整批处理参数
降低单次请求的批处理大小:
--max_batch_size 1 # 单次仅处理一个请求
确保模型没bug,模型搭配的py文件在处理张量逻辑时,也会卡bug。这个只能去找开源作者社区或关注更新。
NCCL通信卡住,直接超时或不动(最常见)。一般是显卡通信问题,使用以下命令查询显卡通信机制,以确认是否异常。一般来说可以尝试通过sys链接的两张卡测试看。
nvidia-smi topo -m
缩写 | 含义 | 典型场景 |
---|---|---|
X |
自身(Self) | GPU 内部环路 |
PXB |
PCIe x16 桥接(Direct PCIe Bridge) | 同一 PCIe 树下的 GPU 直接互联 |
SYS |
系统总线(System Bus) | 通过 CPU/主板 南桥间接连接 |
PIX |
PCIe 交换机(PCIe Switch) | 多 GPU 通过 PCIe 交换机互联 |
模型是多模态,可能不支持奇数或偶数颗显卡。比如qwen2.5-vl-7b,就只支持偶数张卡。
基于docker的话,里面都装好了各种底层和上程环境,我们只需要在宿主机上装好显卡驱动就行,一般版本是535+会比较合适。
拉取官方镜像,官方镜像只在hub.docker.com上(国内无法访问),目前基本国内镜像源都被封禁或关闭了,即使有遇到可以用的镜像源,一样不可能是最新版本,会存在各种问题。
以下是我的版本(digest:d082165a6bc5):
docker pull qwenllm/qwenvl:2.5-cu121
本人已通过设法拉取了该镜像,当前通过docker打包成了tar文件,可直接下载后,通过docker命令导入。 下载的文件名为:qwenvl25_cu121_20250312.tar,导入方案如下:
# 用docker把tar导入到镜像
docker load -i ./qwenvl25_cu121_20250312.tar
# 查看是否导入成功,导入后是这个哈:qwenllm/qwenvl:2.5-cu121
docker images | grep qwen
【点此下载压缩包,资源托管与制作不易!】
【下载有问题可以CSDN私信本人,工作日回复】
【按此方案的,可直接参考第5节简约全流程更直观】
root@gpu2:/data/shared/Qwen# pip list
Package Version
--------------------------------- ---------------------
accelerate 1.3.0
aiofiles 23.2.1
aiohappyeyeballs 2.4.4
aiohttp 3.11.12
aiohttp-cors 0.7.0
aiosignal 1.3.2
airportsdata 20241001
annotated-types 0.7.0
anyio 4.8.0
astor 0.8.1
async-timeout 5.0.1
attrs 25.1.0
av 14.1.0
blake3 1.0.4
blinker 1.4
cachetools 5.5.1
certifi 2025.1.31
charset-normalizer 3.4.1
click 8.1.8
cloudpickle 3.1.1
colorful 0.5.6
compressed-tensors 0.9.1
cryptography 3.4.8
dbus-python 1.2.18
depyf 0.18.0
dill 0.3.9
diskcache 5.6.3
distlib 0.3.9
distro 1.7.0
einops 0.8.0
exceptiongroup 1.2.2
fastapi 0.115.8
ffmpy 0.5.0
filelock 3.17.0
flash-attn 2.7.2.post1
frozenlist 1.5.0
fsspec 2024.6.1
gguf 0.10.0
google-api-core 2.24.1
google-auth 2.38.0
googleapis-common-protos 1.66.0
gradio 5.4.0
gradio_client 1.4.2
grpcio 1.70.0
h11 0.14.0
httpcore 1.0.7
httplib2 0.20.2
httptools 0.6.4
httpx 0.28.1
huggingface-hub 0.28.1
idna 3.10
importlib-metadata 4.6.4
iniconfig 2.0.0
interegular 0.3.3
jeepney 0.7.1
Jinja2 3.1.4
jiter 0.8.2
jsonschema 4.23.0
jsonschema-specifications 2024.10.1
keyring 23.5.0
lark 1.2.2
launchpadlib 1.10.16
lazr.restfulclient 0.14.4
lazr.uri 1.0.6
lm-format-enforcer 0.10.9
markdown-it-py 3.0.0
MarkupSafe 2.1.5
mdurl 0.1.2
mistral_common 1.5.2
more-itertools 8.10.0
mpmath 1.3.0
msgpack 1.1.0
msgspec 0.19.0
multidict 6.1.0
nest-asyncio 1.6.0
networkx 3.1
numpy 1.26.4
nvidia-cublas-cu12 12.1.3.1
nvidia-cuda-cupti-cu12 12.1.105
nvidia-cuda-nvrtc-cu12 12.1.105
nvidia-cuda-runtime-cu12 12.1.105
nvidia-cudnn-cu12 9.1.0.70
nvidia-cufft-cu12 11.0.2.54
nvidia-curand-cu12 10.3.2.106
nvidia-cusolver-cu12 11.4.5.107
nvidia-cusparse-cu12 12.1.0.106
nvidia-ml-py 12.570.86
nvidia-nccl-cu12 2.21.5
nvidia-nvjitlink-cu12 12.1.105
nvidia-nvtx-cu12 12.1.105
oauthlib 3.2.0
openai 1.61.1
opencensus 0.11.4
opencensus-context 0.1.3
opencv-python-headless 4.11.0.86
orjson 3.10.15
outlines 0.1.11
outlines_core 0.1.26
packaging 24.2
pandas 2.2.3
partial-json-parser 0.2.1.1.post5
pillow 10.4.0
pip 22.0.2
platformdirs 4.3.6
pluggy 1.5.0
prometheus_client 0.21.1
prometheus-fastapi-instrumentator 7.0.2
propcache 0.2.1
proto-plus 1.26.0
protobuf 5.29.3
psutil 6.1.1
py-cpuinfo 9.0.0
py-spy 0.4.0
pyasn1 0.6.1
pyasn1_modules 0.4.1
pybind11 2.13.6
pycountry 24.6.1
pydantic 2.10.6
pydantic_core 2.27.2
pydub 0.25.1
Pygments 2.19.1
PyGObject 3.42.1
PyJWT 2.3.0
pyparsing 2.4.7
pytest 8.3.4
python-apt 2.4.0+ubuntu4
python-dateutil 2.9.0.post0
python-dotenv 1.0.1
python-multipart 0.0.12
pytz 2025.1
PyYAML 6.0.2
pyzmq 26.2.1
qwen-vl-utils 0.0.10
ray 2.42.0
referencing 0.36.2
regex 2024.11.6
requests 2.32.3
rich 13.9.4
rpds-py 0.22.3
rsa 4.9
ruff 0.9.5
safehttpx 0.1.6
safetensors 0.5.2
SecretStorage 3.3.1
semantic-version 2.10.0
sentencepiece 0.2.0
setuptools 59.6.0
setuptools-scm 8.1.0
shellingham 1.5.4
six 1.16.0
smart-open 7.1.0
sniffio 1.3.1
starlette 0.45.3
sympy 1.13.1
tiktoken 0.7.0
tokenizers 0.21.0
tomli 2.2.1
tomlkit 0.12.0
torch 2.5.1+cu121
torchaudio 2.5.1+cu121
torchvision 0.20.1+cu121
tqdm 4.67.1
transformers 4.49.0.dev0
transformers-stream-generator 0.0.4
triton 3.1.0
typer 0.15.1
typing_extensions 4.12.2
tzdata 2025.1
urllib3 2.3.0
uvicorn 0.34.0
uvloop 0.21.0
virtualenv 20.29.1
vllm 0.7.2.dev56+gbf3b79ef
wadllib 1.3.6
watchfiles 1.0.4
websockets 12.0
wheel 0.37.1
wrapt 1.17.2
xformers 0.0.28.post3
xgrammar 0.1.11
yarl 1.18.3
zipp 1.0.0
# 假设宿主机模型路径为/data/model/Qwen2.5-VL-7B-Instruct
# 假设宿主机启动脚本路径为:/data/model/qwen2_start.sh
# 83e0e4ecdfa2 这个是我的imageId哈,建议用镜像名qwenllm/qwenvl:2.5-cu121,就是docker image查到的。
# 启动命令, -v就是文件夹映射,端口自己改就行,要和启动脚本上的对应。
docker run -d -p 7860:7860 --gpus all \
--privileged \
--cpus="40" \
--memory="100g" \
-v /data/model/:/model \
--ipc=host \
--network=host \
--name qwen2.5 \
wenllm/qwenvl:2.5-cu121 \
bash -c "/model/qwen2_start.sh"
运行成功的日志如下(docker logs qwen2.5):
【python环境安装依赖多的包,如何避免错误后直接失败,请参考本人博客关于python环境包多依赖易失败的安装方案。】
重点是装python环境,不建议离线,因为依赖底层很麻烦。如果env要离线拷贝,也得相同cuda、内核、cpu、系统版本、GCC版本完全一致,才能拷贝打包到服务器后,能生效。
联网安装python环境步骤如下:
准备好环境后,直接运行qwen2.5_start.sh即可。
# 激活对应环境后。
chmod +x ./qwen2.5_start.sh
bash ./qwen2.5_start.sh
直接用python或类似大模型工具,填写请求即可,openai风格是V1,代码示例如下:
from openai import OpenAI
client = OpenAI(
base_url="http://192.168.111.23:7860/v1",
api_key="token-abc123",
)
model_type = client.models.list().data[0].id
print(f'model_type: {model_type}')
鉴于很开发者技术水平有限,下载环境后无法看出一些基础设置的调整,下面将“基于下载我提供的镜像服务”提供更细节的说明。
#用docker把tar导入到镜像
docker load -i ./qwenvl25_cu121_20250312.tar
# 查看是否导入成功,导入后是这个哈:qwenllm/qwenvl:2.5-cu121
docker images | grep qwen
docker run --gpus all --rm --name qwentest -it qwenllm/qwenvl:2.5-cu121 bash
#!/bin/bash
echo "###########start vl by vllm...##########"
# export GLOO_SOCKET_IFNAME="enp210s0f0"
export CUDA_VISIBLE_DEVICES="1,2"
export VLLM_LOGGING_LEVEL="DEBUG"
export VLLM_ATTENTION_BACKEND="FLASH_ATTN"
vllm serve /model/Qwen2.5-VL-7B-Instruct \
--gpu-memory-utilization 0.8 \
--dtype auto \
--host 0.0.0.0 \
--port 7860 \
--tensor-parallel-size 2 \
--kv-cache-dtype fp8 \
--max-model-len 10000 \
--limit-mm-per-prompt mage=4,video=1 \
--api-key token-abc123 \
特别注意:里面内容根据情况修改,比如显卡用哪几张、多网卡服务去需要绑定网卡、api-key应该设置成什么。chmod +x ./qwen2_start.sh
注意docker容器启动脚本情况:
端口是7860映射,要换其他端口,改前面那个数字(宿主机);
服务器 /data/model/映射到了容器内/model下,我们上一步的模型文件和脚本都在宿主机的 /data/model/下,也即在容器/model下,所以最底下执行的脚本路径如下:bash -c “/model/qwen2_start.sh”。
# 假设宿主机模型路径为/data/model/Qwen2.5-VL-7B-Instruct
# 假设宿主机启动脚本路径为:/data/model/qwen2_start.sh
# 83e0e4ecdfa2 这个是我的imageId哈,建议用镜像名qwenllm/qwenvl:2.5-cu121,就是docker image查到的。
# 启动命令, -v就是文件夹映射,端口自己改就行,要和启动脚本上的对应。
docker run -d -p 7860:7860 --gpus all \
--privileged \
-v /data/model/:/model \
--name qwen2.5 \
qwenllm/qwenvl:2.5-cu121 \
bash -c "/model/qwen2_start.sh"
启动后,我们查看docker执行日志看是否报错:docker logs --tail 100 qwen2.5
有报错的话,就检查下文件是否有问题,再看是否要修改qwen2_start.sh,搞好后重新docker restart进行排查。
如果报错和docker run 有关,那就删除容器,修改启动命令再重建容器。