基于Transformer的聊天机器人生成无意义重复响应问题排查求助
问题
使用Hugging Face transformers库开发聊天机器人,需识别西班牙语、加泰罗尼亚语、英语并调用对应预训练模型回复,但机器人常生成不连贯响应或重复字符。
项目结构
pythonAI/ ├── download.py ├── learner.py ├── main.py ├── model_old.py ├── modelos │ ├── ca │ │ ├── config.json │ │ ├── generation_config.json │ │ ├── merges.txt │ │ ├── model.safetensors │ │ ├── special_tokens_map.json │ │ ├── tokenizer_config.json │ │ ├── tokenizer.json │ │ └── vocab.json │ ├── en │ │ ├── config.json │ │ ├── generation_config.json │ │ ├── merges.txt │ │ ├── model.safetensors │ │ ├── special_tokens_map.json │ │ ├── tokenizer_config.json │ │ ├── tokenizer.json │ │ └── vocab.json │ └── es │ ├── config.json │ ├── generation_config.json │ ├── model.safetensors │ ├── special_tokens_map.json │ ├── tokenizer_config.json │ ├── tokenizer.json │ └── vocab.txt ├── model.py ├── nlp_processor.py ├── __pycache__ │ ├── learner.cpython-39.pyc │ ├── model.cpython-39.pyc │ ├── nlp_processor.cpython-39.pyc │ └── search_engine.cpython-39.pyc ├── README.md ├── search_engine.py └── utils.py
相关代码
nlp_processor.py(语言检测与文本预处理)
from langdetect import detect import re def detect_language(text): try: return detect(text) except: return 'unknown' def preprocess_text(text): text = re.sub(r'\s+', ' ', text).strip() return text
model.py(模型加载与响应生成)
from transformers import AutoModelForCausalLM, AutoTokenizer class ChatModel: def __init__(self): self.models = { 'es': self.load_model('./modelos/es'), 'ca': self.load_model('./modelos/ca'), 'en': self.load_model('./modelos/en') } def load_model(self, model_path): model = AutoModelForCausalLM.from_pretrained(model_path) tokenizer = AutoTokenizer.from_pretrained(model_path) return model, tokenizer def get_response(self, processed_input, lang): model, tokenizer = self.models.get(lang, (None, None)) if model is None or tokenizer is None: return "Estoy aprendiendo, pronto podré hablar en tu idioma. Escríbeme en Español, catalán o inglés." inputs = tokenizer.encode(processed_input, return_tensors='pt') outputs = model.generate(inputs, max_length=50, num_return_sequences=1, pad_token_id=tokenizer.eos_token_id) response = tokenizer.decode(outputs[0], skip_special_tokens=True) return response
main.py(主协调模块)
from nlp_processor import detect_language, preprocess_text from model import ChatModel def main(): chat_model = ChatModel() while True: user_input = input("Pregunta: ") if user_input.lower() in ['salir', 'exit', 'quit']: break detected_lang = detect_language(user_input) if detected_lang not in ['es', 'ca', 'en']: detected_lang = 'unknown' processed_input = preprocess_text(user_input) response = chat_model.get_response(processed_input, detected_lang) print(f"Chatbot: {response}") if __name__ == "__main__": main()
错误示例
输入¿hombre o mujer?时,机器人回复:
Chatbot: ¿ hombre o mujer? ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿lo??????????????????????????????????????
已完成排查
- 验证模型文件完整性
- 检查transformers、torch等依赖版本
- 确认tokenizer与对应模型匹配
环境信息
Python 3.9,transformers 4.12.5,torch 1.10.0,langdetect 1.0.9
原因分析
- 生成参数配置缺失:仅设置
max_length,未配置随机性控制参数,模型倾向于重复高概率token(如标点、常见字符)。 - 输入格式不符合训练范式:多数对话模型需要特定格式(如用户/助手前缀、分隔符),直接输入原始文本会导致生成逻辑混乱。
- tokenizer参数异常:部分模型未正确设置
pad_token,或pad_token_id与eos_token_id不匹配,导致模型无法及时停止生成。 - transformers版本老旧:4.12.5版本的
generate方法对生成逻辑的支持不完善,存在重复生成的底层缺陷。
解决方案
1. 优化生成参数
修改model.py中的generate调用,添加随机性控制参数:
outputs = model.generate( inputs, max_length=100, num_return_sequences=1, pad_token_id=tokenizer.eos_token_id, temperature=0.7, # 控制随机性,值越高输出越多样 top_p=0.9, # 核采样,仅考虑概率前90%的token repetition_penalty=1.2, # 惩罚重复出现的token do_sample=True # 启用采样模式,替代贪婪生成 )
2. 适配模型对话格式
根据所用预训练模型的要求构造输入,例如适配Llama类模型的格式:
# 在get_response方法中修改输入构造 prompt = f"Usuario: {processed_input}\nAsistente:" inputs = tokenizer.encode(prompt, return_tensors='pt')
注:不同模型的对话格式不同,需参考对应模型的官方文档调整。
3. 修复tokenizer参数
加载tokenizer时显式设置pad_token:
def load_model(self, model_path): model = AutoModelForCausalLM.from_pretrained(model_path) tokenizer = AutoTokenizer.from_pretrained(model_path) # 若tokenizer无pad_token,将其设置为eos_token if tokenizer.pad_token is None: tokenizer.pad_token = tokenizer.eos_token return model, tokenizer
4. 升级transformers版本
旧版本存在生成逻辑缺陷,升级到4.30.0+版本:
pip install --upgrade transformers
5. 优化文本预处理
修复西班牙语/加泰罗尼亚语标点后的空格问题,统一输入格式:
def preprocess_text(text): text = re.sub(r'\s+', ' ', text).strip() # 修复标点与文本间的空格 text = re.sub(r'¿\s+', '¿', text) text = re.sub(r'\s+\?', '?', text) text = re.sub(r'¡\s+', '¡', text) text = re.sub(r'\s+!', '!', text) return text
内容的提问来源于stack exchange,提问作者konguele
相关产品推荐
相关产品推荐

