微调Mistral 7B模型后如何限制生成文本长度?
解决Mistral-7B生成过长文本的问题
问题根源
你当前的配置存在几个关键问题:
- tokenizer的
max_length和truncation是用于输入文本预处理的截断规则,无法控制模型生成阶段的输出长度 - 将
pad_token设为unk_token会导致模型对填充token的识别混乱,干扰生成停止逻辑 - 生成阶段未配置控制输出长度和停止条件的核心参数
具体修复方案
1. 修正Tokenizer配置
将pad_token改为eos_token,同时移除tokenizer上全局的max_length和truncation设置(这些应在tokenize输入时按需指定):
tokenizer = AutoTokenizer.from_pretrained(base_model, trust_remote_code=True) tokenizer.padding_side = 'right' # 用eos_token作为pad_token,避免模型混淆 tokenizer.pad_token = tokenizer.eos_token # 确保eos_token已正确设置 tokenizer.add_eos_token = True
2. 生成阶段添加长度控制参数
在调用模型生成时,必须传入以下核心参数来限制输出长度并触发停止:
max_new_tokens:控制模型新增生成的token数量(推荐设为100-300,根据需求调整)eos_token_id:指定模型遇到该token时停止生成early_stopping:确保模型遇到停止token后立即终止do_sample:若不需要随机性,设为False用贪心生成更可控
示例生成代码:
prompt = "你的输入提示文本" # 处理输入 inputs = tokenizer(prompt, return_tensors="pt").to("cuda") # 生成响应 outputs = model.generate( **inputs, max_new_tokens=200, # 控制新增生成的token数 eos_token_id=tokenizer.eos_token_id, early_stopping=True, do_sample=False, # 可选,关闭采样提升可控性 temperature=0.7 # 若开启采样,可调整温度控制随机性 ) # 解码输出 response = tokenizer.decode(outputs[0], skip_special_tokens=True) print(response)
3. 额外优化建议
- 检查微调数据格式:确保微调数据中每个样本都以eos_token结尾,让模型学习正确的停止逻辑
- 若仍出现生成后续问题的情况,可在prompt末尾明确添加停止标识(如"### 回答结束"),并将该标识对应的token加入
stop_token_ids参数中:
stop_token_ids = tokenizer.convert_tokens_to_ids(["### 回答结束"]) outputs = model.generate( **inputs, max_new_tokens=200, eos_token_id=tokenizer.eos_token_id, stop_token_ids=stop_token_ids, early_stopping=True )
内容的提问来源于stack exchange,提问作者Rishita Bapu Mote
相关产品推荐
相关产品推荐

