最近在HuggingFace上找了个热门的Llama-3-8B中文微调版(好像是某团队用Alpaca数据搞的),想在自己的笔记本上跑个推理试试。结果用Transformers库加载,一跑就报RuntimeError: Expected all tensors to be on the same device,但明明已经把模型和输入都移到CPU上了。我怀疑是不是加载时候的参数设置有问题?比如device_map="auto"还是得手动指定?或者那个微调版本本身需要特定的tokenizer配置?
顺便问下,有没有老哥踩过类似的坑?我只有16G内存+无独显,是不是本地根本跑不动8B模型?或者说有什么轻量化的替代方案(比如4bit量化)推荐?求指点,谢谢!
HuggingFace上那个Llama-3中文微调版,为啥在我本地上推理总报错?
全部回复
共 164 条这报错大概率是微调时部分权重绑定了特定设备,加载时device_map='auto'可能会把某些层分配到不存在的设备上。建议试试手动指定model.to('cpu'),同时检查tokenizer有没有单独配置device参数。16G内存跑8B确实吃力,我32G都经常爆显存换CPU推理,你可以考虑用bitsandbytes加载4bit量化版,能省不少内存。
这个问题我也遇到过,当时搞了好久才发现是tokenizer的padding side没设置对,微调模型默认用左侧padding,你试试tokenizer.padding_side = 'left'。另外16G内存跑8B模型确实有点悬,量化到4bit或者用llama.cpp可能更稳,device_map="auto"在无独显时反而容易出幺蛾子。还有那个报错大概率是某个中间层参数卡在GPU上了,建议加个model.to('cpu')再重新加载输入试试。
这报错八成是tokenizer的padding side没对齐,有些中文微调版默认右侧填充但模型训练时用的左侧,导致attention mask错位,试下tokenizer里加个padding_side='left'。另外device_map="auto"在纯CPU环境确实容易出幺蛾子,直接删掉这参数,手动把model.to('cpu')和input_ids.to('cpu')分开写试试。16G内存跑8B量化版勉强能行,但原版fp16肯定爆,建议下个4bit或8bit的GGUF版本用llama.cpp跑,速度反而比transformers快不少。
这问题多半是模型本身带了device_map的预设,你手动加载时又传了CPU,两边冲突了。试试直接删掉device_map参数,或者显式写device_map={"": "cpu"},应该能解决。至于16G内存跑8B,其实纯CPU推理勉强能跑,就是慢得怀疑人生,建议量化成4bit或者用llama.cpp,体验会好很多。另外注意下tokenizer有没有跟着模型一起加载,有的微调版会改special tokens,不匹配也会出幺蛾子。
这报错八成是device_map和tokenizer没配合好,我上次跑别的微调模型也遇到过,手动指定device_map={"": "cpu"}基本能解决。16G内存跑8B确实很勉强,我32G都经常爆显存换内存,建议你试试4bit量化加载,或者直接换7B以下的模型,不然就算不报错推理速度也慢得怀疑人生。
八成是tokenizer和模型没配对,换个微调项目自带的config试试,别用auto硬扛。16G内存跑8B有点悬,建议上4bit量化。
八成是device_map="auto"在没GPU时把层拆散了,你手动设device_map={"": "cpu"}试试,16G内存跑8B得量化到4-bit才行。
这报错我熟,八成不是device_map的锅,是tokenizer返回的attention_mask跟input_ids没对齐。有些中文微调版改过tokenizer的padding侧,你直接默认加载的话,生成的mask可能全在右边,但模型内部又按左边对齐,device不一致就炸了。你试试加载时显式传tokenizer.padding_side = "left",然后把input_ids和attention_mask都单独.to("cpu")再传进去,比用device_map="auto"省心。
另外16G内存纯CPU跑8B真不是闹着玩的,我32G内存跑量化版都卡到怀疑人生。你那个报错其实算轻的,后面还会遇到OOM或者推理慢到像死机。建议先下个4bit或8bit的GGUF版本,用llama.cpp跑,内存占用能压到6G左右,速度勉强能出字。至于那个微调版本身,大概率是训练时用了特殊chat模板,你直接用base模型的tokenizer加载会漏掉一些特殊token,最好去他们GitHub看下有没有配套的conversation模板文件。
这报错八成是tokenizer的padding side或者attention mask没对齐,有些中文微调版改了特殊token,加载时得用他们repo里给的config和tokenizer文件,别直接套原版。device_map="auto"在无GPU机器上反而可能出问题,手动写device="cpu"试试。16G内存跑8B量化版勉强能行,但原版fp16肯定爆,去下个4bit或8bit的GGUF版本吧,llama.cpp比transformers省心多了。
这报错八成是device_map和手动device冲突了,你试试加载时直接删掉device_map参数,然后明确写model.to("cpu"),别让transformers自动分配。16G内存跑8B量化版其实勉强能行,但如果是fp16原版肯定爆,建议下个4bit或8bit量化版,顺便确认下tokenizer是不是用的原版llama3的,有些微调repo会改special token,不匹配也会出诡异问题。
这报错八成不是设备问题,而是模型配置里藏着个硬编码的device索引。很多中文微调版在保存config.json时会把torch_dtype和device_map写死,你手动load的时候它内部某个子模块还在试图往cuda上放。建议先检查下模型的config.json里有没有"device_map"字段,有的话直接删掉再加载,或者用torch_dtype=torch.float32强制覆盖。另外16G内存跑8B确实够呛,光是模型权重fp32就得32G,就算量化到int8也得8G,加上激活值和中间变量,你内存大概率会爆。不过可以试试用load_in_8bit=True配合llm_int8_enable_fp32_cpu_offload=True,但前提是得装bitsandbytes的CPU版,而且速度会慢到怀疑人生。我当初用32G内存跑7B的q4量化版都卡成PPT,你这配置建议直接用llama.cpp的GGUF格式,比Transformers省太多资源。至于tokenizer,中文微调版基本都得从原版Llama-3的tokenizer改,如果报错里没提tokenizer相关的键值对冲突,那大概率不是它的锅。
八成是device_map和tokenizer没对齐,试试手动指定device和pad_token_id。16G内存跑8B确实悬,建议换4bit量化版。
这报错八成是tokenizer没跟着模型一起走,微调版经常改了词表但加载时没指定对应tokenizer,导致输入ID对不上。你试试用AutoTokenizer.from_pretrained加载同一个目录下的tokenizer,别用默认的。另外16G内存跑8B真的够呛,就算勉强加载了,推理速度也会慢到怀疑人生,建议先量化成4bit或者用GGUF版本试试。
这报错八成是tokenizer和模型没对齐,有些中文微调版会改special token,你加载时得用人家仓库里配套的tokenizer文件,别用原版Llama的。device_map="auto"在你这种纯CPU环境反而容易出幺蛾子,直接不写或者设成None,手动model.to("cpu")更稳。16G内存跑8B量化版勉强能行,但fp16肯定爆,建议下4bit或8bit的gguf格式,用llama.cpp跑比transformers省心。我之前也是笔记本没独显,折腾半天最后换llama.cpp才消停。
这报错我熟,八成不是设备映射的事,而是模型内部某些层被硬编码到了GPU上,比如position_ids或者attention_mask的创建逻辑没走model.device。你试试加载时加个torch_dtype=torch.float32,再把device_map=None,然后手动model.to("cpu"),如果还报错就检查下tokenizer返回的input_ids是不是在cpu上,有时候是tokenizer默认返回cuda:0的张量。另外那个微调版如果用了bitsandbytes的4bit量化,没装对应库或者CPU不支持也会出这种幺蛾子。
16G内存跑8B纯CPU推理其实能跑,但速度会非常感人,大概每秒一两token吧,而且容易爆内存,因为transformers默认会把中间激活值全存下来。建议用model.generate(..., use_cache=True)加low_cpu_mem_usage=True,再配合torch.inference_mode(),能省不少内存。不过说实话,这种微调版多半是针对GPU调的,CPU上跑各种隐性bug特别多,不如直接换个GGUF量化版用llama.cpp跑,省心得多。
多半是device_map="auto"在没GPU时抽风了,改成device_map="cpu"试试。16G内存跑8B量化版勉强能行,原版肯定爆。
这报错八成是device_map和tokenizer的锅,有些中文微调版会改pad_token,你试试加载时明确device_map={"": "cpu"},再把tokenizer的pad_token设成eos_token。16G内存跑8B其实能跑,就是慢,但得用4bit量化,不然容易爆内存,我上次用bitsandbytes配load_in_4bit就稳了。
八成是device_map没写好,试试load_in_8bit加手动指定device,16G内存能跑但慢得怀疑人生。
这报错八成是tokenizer和模型没对齐,有些中文微调版改过词表,得用他们仓库里那个tokenizer_config.json,直接用原版Llama的肯定炸。device_map那玩意儿在纯CPU下反而容易出幺蛾子,你直接model.to("cpu")然后input也.to("cpu")试试,别用auto。16G内存跑8B其实够呛,光模型权重就占15G多,再加上中间变量铁定爆,建议你上GGUF量化版,或者用llama.cpp跑,别死磕transformers。
这报错八成是tokenizer和模型没对齐,有些中文微调版会改词表,你直接加载原版tokenizer就容易出这种幺蛾子,建议去项目页确认下有没有配套的tokenizer文件。另外16G内存跑8B确实极限了,就算加载成功生成起来也慢得想砸电脑,我上次用CPU跑7B模型一个回复能等三分钟,不如试下4bit量化或者直接找找小点的中文模型。