最近公司在做私有化部署,选了Qwen2.5-7B-Instruct,用vLLM跑。8张A10(24G)的卡,但业务方要求并发至少50,单卡batch size调大后显存直接爆掉,报OOM。后来试了GPTQ 4bit量化,效果还行但输出偶尔会乱码,不敢上生产。想问问大家,这种7B模型在真实业务场景下,一般怎么配置推理引擎和量化方案?还有,显存占用和并发数之间有没有一个大概的估算公式?现在完全是摸着石头过河,先谢谢各位大佬了。
部署7B大模型到生产环境,显存和并发怎么平衡?
全部回复
共 87 条vLLM里对7B模型,单卡并发撑到50确实有点勉强,A10的24G显存主要卡在KV Cache上。我建议你先用AWQ或GPTQ的4bit,但别用vLLM自带的量化,换成llama.cpp的Q4_K_M试试,乱码问题可能会好很多。估算公式的话,大概每并发要占1-1.5G显存(取决于输入输出长度),所以8卡分摊下来,每张卡留4-6G给模型权重,剩下的全给KV Cache,这样算下来50并发应该刚好够。另外你试试开vLLM的prefix caching,如果业务场景有重复前缀,能省不少显存。
试试awq量化配vllm的gpu-memory-utilization,乱码多半是gptq calibration没喂好数据。
量化乱码大概率是校准集没选好,换AWQ试试,或者把vLLM的max-num-seqs限到16,A10撑50并发其实够呛。
量化乱码大概率是校准集没选好,换AWQ试试。并发50的话7B用8卡有点浪费,砍到4卡配好continuous batching反而更稳。
量化乱码大概率是calibration没弄好,换个awq试试,显存估算直接看kv cache配比就行。
显存和并发本质是token吞吐的博弈,7B用AWQ比GPTQ稳多了,乱码大概率是量化校准集没配好。
量化乱码大概率是校准集没选好,换个awq或smoothquant试试,显存和并发得看单序列长度,留20%余量最稳。
vLLM里开个continuous batching再配合paged attention,7B满血跑50并发24G其实够用,关键别贪batch size。
量化乱码大概率是校准集没选好,换AWQ试试,稳很多。并发50的话7B用4bit加vLLM的continuous batching,8张A10其实够。
量化乱码多半是校准集没对齐,换AWQ试试,显存公式大概batch×seq×2bytes×1.2再加权重。
你这配置其实挺典型的,8张A10跑7B按理说算力是够的,瓶颈主要在显存带宽和KV Cache上。我这边之前也踩过类似的坑,vLLM默认的continuous batching策略对显存预估挺乐观的,但实际并发一高,KV Cache直接吃满,OOM很正常。你试GPTQ乱码的话,建议看看awq或者bitsandbytes的8bit,量化误差比4bit小不少,而且vLLM对awq的支持更成熟,乱码概率低很多。至于估算公式,我一般用:显存占用≈模型权重(7B fp16约14G,4bit约4G)+ KV Cache(每token约0.5-1MB,取决于层数和head数)× 最大并发数 × 平均序列长度。你24G卡,如果序列长度控制在2k,单卡跑25并发左右比较稳,8张卡全开能到200,但业务方只要50的话,其实可以试试把张数分散,比如4张卡各跑12并发,留4张做冗余或者跑别的任务。另外,vLLM的--max-num-seqs参数可以手动限制单卡batch,别让它自己无限往上堆,配合--gpu-memory-utilization调到0.9,能避免很多OOM。最后问一下,你们业务场景的输入输出平均长度大概多少?如果长文本多,KV Cache压力会翻倍,可能得考虑paged attention或者chunked prefill,我这边后来是加了prefix caching才好些。
说实话你这配置和需求有点拧巴,8张A10跑7B其实挺奢侈的,但并发50对单卡batch size要求确实高。我之前用vLLM做类似项目,发现关键不在量化,而是得把max-num-seqs和gpu-memory-utilization调明白,比如给每张卡留1-2G显存做KV cache余量,然后动态batch别开太大,实测单卡塞16个并发序列没问题,8张卡分摊下来完全够。
GPTQ那个乱码我遇到过,多半是校准集没选好或者group-size设太大,换AWQ试试,或者直接用FP8动态量化,效果比GPTQ稳不少,显存占用也就多1-2G。至于公式,大概可以按:显存占用约等于模型权重(FP16下14G,4bit下4G)加上序列长度乘隐藏层维度乘2乘并发数,但实际还要算上激活和临时buffer,建议你拿两三个真实业务prompt跑个压测,看vLLM的日志里KV cache使用率再调。
另外提醒下,A10的显存带宽其实一般,并发高的时候吞吐会掉得厉害,如果业务对首token延迟要求不高,可以试试把调度改成优先填满batch,或者干脆用Tensor Parallel切到4卡,留4卡做容错。我自己的经验是,别一味追求并发数字,先定好P99延迟目标,再反推batch大小,不然调参调到吐。
说实话你这配置选得有点拧巴,8张A10看着多,但单卡24G跑7B满血版本来就很尴尬,vLLM吃显存大头在KV cache和连续批处理,batch size一上去OOM太正常了。我这边之前试过7B用FP16,单卡并发撑死20出头,换A100或者H20会舒服很多,但预算估计你说了不算。量化这块,GPTQ 4bit出乱码大概率是校准集跟你业务数据分布差太远,建议拿真实prompt重新跑一遍calibration,或者试试AWQ,我体感AWQ在代码和中文混合场景下更稳。估算公式其实没那么玄乎,单卡可用显存减去模型权重和激活值,剩下的除以每条请求的KV cache大小,再考虑一下prefill和decode的峰值差异,粗略能算个上限,但实际还得看平均输入长度和输出长度,你们要是长对话场景那并发直接腰斩。另外可以看下--max-num-batched-tokens这个参数,别让它默认值把你坑了,手动调小点能让vLLM更平滑地调度。最后提个醒,如果输出质量不能妥协,还不如降级到Qwen2.5-3B加长上下文,很多时候业务根本用不到7B的智力,3B反而能拉高并发。
8张A10跑7B还压50并发,这配置有点紧啊,试试把max-num-seqs调低点,配合P100看看呢?
学到了,感谢分享!
我们之前也踩过类似的坑,7B其实没必要硬上4bit,试试AWQ或者把vLLM的max-num-seqs调低一点,同时开pipeline并行,8卡分摊下来单卡压力会小很多。乱码大概率是量化敏感层没处理好,建议用llama.cpp的k-quants对比一下。估算公式的话,大致是显存=权重(按2字节算)+KV cache(每序列约0.5-1GB),50并发建议预留20GB以上,A10跑起来其实挺紧的。
另外业务方如果允许,可以加个简单的轮询排队,把峰值并发削平,比硬扛OOM省心多了。我们最后用的FP16+动态batching,50并发稳得很,就是延迟偶尔到2秒,看你们能不能接受。
量化乱码大概率是校准集没选好,试试AWQ或者用8张卡切两套服务分摊压力更稳。
8张A10跑50并发属实有点极限,建议上AWQ量化配合vLLM的continuous batching,乱码大概率是GPTQ校准集没选好。
显存估算可以按峰值KV cache加权重算,7B 4bit权重约占4G,每个并发预留1.5G左右KV,剩下的留白给碎片。
我们团队之前也踩过类似的坑,A10这块卡其实挺尴尬的,24G显存跑7B全精度勉强够,但一旦并发上来就捉襟见肘。你试过GPTQ出乱码,我猜可能是量化参数没调好,尤其是group size和desc_act这两个选项,默认值不一定适合你的数据分布,建议试试用awq或者把calibration dataset换成你们业务相关的prompt,效果会稳很多。
至于并发和显存的估算,我一般这么算:单卡能塞下的batch size主要看KV cache,7B模型fp16的权重大概14G,剩下10G给KV cache,每个token大约需要2KB(按层数和头数算),假设平均输出长度500,那单卡最多同时处理几十个请求,但vLLM的continuous batching效率高,实际能跑的并发往往比理论值高不少。
你们现在8张卡,其实可以试试张量并行切2路,每路管4张卡,这样单卡压力小,同时把max_num_seqs调低一点,比如32,再用paged attention的默认设置,说不定不用量化就能扛住50并发。另外,乱码问题也可能是采样参数里的temperature太高或者top_p太激进,先调成0.1再测测看。
还有个思路是上FP8或者混合精度,A10支持不太好,但可以试下把部分层转成bf16,或者用AutoAWQ的4bit,我觉得比GPTQ在生成质量上更稳。你们如果对延迟不敏感,也可以考虑把模型拆成两半,用流水线并行,但那样运维复杂度会上去。
最后建议一定先在测试环境压测,用你们真实的业务数据跑一遍,别光看benchmark,生产环境的输入长度分布和输出长度差异对显存冲击特别大。希望这些对你有用,我们当时也是折腾了两周才找到适合自己业务的配比。
量化乱码大概率是量化参数没调好,GPTQ换AWQ试试,稳定性会好很多。
这题我熟,之前我们也是7B卡在显存和并发的坑里。vLLM的话可以试试开启prefix caching,业务里重复系统提示词多的话能省不少显存,并发50可能不用量化硬扛。GPTQ乱码大概率是校准集跟你们业务数据分布差太远,换个更贴近实际输入的校准集,或者试试AWQ,稳定性会好一些。估算公式的话,单卡并发大概可以按(24G - 模型权重占用)除以(单条序列最大长度×1.5)粗算,但实际还得看输入输出长度比例,建议直接用vLLM的benchmark脚本压一遍,比公式准。