最近折腾Qwen2.5-7B的本地部署,想搞个简单的对话demo。我用的是一张RTX 3090(24G),按说应该够用,但用transformers加载模型时总是显存溢出,还没跑推理就OOM了。后来试了bitsandbytes的4bit量化,加载成功了,但生成速度特别慢(大概每2秒一个token),而且偶尔还会崩。
部署Qwen2.5-7B时显存总是溢出,是不是我哪里搞错了?
全部回复
共 161 条24G跑7B全精度确实紧巴巴的,transformers默认加载fp16其实还行,但你要注意是不是把max_length和batch设太大了,这俩很吃显存。4bit速度慢大概率是CPU卸载了部分层,检查下bitsandbytes的device_map是不是没设成auto,还有量化时别开8bit的optimizer_state。崩的话试试升级transformers和accelerate版本,老版本兼容性问题不少。我3090跑4bit的Qwen2.5-7B大概能到8-10 token/s,你这个速度明显不正常,先看看是不是推理时没关梯度计算。
3090玩7B应该挺宽裕的,你检查下transformers版本和加载参数,是不是没开device_map?
试试vLLM或者llama.cpp,显存占用和速度都比transformers舒服太多了。
3090跑7B真不用硬上4bit,fp16加flash-attention就够了,先查下是不是装了CPU版torch。
24G跑7B全精度本来就不是拿来直接干推理的,你加载模型的时候transformers默认会按fp16把权重全塞进显存,再加上KV cache和中间激活值,3090确实会爆。我猜你之前是不是没设torch_dtype=torch.float16,只是默认fp32加载?那显存占用直接翻倍,不OOM才怪。
b nb的4bit慢我觉得挺正常的,它那个量化是在CPU上做反量化,每层都要来回搬运数据,3090的PCIe带宽反而成了瓶颈。你试试把load_in_4bit的bnb_4bit_compute_dtype设成torch.float16,然后开device_map="auto",速度能上来一点。另外崩溃可能是bitsandbytes版本跟CUDA不匹配,我上次用0.43.0配CUDA 12.1就老崩,换回0.41.3就稳了。
还有个思路,你要是只想跑demo,可以试试vLLM或者ollama,它们对显存管理优化得更好,Qwen2.5-7B在24G上能直接跑FP16,不用量化,速度还快不少。不过要是非想用transformers调代码,那建议先看看accelerate的init_empty_weights,把模型先放CPU再逐层移到GPU,别一次全塞进去。
3090玩7B其实挺尴尬的,显存卡在24G刚好不上不下,直接全精度加载肯定爆,但量化后速度又拉胯,我怀疑你bitsandbytes没吃满显卡。生成每2秒一个token确实不正常,先看看是不是没开torch.compile或者kv cache没调对,另外3090的带宽跑4bit其实能到每秒十几token的,你这速度大概率是CPU瓶颈或者内存交换了。还有个坑是transformers新版默认会加载tokenizer到显存,有时候光这个就占掉几个G,建议检查一下模型加载前后的显存占用曲线。崩的话可以试试换AWQ或者GPTQ的预量化版本,bitsandbytes那个动态反量化在7B上偶尔会出数值问题。最后问一句,你用的是不是safetensors格式?有时候旧版checkpoint的权重布局会导致碎片化显存分配,换个加载方式可能就解决了。
说实话24G跑7B全精度确实有点紧,但正常来说transformers加载应该不至于直接OOM,你是不是把device_map="auto"给漏了?我之前也踩过这坑,改成device_map="auto"配合torch_dtype=torch.float16基本就够了,生成速度也能接受。至于4bit慢,多半是bitsandbytes的CPU offload或者量化参数没调好,试下load_in_4bit=True外加bnb_4bit_compute_dtype=float16,速度会好很多,崩的话可能跟显存碎片有关,建议开torch.cuda.empty_cache()。你如果只是跑demo,其实不如直接上vLLM或者llama.cpp的GGUF,省心太多。
24G跑7B全精度确实不该OOM,除非你加载时把序列长度或batch设太大了,试试加载前先设一下low_cpu_mem_usage=True,再配合torch_dtype=float16,我3090上跑起来峰值也就14G左右。
4bit慢的话,你检查下是不是量化后把模型搬回GPU了,bitsandbytes有时候会默认走CPU推理,用device_map="auto"或者手动指定一下cuda:0会好很多。崩溃大概率是显存碎片化,关掉其他占显存的应用,或者干脆重启一下环境再试。
我自己也是3090,跑Qwen2.5-7B用4bit加vLLM,速度能到每秒20多个token,虽然偶尔也会崩,但比transformers稳不少,你可以试试换推理框架。如果只是demo,干脆用llama.cpp的Q4_K_M量化版,部署简单还省心。
4bit量化后生成这么慢不太正常,我3090上用bnb 4bit跑7B大概能到20+ token/s。你检查下是不是没装flash-attention,或者用了cpu offload把部分层丢到内存了,那样会巨慢。显存溢出的话,试试把max_memory手动限制一下,别让它自动分配。
这个思路不错,收藏了。
我之前也遇到过类似问题,后来换了方案。
3090跑7B的fp16权重确实要占大概15G左右,加上KV cache和一些中间激活,24G很容易就爆了,你OOM不奇怪。4bit量化慢成2秒一个token有点离谱,感觉像是bitsandbytes没走GPU或者版本不匹配,可以试试换成GPTQ或AWQ的量化模型,速度会正常很多。另外你用的transformers版本和CUDA对不对得上也值得查一下,有时候环境问题比配置问题更坑。
试试vllm部署,显存占用和速度都好很多,transformers硬扛7B确实容易OOM。
24G跑7B的fp16确实挺紧的,模型权重就占15G左右,加上KV cache和CUDA上下文,OOM不奇怪。试试调小max_model_len,或者用device_map="auto"让它自己分配。4bit慢可能是bitsandbytes没编译好,换GPTQ或AWQ量化会快很多,3090跑7B的4bit一般能到几十token每秒。
3090跑7B的fp16其实挺勉强的,模型权重就占14G多,加上KV cache和框架本身的开销,24G确实容易爆。你试试调小max_seq_len,或者直接用vllm加载fp16,它对显存的调度比transformers聪明不少。至于4bit慢成那样不太正常,可能是bnb版本和torch没对齐,我之前踩过这个坑,换新版后速度能回到正常水平。
3090跑7B的fp16其实刚好卡在24G边缘,模型权重就占15G左右,加上CUDA context和tokenizer那些开销,OOM挺正常的,不一定是哪里搞错了。4bit量化慢到2秒一token有点离谱,你试试换成GPTQ或者AWQ的量化版本,推理速度会好很多,bitsandbytes的nf4在有些环境下确实拉胯。另外检查下是不是没装flash-attn,这玩意儿对速度影响挺大的。
24G跑7B的BF16确实会紧张,光权重就15G上下了,加上激活和KV cache,不量化很容易炸。你4bit慢可能不是量化的锅,检查下是不是走了bnb的CPU offload或者没装flash-attn,这两样对速度影响特别大。我之前3090用GPTQ-Int4加exllama,跑7B能到五六十token每秒,比bitsandbytes顺畅多了,你可以试试换vLLM或者llama.cpp的量化版本。
3090跑7B不至于OOM的,我猜你多半是没设置dtype,默认fp32加载的话光权重就要28G,直接就把24G吃满了。试试在from_pretrained里加上torch_dtype=torch.bfloat16或者float16,显存占用能掉到14G左右,推理完全没问题。4bit量化虽然加载省显存,但bitsandbytes在3090这种消费卡上反量化开销挺大的,速度掉到2秒一token也算正常,而且有时候跟CUDA版本不匹配确实会崩。你要是就想跑个对话demo,用vLLM或者llama.cpp的量化版本会舒服很多,前者吞吐高,后者对单卡更友好。另外记得看看是不是max_length或者batch设太大了,有时候OOM不一定是模型本身的锅。
24G加载7B按理说fp16也就14G左右权重,不该直接OOM啊,你是不是没设device_map或者torch_dtype搞成fp32了?我3090跑7B对话一直挺稳的。4bit慢到2秒一token不太正常,建议换GPTQ或AWQ试试,bitsandbytes的推理速度本身就拉胯。还有3090没bfloat16支持,得用float16,这个坑很多人踩。
学到了,感谢分享!
刚入门,这个对我帮助很大。