vllm max_model_len设置

模型与算力

讲清 vLLM 里 max_model_len 到底控制什么、怎么按显存和实际输入长度取一个稳的值,以及设错时的报错排查顺序。

用 vLLM 起服务时,max_model_len 是最容易被随手填大的一个参数:填小了长文档直接被截断,填大了启动就 OOM,或者跑到一半显存被 KV Cache 吃光。这篇不给你一个万能数字,而是给一套判断顺序——先量你的真实输入长度,再看卡上还剩多少显存,最后决定这个值该设多少、要不要顺手调别的参数。

用 vLLM 起服务时,max_model_len 是最容易被随手填大的一个参数:填小了长文档直接被截断,填大了启动就 OOM,或者跑到一半显存被 KV Cache 吃光。这篇不给你一个万能数字,而是给一套判断顺序——先量你的真实输入长度,再看卡上还剩多少显存,最后决定这个值该设多少、要不要顺手调别的参数。

先说结论:这个参数没有标准答案,它取决于你的业务输入长度分布、卡的剩余显存、你愿意接受的并发量。所以本文的写法是给流程,不给数字,任何让你「照着填某个值」的说法都要先怀疑一下,因为对方不知道你的卡和你的流量。

max_model_len 到底卡住了什么

它同时是两个身份:一是能力上限,二是显存开关。作为能力上限,它卡的是单条请求的输入 token 加输出 token 的总和,超了要么报错要么被静默截断,取决于你的客户端怎么处理;作为显存开关,它直接决定 vLLM 要给 KV Cache 预留多大的空间。这两个身份绑在一起,所以调它等于同时动了业务上限和资源账本。

还有一个容易踩的点:它和模型自带的上下文长度、以及你启动时传的其他长度类参数之间,是取小关系而不是覆盖关系。也就是说你把它填得比模型本身支持的还大,不会让模型变强,只会让你误以为能塞进去。动手前先确认你请求里真实最长的 prompt 加最长输出大概是多少 token,对 Token 概念拿不准的可以去 /ai-dict/category/basics 过一遍。

  • 它是输入加输出的总上限,不是只算输入,也不是只算输出
  • 它决定 KV Cache 预留量,所以它一变,能扛的并发也跟着变
  • 和模型自带上下文、其他长度参数之间取小,不会彼此覆盖
  • 估算前先量真实长度分布,别用「感觉最长」代替统计

按显存倒推一个稳的值

倒推的顺序是:先算权重占了多少。量化档位不同,同一个模型加载后的占用差别很大,拿不准就按 /models/deploy 的测算口径先估一遍,别拍脑袋。权重之外的剩余显存,才轮到 KV Cache 去分。这里要留够「并发数 × 序列长度 × 每 token 开销」,并发越高,你能给单条序列的长度就越短,这是个此消彼长的关系。

实用做法是从一个偏保守的值起步,跑真实流量稳住之后再慢慢往上加,而不是一上来就顶满。顶满的代价是:启动可能没事,但并发一上来就抢显存,表现是延迟抖动甚至进程被杀,排查起来比启动 OOM 麻烦。这里有个明确不适用的场景——单卡跑超大模型、权重本身就快把显存占满时,max_model_len 调多少都救不了,该走的是张量并行或多卡,不要在这个参数上反复试探。

你的情况优先动作暂时别做
权重已占大半显存考虑多卡或张量并行把 max_model_len 来回调
并发需求高、长度中等压低单请求长度上限把并发上限继续往上开
偶尔有超长文档保留长上限但限制并发默认放开给所有请求
量化后显存宽裕先定长度再试并发一上来就顶满显存

设错之后的典型症状与排查顺序

按症状分三条路走,别一上来就换卡或重装。第一类,启动阶段直接 OOM:多半就是这个值给太大,先把配置减半再试一次,确认是不是它引起的,不要急着归因到硬件。第二类,能起服务但一并发就崩:问题通常在 KV Cache 不够,可以按并发、缓存、显存碎片三步走,具体思路参考 /vram-full-troubleshoot-guide 这类排查路径。

第三类最阴——长输入被静默截断:客户端不报错,但答案明显缺内容。这时候要么把这个值调上去,要么改用分块加检索的方式把长文档拆开喂。还有一种常见误会是输出长度对不上,注意 max_model_len 是输入加输出的总和,输出额度被输入挤掉是正常现象,不是模型偷懒。

  1. 复现用一个固定长度的请求跑一遍,确认是必现还是偶发,必现的多半是配置问题。
  2. 减半验证把这个值先减半重启,能起来就说明方向对了,再逐步往上试。
  3. 看并发单条跑通后加并发,观察是否崩,崩了就往 KV Cache 方向查。
  4. 查截断对比原始输入和模型实际收到的长度,确认有没有被静默砍掉。

有几个参数和它是互相挤压的关系,单独改它往往看不到效果。显存利用率类的参数决定 vLLM 敢用多少显存,调大它等于给 KV Cache 松绑,但也更容易把卡吃满;批处理与并发相关的上限会直接放大 KV Cache 压力,调大之前先把长度确认清楚,否则就是两个变量一起动,出问题说不清是谁干的。

量化档位是另一个总开关,同样的目标长度在不同档位下可行性完全不同,取舍逻辑可以参考 /quantization-tier-choice。验证方式也很关键:改完参数别只看能不能启动,用一次真实的、接近最长长度的请求压一遍,去 /tools/speed-test 记录前后延迟变化,只看启动成功会漏掉并发下的问题。

显存利用率类参数
决定 vLLM 敢用多少显存,和长度上限互相挤压
并发/批处理上限
放大 KV Cache 压力,调大前先确认长度
量化档位
影响权重占用,进而改变长度上限的可行性
下一步把你这边的真实长度分布和改动前后的延迟记下来,到站内的速度测试与部署测算页面核对口径,比单看一个配置值可靠得多。

常见问题

max_model_len 设置成和模型最大上下文一样大,是不是最省事?

多数情况下不是。模型标称的最大上下文是理论上限,不是你这张卡能扛住的上限。设成和标称一样大,等于让 vLLM 按最坏情况预留 KV Cache,权重稍微大一点就直接起不来服务。更稳的做法是按你真实业务里最长的请求来定,留出一点余量,跑顺了再往上加。

这个参数设小一点,模型回答质量会变差吗?

只影响你的请求能不能被完整放进上下文,不影响模型本身的水平。但如果设得太小,长文档被截断、多轮对话里早期内容被丢掉,你看到的答案就会"答非所问"——这容易被误判成模型变笨。真正的判断方法是拿同一个问题、在同一个长度设定下对比截断前后结果,而不是凭感觉怪模型。

已经出现了显存不够,第一步该动这个参数还是换量化?

先别急着换量化,量化会动模型本身、要重新验证效果。按顺序排查:先看是不是 max_model_len 给太满,把它降下来;再看并发上限是不是比实际需要开得大;都不行,再考虑张量并行拆到多卡;最后才是降量化档位。每一步都拿真实流量复测一次,比一次性全改更容易定位问题。

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