vllm docker 部署 qwen3 5

模型与算力

给出用 Docker 起 vLLM 服务加载 Qwen 模型的实操步骤,从镜像选择、模型挂载到参数设置与常见报错排查一条线走完。

你大概遇到过这种情况:想用 vLLM 跑 Qwen,本地装依赖装到崩溃,CUDA、torch、vllm 版本互相打架。Docker 能把环境一次性隔离开,但镜像选哪个、模型权重怎么挂进去、启动参数写什么,网上说法又各不一样。这篇按排查顺序把这几步讲清楚,让你能自己起一个 OpenAI 兼容的服务,并且知道卡住时先看哪里。

你大概遇到过这种情况:想用 vLLM 跑 Qwen,本地装依赖装到崩溃,CUDA、torch、vllm 版本互相打架,重装一遍还未必能复现成功。Docker 的好处是把这套环境一次性隔离开,镜像里带什么就是什么,不会跟你宿主机的 Python 环境互相污染。

但换到 Docker 之后,问题只是从「装不上」变成「镜像选哪个、权重怎么挂进去、启动参数写什么」。网上说法各不一样,照抄一条命令很可能卡在加载阶段。这篇按排查顺序把这几步讲清楚,让你能自己起一个 OpenAI 兼容的服务,并且知道卡住时先看哪里。

开工前先对齐三件事:显卡、驱动、镜像

这一步不通,后面全是白费。先在宿主机上确认 NVIDIA 驱动能正常识别显卡,再确认容器运行时已经装好、能把 GPU 直通进容器。很多人卡在这里不是显卡不行,而是没装容器工具链,导致容器里看不到卡。

  1. 验宿主机在宿主机执行显卡状态查询,能看到卡型号和驱动版本才算过。看不到就先去修驱动,别往下走。
  2. 验容器直通随手起一个带 CUDA 的容器,进去再查一次显卡状态。宿主机能看到、容器里看不到,问题就在容器运行时没配对。
  3. 验镜像匹配把镜像里的 CUDA 版本和你要加载的模型权重对一下。别拿很老的镜像去跑新权重,也不要用太新的镜像配旧驱动,两头都会报错。
  4. 想清权重来源从模型库现拉,还是提前下好挂本地目录,先定下来。离线机器只能选后者,提前下好也更省事。

模型权重怎么拿到、放哪里

建议把权重落到宿主机一个固定目录,容器启动时做只读挂载。这样容器删了重建,权重还在原处,不用重新下一遍。目录名尽量固定,方便写进启动脚本,也方便以后换模型时对照。

权重目录里必须确认配置文件、分词器相关文件齐全。缺文件的时候,报错往往出现在模型加载阶段而不是容器启动阶段,日志里看着像启动失败,其实只是加载没读到东西,别一上来就怀疑镜像。

权重目录
放模型文件的宿主机路径,挂进容器后保持只读,避免误改
缓存目录
vLLM 编译和临时文件落盘的地方,单独挂出来能省下一次启动的等待
配置文件
描述模型结构的那份,缺了会直接加载失败
分词器文件
处理输入输出的那组,缺了可能服务能起但请求报错

不同 Qwen 系列的规格、许可证和能不能商用,别凭记忆判断。到站内模型资料库核对当时的说明,尤其是许可证那一栏,商用和非商用差别很大。

核对模型规格权重来源和许可证先查清楚,再动手拉,比拉完发现用不了省事

启动命令的结构:镜像、挂载、参数三段看

一条启动命令看着很长,其实拆成三段就清楚了:镜像是环境,挂载决定容器能看见宿主机什么,参数决定它怎么跑。排错时也可以按这三段定位,先确认镜像是哪个,再看挂载对不对,最后才调参数。

docker run -d \
  --gpus all \
  --shm-size 8g \
  -v /宿主机/权重目录:/models:ro \
  -v /宿主机/缓存目录:/cache \
  -p 8000:8000 \
  镜像名 \
  --model /models \
  --served-model-name 你的服务名 \
  --max-model-len 上下文长度 \
  --gpu-memory-utilization 显存占用比例
命令片段作用出错时的表现
--gpus all把 GPU 直通进容器容器里查不到卡,启动即失败
-v 权重挂载把宿主机模型目录映射进去参数写对也找不到模型,加载阶段报错
--shm-size给共享内存留空间高并发下报共享内存相关错误
--max-model-len限制上下文长度设太大直接显存不够起不来
--gpu-memory-utilization控制显存占用比例设太高会挤掉其他进程,设太低跑不满

参数里最容易把显存一次吃满的就是上下文长度和显存占用比例这两项。第一次跑建议都往保守里设,先让服务起来,再根据实际并发慢慢调。端口映射则要提前想好:只给自己本机调用,和要给局域网里其他机器调用,绑定的地址不一样。

起来之后怎么验证服务真的通了

容器起来不代表服务可用,按三层验:探活、格式、压力。第一层只确认端口通、接口活着;第二层确认返回结构是标准兼容格式,调用方不用改代码就能接;第三层才是压一压上下文长度参数是不是真的生效。

  • 先用一条最短的请求探活,看有没有正常返回,别一开始就灌长文本;
  • 再发一条稍长的输入,确认返回内容完整、没有被截断,说明上下文参数生效了;
  • 换一个和你实际用途接近的输入试一次,看输出质量是否符合预期;
  • 服务通了但速度不对劲时,用站内工具量个延迟基线,比凭感觉判断靠谱

速度慢不一定是模型的问题,也可能是首次加载在编译、也可能是并发参数没调好。量出基线之后再改参数,才知道改的是不是有效的那一项。要对比不同部署方式的延迟表现,到站内速度测试工具上跑一轮当时的数字。

量一下延迟基线先把基线记下来,之后调参才有参照,不然改完也不知道是变快还是变慢

常见卡点的排查顺序

报错信息很长,但先分大类能省一半时间:是容器根本没起来、是权重加载失败了、还是服务起来了但请求报错。这三类的排查方向完全不同,混在一起看日志只会越看越乱。

  1. 容器起不来先看容器日志末尾几行。多半是镜像不匹配、容器运行时没配对,或者端口被占用。换端口、换镜像各试一次就能区分。
  2. 权重加载失败回头确认挂载路径对不对、目录里配置文件齐不齐。路径写错是最常见的原因,日志里的报错信息通常会直接指出找不到哪个文件。
  3. 显存不够优先怀疑上下文长度和并发参数,把上下文长度调小重试,能起来就说明是参数问题,不是模型下错了。
  4. 请求报错但服务活着看请求体的字段名和返回结构对不对,格式不对和内容不对是两种报错,先分清是哪一种。
  5. 版本不兼容核对镜像里的 vLLM 版本和权重要求的版本是否对得上。对不上就换镜像,别在这个组合上继续试参数。

如果你后面打算把服务接到中转站或者自己搭网关转发,那选哪个上游、怎么比对可信度是另一个话题,和这次部署不是一回事。先把手里的服务起通、验证过,再考虑接出去。

部署这件事,先把最小可用的那一步跑通,再谈调优;顺序反了,问题会互相掩盖。

常见问题

Docker 起 vLLM 和直接 pip 装有什么区别?

Docker 主要省掉环境依赖的折腾,CUDA、torch、vLLM 的版本组合被固定在镜像里,不会因为你宿主机装过别的东西而冲突。代价是镜像体积大、改配置要重建或重挂。如果宿主机环境很干净、你也熟悉版本对应关系,直接装也能跑;一旦出现版本报错,换成容器通常更快脱身。

模型权重必须放在容器里吗?

不用,也不建议。把权重放宿主机目录、以只读方式挂进容器是常见做法,容器重建时不用重新下载,几份配置还能共用同一份权重。要注意的是挂载路径在容器内的位置要和启动参数里写的路径一致,路径写错最常见的表现是启动时报找不到配置文件,而不是提示权限问题。

服务起不来,应该从哪查起?

按这个顺序:先看容器有没有正常启动和退出码,再看日志里是加载阶段还是监听阶段出的错,最后才怀疑参数。加载阶段的错多半是权重文件不全或路径不对,监听阶段的错多半是端口被占或参数写错。显卡没直通进去的话,日志里通常会出现看不到设备的提示,这个信息比报错原文更有用。

本文依据各平台公开文档与官方公告整理,只做中文归纳;具体做法、参数与限制以官方文档为准。