最近在试着把7B的模型部署到本地,显卡是3090(24G),按理说应该够用,但一加载就说CUDA out of memory。我试了加载时传low_cpu_mem_usage=True,也试了把max_memory分配给GPU,但好像没多大用。我看网上说用bitsandbytes做4bit量化,但装了之后又报错说找不到CUDA的setup.py,心态有点崩。就想问问大家,实际部署的时候一般怎么配参数?是不是需要把加载的模型分片到多卡或者用offload?另外,除了量化,还有哪些比较实用的显存优化思路?希望能给个可操作的步骤,谢谢了。
部署LLaMA模型一直OOM,大佬们都是怎么优化显存的?
全部回复
共 103 条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,但推理速度会明显变慢,看你能不能接受。
7B模型全精度加载确实得14G显存,但推理时KV cache和中间激活一叠加就容易爆,尤其batch开大了。你试试device_map="auto"配合load_in_4bit=True,bitsandbytes那个setup.py报错一般是CUDA版本没对上,重装跟torch匹配的版本就行。另外把torch_dtype设成float16也能省一半,再不行就上vLLM或者llama.cpp的量化推理,比直接transformers加载省心很多。
7B模型24G按理说确实够,你卡在加载阶段多半是默认用fp32加载了,7B乘4字节就28G直接爆。试试torch_dtype=torch.float16,配合device_map="auto",基本能压到14G左右。bitsandbytes那个setup.py报错一般是CUDA版本和包不匹配,建议直接用pip装对应cuda版本的wheel,或者干脆上GPTQ/AWQ的量化权重,比在线量化省心。offload能救急但推理会慢很多,能不上就不上。
3090跑7B还OOM挺奇怪的,除非你加载的是fp32权重,那确实要28G左右直接爆掉。先确认一下你用的dtype是不是float16或者bfloat16,这个不设的话默认float32最容易踩坑。bitsandbytes那个setup.py报错一般是CUDA版本和编译环境没对上,可以试试装预编译wheel或者直接用官方推荐的版本组合,别自己硬编。真要用4bit量化的话,load_in_4bit=True配合bnb_4bit_compute_dtype=float16基本能把7B压到6G以内,3090绰绰有余。另外device_map="auto"让它自己分,别手动max_memory,有时候手动分配反而把权重全塞一张卡上了。如果还不行就上accelerate的offload,把部分层丢到CPU内存,速度慢点但能跑起来。其实还有个容易被忽略的点,推理时的KV cache也吃显存,batch开大了照样炸,把max_new_tokens和batch size控制一下会好很多。
3090跑7B按理说真不该OOM,先看看是不是加载时用了fp32,改成torch_dtype=torch.float16能省一半。bitsandbytes那个报错一般是CUDA版本和包对不上,建议直接用pip装对应cuda版本的wheel,别自己编译。量化之外还可以试试device_map="auto"配合accelerate做CPU offload,或者用vLLM这类推理框架,显存管理比transformers好很多。
7B加载就OOM大概率是默认fp32加载了,你试试torch_dtype=torch.float16或者bfloat16,显存直接砍一半。bitsandbytes那个报错是编译环境问题,装个预编译wheel或者直接用pip install bitsandbytes --upgrade应该能解决。另外推理时把max_new_tokens和batch压小点,KV cache也很吃显存。offload确实能用但速度会明显变慢,3090单卡跑7B 4bit其实挺稳的。
7B加载OOM有点怪,3090跑fp16也就14G左右,你先确认下是不是加载时默认用了fp32。bitsandbytes那个setup.py报错基本是CUDA版本和它编译时对不上,建议直接pip装跟torch匹配的wheel版本,别自己编译。量化之外可以试试device_map="auto"配合accelerate做CPU offload,或者用vLLM、llama.cpp这类推理框架,它们对显存的管理比裸transformers好不少。
试试device_map="auto"配合4bit量化,显存能压到8G左右,基本能跑。