一个 7B 模型,用 vLLM 部署在一张 24G 显存的卡上。压测时把并发从 4 提到 32,期望吞吐跟着线性上涨,结果吞吐只涨了不到一倍,单请求延迟从 800 毫秒掉到 4 秒多,再往上加请求直接 OOM 崩掉。团队的第一反应通常是"卡太小了,换张大的"。但换卡之前有一笔账必须算清楚,否则换完还是会以同样的方式踩进去。
单个请求做自回归解码时,每生成一个 token 都要把整个模型的权重从显存读进计算单元一遍。这个过程的瓶颈是访存带宽而不是算力——GPU 大部分时间在等数据搬过来,计算单元闲着。把 N 个请求攒成一批,一次把权重读进来给所有请求复用,同一份数据搬运工作量摊到 N 个请求头上,单位时间产出的 token 数自然上去了。
代价写在另一边:一批请求要么一起进入 prefill,要么一起排队,快的请求要等慢的走完才能交代自己的位置。批越大,单个请求被摊到的平均等待时间越长。所以"吞吐翻倍"和"延迟不变"在数学上就是冲突的,任何声称两者同时大幅提升的说法,基本都换了统计口径。
正确的判断顺序是反过来的:先由业务定 SLO。比如交互式对话要求 TTFT(首 token 延迟)不超过 1 秒、单 token 生成间隔不超过 50 毫秒,这是硬约束;在这个约束下,尽可能把并发往上堆,直到 P99 触到天花板为止,此时拿到的吞吐才是"有效吞吐"。
反过来做会出问题:先追求吞吐峰值,压到 GPU 打满,然后才发现 P99 延迟早就翻了几倍,线上用户已经在骂了。压测时至少要看三个分位数——P50 看体感、P90 看多数、P99 看有没有 hung 住的请求叠加造成的排队雪崩。只看平均值的团队,往往在上线后才发现平均延迟很好看、实际体验很糟。
离线批量场景(文档摘要、数据清洗、批量标注、夜间跑批处理任务)没有人在屏幕那头等,用户感知到的是"这批活多久跑完"。这类场景应该把并发拉到显存允许的最大值,最大化 tokens/s,延迟高到十几秒也没关系。
交互式对话、代码补全、实时客服这些场景恰好相反。人盯着光标等字一个个蹦出来,单 token 间隔超过 50 毫秒就能明显感觉到卡。这类场景的 SLO 压得很死,宁可牺牲一半吞吐也要把 TTFT 和 TPOT 压住。还有一类混合场景:白天跑在线对话、夜里跑批量任务,那就需要按时间段切换配置策略,而不是一套参数吃到底。
权重这块是静态的,与并发无关。算法就是参数量 × 每参数字节数。FP16 / BF16 是 2 字节,INT8 是 1 字节,FP8 也是 1 字节,GPTQ 压到 4bit 就是 0.5 字节。
按 7B 规模、FP16 加载:7,000,000,000 × 2 = 14,000,000,000 字节。换算成 1024 进制的 GiB,14,000,000,000 ÷ 1,073,741,824 ≈ 13.04 GiB。这就是这张卡上"开门就要付的固定房租",无论有没有请求进来都占着。再算上 embedding 层输出/logits、CUDA context、cuBLAS 工作区这些零碎开销,实际还要再往上加 1~2 GiB。
这是唯一会随负载动态膨胀的部分,也是压测时 OOM 的直接来源。通用算式:
每 token 占用 ≈ 2(K 和 V)× 层数 L × KV 头数 n_kv × head_dim d × 每元素字节数 b
下面用一组示例假设把账算完(这些结构参数是示例值,实际必须按你手上模型的 config.json 替换):层数 L = 32,KV 头数 n_kv = 8,head_dim d = 128,数据类型 FP16 即 b = 2。
第一步,单 token:
2 × 32 = 64
64 × 8 = 512
512 × 128 = 65,536
65,536 × 2 = 131,072 字节/token
第二步,换成 KiB:131,072 ÷ 1024 = 128 KiB/token,也就是 0.125 MiB。
第三步,一条 4K(4096 token)上下文的请求:
4096 × 128 KiB = 524,288 KiB
524,288 ÷ 1024 = 512 MiB
512 ÷ 1024 = 0.5 GiB
也就是说,在这个配置下,一条 4K 上下文的请求吃掉 512 MiB 显存,包括已处理的 prompt 和已经生成的输出,两者都算。
第四步,乘并发数:
并发 4:4 × 512 MiB = 2,048 MiB = 2 GiB
并发 16:16 × 512 MiB = 8,192 MiB = 8 GiB
并发 32:32 × 512 MiB = 16,384 MiB = 16 GiB
24G 标称容量,扣掉固件、ECC、显示保留区,实际能拿到大约 22.5 GiB。vLLM 的 gpu_memory_utilization 默认 0.90,也就是引擎最多用 22.5 × 0.9 ≈ 20.2 GiB。再减掉权重 13.04 GiB 和零碎开销约 1.5 GiB,留给 KV cache 的预算只有:
20.2 − 13.04 − 1.5 ≈ 5.7 GiB
用 5.7 GiB ÷ 0.5 GiB ≈ 11 条 4K 请求。这就是这张卡在 4K 上下文下的并发天花板——不是 32,是 11。团队把并发提到 32 时显存缺口大约 10 GiB,OOM 是必然结果,延迟则是先于 OOM 出现、由排队造成的预警信号。
换个角度记忆会更直观:这条算式里任何一个变量翻倍,单请求的 KV 占用就翻倍。上下文翻倍 → 占用翻倍;KV 头数翻倍 → 占用翻倍;FP16 换成 FP8 → 占用减半。
上面的示例假设 n_kv = 8,这属于分组查询注意力(GQA)。如果你手上的是 Llama-2 7B 这类多头注意力(MHA)模型,n_kv = 32,那么:
2 × 32 × 32 × 128 × 2 = 524,288 字节 = 512 KiB/token;4096 token 就是 2 GiB;同样的 5.7 GiB 预算只够放 2~3 条并发。
同一张卡、同一个"7B",并发能力差了四倍。所以网上那些"某张卡能跑多少并发"的数字,脱离了模型结构和上下文长度就没有参考价值。选型之前第一件事不是问别人跑了多少,而是打开 config.json 把 num_hidden_layers、num_key_value_heads、hidden_size ÷ num_attention_heads(得到 head_dim)抄下来,套进上面的算式。
推理阶段的激活值远小于训练,但 prefill 阶段要一次性处理几千个 token,中间状态会有一个瞬时峰值;还要预留 beam search 缓冲、logits 张量(vocab 很大的模型尤其明显,7B 模型 vocab 32k × batch × 4 字节并不算小)、采样器临时空间。这部分一般给 1~2 GiB 的余量处理,压测时观察峰值,别把它算成零。
传统静态 batching 的做法是攒够 N 个请求一起跑,整批走完才释放资源、才能接下一批。问题是同一批里的请求输出长度天然不齐——有的生成 50 个 token 就收尾,有的要写 800 个。跑得快的那个先完成,可它的槽位还占着,要一直等到整批结束。GPU 在这种"填充空闲"上白白浪费了算力。
连续批处理(continuous batching)把粒度从"批"降到了"请求":调度每个 decode step 重新组一次批。已经完成的请求立刻退出、立刻释放它的 KV cache 块;队列里的新请求在下一个 step 就能插入。结果是 GPU 几乎不空转,吞吐相比静态批处理有量级提升,这也是 vLLM 这类框架的核心卖点。
把这一节和第 2 节的算式连起来看,因果关系就很直白了。连续批处理的调度策略会尽量让更多请求同时在跑——这正是它提升吞吐的手段。而"同时在跑"意味着每条请求的 KV cache 都实打实地占在显存里,互不释放。于是:
并发 4 → 同时占用 2 GiB;并发 11 → 同时占用 5.5 GiB,刚好打满预算;并发再往上 → 没有新块可分配,请求只能进等待队列,TTFT 飙升;若连队列都放不下或权重被挤,直接 OOM。
所以"并发提到 32 没换来吞吐翻倍",中间的损耗来自两层:一是延迟层的排队——超出的请求在等待前面的释放块,这段时间不计入算力只计入延迟;二是显存层的天花板——有效并发其实从来没到过 32,后半程的并发请求多数时间是在排队而不是在算。
请求在等待 Swapped / Waiting 状态时,它的 prompt 已经算过的部分可能被丢弃或换出,重算要付出额外的 prefill;就算保留,也会持续占用 CPU 侧内存与管理结构。监控系统如果只看 GPU 利用率,会看到"利用率很高"的假象——因为 GPU 忙着处理已经在批里的少数几条长请求,而队列外的请求正在超时。这就是为什么必须把"排队长度"和"等待时间"作为独立指标单独盯。
在 PagedAttention 出现之前,主流做法是为每条请求按 max_model_len 预分配一整块连续显存。假如 max_model_len 设为 32K,而实际请求平均只有 2K 上下文,那么每条请求有 93% 的预留空间是空的、还不能被别人用。这属于典型的内部碎片,加上不同长度请求造成的外部碎片,可用显存常常有一半以上被浪费。
PagedAttention 借鉴操作系统虚拟内存的分页思路:把 KV cache 切成固定大小的块(block),每个块装固定数量的 token(常见 block size 为 16 或 32),逻辑上连续的序列可以映射到物理上不连续的块。请求生成一个 token 就申请一个块,用多少拿多少;请求结束立刻归还块给全局池。显存利用率因此被拉到接近理论上限,浪费通常能被压到个位数百分比。
块越小,末尾那个块里没用满的部分越少(内部碎片越小),但元数据条目变多、访存时需要跳转的块序列更长,GPU 的访存效率下降,尤其体现在多头注意力的 kernel 上;块越大访存越连续,但短请求也会占掉一整块,浪费上升。实践中 16 是一个被广泛采用的折中值,32 在长文本占多数的负载里更划算。这个值通常不建议手改,除非你有明确的长度分布数据支撑,改动前要重测。
必须说清楚一件事:PagedAttention 捡回来的是原本浪费掉的那部分,它没有改变上面那条算式里的任何一个变量。如果你的请求长度分布很集中、大家都接近 max_model_len,那么原本的浪费就很少,PagedAttention 能带来的收益也很少;如果长短参差又被 // 开了长 tail,收益才明显。
所以问"开了 PagedAttention 能省多少显存",答案永远是"看你的长度分布",而不是某个固定倍数。想知道实际收益,去读 vLLM 启动日志里的 KV cache size 输出,它会直接告诉你"GPU KV cache size: xxx tokens",那个数字除以单请求 token 数就是真实并发上限。
AWQ、GPTQ、SmoothQuant 这一类是作用在模型权重上的。7B 在 FP16 下是 13.04 GiB,压到 INT4(0.5 字节)大约是 7,000,000,000 × 0.5 = 3.5e9 字节 ≈ 3.26 GiB。省下来的接近 10 GiB 全部转化成了 KV cache 预算。
但要注意:权重量化对延迟的改善有限,甚至可能让单请求变慢——低比特 kernel 需要额外的反量化步骤,某些实现在小 batch 下反而比 FP16 慢。它的核心价值是"腾出空间",不是"跑得更快"。
FP8 KV cache 是把算式里的 b 从 2 改成 1。按前面的示例:2 × 32 × 8 × 128 × 1 = 65,536 字节 = 64 KiB/token,4096 token 变成 256 MiB,比原来的 512 MiB 减半。同样的 5.7 GiB 预算能放 22 条,翻倍。
这里有个很容易搞混的点:并发上不去的时候,该动的是 KV 而不是权重。因为并发天花板等于"KV 预算 ÷ 单请求 KV 占用",权重只影响分子(预算),KV 的数据类型直接影响分母。两者能差出好几倍的量级,选错了方向白量一场。
量化一定有代价。权重 INT4 在多数任务上困惑度(perplexity)上升不明显,但在需要精确数值推理、多步逻辑链、代码生成、低资源语言这几类任务上退化可能肉眼可见,而且退化不均匀——某些子集突然崩掉,而整体指标看起来还好。KV cache 量化对长上下文的召回能力影响更敏感,长文档问答里"中间部分被忽略"的现象会加重。
判断口径给三条:一,涉及金融、医疗、法律等对事实准确性要求高的场景,优先保精度,用更大显存的卡换空间;二,短输出、高容错的场景(分类、抽取、摘要)可以放心量化;三,无论哪种,上线前必须跑业务自有数据集的回归评测,对比量化前后在同一评测集上的表现,不能只看公开的通用基准。
max_model_len 直接决定一条请求最多能吃多少 KV。把它设成模型理论支持的最大值(比如某些模型标称 128K),意味着调度器必须为最坏情况留出可能性,实际并发会被压到个位数。正确做法是按业务真实的长度分布设定:统计线上请求 prompt + 预期输出长度的 P99,留 20%~30% 余量。如果 P99 是 4K,就设 6K 左右,而不是 128K。
如果确实偶尔要处理超长输入,更划算的做法是分层部署:绝大多数请求打到短上下文实例上,极少数长请求路由到另一组长上下文实例。用一套配置覆盖两极分布,永远是最贵的方案。
这个参数控制 vLLM 最多能占用 GPU 总显存的比例。设太高会挤压其它进程(同卡上还有 embedding 模型或 rerank 模型时尤其危险),设太低则白白浪费。同卡单服务时 0.90 左右常见;同卡多服务必须按每个服务的实际需要切分,并且要保证总和留有余地。
这个值不是"越大越好",而是应该等于你算出来的天花板。设得超过显存能支撑的量,超出的请求只会进队列,把 TTFT 拖爆,对吞吐毫无帮助;设得太低则浪费了调度能力。用第 2 节的算式算出并发上限,然后把 max_num_seqs 定在那个值附近,再压测微调。
很多业务有一大段固定的系统提示,客服机器人可能动辄 2000 token 的"人设与规则",多轮对话每轮都要带着历史重算。开启 prefix caching(前缀缓存)后,相同前缀的 KV 块被复用,命中时不重复计算也不重复占新块。
收益大小取决于前缀的重复率:系统提示完全一致、多轮共享同一段历史的场景,命中率高,prefill 阶段的时间能省掉大半,显存也能省一块;反之如果每个请求前缀都不一样(比如每条都塞了不同的长文档),命中率接近零,还会因为哈希索引徒增开销。这类场景下有个实用技巧:把可变内容放在后面,把稳定不变的部分放在 prompt 最前面。
| 扩容路线 | 单请求延迟 | 吞吐上限 | 显存占用构成 | 成本量级 | 适用场景 |
|---|---|---|---|---|---|
| 路线一:单卡 + 限长度保低延迟 压低 max_model_len,保守并发 |
最优,TTFT 与 TPOT 都能压住,队列极少 | 最低,单批规模受限,GPU 难喂满 | 权重占大头,KV cache 占比小,余量充足 | 零新增硬件支出,仅配置调整 | 交互式对话、实时客服、代码补全等有明确延迟 SLO 的在线业务 |
| 路线二:单卡 + 量化 + 提高并发 KV 量化优先,权重量化为辅 |
中等,并发提高后尾延迟会抬升 | 较高,同样预算下并发数可翻倍 | 权重压缩释放空间,KV 单份减半是主要收益来源 | 无硬件成本,但需投入评测与回归的人力 | 离线批量、摘要/分类等高容错任务,或延迟要求不严的内部系统 |
| 路线三:多卡并行 / 换更大显存卡 张量并行或整机替换 |
取决于并行策略与卡间互联,单请求延迟可能略升 | 最高,且长上下文能力同步提升 | 权重被切分或换 Larger 卡后一次性抬升可用总量 | 硬件支出显著上升,需询价评估 | 长上下文 RAG、高并发生产环境、不准许量化掉点的业务 |
把前面那套算式倒着用:先定业务要支持的并发数与上下文长度,算出需要的 KV 总量,加上权重与开销,得到显存门槛,再去挑硬件。这一步没有捷径,跳过它就意味着用试错代替计算。
倒推之后还有一层"能不能装下整个模型"的判断。单卡放不下时,张量并行(把一层切开到多张卡)是唯一选择,代价是每一步都要跨卡同步,卡间互联带宽就成了新的瓶颈——有 NVLink 的机器和只走 PCIe 的机器,表现可能差出一倍以上。多实例(每张卡跑一个完整副本)则走另一条路:模型必须单卡放得下,换来的是完全的横向扩展和更好的隔离性。判断口径很简单:先看单卡能不能装下并且留出合理的 KV 预算,能就多实例,不能才上张量并行。
CPU 负责分词(tokenize)与反分词、采样、请求解析、JSON 序列化这些前后处理。并发一高,这部分会先成为瓶颈,典型现象是 GPU 利用率曲线锯齿状、长期低于 60%,nvidia-smi 里看不出问题,但吞吐就是上不去——这时候去看进程 CPU 占用,往往已经打满。内存要装得下模型权重做加载时的临时映射,一般按权重的 2 倍留比较稳妥;磁盘影响的是冷启动,几 GB 的权重文件在机械盘上加载可能要几分钟,NVMe 能把模型加载时间压到几十秒级别;网络则决定了多机扩展时参数同步和请求分发的上限。
判断口径很直接:GPU 利用率长期高于 85% 且伴随显存吃满,说明该加卡或者切更高效的部署;GPU 利用率低于 60% 而 CPU 打满、队列堆积,先升级 CPU 或加机器拆流量,别急着加 GPU,加了也用不上;显存够但延迟高,多半是排队策略或者 max_num_seqs 设得过大,调参而不是加钱;多实例部署时单机 CPU/内存/网络先到顶,这时候应该横向加机器,而不是继续往一台机器上堆卡。
选 GPU 服务器时,建议把显存容量与卡间互联形态(NVLink 还是 PCIe、代际如何)放在第一位比较,之后再核对 CPU 核数与主频、内存容量、NVMe 的顺序读带宽,价格放到收尾再看。一万网络深耕 19 年(成立于 2007 年),GPU 服务器与裸金属部署在华南、华东、华北、中国香港以及海外多个节点,工程师可以 1 对 1 协助完成 CUDA、cuDNN、TensorRT、PyTorch、TensorFlow 这类深度学习环境的一对一部署;像 T4 ¥900/月、RTX3090 24G ¥1750/月、A100 40G ¥2800/月这类官网明示配置,可以作为做容量与预算推算时的锚点(以官网实时价为准),H100 等更高规格的整机与多卡方案则需要按实际配置实时询价。
SSE / WebSocket 流式输出会让每个生成中的请求长时间占着一条连接和一个服务端线程。并发 100 的流式服务,实际是 100 条连接持续挂着几十秒。反代层的连接数上限、worker 数、超时时间都要跟着调,否则会看到"GPU 很闲但新请求 502"。超时设置要区分首字节超时和整体超时,长生成最怕被中间层的固定超时一刀切。
队列必须设上限并明确超时返回,否则雪崩时所有请求一起等到超时,用户看到的是全站不可用而不是部分降级。做法上区分两类:低于阈值的请求快速失败并返回重试提示,高于阈值的请求才进队列;同时在响应头里带上排队耗时,便于客户端做退避。
即便有 PagedAttention,长期运行后块池仍可能出现效率下降,尤其在请求长度分布频繁变化时。运维上要有明确的重启周期和滚动重启方案,多实例部署时这一点尤其重要——逐个重启不影响服务。
换模型的瞬间,旧实例的权重还没释放、新实例已经开始加载,显存会出现短暂的双份占用。单卡部署时必须先停旧再起新,或者预留出足够容纳两份权重的余量;多实例部署则可以滚动替换,代价是短暂容量下降。
最少要有一组:GPU 显存占用与 gpu_cache_usage(KV 占用率)、等待队列长度与平均等待时间、TTFT 的 P50/P90/P99、TPOT(单 token 生成间隔)、每秒输出 token 总量、请求成功率与超时率。这六个指标组合起来,才能区分"算力不够""显存不够""排队策略不对""CPU 拖后腿"这四种截然不同的病因。
坑:为了"以后可能用到",直接设成 128K 或模型标称上限。
为什么:调度器要为最坏情况预留可能,单请求 KV 上限一抬高,同等显存下能容纳的并发数直接塌到个位数。
怎么判断:看日志里的 KV cache size 与实际并发数,如果 max_num_seqs 设了 64 但实际稳定跑不到 10 条,基本就是这个原因。
规避:按线上 prompt + 输出长度的 P99 加余量设定,长尾需求用单独的实例池承接。
坑:压测报告里 tokens/s 很好看,上线后用户抱怨卡顿。
为什么:平均值掩盖了尾部的排队堆积,而用户体验恰恰由尾延迟决定。
怎么判断:把 P99 和平均值放一起做对比,正常情况下 P99 应该是均值的 2~3 倍以内,超过 5 倍说明存在严重的排队。
规避:压测 SLO 直接写在 P99 上,超过阈值就停止加压,而不是继续堆。
坑:换上 INT4 权重,人工问几句觉得"差不多",直接发布。
为什么:量化退化是不均匀的,多数任务看不出差别,个别子集会突然崩掉,抽样对话很难碰到。
怎么判断:拿业务自己的历史请求或评测集,量化前后同批对比,看逐条差异而非总分。
规避:建立固定评测集与阈值门槛,达标才放行,并保留快速回滚到 FP16 的路径。
坑:买了好卡,配置也不差,吞吐就是上不去。
为什么:分词、采样、JSON 处理这些前后处理压在 CPU 上,请求还没进 GPU 就先堵住了。
怎么判断:看 GPU 利用率是否长期低于 60% 且伴随 CPU 打满、请求排队时间长。
规避:这里有个省钱的优先级问题——先把 CPU 核数与主频提上去,或者用多实例把负载分摊到不同机器;批处理前合并小请求也能降低前后处理开销。
坑:两张卡明明可以张量并行跑一个大模型,却起成了两个独立实例,结果单实例显存不够;或者反过来,本来该横向扩展的高并发场景,非要做张量并行。
为什么:张量并行解决的是"装不下",多实例解决的是"跑不够",两者的目标完全不同。
怎么判断:看单请求最长 KV 需求是否超过单卡预算——超过就必须张量并行;只是并发不够则优先加实例。
规避:先用第 2 节的算式判定装不装得下,再决定并行策略;容器环境里务必为每个实例明确限制可见设备与显存配额,避免多实例互相抢占导致不可预测的 OOM。
Q1:7B 模型做推理到底需要多大显存?
A1:只看"能不能跑起来",FP16 加载需要约 13.04 GiB 权重再加 1~2 GiB 的 CUDA 上下文与框架开销,所以 16G 的卡勉强能加载但几乎做不了事。真正有意义的问题是"加载完还剩多少给 KV cache"——按 n_kv=8、head_dim=128 的示例配置,每 token 需要 128 KiB,一条 2K 请求就是 256 MiB。所以选卡时应该从业务要支持的并发与上下文长度反推,而不是笼统问一张卡够不够。以 A100 40G 为例,扣除权重与开销后能留给 KV 的空间大约是 24~25 GiB,是 24G 卡的近五倍。
Q2:一张 24G 的卡能撑多少并发?
A2:取决于上下文长度和模型结构,没有统一答案。按 7B、32 层、n_kv=8、head_dim=128、FP16 这组示例假设,单 token 占 128 KiB,4K 请求占 512 MiB;扣除权重约 13.04 GiB 与开销后,KV 预算约 5.7 GiB,能支撑 11 条左右的 4K 并发。若把上下文压到 2K,同样的预算可以放约 22 条;如果模型是 MHA 结构(n_kv=32),同样条件只能放 2~3 条。请先按算式核算自己的配置。
Q3:上下文长度翻倍,显存占用是不是也翻倍?
A3:KV cache 部分严格线性,翻倍就是翻倍,这点没有例外。但总显存不是翻倍——权重是固定的,只有 KV 随长度增长。假设 KV 占总占用的一半,那么长度翻倍时总占用只增加 50%。还要留意 prefill 阶段的处理时间大致随长度平方增长(注意力计算复杂度),所以长度翻倍后首 token 延迟往往涨得比显存快得多,这是比显存更早到来的约束。
Q4:量化之后模型质量会掉多少?
A4:没有统一数值,取决于量化位宽、量化算法和业务任务。权重量化到 INT8 通常几乎没有可感知的损失;INT4 在通用指标上退化有限,但在精确数值推理、多步逻辑、代码和低资源语言这几类任务上可能明显变差。KV cache 量化到 FP8 对短上下文影响很小,对长上下文的信息召回影响更值得关注。评估不能只看公开基准,必须用业务自己的数据集逐条对比。
Q5:并发上不去,该加并发数还是该换更大的卡?
A5:先分清是"排队"还是"显存不足"。如果 GPU 利用率还有余裕、显存占用不高却出现了排队,多半是 max_num_seqs 设得过大或请求本身不需要那么多并发,这时候调参数就行;如果 KV 占用已经接近上限,先考虑限制 max_model_len 和开启 prefix caching,再考虑 FP8 KV 量化;这些都做完仍不够,才谈换卡。换卡之前务必确认 CPU、磁盘与网络不成为新的瓶颈。
Q6:多卡部署该选张量并行还是起多个实例?
A6:判断口径是"单卡能不能装下"。单卡装不下整个模型(含合理的 KV 预算)就必须用张量并行,同时要保证卡间有 NVLink 等高带宽互联,否则同步开销会吃掉并行收益。单卡能装下的话,多实例是更优选择:横向扩展线性度高、实例之间天然隔离、单个实例故障不影响全局、也方便滚动重启和灰度发布。如果瓶颈在 CPU 侧,多实例还能把前后处理分散开。
Q7:vLLM 和直接用 PyTorch / Transformers 推理有什么区别?
A7:核心差别在显存管理和调度。原生 generate 通常采用静态批处理和按最大长度预留显存,浪费大、GPU 空转多;vLLM 的 PagedAttention 把 KV cache 切块按需分配,连续批处理让请求随时进批、完成即退出,两者叠加让同等硬件下的吞吐有数量级提升。它还内置了 prefix caching、多种量化支持、OpenAI 兼容接口等生产化能力。代价是引入了更多需要理解的参数,配置不当反而更容易出问题。
Q8:长文本场景(文档问答、长上下文 RAG)该怎么配?
A8:长文本的第一约束是单请求 KV 占用,不是显存总量。建议分池部署:把 8K 以下请求打到短上下文实例,长请求单独走一组配置了更大 max_model_len 的实例,这样短请求不被长请求拖累。次选手段是开启 prefix caching 复用模板与历史,压缩上下文时优先压缩中间的检索片段而不是首尾指令。务必先用真实文档长度分布做容量核算,长尾往往比想象中更肥。
本文关于连续批处理(continuous batching)、PagedAttention 分页显存管理、显存分块与前缀复用机制的说明,参考 vLLM 官方项目文档与 arXiv 上 PagedAttention 相关论文所公开的技术描述;针对请求级调度、块分配与抢占机制的说明,属于对上述公开材料的工程化解读。文中所有数字均为按给定假设做的可复算示例:7B 参数规模、32 层、KV 头数 8、head_dim 128、FP16 这五个值是作者为演示算式而选取的示例假设,实际部署时必须替换为自己模型的 config.json 中的真实结构参数(num_hidden_layers、num_key_value_heads、hidden_size ÷ num_attention_heads)。除此之外,24G 卡可用容量约 22.5 GiB、框架开销 1~2 GiB 属于工程经验范围估计,不同驱动版本与实现会有出入。本文不提供任何实测数据。文中出现的 T4 ¥900/月、RTX3090 24G ¥1750/月、A100 40G ¥2800/月为一万网络官网明示价格,仅作推算锚点,实际以官网实时报价为准;其余更高规格机型与多卡方案价格需实时询价,具体以签约时最新报价与合同为准。参考与询价入口:https://www.idc10000.net/。
把并发从 4 提到 32 之前的判断顺序是固定的:先定延迟 SLO → 再按权重算式算出 KV 预算 → 由预算反推 max_model_len 与并发上限 → 还不够再动 KV 量化 → 走到这一步才考虑加卡。这条路径里,前两步不花钱,往往就能救回大半的性能。具体到本研究涉及的单卡 24G 场景:如果业务属于交互式对话,结论明确走向"限长度保低延迟",把 max_model_len 压到真实分布的 P99 附近,并发反而可能下降但体验更好;如果是离线批量任务,优先开启 FP8 KV 量化提高并发,比换卡划算得多;只有当单卡已经无法容纳整个模型的权重加最低限度的 KV 预算,或者业务明确不准许任何量化掉点时,升级到 40G 以上的卡或做多机多实例部署才是绕不开的一步。至于何时该加机器而不是加卡,判断依据很简单:GPU 利用率上不去而 CPU、队列先到瓶颈时,加 GPU 是浪费预算。
一万网络深耕 19 年(成立于 2007 年),提供 GPU 服务器、裸金属服务器与多地节点的算力租用,节点覆盖华南、华东、华北、中国香港与海外。深度学习环境由工程师 1 对 1 协助完成 CUDA、cuDNN、TensorRT、PyTorch、TensorFlow 的部署配置,硬件故障可在 10 分钟内自动迁移,配套 7×24 中文工单、平均 5 分钟响应、免费系统盘快照(每日 3 份、30 秒回滚)、免费备案协助与 5–20G 免费 DDoS 防护,自营机柜最快 1 分钟上架;网络侧为 BGP 多线并支持 CN2 GIA 回国线路,实际延迟需按运营商、线路与具体机房实测确认。
如果您正在做 vLLM、TensorRT-LLM 或 Ollama 一类的大模型推理部署,可以把您的模型规模、目标并发、上下文长度(以及是否允许量化)告诉我们,由工程师按本文的算式代为核算显存与并发预算,并给出匹配的机型与数量的选型建议。需要注意的是,具体机型、带宽与价格均需实时询价,官网明示的 T4 ¥900/月、RTX3090 24G ¥1750/月、A100 40G ¥2800/月等配置仅供参考,H100 及多卡整机方案公开渠道差异较大、一律需询价,最终以官网实时报价与合同为准。
Copyright © 2013-2020 idc10000.net. All Rights Reserved. 一万网络 科技有限公司 版权所有 深圳市科技有限公司 粤ICP备07026347号
本网站的域名注册业务代理北京新网数码信息技术有限公司的产品