最近折腾Qwen2.5-7B的本地部署,想搞个简单的对话demo。我用的是一张RTX 3090(24G),按说应该够用,但用transformers加载模型时总是显存溢出,还没跑推理就OOM了。后来试了bitsandbytes的4bit量化,加载成功了,但生成速度特别慢(大概每2秒一个token),而且偶尔还会崩。
部署Qwen2.5-7B时显存总是溢出,是不是我哪里搞错了?
全部回复
共 148 条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手动限制一下,别让它自动分配。