你大概是在本地或测试机上试了 vLLM,命令敲半天,服务起来了但接口路径对不上、模型挂不进去、并发一上来就 OOM。这篇不聊原理,只按「拉镜像 — 挂模型 — 起服务 — 验接口 — 压一下」的顺序把每一步该核对什么讲清,顺带说明哪些情况下这条路不适合你,该换别的方案。
你大概是在本地或测试机上试了 vLLM,命令敲半天,服务起来了但接口路径对不上、模型挂不进去、并发一上来就 OOM。这篇不聊原理,只按「拉镜像 — 挂模型 — 起服务 — 验接口 — 压一下」的顺序,把每一步该核对什么讲清。
先给个预期:这不是一条傻瓜路线,它更接近「自己搭一台推理服务器」。好处是接口按 OpenAI 那套暴露,你现有的客户端代码基本不用改;代价是显存、路径、驱动这些细节全得你自己管。下面每个环节都给一个能验证的检查动作,别跳步。
先把镜像和模型目录这两件事对齐
镜像 tag 不要直接抄别人的命令。你要看的是自己这张卡支持到什么 CUDA 版本、驱动装到哪个版本,再回去挑对应的镜像。挑错了通常不是报一句友好错误,而是启动到一半挂掉,日志还很难读。另一个高频误区:镜像里一般不带权重,模型是你挂进去的,不是它自带的。
- 选 tag先确认宿主机驱动和 CUDA 能力,再对到镜像 tag;不确定就去站内页面查这套镜像当前的适用说明,别凭记忆写。
- 下权重把权重提前下到宿主机某个固定目录,下完核对目录里的文件数量和总大小,别下到一半就开始启动。
- 挂目录启动时用挂载参数把宿主目录映射进容器,容器内路径必须和启动命令里写的模型路径完全一致,差一层目录就是找不到模型。
- 看显卡加上显卡透传参数,进容器后自己跑一次看卡的命令,确认卡真的在里面;只传了设备没给权限是常见坑。
- 查权限模型目录的属主、读写权限和剩余磁盘空间都看一眼,这几项出问题时的报错往往和真实原因对不上。
起服务的参数按什么顺序定
参数别一次写全。先跑通一条最小的启动命令,服务能起来、能响应,再往上加调优项。最小集就几组:模型路径、监听地址与端口、每卡显存占用比例、最大上下文长度。顺序上先把前两组定死,后两组用保守值。
- 监听地址
- 写回环地址就只有本机能连;要让同事或应用连,得改成对外可访问的地址,同时想清楚这台机的网络边界。
- 显存占用比例
- 决定服务能占多少卡上显存,先给保守值把服务拉起来,再按实测往上调。
- 最大上下文长度
- 和显存此消彼长,开太大最容易在启动阶段直接崩,先用小值验证通路。
- 张量并行
- 多卡才用,填的卡数和实际卡数对不上会直接启动失败;单卡就别填这一项。
想加调优参数之前,先确认服务在最小配置下是稳定的——连续发几次请求都不报错,再动参数。改一次只改一个变量,否则出问题你不知道是哪个引起的。这套启动方式在单机、固定卡数、流量可预期的前提下够用;一旦你要多副本、要滚动发布,手动起容器的做法就开始变成负担。
按 OpenAI 兼容的方式把接口验通
服务默认就是按 OpenAI 那套路径暴露的,客户端把 base_url 指到你的服务地址就行,SDK 层面基本不用改代码。这里最容易踩的是模型名:以服务启动日志里报的那个名字为准,不是权重目录名,填错会直接返回找不到模型。
- 先用最简单的文本请求跑一次,确认能返回内容,再换对话格式试
- 接着试流式输出,这一环最容易暴露反向代理和网关的缓冲配置问题
- 把超时时间设得比你以为的宽松一点,冷启动或首个请求往往更慢
- 要接工具调用、多模态这类字段前,先确认兼容层到底覆盖了哪些端点,别默认全都原样支持
- 验证通过后把 base_url、模型名、超时这三项记下来交给调用方,少一次来回问
| 现象 | 先查什么 |
|---|---|
| 返回找不到模型 | 服务启动日志里的模型名,而不是目录名 |
| 连不上服务 | 监听地址是不是回环、端口有没有被防火墙挡 |
| 流式没有逐段返回 | 中间的代理是否开了缓冲,或超时设太短 |
| 启动阶段直接退出 | 最大上下文和显存占用比例是否给得太激进 |
| 卡不在容器里 | 显卡透传参数和容器权限 |
先把 base_url、模型名、超时这三件事对齐,接口对接的沟通成本能省掉一大半。
并发上来之后该看哪几个数
压之前先量基线。单请求的延迟和吞吐各是多少,先自己跑一遍链路,别一上来就堆并发。站内 /tools/speed-test 可以先拿来做一次链路自测,把这条链路上非模型部分的开销摘出去,再去调服务参数,不然你调的是网络不是模型。
- 量基线单请求跑若干次,记录延迟分布,别只看平均值。
- 找瓶颈真正决定并发上限的是显存里给 KV 缓存留的空间,先把显存占用比例调低、上下文调小,再看并发能不能起来。
- 定上限并发不是越高越好,排队请求的延迟会明显变差;按你能接受的最慢响应时间反推上限,而不是按卡的上限。
- 分实例长请求和短请求混在一起会互相拖累,必要时按请求类型拆成不同实例。
这套调法适用的前提是你能接受手工看指标、手工改参数。如果你需要的是自动扩缩容和高可用,那要看的就不是这几个数,而是编排层和网关的配置,方向不同。需要横向对比同类服务的大致表现,可以到 /rankings 看当时的榜单说明,注意榜单的口径和你自己的场景往往不一样。
什么情况下别用这条路
- 只是自己单机试玩、想一键拉模型开聊,这种场景用更轻量的本地工具更省事,这套复杂度换不来收益
- 需要多副本编排、弹性扩缩容、灰度发布,手动起容器撑不住,该上编排层和网关
- 团队里没人愿意维护镜像版本和卡上驱动,就别把生产链路挂上来,驱动不匹配会很难查
- 流量很小且长期稳定,专门的推理服务反而增加运维面,先评估是不是直接用托管接口更划算
- 对延迟要求极严且请求形态非常单一,可能需要的是针对场景做过优化的方案,而不是通用服务
判断标准其实就一条:你愿不愿意为「自己掌控推理服务」这件事持续付出运维成本。愿意,这条路很值;不愿意,早点换成托管接口或者更简单的本地方案。想先看看市面上有哪些中转和托管选择、各自的可信度怎么判断,可以去 /sites 按自己的场景筛一遍,再决定要不要自建。
下一步把你本机的卡、驱动和现有调用链记下来,先去站内核对当前适用的镜像与模型目录说明,再决定是自建还是走托管;对照着看能省掉不少试错时间。→常见问题
镜像里的模型名和我的目录名对不上,报模型不存在怎么办?
服务启动后会把它实际注册的模型名打进日志,客户端请求里填的是那个名字,不是权重目录名。先看启动日志确认,再改客户端。多模型或者带别名的情况下更容易混,所以每次换权重都回头看一眼日志。
容器启动了但看不到显卡,或者显存只有一点点?
通常是显卡透传参数没加、驱动和容器运行时的版本不匹配,或者宿主机的容器工具链没配好。先在宿主机上确认卡本身正常,再进容器里看一眼设备在不在,两层分开查,比对着报错猜快得多。
接口能通,但并发一上来就报显存不足,是少配了什么参数吗?
多半不是参数问题,而是显存预算和并发量本身不匹配。先把显存占用比例、最大上下文这些压下来,量出单实例的真实并发上限,再用多实例去堆。具体能撑多少,去站内 /models/deploy 按你的模型和卡算一遍再定。