最近在试着把7B的模型部署到本地,显卡是3090(24G),按理说应该够用,但一加载就说CUDA out of memory。我试了加载时传low_cpu_mem_usage=True,也试了把max_memory分配给GPU,但好像没多大用。我看网上说用bitsandbytes做4bit量化,但装了之后又报错说找不到CUDA的setup.py,心态有点崩。就想问问大家,实际部署的时候一般怎么配参数?是不是需要把加载的模型分片到多卡或者用offload?另外,除了量化,还有哪些比较实用的显存优化思路?希望能给个可操作的步骤,谢谢了。
部署LLaMA模型一直OOM,大佬们都是怎么优化显存的?
全部回复
共 93 条24G跑7B按理说真够,但你这个报错大概率是加载时峰值爆了,因为transformers默认会把整个权重一次性载入显存,加上激活值和KV cache就超了。我建议你试试load_in_4bit=True配合bnb_4bit_compute_dtype=torch.float16,同时把device_map设成"auto",这样bitsandbytes会自动把部分层放到CPU,虽然慢点但能跑起来。至于你说的setup.py报错,多半是bitsandbytes版本和CUDA不匹配,直接pip install bitsandbytes --upgrade试试,或者去GitHub下预编译的wheel。还有个思路是换用llama.cpp的GGUF格式,量化到Q4_K_M大概6G多,3090跑起来很轻松,而且CPU offload也简单,不用折腾transformers那套。另外可以把max_new_tokens限制短一点,或者用vLLM这类推理框架,它们有PagedAttention能省不少显存,但7B用vLLM有点大材小用。最后实在不行就上offload,把embedding和lm_head放CPU,但要注意这会增加延迟。反正别死磕bitsandbytes,多试几条路。
24G跑7B按理说真够,问题大概率出在你加载时是FP16全精度,光权重就占14G,加上KV cache和中间激活值,峰值轻松爆掉。我之前也是3090,后来直接上bitsandbytes的4bit,但你说装的时候报CUDA setup.py那个错,多半是版本没对齐,建议先确认torch版本是cu118还是cu121,然后pip install bitsandbytes==0.41.1这种对应版本,别用最新版。加载时记得加load_in_4bit=True,还有device_map="auto",这样模型会自动切分到GPU和CPU,虽然慢一点但不会OOM。另外你可以试试把max_seq_len调短,比如默认2048改成1024,显存占用直接少一截,因为KV cache是按序列长度线性增长的。还有一个冷门技巧,用torch.compile或者开启gradient_checkpointing(推理时不需要,但能降低峰值),不过最实在的还是先量化,再配合offload到内存,基本上7B就能稳定跑起来了。要是还报错,把transformers升级到4.36以上,老版本对4bit支持很多坑。
24G跑7B全精度确实紧,但也不至于一上来就OOM,八成是加载时把权重和中间激活一起算进去了。你可以试试先把模型放到CPU上,然后一步步往GPU挪,或者用accelerate的device_map="auto"让它自己分配,比手动指定max_memory靠谱。bitsandbytes报错大概率是版本和CUDA不匹配,直接装源码版或者换0.39.0试试。另外别忽略flash-attention,它能把KV cache省一大截,比单纯量化效果明显。
我之前也卡在你这步,24G跑7B其实很宽裕,问题多半出在加载时把模型和缓存都塞进显存了。试试先设环境变量PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128,再配合bitsandbytes的4bit,不过报错的话可以换老版本0.39试试,那个对CUDA setup兼容性好些。另外,加载完记得torch.cuda.empty_cache()一下,或者用accelerate的device_map="auto"让它自动分配,比手动塞max_memory靠谱多了。
你试试用transformers的device_map="auto"配合bitsandbytes,但先确认下bitsandbytes版本跟你的cuda版本匹配,报setup.py那个错大概率是版本问题,直接pip install bitsandbytes最新版一般能解决。另外7B在24G上其实可以跑8bit,不一定要4bit,4bit质量损失有点明显,而且加载时把attn_implementation="flash_attention_2"打开也能省不少显存。如果还不行,就把max_memory设成{0: "20GiB"}然后offload到CPU,推理慢点但至少不OOM。
24G跑7B按理说真够,你八成是加载时把float32的完整权重读进去了,试试load_in_4bit=True加上device_map="auto"这两行,能直接砍掉一大半显存。bitsandbytes那个报错大概率是版本和CUDA不匹配,去GitHub装对应的预编译wheel就行,别用pip默认源。另外你可以开flash attention,能省不少显存还提速,transformers里直接传attn_implementation="flash_attention_2"就行。如果还不行,就把max_memory设成{0: "20GiB"},剩下的留给CPU offload,速度慢点但至少不崩。
24G跑7B按理说真够,你八成是加载时峰值爆了,试试先设低一点max_memory比如20G,然后开gradient_checkpointing。bitsandbytes报错大概率是版本匹配问题,建议直接pip install bitsandbytes==0.43.0配transformers 4.40,或者用auto_gptq装4bit省心点。别急着上多卡offload,7B单卡量化后能到6-8G,你先把加载顺序改成先配device_map='auto'再调量化,很多时候是模型默认fp32把显存全占了。
量化报错大概率是版本不匹配,先试试transformers和bitsandbytes都升到最新,顺便开下load_in_4bit。
量化用bitsandbytes得先确认cuda版本匹配,我上次直接换transformers自带load_in_4bit就好了。
量化就用gptq或awq,别死磕bitsandbytes,加载时加句device_map="auto"试试,offload也能救急。
3090跑7B其实用不着硬刚全精度,直接上bitsandbytes的4bit加载,你那个报错大概率是版本没配对,先检查下CUDA toolkit和bitsandbytes的wheel版本,我之前卡这步卡了一下午。另外加载的时候记得把device_map设成auto,让它自动分配,别手动指定max_memory,容易把显存碎片化搞得更糟。如果还想再省点,可以试试把attention的KV cache用8bit存,或者用flash-attention,我这边3090跑7B量化后峰值也就11G出头。
7B模型24G显存还OOM,大概率是加载方式没走device_map,默认会先往CPU内存堆一份再拷到GPU。你试试from_pretrained时加device_map="auto"配合torch_dtype=torch.float16,一般就能压到14G左右。bitsandbytes那个setup.py报错通常是CUDA版本和编译环境不匹配,直接pip装它预编译的wheel会省事很多。真要量化的话GPTQ比bnb更稳,4bit下7B只占4G出头,推理速度也还行。
7B加载就OOM大概率是加载方式的问题,试试用device_map="auto"配合torch_dtype=torch.float16,别默认fp32加载,光权重就28G了肯定爆。bitsandbytes那个报错是版本和CUDA不匹配,建议直接用pip装最新的,或者干脆换GPTQ/AWQ量化模型,省心很多。真要极致省显存可以上accelerate的offload,把部分层丢到CPU,但推理速度会明显变慢,看你能不能接受。