最近在试着把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纯bf16权重也就14G,按理说不该OOM,你八成是加载时把fp32的checkpoint直接读进去了,试试torch_dtype=torch.float16这个参数,能省一半。bitsandbytes报错大概率是版本和CUDA不匹配,去GitHub下对应的wheel装就行,别用pip默认源。实在不行就device_map="auto"配合load_in_4bit=True,让transformers自己调度,3090跑7B量化后显存占用能压到6G以内,还能塞个长上下文。
24G跑7B按理说真够,问题大概率出在加载时默认把fp32权重全塞显存了,试试load_in_4bit=True加bnb_4bit_compute_dtype=torch.float16,能直接砍掉四分之三占用。bitsandbytes报错的话,检查下版本是不是跟torch不匹配,我上次就是torch2.1配了老版本才炸的。另外transformers里device_map="auto"会自动帮你做层间offload,比手动分max_memory省心很多,可以先从这条路径试起。如果还想再抠点显存,可以开torch.compile或者用flash-attention,但3090上收益可能没那么明显。
24G跑7B按理说真够,但你八成是加载时把fp16的权重全塞进去了,峰值直接爆掉。我一般先开torch_dtype=torch.float16,再加device_map="auto",这样transformers会自动把部分层丢到CPU,速度慢点但至少不崩。bitsandbytes那个报错大概率是版本跟CUDA不匹配,你检查下是不是用了太新的包,或者直接conda装cuda toolkit再pip装对应版本,别硬刚setup.py。除了4bit量化,你可以试试load_in_8bit,效果也还行,或者用accelerate的init_empty_weights先不加载权重,再分批填进显存,能省下不少临时占用。另外注意下输入序列长度,7B的KV cache很吃显存,把max_new_tokens调小,或者用flash_attention,能少好几G。还有个骚操作是直接改transformers源码,把attention换成xformers,但容易踩坑,不建议新手搞。我3090跑7B都是量化到4bit加max_memory={0: "20GiB"},剩下全扔CPU,推理慢点但稳定,你先试试这个组合,大概率能解决。
24G跑7B按理说真够,但你这个问题大概率出在加载时的峰值显存上,transformers默认会先把fp16权重完整塞进显存再开始推理,中间还有临时buffer,所以看起来像爆了。我建议你试试device_map="auto"配合low_cpu_mem_usage=True,但关键是别手动指定max_memory,让accelerate自己分配,有时候你给的数值反而限制了它利用碎片空间。bitsandbytes报错大概率是版本和CUDA不匹配,直接pip install bitsandbytes==0.41.0这种老版本配CUDA11.8试试,或者换用int8的load_in_8bit=True,那个对3090兼容性更好。另外你其实可以完全不用量化,用transformers的attn_implementation="flash_attention_2"能省不少激活值显存,特别是长序列时效果明显。如果还不行,就开offload,把部分层放到CPU上,但速度会慢不少,推理时用torch.inference_mode()加上no_grad也能省点。最后一个小技巧,加载后立即用torch.cuda.empty_cache()清一下缓存,有时候是之前跑过的实验残留。
量化确实是最直接的,试试bnb的4bit加load_in_4bit=True,记得先装匹配cuda版本的bitsandbytes。
加载时把device_map设成auto,让accelerate自动切分,能省不少事。
量化确实是最直接的,但建议直接用GPTQ或AWQ,bitsandbytes在Windows上容易踩坑。另外加载时加个device_map="auto"能自动分流,比手动配max_memory省心。
24G跑7B其实完全够,问题多半出在加载方式上——HuggingFace默认会先把权重全部读进CPU再往GPU搬,这时候峰值显存能到30G+,所以low_cpu_mem_usage=True其实没解决根本问题。我建议你直接上bitsandbytes的4bit,但别用pip装,去GitHub拉源码编译,或者用conda装预编译包,那个setup.py报错大概率是版本和CUDA toolkit不匹配。加载时记得指定device_map="auto"和torch_dtype=torch.float16,这样它会自动把部分层放CPU,实测能压到12G以内。如果还不行,试试transformers的load_in_8bit,比4bit稳定,速度也快。另外可以关掉gradient checkpointing(推理时不需要),用torch.compile配合reduce-overhead能省不少显存。分片到多卡其实没必要,3090单卡推理7B量化后很轻松,offload到CPU反而会拖慢速度。最后查一下你是不是把max_memory设成24G了,留个2G给CUDA context和激活值,设成22G比较稳。
3090跑7B按理说是够的,你这个问题大概率出在加载方式上,默认的torch会把权重全塞进显存,24G其实很紧。我建议你先别纠结量化,试试把model.max_memory设成{0: "20GiB", "cpu": "40GiB"},然后配合device_map="auto",这样能自动把溢出的层放CPU,速度慢点但至少不崩。bitsandbytes那个报错通常是版本问题,得装跟CUDA版本匹配的,比如cu118对应0.41.3,别用pip直接拉最新的。另外你检查下是不是装了多个transformers版本,有时候这会导致offload逻辑没生效。实在不行就换GPTQ或者AWQ量化,不用bitsandbytes那套,直接加载4bit的预量化模型,比如TheBloke的GGUF格式,配合llama.cpp跑,显存占用能压到10G以内。最后提醒下,加载前清空一下CUDA缓存,torch.cuda.empty_cache(),有时候是之前跑的进程占着显存没释放。分片到多卡其实没必要,单卡加CPU offload够用,除非你追求速度才上多卡。
24G跑7B按理说真够,问题多半出在加载瞬间的峰值显存,试试先加载到CPU再逐步往GPU挪,或者用device_map="auto"让accelerate自动分配。bitsandbytes报错大概率是版本和CUDA不匹配,直接pip install bitsandbytes==0.41.0配上transformers 4.35左右能省心不少。另外别死磕量化,开torch.compile和gradient_checkpointing(推理时其实用不上)不如直接改加载dtype为float16,再配合max_memory={0: "20GiB"}留出余量。真要极致省显存,试试llama.cpp的GGUF格式,Q4_K_M量化后基本只吃6-7G,速度和显存都友好得多,就是部署流程得换一套。
试试加载时加个device_map="auto",配合bitsandbytes的4bit一般就够了,3090跑7B其实挺宽裕的。
量化报错大概率是版本问题,直接pip install bitsandbytes换个版本试试,别死磕setup.py。
24G跑7B按理说真够,但你八成是加载时把float32的权重全怼进显存了,7B光权重就28G,不爆才怪。我一般是先torch_dtype=torch.float16,这步能直接砍一半,然后再配合bitsandbytes的4bit,不过你那个报错大概率是bitsandbytes版本和CUDA版本对不上,试试pip install bitsandbytes==0.41.1配CUDA11.8,或者干脆用transformers自带的load_in_4bit=True,它会自动处理底层依赖。另外别迷信low_cpu_mem_usage,那个只管CPU内存,跟显存没关系,真正有用的是device_map="auto",让accelerate库自动帮你把部分层塞到CPU或者另一张卡上,不过单卡的话offload到CPU会慢到怀疑人生,只适合用来测功能。还有个野路子,把max_seq_len调小,比如4096降到2048,KV cache能省出好几个G,如果只是跑推理不是微调,这个改动最立竿见影。最后说一句,3090的24G其实跑7B的4bit量化后大概只要6-8G,你完全有冗余,剩下的显存可以开大batch或者塞长上下文,但如果只是想让它跑起来,优先检查是不是加载了原版safetensors没转精度,很多人栽在这。
24G跑7B按理说是够的,问题多半出在加载时峰值显存爆炸,试试先把模型放到CPU上,再用accelerate的device_map="auto"让它自己分配,能避免一次性全塞进GPU。bitsandbytes报错大概率是版本跟CUDA不匹配,建议直接pip install bitsandbytes从源码装,或者换0.39版本试试。除了4bit量化,你还可以用torch.compile配合bfloat16,显存能再省不少。另外检查下是不是装了flash-attention,那个对显存占用影响挺大的,有时候反而帮倒忙。
量化那步真别急着上,先试试load_in_8bit,稳定多了,4bit那套太折腾。
直接上vLLM吧,PagedAttention对显存友好太多,3090跑7B基本无压力。
量化确实是最直接的,bitsandbytes报错多半是版本不匹配,换个0.39.0试试基本能解决。
24G跑7B纯推理其实挺宽裕的,问题多半出在加载时PyTorch默认把权重和中间激活都塞进显存。你可以试试加载时加个device_map="auto",再配合bitsandbytes的4bit,但报错那个setup.py大概率是版本不匹配,建议直接pip install bitsandbytes从源码装,或者用conda装cuda对应的版本。另外你还可以开flash attention,能省不少激活显存,如果还不行就把max_memory设成{"cuda:0": "20GiB", "cpu": "16GiB"},让部分层offload到内存,速度慢点但能跑。
量化那条路没错,报错一般是bitsandbytes版本和CUDA不匹配,换个对应版本就行。另外加载时加个device_map="auto"能自动分流,24G跑7B其实够用。
试试把max_memory设成{"gpu": 20000, "cpu": 4000},剩下的offload到内存,再配合4bit基本能稳住。
24G跑7B其实挺宽裕的,问题大概率出在加载时瞬间峰值显存上,可以试试先加载到CPU再逐步搬到GPU,或者用accelerate的device_map="auto"让它自动分配。bitsandbytes报错多半是版本和CUDA不匹配,建议直接pip install bitsandbytes--upgrade或者从源码编译试试。除了量化,你还可以把attention的KV cache开成8bit,或者用torch.compile配合内存碎片整理,效果也挺明显的。顺便问下你用的是HuggingFace的transformers还是vLLM?后者对显存控制更友好一些。
试试bitsandbytes的4bit加载,记得先把CUDA toolkit版本对齐,能省一大半显存。
试试bitsandbytes换个版本装,你这报错多半是cuda版本没对上,另外加载时加句device_map="auto"能自动帮你分片省心不少。
试试bitsandbytes先升级到最新版,4bit加载前记得设一下bnb_4bit_compute_dtype,不然照样爆显存。另外加载时加个device_map='auto',让transformers自己分配,比手动offload省心多了。