最近在试着把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按理说真够,你八成是加载时默认fp16还把权重全塞显存了,试试device_map="auto"加load_in_4bit=True,bitsandbytes装不上多半是版本和CUDA不匹配,去GitHub下对应wheel包手动装就行。另外OOM还有个常见坑是transformers版本太老,升级到最新版配合accelerate,它能自动分片到CPU和GPU。实在不行就开swap或者用torch.compile把激活内存压一压,但最省心的还是量化,4bit下7B大概只要6G多。
24G跑7B按理说真够,但OOM多半是加载时峰值爆了,试试load_in_4bit=True配合device_map="auto",bitsandbytes报错大概率是版本和CUDA不匹配,直接pip install bitsandbytes==0.43.0再试试。另外加载前先清一下缓存torch.cuda.empty_cache(),然后生成时把max_new_tokens调小点,7B全精度推理其实也就需要14G左右,你大概率是中间某个环节没释放显存。
3090跑7B按理说真够用,问题大概率出在加载方式上,默认会先把整个fp16权重塞进显存,24G其实刚好卡在边缘,稍微有点上下文就爆。你试试先加载到CPU再逐层搬到GPU,用device_map="auto"让transformers自己分配,同时把torch_dtype设成torch.float16,这样比手动max_memory靠谱得多。
bitsandbytes报错多半是版本和CUDA不匹配,别装最新的,去GitHub看下对应你CUDA版本的wheel,或者直接用pip install bitsandbytes==0.39.0这种老版本,反而稳。4bit量化后显存能压到6G左右,跑起来很轻松。
另外offload确实有效,但别全offload到CPU,不然推理慢到怀疑人生。可以试试把部分层放CPU,部分放GPU,配合accelerate的init_empty_weights,这样能压到10G以内。还有个偏方是减小max_seq_len,默认512可能就够,改成256能省不少显存。
实在不行就上flash-attention,虽然安装麻烦点,但对显存和速度的提升都很明显。还有个思路是换更小的模型,比如7B的量化版直接下GPTQ的4bit文件,加载更省事,不用自己折腾量化流程。
24G跑7B按理说真够,但OOM多半不是显存容量问题,而是加载时峰值爆了——模型权重、激活值、KV cache和CUDA context全挤一起,尤其transformers默认会一次性把所有参数塞进显存。你试试先加载到CPU再逐层转cuda,别直接model.to('cuda'),或者用accelerate的device_map="auto",它能自动分层放。bitsandbytes报错大概率是版本跟CUDA不匹配,直接pip install bitsandbytes==0.41.1再配个适配的transformers版本,别装最新的。除了量化,你还可以把torch.compile打开,能省不少内存,另外训练时用gradient_checkpointing,推理时把batch size设成1,max_new_tokens限制一下。如果还不行,就考虑用llama.cpp的GGUF格式,加载时直接mmap,虚拟内存映射到磁盘,显存占用直接砍半,3090跑7B基本稳。offload到CPU是最后手段,速度会慢很多,但至少不会崩。
24G跑7B按理说真够,你八成是加载时把fp16的权重全塞显存了,试试load_in_4bit=True配合device_map="auto",bitsandbytes报错大概率是版本和CUDA不匹配,去GitHub装对应的预编译wheel就行。另外可以开gradient_checkpointing(虽然推理时用不上但能省不少),或者把max_new_tokens限制一下,KV cache也会爆。分片到多卡其实没必要,单卡offload到CPU慢得你想砸电脑,实在不行就上llama.cpp的GGUF量化,Q4_K_M效果挺稳的。
试试4bit量化加load_in_4bit=True,bitsandbytes记得装对应cuda版本的wheel,别用pip默认源。
量化后24G跑7B绰绰有余,还能开长上下文,实在不行就换8bit,别死磕4bit。
24G跑7B按理说真够,但你这OOM大概率是加载时fp16权重+梯度+激活值一起爆了,试试load_in_4bit=True配bnb_4bit_compute_dtype=float16,bitsandbytes报错的话大概率是版本和cuda toolkit不匹配,换一下对应版本就行。另外加载完记得跑一次torch.cuda.empty_cache(),有时候显存碎片化也会导致明明总量够却分配失败。还有个野路子是把model.half()改成model.bfloat16(),某些卡上能省不少。
24G跑7B全精度确实紧,但OOM大概率是加载时峰值爆了,试试加载完再调用.to('cuda'),别在from_pretrained里直接指定device。4bit报错一般是bitsandbytes版本和CUDA不匹配,手动指定一下BNB_CUDA_VERSION环境变量能解决。另外可以开load_in_8bit配合torch_dtype=torch.float16,显存能压到10G左右。我3090之前跑7B还开了gradient_checkpointing,推理时用torch.inference_mode(),基本能稳。
24G跑7B按理说是够的,你这个问题大概率出在加载时torch默认把整个模型塞进显存而不是按需分配。试试先加载到CPU再用accelerate的device_map="auto",配合bitsandbytes的4bit,一般能压到6-8G占用。报错那个setup.py多半是版本不匹配,直接pip install bitsandbytes==0.39.0配transformers>=4.30就能绕过去。还有个小技巧是把max_new_tokens调低,生成时用flash-attention,显存峰值能再降一截。
我之前也卡在你这步过,24G跑7B其实挺宽裕的,问题多半出在加载时峰值爆了。可以先试试把model放到meta设备上再加载权重,或者用device_map="auto"让transformers自己安排,别手动指定max_memory。bitsandbytes那个报错一般是版本不匹配,建议直接pip install bitsandbytes==0.43.0,配transformers 4.41左右基本稳。另外开gradient_checkpointing和torch.compile也能省不少,但推理时记得关掉梯度。
试试bitsandbytes先装对版本,或者直接用transformers的load_in_4bit=True,3090跑7B完全够。
我上次也卡这,后来发现是tokenizer和model的device_map没对齐,改成auto就稳了。
3090跑7B按理说真够,问题大概率出在加载瞬间的峰值显存,你直接load_model的时候它会先把fp16权重全塞进去再开始算,24G刚好卡在临界点。我建议别硬怼max_memory,直接把加载改成device_map="auto"配合torch_dtype=torch.float16,这样transformers会自动帮你拆分层到CPU和GPU之间,虽然慢点但至少不OOM。bitsandbytes那个报错很常见,因为新版需要自己编译或者装预编译wheel,你检查下CUDA版本和bitsandbytes的匹配,直接pip install bitsandbytes==0.41.1这种老版本反而稳。除了量化,你可以试试把attention的显存优化打开,比如用xformers或者flash-attention,能省不少激活内存,7B推理时激活值占大头。还有个小技巧,加载前先torch.cuda.empty_cache()并设置PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128,碎片化问题能缓解很多。真要长期跑,建议用vLLM或者llama.cpp的GGUF格式,后者直接CPU+GPU混合跑,显存占用能压到12G以内,3090完全没压力。
3090跑7B按理说真够,你八成是加载时float32直接把显存吃满了,试试torch_dtype=torch.float16,能省一半,另外bitsandbytes那个报错大概率是版本和CUDA不匹配,换conda装能省心不少。我自己的经验是4bit量化后7B大概只要6-7G,剩下的显存还能塞下长上下文,你先把transformers升到最新版再试一次。要是还不行,就加一句device_map="auto",让模型自己决定怎么塞,比手动设max_memory靠谱多了。
24G跑7B按理说真够,问题多半出在加载时峰值显存爆了,试试先加载到CPU再逐步转移到GPU,或者用device_map="auto"让它自动分配。4bit报错大概率是bitsandbytes版本和CUDA不匹配,换0.39.0或者0.41.0试试,别装最新版。除了量化,可以把max_seq_len调小到1024甚至512,很多OOM是KV cache撑爆的。offload到CPU是条路但速度会慢不少,建议先用transformers的load_in_4bit配合bnb_4bit_compute_dtype=float16,基本能压到8G以内。
24G跑7B按理说真够了,你八成是加载时峰值显存爆了,试试先把模型用load_in_4bit=True直接量化加载,同时把device_map设成auto,让它自动分配。bitsandbytes报错的话,检查下是不是CUDA版本和它不匹配,换对应wheel包重装就行。另外加载前清下缓存,torch.cuda.empty_cache()有时候挺管用,我上次就这么救回来的。
24G跑7B真的够,问题多半出在加载时峰值显存爆了,模型权重、CUDA context和中间激活叠一起就超了。试试先设置环境变量PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128,然后加载时用torch_dtype=torch.float16,应该能立竿见影。bitsandbytes那个报错大概率是版本和CUDA版本不匹配,建议直接用pip install bitsandbytes从源码装,或者干脆换用GPTQ量化,省心不少。另外把加载后的模型用model.half()再包装一下,也能省不少。
直接上4bit量化吧,bitsandbytes报错多半是cuda版本没配对,换pip装对应版本就行。
加载时记得加device_map="auto",让transformers自己分配显存,比手动设max_memory靠谱。
24G跑7B全精度确实紧,但你这个问题大概率出在加载方式上,试试先加载到CPU再逐步挪到GPU,或者直接用device_map="auto"让transformers自己分配。bitsandbytes报错一般是版本和CUDA不匹配,换0.39.0配CUDA11.8基本能解。另外量化除了4bit,8bit也够用且精度损失小,配合gradient checkpointing和torch.compile能省不少。实在不行就上vLLM,它对显存管理优化得比原生推理强很多,3090跑7B应该能稳。
试试bitsandbytes用最新版别走pip,直接源码编译,4bit量化后7B大概只要6G,绝对够用。
你这情况先看下是不是transformers版本太老,升级到最新再配load_in_4bit=True,基本能解决。
24G跑7B按理说真够,你八成是加载时把torch的默认缓存吃满了,试试在load_model之前先torch.cuda.empty_cache(),然后加载的时候把device_map设成auto,low_cpu_mem_usage其实对显存没多大帮助。bitsandbytes报错通常是版本和cuda toolkit不匹配,建议直接pip install bitsandbytes最新版,别用源码装。另外可以开gradient_checkpointing,推理时虽然没用但能减少峰值,还有attention用flash-attn,显存能省20%左右。实在不行就上llama.cpp的GGUF格式,Q4_K_M量化,CPU+GPU混合推理,3090跑起来很稳。