当你在 ChatGPT 中输入一个问题,模型生成一段流畅的回答后优雅地停下——这个看似简单的"停止"动作背后,隐藏着一个被大多数人忽视却至关重要的机制:EOS Token。这个特殊的词汇表条目,像一个隐形的句号,决定了大模型何时该闭嘴。

一个被低估的基础概念

在自然语言处理领域,End of Sequence Token(序列结束标记)通常简写为 EOS 或 <eos>,是词汇表中一个预留的特殊 token。当模型在自回归生成过程中输出这个 token 时,生成流程就此终止。

这个概念听起来简单得近乎平庸。然而,正是这个简单的机制,支撑着所有现代大语言模型的生成行为。从 GPT-2 的 ``, 到 Llama 的 </s>,从 Mistral 的 <|im_end|> 到各种自定义模型的专属标记,每个模型都必须面对同一个问题:如何教会一个神经网络知道自己该什么时候停下来。

graph LR
    subgraph 序列生成流程
        A[输入 Token 1] --> B[输入 Token 2]
        B --> C[...]
        C --> D[下一个 Token 预测]
        D --> E{是否 EOS?}
        E -->|是| F[停止生成]
        E -->|否| G[继续预测]
        G --> D
    end
    
    style E fill:#ff9800,stroke:#f57c00,color:#fff
    style F fill:#4caf50,stroke:#388e3c,color:#fff

为什么不能只靠最大长度限制

一个自然的疑问是:为什么不能简单地设置一个最大生成长度,让模型生成到指定字数就强制停止?

这种做法存在致命缺陷。首先,它会破坏文本的完整性——一句"今天天气很好,适合出门"可能在"出"字处被截断,变成语义残缺的碎片。其次,不同场景需要的回答长度差异巨大:一个简单的"是"或"否"可能只需要一个词,而复杂的技术解释可能需要数百字。固定的最大长度无法适应这种多样性。

graph TD
    subgraph 最大长度截断的问题
        A1["完整的句子:<br/>今天天气很好,适合出门散步"] --> B1["截断后:<br/>今天天气很好,适合出门"]
        B1 --> C1["❌ 语义不完整"]
    end
    
    subgraph EOS Token 的优雅方案
        A2["模型学习自然结束点"] --> B2["根据上下文决定何时停止"]
        B2 --> C2["✓ 语义完整的输出"]
    end
    
    style C1 fill:#f44336,stroke:#d32f2f,color:#fff
    style C2 fill:#4caf50,stroke:#388e3c,color:#fff

EOS token 提供了一种优雅的解决方案:让模型自己决定何时结束。模型通过学习训练数据中的结束位置,能够根据上下文自然地终止生成,产生语义完整的输出。

模型如何学习"何时停下"

预训练阶段的 EOS 学习

在预训练阶段,模型通过下一个 token 预测任务学习语言。训练数据通常由大量文档组成,每个文档末尾会被添加一个 EOS token。模型的目标是在给定前面所有 token 的情况下,预测下一个 token 是什么。

# 典型的预训练数据格式
document = "The quick brown fox jumps over the lazy dog."
training_sequence = document + "``"

# 模型学习在文档末尾预测 EOS token
# Input: "The quick brown fox jumps over the lazy dog"
# Target: "``"
graph LR
    subgraph 预训练数据格式
        A[文档内容] --> B[添加 EOS Token]
        B --> C["The quick brown fox... + &lt;eos&gt;"]
    end
    
    subgraph 训练目标
        D["输入: ...lazy dog"] --> E["目标: &lt;eos&gt;"]
        F["输入: ...brown fox"] --> G["目标: jumps"]
    end
    
    C --> D

当模型在训练中反复看到"文档结尾 → EOS token"的模式,它逐渐学会在语义完整的文本末尾输出 EOS。这不仅仅是记忆特定位置,而是理解什么样的文本结构标志着结束。

关键的训练细节:损失掩码

在训练过程中,一个关键的技术细节是如何处理 padding 和 EOS token 的损失计算。HuggingFace 的 DataCollator 采用了 -100 作为忽略索引的惯例:

# HuggingFace DataCollator 中的典型处理
if self.tokenizer.pad_token_id is not None:
    labels[labels == self.tokenizer.pad_token_id] = -100

这个 -100 在 PyTorch 的 CrossEntropyLoss 中会被自动忽略,不参与梯度计算。这确保了模型只在有意义的内容 token 和 EOS token 上学习,而不是在填充的无意义 token 上浪费计算资源。

graph TD
    subgraph 批量训练数据示例
        A["样本1: Hello world &lt;eos&gt; &lt;pad&gt; &lt;pad&gt;"]
        B["样本2: This is a longer sentence &lt;eos&gt;"]
    end
    
    subgraph 损失掩码处理
        C["Token IDs"] --> D["Labels"]
        E["&lt;pad&gt; → -100<br/>内容 → 保留<br/>&lt;eos&gt; → 保留"]
    end
    
    subgraph 最终损失计算
        F["只在内容 token<br/>和 EOS token 上计算损失"]
        G["忽略 -100 索引<br/>不参与反向传播"]
    end
    
    A --> C
    B --> C
    C --> D
    D --> E
    E --> F
    F --> G
    
    style G fill:#4caf50,stroke:#388e3c,color:#fff

多轮对话中的 EOS

对于聊天模型,情况更加复杂。在多轮对话训练中,每一轮助手回复的末尾都需要添加 EOS token,告诉模型这是一个完整回复的结束点:

<s>[INST] <<SYS>>
{system_prompt}
<</SYS>>
{user_message_1} [/INST] {model_answer_1} </s>
<s>[INST] {user_message_2} [/INST] {model_answer_2} </s>
graph TD
    subgraph 多轮对话数据格式
        A["&lt;s&gt; [INST] 用户问题1 [/INST]"] 
        B["模型回答1 &lt;/s&gt;"]
        C["&lt;s&gt; [INST] 用户问题2 [/INST]"]
        D["模型回答2 &lt;/s&gt;"]
    end
    
    A --> B
    B --> C
    C --> D
    
    subgraph 关键标注
        E["每一轮助手回复<br/>末尾都有 EOS"]
        F["每个新对话轮次<br/>以 BOS 开始"]
    end
    
    B -.-> E
    A -.-> F
    
    style B fill:#2196f3,stroke:#1976d2,color:#fff
    style D fill:#2196f3,stroke:#1976d2,color:#fff

这种设计让模型学会在每个回复结束后自然终止,而不是继续生成下一个用户的问题或无关内容。

跨模型的实现差异

虽然 EOS token 的核心概念是一致的,但不同模型家族在具体实现上存在显著差异。

GPT 系列的 ``

GPT-2 开创了 `` 这一表示法,它在词汇表中的 ID 是 50256。这个标记在 GPT-3 和早期版本的 GPT-4 中被沿用。值得注意的是,在某些实现中,这个 token 同时被用作文档分隔符和序列结束标记。

Llama 系列的特殊设计

Llama 模型采用了 SentencePiece 分词器,其 EOS token 表示为 </s>,token ID 为 2。在 Llama 2 和 Llama 3 中,这套标记体系得到了延续:

Token 符号 ID 用途
BOS <s> 1 序列开始
EOS </s> 2 序列结束
PAD <pad> 0 填充(通常借用 EOS)

值得注意的是,Llama 3 Instruct 版本引入了额外的 eot_id(End of Turn)和 eos_id 的区分,以更好地处理多轮对话场景。

Mistral 和其他模型

Mistral 模型采用了更复杂的标记体系,包括 <|im_end|> 等特殊 token,专门用于标记对话轮次的结束。不同模型的选择反映了它们对不同应用场景的优化考量。

graph TD
    subgraph GPT系列
        GPT2["GPT-2<br/>Token ID: 50256<br/>&lt;&#124;endoftext&#124;&gt;"]
        GPT3["GPT-3<br/>沿用 GPT-2 格式"]
    end
    
    subgraph Llama系列
        Llama2["Llama 2<br/>Token ID: 2<br/>&lt;/s&gt;"]
        Llama3["Llama 3<br/>Token ID: 2<br/>+ eot_id 区分"]
    end
    
    subgraph Mistral系列
        Mistral["Mistral<br/>&lt;&#124;im_end&#124;&gt;<br/>对话轮次结束"]
    end
    
    EOS["EOS Token 核心概念<br/>序列结束信号"]
    
    EOS --> GPT2
    EOS --> Llama2
    EOS --> Mistral
    GPT2 --> GPT3
    Llama2 --> Llama3

斯坦福研究:EOS 决策的深远影响

2020 年,斯坦福大学自然语言处理组发表了一篇开创性的论文《The EOS Decision and Length Extrapolation》,由 Benjamin Newman、John Hewitt、Percy Liang 和 Christopher D. Manning 撰写。这项研究揭示了 EOS token 训练目标对模型外推能力的深刻影响。

核心发现:长度流形与长度吸引子

研究者比较了两种训练条件:+EOS(标准训练,包含 EOS token 预测)和 -EOS(不包含 EOS token 预测)。通过分析模型的隐藏状态,他们发现了两个关键现象:

长度流形(Length Manifolds)+EOS 模型的隐藏状态会按照序列中的线性位置形成分层结构。在主成分分析(PCA)可视化中,可以清晰看到隐藏状态沿着"时间轴"排列。这种结构意味着模型在跟踪绝对位置,而非相对结构关系。

长度吸引子(Length Attractors):当 +EOS 模型对 EOS token 赋予较高概率时,其隐藏状态会陷入一个稳定的聚类,难以继续转移。这导致模型过早预测序列结束。

graph TD
    subgraph "+EOS 模型隐藏状态结构"
        A1["位置 1-10"] --> A2["位置 11-20"]
        A2 --> A3["位置 21-30"]
        A3 --> A4["..."]
        A4 --> A5["长度流形边界"]
        A5 --> A6["❌ 超出训练长度后崩溃"]
    end
    
    subgraph "-EOS 模型隐藏状态结构"
        B1["隐藏状态均匀分布"] --> B2["基于结构而非位置"]
        B2 --> B3["✓ 成功外推到更长序列"]
    end
    
    style A6 fill:#f44336,stroke:#d32f2f,color:#fff
    style B3 fill:#4caf50,stroke:#388e3c,color:#fff

Dyck 语言实验

研究者在 Dyck-(k, m) 语言(平衡括号语言)上进行了实验。任务是判断括号是否正确闭合。结果显示:

嵌套深度 m +EOS 准确率 -EOS 准确率
4 0.60 0.86
6 0.68 0.98
8 0.68 0.96

在训练时见过的最大长度 10 倍的测试序列上,-EOS 模型表现出惊人的外推能力,而 +EOS 模型则严重退化。

graph LR
    subgraph 实验结果对比
        A["训练长度: 100 tokens"]
        B["测试长度: 1000 tokens<br/>(10倍外推)"]
    end
    
    subgraph "+EOS 模型"
        C["准确率: 60-68%"]
        D["隐藏状态偏离<br/>预测能力崩溃"]
    end
    
    subgraph "-EOS 模型"
        E["准确率: 86-98%"]
        F["保持稳定<br/>成功外推"]
    end
    
    A --> B
    B --> C
    B --> E
    C --> D
    E --> F
    
    style D fill:#f44336,stroke:#d32f2f,color:#fff
    style F fill:#4caf50,stroke:#388e3c,color:#fff

隐藏状态的几何结构

研究者通过 PCA 可视化揭示了两种模型的根本差异:

+EOS 模型在处理超出训练长度的序列时,隐藏状态会偏离训练时学到的"长度流形"边界,导致预测能力崩溃。相比之下,-EOS 模型的隐藏状态空间更加均匀,不依赖绝对位置信息。

graph LR
    subgraph "+EOS 模型问题"
        A1["训练时学习<br/>绝对位置"] --> B1["形成长度流形"]
        B1 --> C1["超出训练长度后<br/>隐藏状态偏离"]
        C1 --> D1["预测能力崩溃"]
    end
    
    subgraph "-EOS 模型优势"
        A2["不预测 EOS"] --> B2["隐藏状态均匀分布"]
        B2 --> C2["基于结构而非位置"]
        C2 --> D2["成功外推到<br/>10倍长度"]
    end

对模型设计的启示

这项研究对大模型训练有重要启示:预测 EOS token 的要求会诱导模型学习绝对位置表示,从而损害其对未见长度的泛化能力。这解释了为什么某些模型在处理超长输入时表现不佳。

然而,研究者也指出,对于实际的自然语言任务(如机器翻译),情况更为复杂。自然语言中有许多隐含的长度线索(如标点符号、句子结构),这些可能部分缓解了 EOS token 带来的问题。

常见故障模式与诊断

故障一:模型永不停止

这是最常见的 EOS 相关问题。用户调用模型生成文本时,模型持续输出直到达到最大长度限制,从不主动结束。

可能原因:

  1. 训练数据中 EOS 信号不足:如果训练数据中文档结束位置的模式不够一致,模型难以学习何时输出 EOS。

  2. 微调时 EOS token 处理错误:一个常见的错误是微调时没有在目标文本末尾添加 EOS token:

# 错误示例:缺少 EOS token
training_example = {
    "input": "Translate to English:",
    "output": "Hello, world!"  # 缺少 EOS
}

# 正确示例
EOS_TOKEN = tokenizer.eos_token
training_example = {
    "input": "Translate to English:",
    "output": "Hello, world!" + EOS_TOKEN
}
  1. padding 与 EOS 混淆:当 pad_token 被设置为 eos_token 时,模型可能在训练中学会了忽略这个 token,因为它通常被损失掩码屏蔽。
graph TD
    subgraph 问题: 模型永不停止
        A["用户输入问题"] --> B["模型开始生成"]
        B --> C["生成内容..."]
        C --> D["继续生成..."]
        D --> E["达到最大长度限制"]
        E --> F["❌ 输出被强制截断"]
    end
    
    subgraph 常见原因
        G["训练数据缺少 EOS 信号"]
        H["微调时未添加 EOS token"]
        I["padding 与 EOS 混淆"]
    end
    
    style F fill:#f44336,stroke:#d32f2f,color:#fff

故障二:模型过早停止

相反的问题:模型在应该继续生成的时候过早输出 EOS token,导致回复残缺。

可能原因:

  1. 训练数据过短:如果训练样本普遍较短,模型会形成对短序列的偏好。

  2. 长度分布偏差:训练数据中不同长度样本的比例不均衡,导致模型偏向常见长度。

  3. 位置编码限制:某些位置编码方案(如原始 Transformer 的正弦编码)在超出训练长度后表现异常,可能诱导模型提前结束。

graph TD
    subgraph 问题: 模型过早停止
        A["用户: 请详细解释量子计算"] --> B["模型: 量子计算是..."]
        B --> C["模型输出 &lt;eos&gt;"]
        C --> D["❌ 回复不完整"]
    end
    
    subgraph 常见原因
        E["训练数据过短"]
        F["长度分布偏差"]
        G["位置编码限制"]
    end
    
    style D fill:#f44336,stroke:#d32f2f,color:#fff

诊断与调试策略

当遇到 EOS 相关问题时,以下策略有助于诊断:

# 检查模型是否真的在预测 EOS
import torch

def analyze_eos_probability(model, tokenizer, input_text):
    inputs = tokenizer(input_text, return_tensors="pt")
    with torch.no_grad():
        outputs = model(**inputs)
        logits = outputs.logits
    
    # 获取最后一个位置的 EOS token 概率
    last_token_logits = logits[0, -1, :]
    probs = torch.softmax(last_token_logits, dim=-1)
    eos_prob = probs[tokenizer.eos_token_id].item()
    
    print(f"EOS token 概率: {eos_prob:.4f}")
    return eos_prob
graph LR
    subgraph 诊断流程
        A["模型输出异常"] --> B{是否停止?}
        B -->|永不停止| C["检查训练数据 EOS 信号"]
        B -->|过早停止| D["检查训练数据长度分布"]
        C --> E["验证微调数据格式"]
        D --> F["分析 EOS token 概率"]
        E --> G["定位问题根源"]
        F --> G
    end

微调中的 EOS 实践

数据准备的关键细节

在监督微调(SFT)中,正确处理 EOS token 是确保模型学会正确停止的关键。

# 推荐的微调数据格式化方式
def format_training_example(instruction, input_text, output, tokenizer):
    """
    格式化训练样本,确保正确添加 EOS token
    """
    # 构建完整的输入提示
    if input_text:
        prompt = f"### Instruction:\n{instruction}\n\n### Input:\n{input_text}\n\n### Response:\n"
    else:
        prompt = f"### Instruction:\n{instruction}\n\n### Response:\n"
    
    # 完整文本 = prompt + output + EOS
    full_text = prompt + output + tokenizer.eos_token
    
    return {
        "text": full_text,
        "response_start": len(prompt),  # 用于损失计算
        "response_end": len(full_text) - len(tokenizer.eos_token)
    }
graph TD
    subgraph 微调数据格式化流程
        A["原始数据"] --> B["构建 Prompt"]
        B --> C["添加输出内容"]
        C --> D["追加 EOS Token"]
    end
    
    subgraph 最终格式
        E["### Instruction:<br/>翻译这段文字<br/><br/>### Input:<br/>Hello world<br/><br/>### Response:<br/>你好世界&lt;eos&gt;"]
    end
    
    D --> E
    
    style D fill:#4caf50,stroke:#388e3c,color:#fff

多轮对话的特殊处理

对于多轮对话微调,需要在每个助手回复后添加 EOS,但只计算助手回复部分的损失:

def format_conversation(messages, tokenizer):
    """
    格式化多轮对话
    
    messages: [{"role": "user/assistant", "content": "..."}]
    """
    conversation = ""
    labels = []
    
    for msg in messages:
        if msg["role"] == "user":
            text = f"[]=len(tokenizer.encode(text)))  # 不计算用户输入的损失
        else:
            text = f"[]
            # 只计算助手回复的损失
            token_ids = tokenizer.encode(text)
            labels.extend(token_ids)
    
    return conversation, labels

与 Chat Template 的协调

现代框架如 HuggingFace Transformers 引入了 Chat Template 机制,自动处理特殊 token 的添加:

# 使用 chat_template 自动处理 EOS
messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "What is the capital of France?"},
    {"role": "assistant", "content": "The capital of France is Paris."},
]

# apply_chat_template 会自动添加 EOS token
formatted_text = tokenizer.apply_chat_template(
    messages, 
    tokenize=False,
    add_generation_prompt=True
)

BOS Token 与注意力汇聚假说

与 EOS token 密切相关的是 BOS(Beginning of Sequence)Token。近年来的研究发现,BOS token 扮演着比预期更重要的角色。

注意力汇聚现象

研究表明,Transformer 模型在推理时会对第一个 token(通常是 BOS)分配异常高的注意力权重。这种现象被称为"注意力汇聚"(Attention Sink)。

一篇 2025 年发表在 arXiv 的论文《Why do LLMs attend to the first token?》深入分析了这一现象。研究者发现:

  1. 位置无关性:无论第一个 token 是什么内容,模型都会对其分配高注意力。
  2. 功能必要性:移除第一个 token 后,模型的生成质量显著下降。
  3. 全局聚合作用:第一个 token 充当全局信息的汇聚点。
graph TD
    subgraph Transformer注意力机制
        Input["输入序列<br/>&lt;s&gt; Hello world"] --> Attention["注意力权重分布"]
        Attention --> Sink["注意力汇聚<br/>BOS Token 获得<br/>异常高权重"]
    end
    
    subgraph 注意力权重示例
        T1["&lt;s&gt;<br/>权重: 0.35"]
        T2["Hello<br/>权重: 0.20"]
        T3["world<br/>权重: 0.25"]
        T4["other<br/>权重: 0.20"]
    end
    
    Sink --> T1
    Sink --> T2
    Sink --> T3
    Sink --> T4
    
    style T1 fill:#ff9800,stroke:#f57c00,color:#fff

对模型架构的影响

这一发现解释了为什么某些模型(如 StreamingLLM)即使移除早期 token 的 KV cache 也能正常工作——只要保留第一个 token 的 KV 对,模型就能维持稳定的注意力分布。

Pythia 模型的特殊案例

有趣的是,EleutherAI 的 Pythia 模型系列采用了相同的 token 作为 BOS 和 EOS。这种设计选择可能对模型的行为产生独特影响,值得在模型选择时考虑。

推理时的 EOS 处理

HuggingFace 的停止条件机制

HuggingFace Transformers 库提供了灵活的停止条件机制:

from transformers import StoppingCriteria, StoppingCriteriaList

class MultipleEOSCriteria(StoppingCriteria):
    """
    支持多个 EOS token ID 的停止条件
    """
    def __init__(self, eos_token_ids):
        self.eos_token_ids = eos_token_ids if isinstance(eos_token_ids, list) else [eos_token_ids]
    
    def __call__(self, input_ids, scores, **kwargs):
        # 检查是否任一 EOS token 出现在序列末尾
        for eos_id in self.eos_token_ids:
            if input_ids[0, -1] == eos_id:
                return True
        return False

# 使用示例
stopping_criteria = StoppingCriteriaList([
    MultipleEOSCriteria([tokenizer.eos_token_id, tokenizer.convert_tokens_to_ids("<|im_end|>")])
])

output = model.generate(
    input_ids,
    stopping_criteria=stopping_criteria,
    max_length=100
)
graph TD
    subgraph HuggingFace 停止条件机制
        A["model.generate()"] --> B["检查停止条件"]
        B --> C{EOS token?}
        C -->|是| D["停止生成"]
        C -->|否| E["继续生成"]
        E --> F{达到 max_length?}
        F -->|是| D
        F -->|否| B
    end
    
    subgraph 自定义停止条件
        G["MultipleEOSCriteria<br/>支持多个 EOS ID"]
        H["StoppingCriteriaList<br/>组合多个条件"]
    end
    
    style D fill:#4caf50,stroke:#388e3c,color:#fff

处理不停止的情况

当模型训练不足或配置错误时,可能需要强制处理"永不停止"的情况:

def safe_generate(model, tokenizer, prompt, max_new_tokens=512, timeout_seconds=30):
    """
    带超时保护的生成函数
    """
    import signal
    
    class TimeoutError(Exception):
        pass
    
    def timeout_handler(signum, frame):
        raise TimeoutError("Generation timed out")
    
    signal.signal(signal.SIGALRM, timeout_handler)
    signal.alarm(timeout_seconds)
    
    try:
        inputs = tokenizer(prompt, return_tensors="pt")
        outputs = model.generate(
            **inputs,
            max_new_tokens=max_new_tokens,
            eos_token_id=tokenizer.eos_token_id,
            pad_token_id=tokenizer.pad_token_id or tokenizer.eos_token_id
        )
        return tokenizer.decode(outputs[0], skip_special_tokens=True)
    except TimeoutError:
        return "Generation timed out"
    finally:
        signal.alarm(0)

未来方向与研究前沿

替代 EOS 的可能性

斯坦福的研究提出了一个根本性问题:是否存在更好的方式来参数化序列结束?研究者发现,即使不训练预测 EOS token,模型的隐藏状态中仍然存在线性可分的"结束状态"。这暗示可能存在不依赖特殊 token 的替代方案。

graph TD
    subgraph 传统方案
        A["训练预测 EOS token"] --> B["模型学习绝对位置"]
        B --> C["长度外推能力受限"]
    end
    
    subgraph 可能的替代方案
        D["对抗性长度预测"] --> E["惩罚绝对位置学习"]
        F["隐式停止信号"] --> G["基于隐藏状态几何"]
        H["动态停止阈值"] --> I["语义完整性指标"]
    end
    
    E --> J["更好的外推能力"]
    G --> J
    I --> J
    
    style C fill:#f44336,stroke:#d32f2f,color:#fff
    style J fill:#4caf50,stroke:#388e3c,color:#fff

可能的研究方向包括:

  1. 对抗性长度预测:在训练中引入对抗损失,惩罚模型对绝对位置的预测,鼓励其学习相对结构信息。

  2. 隐式停止信号:不依赖特定 token,而是通过隐藏状态的几何特性判断序列是否应该结束。

  3. 动态停止阈值:根据生成内容的质量指标(如语义完整性、语法合法性)动态决定是否停止。

长上下文模型的挑战

随着 Claude、GPT-4 等模型支持越来越长的上下文窗口,EOS token 的作用面临新的挑战。在数万 token 的生成中,模型需要多次判断"是否继续",单次判断错误的影响被放大。

研究显示,长度外推问题在超长上下文中更加突出。位置编码方案(RoPE、ALiBi 等)与 EOS 决策的交互成为重要的研究课题。

总结

EOS Token 这个看似简单的概念,实际上涉及大语言模型训练和推理的核心机制。从预训练中的下一个 token 预测,到微调时的数据格式化,再到推理时的停止条件判断,EOS token 贯穿了大模型的整个生命周期。

斯坦福大学的研究揭示了 EOS 训练目标对模型外推能力的深远影响,提醒我们在设计模型训练流程时需要更加审慎。同时,注意力汇聚现象的发现为理解 BOS/EOS token 在模型内部的作用提供了新视角。

对于实践者而言,正确处理 EOS token 是确保模型生成质量的关键。无论是准备训练数据、调试生成问题,还是设计自定义的停止条件,对 EOS 机制的深入理解都是不可或缺的。

这个小小的特殊 token,承载着让模型"知道何时停下"的重任——这或许是大模型与人类语言能力之间最微妙的一个交汇点。


参考文献

  1. Newman, B., Hewitt, J., Liang, P., & Manning, C. D. (2020). The EOS Decision and Length Extrapolation. Stanford NLP Group.

  2. Vaswani, A., Shazeer, N., Parmar, N., et al. (2017). Attention Is All You Need. NeurIPS.

  3. Radford, A., Wu, J., Child, R., Luan, D., Amodei, D., & Sutskever, I. (2019). Language Models are Unsupervised Multitask Learners. OpenAI.

  4. Touvron, H., Lavril, T., Izacard, G., et al. (2023). LLaMA: Open and Efficient Foundation Language Models. arXiv preprint arXiv:2302.13971.

  5. HuggingFace Transformers Documentation. Generation Configuration and Stopping Criteria.

  6. Meta AI. Llama 2 Model Cards and Prompt Formats. llama.com

  7. Meta AI. Llama 3 Model Cards and Prompt Formats. llama.com

  8. Xiao, G., Tian, Y., Chen, B., Han, S., & Lewis, M. (2023). Efficient Streaming Language Models with Attention Sinks. ICLR.

  9. Why do LLMs attend to the first token? (2025). arXiv:2504.02732.

  10. HuggingFace Community Discussions. EOS Token and Padding Token Configuration.

  11. Kaitchup Blog. Fine-tuning LLMs with a Chat Template.

  12. GitHub Issues. unslothai/unsloth - EOS token prediction issues during fine-tuning.

  13. Reddit r/LocalLLaMA. Why does the model refuse to predict EOS token?

  14. Medium. Understanding eos_token and pad_token in model generate config.

  15. Stanford NLP. Dyck Language Experiments and Neural Network Length Generalization.

  16. Lake, B., & Baroni, M. (2018). Generalization without Systematicity: On the Compositional Skills of Sequence-to-Sequence Recurrent Networks. ICML.

  17. Collins, M. (1999). Head-driven Statistical Models for Natural Language Processing. PhD Dissertation, University of Pennsylvania.

  18. Shi, X., Knight, K., & Yuret, D. (2016). Why Neural Translations are the Right Length. EMNLP.

  19. Weiss, G., Goldberg, Y., & Yahav, E. (2018). On the Practical Computational Power of Finite Precision RNNs for Language Recognition. ACL.

  20. Murray, K., & Chiang, D. (2018). Correcting Length Bias in Neural Machine Translation. WMT.

  21. Dubois, Y., Dagan, G., Hupkes, D., & Bruni, E. (2020). Location Attention for Extrapolation to Longer Sequences. ACL.

  22. Hupkes, D., Dankers, V., Mul, M., & Bruni, E. (2020). Compositionality Decomposed: How Do Neural Networks Generalise? JAIR.

  23. Suzgun, M., Belinkov, Y., Shieber, S., & Gehrmann, S. (2019). LSTM Networks Can Perform Dynamic Counting. SCiL.

  24. Hewitt, J., Hahn, M., Ganguli, S., Liang, P., & Manning, C. D. (2020). RNNs can Generate Bounded Hierarchical Languages with Optimal Memory. EMNLP.

  25. EleutherAI. Pythia Suite of Language Models.

  26. Mistral AI. Mistral Model Documentation.

  27. OpenAI. GPT-4 Technical Report.

  28. Anthropic. Claude Model Documentation.

  29. Devlin, J., Chang, M. W., Lee, K., & Toutanova, K. (2019). BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. NAACL.

  30. Sennrich, R., Haddow, B., & Birch, A. (2016). Neural Machine Translation of Rare Words with Subword Units. ACL.

  31. Kudo, T., & Richardson, J. (2018). SentencePiece: A Simple and Language Independent Subword Tokenizer and Detokenizer for Neural Text Processing. EMNLP.

  32. Press, O., Smith, N. A., & Lewis, M. (2022). Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation. ICLR.

  33. Su, J., Lu, Y., Pan, S., Wen, B., & Liu, Y. (2024). RoFormer: Enhanced Transformer with Rotary Position Embedding. Neurocomputing.

  34. Chen, S., Wong, S., Chen, L., & Tian, Y. (2023). Extending Context Window of Large Language Models via Positional Interpolation. arXiv.

  35. Peng, B., Alcaide, E., Anthony, Q., et al. (2023). RWKV: Reinventing RNNs for the Transformer Era. EMNLP.

  36. Gu, A., & Dao, T. (2024). Mamba: Linear-Time Sequence Modeling with Selective State Spaces. ICML.

  37. Brown, T., Mann, B., Ryder, N., et al. (2020). Language Models are Few-Shot Learners. NeurIPS.

  38. Ouyang, L., Wu, J., Jiang, X., et al. (2022). Training Language Models to Follow Instructions with Human Feedback. NeurIPS.

  39. Wei, J., Wang, X., Schuurmans, D., et al. (2022). Chain-of-Thought Prompting Elicits Reasoning in Large Language Models. NeurIPS.

  40. Hoffmann, J., Borgeaud, S., Mensch, A., et al. (2022). Training Compute-Optimal Large Language Models. arXiv.

  41. Chowdhery, A., Narang, S., Devlin, J., et al. (2023). PaLM: Scaling Language Modeling with Pathways. JMLR.

  42. Thoppilan, R., De Freitas, D., Hall, J., et al. (2022). LaMDA: Language Models for Dialogical Applications. arXiv.

  43. Zhang, S., Roller, S., Goyal, N., et al. (2022). OPT: Open Pre-trained Transformer Language Models. arXiv.

  44. Wang, Y., Kordi, Y., Bhagavatula, C., et al. (2023). Self-Instruct: Aligning Language Models with Self-Generated Instructions. ACL.

  45. Taori, R., Gulrajani, I., Zhang, T., et al. (2023). Alpaca: A Strong, Replicable Instruction-Following Model. Stanford CRFM.