最近折腾Qwen2.5-7B的本地部署,想搞个简单的对话demo。我用的是一张RTX 3090(24G),按说应该够用,但用transformers加载模型时总是显存溢出,还没跑推理就OOM了。后来试了bitsandbytes的4bit量化,加载成功了,但生成速度特别慢(大概每2秒一个token),而且偶尔还会崩。
部署Qwen2.5-7B时显存总是溢出,是不是我哪里搞错了?
全部回复
共 148 条试试加载时加个low_cpu_mem_usage=True,再配合gradient_checkpointing,能省不少显存。
试试用vLLM或SGLang做推理,显存占用能压下来不少,3090跑7B全精度应该没问题的。
24G跑7B全精度确实会卡在边缘,FP16权重就要14G左右,加上激活值和CUDA上下文很容易爆。你试试用device_map="auto"加load_in_8bit,比4bit稳定不少,速度也能接受。另外生成慢可能是量化后没开use_fast内核,或者beam search开太大了,改成greedy解码能快很多。崩溃的话看看是不是bitsandbytes版本和CUDA不匹配,这坑我踩过。
别急着怀疑自己,3090跑7B本来就很紧,transformers默认会缓存整个模型加注意力机制,容易超。你可以试试用vLLM或者llama.cpp的GGUF格式,显存占用能压到10G以内,速度比bitsandbytes快一个量级。4bit慢可能是你没设置低精度计算,加个torch_dtype=float16试试,另外崩多半是量化层和某些算子冲突。
我也遇到过这情况,后来发现是transformers版本太新,默认加载方式变了。你可以先设一下low_cpu_mem_usage=True,再配合max_memory限制显存,把部分层放到CPU上。4bit慢的话,检查一下是不是没开bnb_4bit_compute_dtype为fp16,默认fp32会拖慢。崩溃的话试试把trust_remote_code=False关掉,有时是模型
24G跑7B全精度本来就很勉强,transformers默认加载fp16权重,加上CUDA上下文和KV cache,峰值轻松超20G,3090显存带宽又没上代A100那么宽裕,OOM不奇怪。4bit能跑起来说明方向对了,但你遇到的生成慢大概率不是量化本身的问题,而是bitsandbytes在3090上对某些算子支持不完善,触发了慢速的fallback路径。我之前也踩过这个坑,后来换用GPTQ模型配合AutoGPTQ加载,速度能快两三倍,而且崩的概率小很多。另外你生成时是不是忘了设低KV cache?可以把max_new_tokens调小,或者用streaming输出,别一次性生成太长。还有个细节,加载时加上torch_dtype=auto,device_map=auto,让bitsandbytes自己分配层到GPU和CPU,能省不少显存。要是还崩,试试vLLM或者llama.cpp的GGUF格式,前者对显存利用率高很多,后者用CPU+GPU混合推理,3090能完全吃满。你用的transformers版本是多少?老版本对量化层的bug特别多,更新到4.45以上会有明显改善。
3090 24G跑7B按理说真够,但直接用fp16加载肯定会爆,transformers默认会留不少缓存,试试加载前清一下CUDA cache,或者用device_map="auto"让模型自己分配。4bit慢大概率是没开flash attention,而且bitsandbytes的4bit在3090上对某些算子支持不行,容易崩。你可以换成AWQ或GPTQ量化,配合vLLM或ExLlamaV2跑,速度和稳定性都会好很多,我上次用同样配置能到每秒十几token。
24G跑7B全精度确实有点紧,但也不至于连加载都OOM,你检查下是不是transformers默认用了float32,换torch_dtype=float16能省一半显存。4bit慢的话可以试试把低秩适配或量化位数调高到8bit,速度会明显改善,崩溃大概率是量化配置和attention实现冲突,换个版本或者用vLLM试试。另外生成速度还跟beam search参数有关,先关掉采样优化再测。
3090跑7B按理说不会连加载都爆显存,你试试把torch_dtype改成float16,然后设一下low_cpu_mem_usage=True,加载前先清一下缓存。另外bitsandbytes慢的话,可以考虑用GPTQ的4bit,速度和显存占用都比bnb好不少。崩溃大概率是量化时某些层没转好,你可以换个量化库或者直接用llama.cpp,效果可能更稳定。
3090跑7B按理说真不该这样,我怀疑你多半是加载时没关掉梯度计算或者没开eval模式,试试model.eval()加torch.no_grad(),能省不少显存。4bit慢的话可以看看是不是量化时把计算图留在GPU上了,或者换一下Attention实现,比如flash-attn,速度能有明显提升。另外bitsandbytes偶尔崩也可能是版本和transformers不兼容,建议固定下版本组合试试。
24G跑7B原版应该稳的,除非你输入序列特别长或者batch不是1,先检查下有没有残留的缓存变量在显存里。4bit慢的话,可以试试GPTQ或AWQ,比bitsandbytes的dynamic量化快不少,我3070跑7B都能每秒10来个token。崩的话看下是不是CUDA版本和bitsandbytes对不上,重新装个匹配的版本大概率能解决。
我去年也踩过这坑,transformers默认会加载fp32权重,7B直接吃满28G,你3090肯定爆,得先fp16加载,再加low_cpu_mem_usage=True。4bit慢可能是你生成的max_new_tokens设太大了,或者没开use_cache,这俩都会拖慢速度。崩的话试下排除法,先不量化跑跑看,再逐步加功能,定位下是哪一步出的问题。
3090跑7B按理说真不该这么惨,我怀疑你加载的时候是不是没开gradient checkpointing,或者直接把模型塞进了GPU而不是用device_map="auto"?transformers默认行为有时候会把所有层都怼到显存里,这玩意儿特别坑。另外bitsandbytes那个4bit加载慢很正常,毕竟CPU offload和量化反序列化都要时间,但你每2秒一个token也太离谱了,建议看看是不是没设use_fast=True,或者生成参数里max_length太小导致频繁做KV cache重算。还有,偶尔崩溃多半是显存碎片化,试试在加载前清一下cuda cache,或者用torch.cuda.empty_cache()在每次推理后调一下。我自己的经验是,7B模型用4bit量化大概要预留10-12G显存,你24G理论上很宽裕,倒不如直接试试8bit,速度会快很多,实在不行就用vLLM或者llama.cpp这类专门优化的推理框架,比transformers省心多了。你跑的时候有没有监控过nvidia-smi啊?我怀疑是不是有别的进程占着显存。
24G跑7B全精度确实紧,但直接OOM大概率是transformers默认加载了fp32,试试load_in_8bit或者直接开device_map="auto"让层分散到CPU,能缓解不少。4bit慢的话检查下是不是没开torch.compile或者显存碎片化严重,3090跑7B生成速度应该能到10+ token/s。另外崩的问题可以试试升级bitsandbytes到最新版,老版本对Qwen2.5支持确实有bug。
24G跑7B其实挺宽裕的,你这问题大概率不是显存容量,而是transformers默认加载的full precision权重直接占满显存了,再加上推理时的KV cache和中间激活值,3090也会被瞬间塞爆。我建议你试试vLLM或者SGLang这类推理框架,它们对显存管理更激进,能自动做continuous batching和paged attention,我之前用vLLM加载同样的模型,显存占用比transformers少了将近一半,生成速度也快很多。
关于4bit量化后速度慢的问题,bitsandbytes的4bit其实没有做计算优化,它只是把权重压缩了,但推理时还是要反量化回fp16计算,反而增加了开销。你可以换用GPTQ或者AWQ格式的4bit模型,配合ExLlamaV2或者AutoGPTQ加载,速度会快好几倍,我之前在3090上跑Qwen2.5-7B的AWQ版,每秒能出20多个token。另外崩溃的话,检查下CUDA版本和bitsandbytes是否匹配,这玩意儿对版本特别敏感,经常莫名崩。
还有个思路是直接用Ollama或者llama.cpp,它们对显存管理更灵活,能自动把部分层offload到CPU内存,虽然慢点但至少不OOM。你那个demo如果只是对话测试,其实可以用更轻量的Qwen2.5-3B甚至1.5B先跑通流程,再换7B调优。最后建议你开个nvidia-smi监控看下显存峰值到底在哪一步爆的,是加载时还是生成时,这样能更精准定位问题。
24G跑7B全精度确实会卡在边缘,因为transformers默认会加载fp16权重加激活值,峰值轻松超24G,建议先用device_map="auto"加load_in_8bit试试,能减少不少显存占用。你4bit慢可能是bitsandbytes没走量化算子,或者生成长度设太大,把max_new_tokens调小点看看。另外崩的话大概率是显存碎片问题,可以试试torch.cuda.empty_cache()或者换个推理框架,比如vLLM或者llama.cpp,速度和稳定性都会好很多。
24G跑7B全精度确实有点勉强,transformers默认加载fp16或者bf16的话占用的显存不只是权重本身,还有KV cache和中间激活值,你试试把max_length调小一点,像512或者1024,再把torch_dtype设成auto,应该能省出来不少。4bit慢的话可能是bitsandbytes没有走4bit的fast kernel,检查下你的CUDA版本和库匹配不匹配,我这边用同样的卡跑Qwen2.5-7B的4bit大概能到每秒8到10个token,你这速度明显不正常。崩的问题多半是量化时某些层不支持导致的,可以试下用gptq模型替代bnb,或者把trust_remote_code打开看看。
24G跑7B全精度确实有点悬,FP16光权重就占14G,加上激活和KV cache,推理时峰值很容易冲过20G。你试试用device_map="auto"加load_in_8bit,比4bit稳定不少,速度也会快一些。另外生成慢可能跟beam search有关,换成贪心解码试试。崩的话查下是不是bitsandbytes版本和CUDA不匹配,我之前升级到0.43就解决了。
24G跑7B其实很宽裕了,问题大概率出在transformers默认加载的float32权重上,直接占满显存还留不出计算空间。你可以试试在加载时直接指定torch_dtype=“auto”,或者用device_map=“auto”让模型自动分配层到CPU和GPU,很多情况下能绕开OOM。4bit慢的话,检查下是不是没开flash attention或者推理时把模型切到了CPU层,另外bitsandbytes偶尔崩可能是版本和CUDA不匹配,换个0.43.0试试。
24G跑7B全精度确实紧,试试加载时加个low_cpu_mem_usage=True,能省不少显存。
量化后慢大概率是CPU offload了,把device_map改成auto,让模型尽量留在GPU上。
24G跑7B全精度本来就紧巴巴的,建议先用vLLM试试,加载快很多也不会OOM。
24G跑7B按理说真够,但transformers默认加载fp16会把权重和激活都塞显存,尤其是长序列时KV cache涨得飞起,我怀疑你输入长度没限制。4bit慢可能因为bitsandbytes在3090上没走对计算核心,试试加载时加load_in_4bit=True并且把device_map="auto",再配合torch.compile,速度能快不少。崩溃的话检查下是不是CUDA版本和bitsandbytes不匹配,我换到0.43.0就稳了。你生成时把max_new_tokens调小点,或者开下use_cache=True,也能省显存。
24G跑7B全精度确实紧张,fp16光权重就14G,加上激活和KV cache肯定爆。你试试用device_map="auto"加load_in_8bit,或者干脆用vLLM加载,显存占用能省不少。4bit慢可能是没开flash attention,另外bitsandbytes偶尔崩是正常的,建议换个推理框架比如llama.cpp,量化后速度会好很多。
24G跑7B按理说真不该OOM,你试试加载的时候把device_map设成auto,然后torch_dtype用float16,transformers默认可能给你塞成fp32了,直接翻倍显存。另外你那个每秒2个token的4bit速度有点离谱,bitsandbytes的4bit在3090上不至于这么慢,检查下是不是没开flash-attention,或者量化时把计算图搞复杂了。我怀疑你崩的原因可能是transformers版本和bitsandbytes不兼容,最近这两货更新频繁,经常出幺蛾子,你试试锁个稳定版本比如transformers 4.43。还有一个骚操作,可以先用vLLM或者llama.cpp跑,虽然配置麻烦点,但显存控制和速度都比transformers稳得多,尤其你要做demo的话,vLLM自带OpenAI兼容接口,省事不少。最后,如果只想验证模型能不能跑通,直接加载Qwen2.5-7B-Instruct的AWQ量化版,那个对显存友好,速度也比bitsandbytes快,别死磕transformers全家桶。