You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

加载含自定义AddedTokens的微调Llama模型尺寸不匹配问题求助

解决Llama-2微调后embed_tokens/lm_head权重尺寸不匹配的加载问题

核心原因

你微调时给分词器新增了3个自定义token,导致词汇表大小从32000变为32003,对应的embed_tokens和lm_head权重维度也同步扩容。但直接用AutoModelForCausalLM.from_pretrained加载时,默认会先加载原Llama-2基础模型(词汇表大小32000),再合并LoRA权重,这就触发了维度不匹配。而ignore_mismatched_sizes=True在此场景无效,因为它仅处理部分层参数数量差异,无法解决整个词汇表维度的变化问题。

正确加载步骤

1. 先加载自定义分词器

必须先加载微调时使用的、已添加新token的分词器,确保模型加载时获取正确的词汇表大小:

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("你的本地微调模型路径")
# 确认词汇表大小为32003
print(tokenizer.vocab_size)

2. 加载模型时指定词汇表大小并正确合并LoRA权重

方法一:使用peft库加载(推荐)

由于是LoRA微调,peft库可自动处理词汇表尺寸匹配:

from transformers import AutoModelForCausalLM
from peft import PeftModel, PeftConfig

# 加载LoRA配置
peft_config = PeftConfig.from_pretrained("你的本地微调模型路径")
# 加载基础模型时,用分词器的词汇表大小覆盖默认值
base_model = AutoModelForCausalLM.from_pretrained(
    peft_config.base_model_name_or_path,
    vocab_size=tokenizer.vocab_size,
    device_map="auto"
)
# 合并LoRA权重到基础模型
model = PeftModel.from_pretrained(base_model, "你的本地微调模型路径")
model = model.merge_and_unload()

# 验证尺寸匹配
print(model.get_input_embeddings().weight.shape)  # 应为[32003, 4096]
print(model.get_output_embeddings().weight.shape)  # 应为[32003, 4096]

方法二:手动调整模型尺寸后加载权重

若不使用peft库,可手动扩容基础模型的embed_tokens和lm_head,再加载微调权重:

from transformers import AutoModelForCausalLM

# 加载基础模型
base_model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-chat-hf")

# 扩容输入embedding层
old_embeddings = base_model.get_input_embeddings().weight
new_embeddings = base_model._get_resized_embeddings(old_embeddings, tokenizer.vocab_size)
base_model.set_input_embeddings(new_embeddings)

# 扩容输出lm_head层
old_lm_head = base_model.get_output_embeddings().weight
new_lm_head = base_model._get_resized_lm_head(old_lm_head, tokenizer.vocab_size)
base_model.set_output_embeddings(new_lm_head)

# 加载微调后的权重,此时尺寸已匹配
model = AutoModelForCausalLM.from_pretrained(
    "你的本地微调模型路径",
    state_dict=base_model.state_dict(),
    device_map="auto"
)

3. 验证加载结果

加载完成后,可通过简单生成测试确认模型正常处理自定义token:

inputs = tokenizer("<|move|>测试内容<|endmove|><|end|>", return_tensors="pt").to("cuda")
outputs = model.generate(**inputs, max_new_tokens=50)
print(tokenizer.decode(outputs[0], skip_special_tokens=False))

关键注意点

  • 必须保证分词器与模型的词汇表大小完全一致,这是解决此类问题的核心。
  • LoRA微调场景优先用peft库加载,它会自动处理权重匹配细节,避免手动调整的繁琐。
  • ignore_mismatched_sizes=True不适合词汇表整体扩容的场景,它无法自动扩容embedding层,只会跳过不匹配权重,导致模型缺失新token的embedding参数。

内容的提问来源于stack exchange,提问作者Stefano Mezza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 09:42:37