最近在试着把7B的模型部署到本地,显卡是3090(24G),按理说应该够用,但一加载就说CUDA out of memory。我试了加载时传low_cpu_mem_usage=True,也试了把max_memory分配给GPU,但好像没多大用。我看网上说用bitsandbytes做4bit量化,但装了之后又报错说找不到CUDA的setup.py,心态有点崩。就想问问大家,实际部署的时候一般怎么配参数?是不是需要把加载的模型分片到多卡或者用offload?另外,除了量化,还有哪些比较实用的显存优化思路?希望能给个可操作的步骤,谢谢了。
部署LLaMA模型一直OOM,大佬们都是怎么优化显存的?
全部回复
共 81 条24G跑7B按理说真够,你大概率是加载时峰值爆了,试试model = AutoModelForCausalLM.from_pretrained(..., device_map="auto"),让transformers自己切层,别手动指定max_memory,经常越指越乱。bitsandbytes那个报错一般是版本和CUDA不匹配,直接pip install bitsandbytes==0.39.0配CUDA 11.8基本能解决,或者干脆用GPTQ的4bit,加载方式更稳。除了量化,顺手把torch.backends.cuda.matmul.allow_tf32设成True,推理时用torch.inference_mode()包起来,能省不少显存。如果还卡,就开flash-attention,3090支持很好,显存占用能降一大截。
24G跑7B按理说真够,但你八成是加载时峰值爆了,试试先设环境变量PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128,再配合bitsandbytes的4bit,加载时加个device_map="auto"让它自动分配,别手动指定max_memory。另外bitsandbytes报setup.py错误大概率是版本不匹配,得装跟CUDA版本对应的轮子,别用pip默认源。还有个野路子,加载后调用torch.cuda.empty_cache()清下缓存,有时候能救急。要是还不行,就换llama.cpp的GGUF格式,cpu+gpu混合跑,24G跑7B Q4量化版基本无压力。
3090跑7B理论够但加载峰值会爆,试试device_map="auto"加load_in_4bit,一步到位。
量化报错大概率是bitsandbytes版本和CUDA不匹配,换0.43.0版本基本能解。
试试bitsandbytes的4bit加载,配好CUDA版本基本能压到10G内,3090跑7B完全够用。
24G跑7B其实挺宽松的,你这个问题大概率不是显存容量不够,而是加载时峰值爆了。transformers默认会一次性把权重载入内存再搬到GPU,这时候峰值可能翻倍,试试load_in_4bit=True配合device_map="auto",bitsandbytes报错多半是版本和CUDA不匹配,装个最新版或者直接conda装会省心很多。另外你提到offload,建议别急着用,因为7B全量fp16也就14G,3090完全塞得下,问题出在缓存和中间激活值上,可以试试把max_seq_len调小,或者用torch.compile开显存优化模式。还有个野路子,加载前先跑一遍torch.cuda.empty_cache(),有时候残留显存碎片也会导致误报OOM。如果量化实在搞不定,先用transformers的load_in_8bit顶着,效果也够,就是稍微损失点精度。最后提醒下,别用accelerate的默认配置,手动指定device_map={"": 0}强制单卡,有时候分片反而会额外吃显存。
24G跑7B按理说真够,你八成是加载时把torch默认的float32全塞进去了,试试load_in_4bit=True加上device_map="auto",bitsandbytes报错大概率是版本和CUDA不匹配,去GitHub下对应轮的whl直接装就行。另外加载前先清一下显存缓存,torch.cuda.empty_cache()有时候能救急,3090跑7B量化完基本能剩10G左右。分片和offload其实不太必要,单卡能搞定的事别搞复杂,除非你要同时跑长上下文。
24G跑7B按理说真够了,问题多半出在加载时峰值显存爆掉,试试在from_pretrained里加device_map="auto",让transformers自己分配,别手动指定max_memory。bitsandbytes报错大概率是版本和CUDA不匹配,换pip install bitsandbytes==0.43.0这种老版本试试,或者直接改用torch_dtype=torch.float16加载,能省一半显存。实在不行就开load_in_8bit,效果比4bit稳定得多,而且3090上8bit跑7B基本没精度损失。
试试bitsandbytes先装对应cuda版本的wheel,加载时加device_map="auto"和load_in_4bit=True,基本能压到10G内。
24G跑7B按理说真够,你八成是加载时把float32的权重全塞进去了,试试load_in_4bit=True配合torch_dtype=torch.float16,bitsandbytes报错大概率是版本和cuda toolkit不匹配,去github装预编译wheel就行。另外可以开gradient_checkpointing,推理时用flash-attention,显存能再省一截。要是还爆就把max_memory设成{0: "20GiB"},剩下的offload到cpu,速度慢点但至少能跑。
试试加载时加个device_map="auto",让transformers自动分配层,再配合bitsandbytes的4bit,3090跑7B很稳。
量化报错多半是版本不匹配,直接pip install bitsandbytes换0.43版,或者用llama.cpp的GGUF格式,省心很多。
24G跑7B其实很宽裕了,问题多半出在加载瞬间的峰值显存上,你试试先加载到CPU再逐步转移,或者用device_map="auto"让它自己分配,别手动指定max_memory,有时反而会卡住。bitsandbytes报错一般是版本和CUDA不匹配,建议直接用pip装最新版,或者用transformers里集成的load_in_4bit=True,省去手动配置的麻烦。我自己的经验是,加载时加个torch_dtype=torch.float16能立刻砍一半显存,推理时再用flash-attention,显存占用能压到10G以内。分片和offload是最后手段,3090单卡其实没必要,反而会拖慢速度。另外你可以试试把max_new_tokens设小点,或者用batch_size=1,有时候OOM是生成长文本时KV cache爆了,跟模型加载无关。还有个冷门技巧,用torch.cuda.empty_cache()在加载后清一次缓存,有时候碎片化也会误报OOM。真要量化的话,推荐先用GPTQ或者AWQ,比bitsandbytes稳定,而且4bit下7B效果损失不大。
试试bitsandbytes换0.39版,然后加载时加device_map="auto"配合4bit,我3090跑7B稳得很。
量化加offload一起开,24G跑7B其实富余,别死磕max_memory参数。
24G跑7B按理说真够,你OOM大概率是加载时把fp32的权重全塞显存了,7B光参数就28G,不爆才怪。我一般用transformers的from_pretrained直接加device_map="auto",它会自动帮你分片到CPU和GPU,配合load_in_4bit=True走bitsandbytes,基本能压到6G左右。bitsandbytes报错那个事,大概率是版本和CUDA不匹配,你试试pip install bitsandbytes --upgrade,或者直接装源码版,别用conda的。另外你max_memory别手动分太细,让它自己调度就行,手动设置反而容易碎片化。除了量化,你可以考虑用torch.compile或者开启gradient_checkpointing(如果是推理就用不着),还有flash-attention能省不少显存,就是安装麻烦点。最土的办法是加载时把torch_dtype设成torch.float16,直接砍一半,效果立竿见影。分卡跑的话3090单卡其实没必要,除非你想上70B,7B单卡量化后绰绰有余。先试device_map="auto"加load_in_4bit,如果还报错就把bitsandbytes的安装日志贴出来看看,基本就是编译时CUDA路径没对。
24G跑7B按理说真够,但你大概率是卡在加载瞬间的峰值显存上,transformers默认会一次性把权重全塞进显存,low_cpu_mem_usage只是优化CPU侧,跟GPU峰值没关系。我建议你先试一下torch_dtype=torch.float16,这能直接砍一半显存,如果还OOM就加device_map="auto",让accelerate自动分配,别手动指定max_memory,那个参数反而容易触发碎片化问题。bitsandbytes报错大概率是版本跟CUDA不匹配,试试pip install bitsandbytes==0.41.0,或者直接换用GPTQ量化,现在很多项目都直接用AutoGPTQ,加载时quantize_config一配就完事,比bnb省心。另外你可以开gradient_checkpointing,虽然推理时不需要但有些库加载模型时会强制开启,顺手把attention实现换成flash_attention,能省不少激活显存。还有个小技巧,加载前先跑torch.cuda.empty_cache(),有时候是之前跑的进程没释放干净。如果还不行,就分片加载,用device_map="sequential"然后设置offload_folder,把部分层放到CPU,牺牲一点速度换稳定。反正别硬刚,先跑通再优化速度。
我也碰到过一模一样的情况,3090跑7B按理说真不该OOM,问题多半出在加载方式上。你试试改成model = AutoModelForCausalLM.from_pretrained(..., device_map="auto", torch_dtype=torch.float16),别手动分配max_memory,让accelerate库自己调度,这样有时能绕过一些奇怪的显存碎片问题。bitsandbytes那个报错大概率是版本和CUDA不匹配,建议直接pip install bitsandbytes==0.43.0,然后配合load_in_4bit=True,但注意要同时传quantization_config,别只传一个参数。除了量化,你可以开gradient_checkpointing(虽然推理时没啥用),或者用transformers的bettertransformer把注意力换成flash attention,能省不少峰值显存。更粗暴的办法是直接上vLLM或者llama.cpp的GGUF格式,前者用PagedAttention管理KV cache,后者把权重量化到5bit甚至3bit,效果立竿见影。最后提个冷门技巧——先加载到CPU再逐层挪到GPU,用model.hf_device_map手动指定几层放CPU,虽然慢点但绝对不会爆。你现在的报错是发生在加载中途还是真正跑推理的时候?如果是后者,那得看你的输入序列长度和batch size,把max_new_tokens调小一点可能就解决了。
试试4bit量化吧,换transformers新版加载就行,老版本才报setup.py的错,显存能压到7G左右。
兄弟3090跑7B肯定够,别硬怼max_memory,开load_in_4bit加device_map="auto"一步到位,报错就升下库版本。
24G跑7B按理说真够,但OOM多半不是模型权重本身,而是加载时KV cache和中间激活值把显存撑爆了。你试试加载后先用torch.no_grad()跑一个dummy输入,看峰值显存到底多少,我怀疑是序列长度设太大,默认2048直接吃满。bitsandbytes那个报错大概率是版本和CUDA不匹配,建议直接conda装cuda toolkit再pip install bitsandbytes,别用系统自带的。另外你可以考虑用transformers的device_map="auto"配合load_in_8bit=True,比4bit稳定,精度损失也小,3090跑8bit的7B大概显存能压到10G左右。如果还是紧张,就把max_new_tokens调小,或者用vLLM加载,它的PagedAttention对显存管理比原生推理强很多。还有个冷门技巧,把模型放到CPU上,但把embedding层和lm_head留在GPU,能省个1-2G。最后实在不行就上llama.cpp的GGUF量化,Q5_K_M格式在3090上速度飞快,显存占用不到6G,部署起来比transformers省心多了。
3090跑7B其实挺稳的,你先把torch和CUDA版本对齐到官方推荐那套,很多时候OOM是版本不一致导致显存分配异常。4bit量化值得搞,报错大概率是bitsandbytes版本和CUDA不匹配,换个预编译wheel包就行。另外加载前记得清一下显存缓存,torch.cuda.empty_cache()有时候能救急。如果还不行,就用device_map="auto"把部分层offload到CPU,速度慢点但至少不崩。
24G跑7B按理说真够,你大概率是加载时峰值爆了,试试先加载到CPU再慢慢挪到GPU,或者直接用device_map="auto"让transformers自己调度。4bit的话bitsandbytes确实容易踩坑,装之前确认下CUDA版本和torch匹配,实在不行可以换gguf格式用llama.cpp跑,省心很多。另外把max_seq_len调小,或者开启gradient_checkpointing(如果是推理就开KV cache量化),能挤出不少显存。你报错的具体是transformers版本问题还是bitsandbytes编译问题?贴个日志可能更好排查。
量化是最直接的,加载时记得把torch_dtype设成float16,bitsandbytes报错多半是版本不匹配,换个0.39版试试。