Llama-3.2-1B-Instruct调用transformers未触发停止令牌问题排查
问题原因
- Prompt格式不符合模型训练规范:Llama-3.2-1B-Instruct是基于结构化对话格式训练的,你自定义的
### Instruction/Draft/Revision分段格式未被模型识别为任务结束信号,导致模型无法判断何时停止生成。而Ollama和Hugging Face Playground会自动套用模型官方的聊天模板,因此能正常终止输出。 - 未配置停止序列:调用
generate方法时未指定停止令牌,模型只能依赖max_new_tokens强制截断,进而出现循环生成重复内容的情况。
解决方案
1. 使用模型官方聊天模板构建Prompt
Llama-3.2-Instruct要求输入遵循特定对话格式,通过tokenizer.apply_chat_template可自动生成合规的Prompt结构,让模型准确识别任务边界。
2. 配置生成时的停止条件
明确指定对话结束的停止令牌,让模型完成任务后自动终止生成。
修改后的完整代码:
from transformers import AutoTokenizer, AutoModelForCausalLM model_name = "meta-llama/Llama-3.2-1B-Instruct" # 加载tokenizer和模型 tokenizer = AutoTokenizer.from_pretrained(model_name) tokenizer.pad_token = tokenizer.eos_token model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto") original_text = "Hi guys, just checking in to see if you finally finished the slides for next week when we meet with Jack. Let me know asap. Cheers, John" # 用官方对话模板构建任务请求 messages = [ { "role": "user", "content": f"""Revise the following draft email so that it reads in a professional voice, preserving meaning but improving clarity, structure, and tone. Only provide the revised email and nothing else. Draft: {original_text}""" } ] # 生成合规Prompt,add_generation_prompt=True自动添加助手回复的起始标记 prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) # 生成输出,指定对话结束令牌作为停止条件 inputs = tokenizer(prompt, return_tensors="pt").to(model.device) outputs = model.generate( **inputs, max_new_tokens=200, stop_strings=[tokenizer.eos_token, "<|eot_id|>"], temperature=0.7 # 可选,控制生成内容的随机性 ) # 解码并提取助手的有效回复 result = tokenizer.decode(outputs[0], skip_special_tokens=True) assistant_response = result.split("<|start_header_id|>assistant<|end_header_id|>")[1].strip() print(assistant_response)
额外说明
- 若坚持使用自定义分段格式,可手动将
###设置为停止序列(在generate中添加stop_strings=["###"]),但这种方式的可靠性远低于官方模板。 - 后续进行风格迁移微调时,训练数据也必须遵循Llama-3.2的对话格式,否则模型无法正确理解任务边界,影响微调效果。
内容的提问来源于stack exchange,提问作者user2101255




