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

LLM生成文本输出<|endoftext|>特殊令牌的原因及解决方法咨询

kullm-polyglot-12.8b-v2流式生成末尾出现<|endoftext|>的问题解析与优化方案

问题原因

  • 令牌ID配置不匹配:你在生成参数generation_kwargs中手动指定了eos_token_id=2,但该ID可能与tokenizer实际对应的<|endoftext|>令牌ID不一致。模型生成时无法识别这个ID为终止信号,导致<|endoftext|>被当作普通文本输出。
  • Streamer默认行为:TextIteratorStreamer默认会解码并输出模型生成的所有令牌,包括特殊终止令牌,不会自动过滤。
  • 量化模型的令牌处理差异:AutoGPTQ量化后的模型在令牌识别逻辑上可能与原模型存在细微偏差,导致终止令牌未被正确拦截。

更优解决方法

方法1:统一EOS令牌配置

确保生成参数中的eos_token_id与tokenizer的配置完全一致,避免手动指定错误ID:

generation_kwargs = dict(
    input_ids=inputs.input_ids[..., :-1],
    streamer=streamer, 
    max_new_tokens=self.max_len, 
    no_repeat_ngram_size=3, 
    eos_token_id=self.tokenizer.eos_token_id,  # 使用tokenizer自带的EOS ID
    pad_token_id=self.tokenizer.eos_token_id   # 通常pad和EOS令牌一致
)

方法2:让Streamer自动过滤特殊令牌

初始化TextIteratorStreamer时设置skip_special_tokens=True,Streamer会自动过滤所有特殊令牌(包括<|endoftext|>):

streamer = TextIteratorStreamer(self.tokenizer, skip_prompt=True, skip_special_tokens=True)

方法3:循环读取时主动终止并过滤

在读取Streamer输出的循环中,检查并过滤特殊令牌,同时提前终止生成循环:

generated_text = ''
for new_text in streamer:
    if '<|endoftext|>' in new_text:
        new_text = new_text.replace('<|endoftext|>', '')
        if new_text:
            flg = [True for i in new_line_chr if i in new_text]
            if flg:
                print(new_text)
            else:
                print(new_text, end='')
        break  # 终止循环,不再读取后续内容
    # 原有处理逻辑
    flg = [True for i in new_line_chr if i in new_text]
    if new_text and flg:
        print(new_text)
    elif new_text:
        print(new_text, end='')

完整修改后的核心代码示例

def qa(self, question, instruction=''):
    if instruction:
        prompt = self.prompter_gen.generate_prompt(instruction, question)
        self.max_len *=2
    else:
        prompt = self.prompter.generate_prompt(question)

    inputs = self.tokenizer(prompt, return_tensors="pt")
    # 开启特殊令牌过滤
    streamer = TextIteratorStreamer(self.tokenizer, skip_prompt=True, skip_special_tokens=True)

    generation_kwargs = dict(
        input_ids=inputs.input_ids[..., :-1],
        streamer=streamer, 
        max_new_tokens=self.max_len, 
        no_repeat_ngram_size=3, 
        eos_token_id=self.tokenizer.eos_token_id,
        pad_token_id=self.tokenizer.eos_token_id
    )
    
    thread = Thread(target=self.model.generate, kwargs=generation_kwargs)

    return thread, streamer

内容的提问来源于stack exchange,提问作者JS J

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 16:07:49