今天我们来聊一聊关于input_ids,attention_mask,token_type_ids 关于这三个核心张量
首先,在使用 BERT 模型(或其衍生模型)进行文本处理时,input_idsattention_masktoken_type_ids 是模型输入层的三大核心张量,它们共同将原始文本转换为模型可理解的数值格式。再一个就是他们同时也是 BERT tokenizer方法的分词结果的三大输出,同时作为BERT的输入,也就是说他们具有双重身份
三者的作用、生成逻辑和含义各不相同,下面我们作以下讨论:

一、input_ids:文本的 “数字身份证”

input_ids文本经过 Tokenize(分词)后,每个 Token 对应的唯一整数编码,本质是将 “文字” 映射为 “模型能计算的数字”,相当于给每个 Token 发了一张 “数字身份证”。

核心细节:

  1. 生成逻辑

    • 第一步:用 BERT 专属的Tokenizer(如BertTokenizer)对文本分词。BERT 的分词方式是 “WordPiece”(子词分词),例如 “unhappiness” 会拆分为 “un”“##happiness”,既能处理未登录词(OOV),又能平衡分词粒度。
    • 第二步:根据 Tokenzier 内置的词汇表(vocab.txt),将每个分词后的 Token 替换为词汇表中对应的整数 ID。例如词汇表中 “[CLS]” 对应 101、“[SEP]” 对应 102、“我” 对应 2765(不同预训练模型的词汇表可能不同,ID 值会有差异)。
  2. 特殊 Token 的强制添加

    BERT 对输入格式有严格要求,Tokenizer会自动在文本前后添加特殊 Token,因此input_ids的长度会比原始分词结果长:

    • 句首:添加[CLS](ID=101),用于聚合整个文本的语义(如分类任务的最终特征从该位置提取)。
    • 句尾(或句间):添加[SEP](ID=102),用于分隔不同句子(单句输入时也需在句尾加 1 个[SEP];两句输入时在第一句尾和第二句尾各加 1 个[SEP])。
  3. 示例

    若输入单句 “我爱中国”,Tokenizer处理后:

    • 分词结果:[CLS][SEP]
    • 对应的input_ids(假设词汇表 ID):[101, 2765, 2293, 2001, 3588, 102]
  4. 形状:通常为[batch_size, seq_len](batch_size = 批量大小,seq_len = 序列长度,即每个样本的 Token 总数,需满足模型最大输入长度限制,如 BERT-base 最大为 512)。

二、attention_mask:“告诉模型该关注谁”

attention_mask用于标记 “有效 Token” 和 “填充 Token” 的掩码,核心作用是让模型在计算 “自注意力(Self-Attention)” 时,只关注有效文本,忽略填充的无效 Token,避免无效信息干扰模型计算。

核心细节:

  1. 为什么需要它?

    BERT 处理批量文本时,要求所有样本的input_ids长度一致(即seq_len相同)。若不同样本的原始文本长度不同,短文本会用填充 Token([PAD],ID=0) 补到seq_len长度。例如:

    • 样本 1(长文本):[CLS]我爱吃苹果[SEP](长度 6)

    • 样本 2(短文本):

      [CLS]你好[SEP][PAD][PAD][PAD]

      (补 3 个[PAD]到长度 6)

      此时模型若 “关注” [PAD],会浪费计算资源且引入噪声,因此需要 attention_mask 标记有效位置。

  2. 生成逻辑

    • input_ids有效 Token(非 [PAD])attention_mask对应位置设为1(表示 “需要关注”);
    • input_ids填充 Token([PAD])attention_mask对应位置设为0(表示 “忽略”)。
  3. 示例

    延续上述短文本示例,input_ids[101, 872, 102, 0, 0, 0](“你好” 对应 ID=872,[PAD]对应 ID=0),则:

    • attention_mask[1, 1, 1, 0, 0, 0](前 3 个有效 Token 标 1,后 3 个[PAD]标 0)。
  4. 形状:与input_ids完全一致,即[batch_size, seq_len],确保每个 Token 都有对应的掩码标记。

三、token_type_ids:“区分句子的边界”

token_type_ids用于区分 “多句输入中不同句子” 的类型标记,仅在处理 “句子对” 任务(如句子相似度、文本蕴含、问答)时有效,单句输入时可省略(或全为 0)。

核心细节:

  1. 适用场景

    BERT 的预训练任务包含 “下一句预测(NSP)”,需要模型判断两个句子是否为连续的上下文(如 “我喜欢跑步” 和 “跑步能锻炼身体” 是连续句,“我喜欢跑步” 和 “今天天气很好” 是非连续句)。因此,处理句子对时,需要token_type_ids告诉模型 “哪些 Token 属于第一句,哪些属于第二句”。

  2. 生成逻辑

    • 第一句的所有 Token(包括句首的 [CLS] 和句尾的 [SEP])token_type_ids对应位置设为0
    • 第二句的所有 Token(包括句尾的 [SEP])token_type_ids对应位置设为1
    • 填充 Token([PAD])token_type_ids对应位置设为0(或 1,不影响,因attention_mask已标记为忽略)。
  3. 示例

    若输入句子对 “我爱中国。中国很美丽。”,Tokenizer处理后:

    • 分词结果:[CLS][SEP][SEP]
    • 对应的token_type_ids[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1](前 7 个 Token 属于第一句,标 0;后 7 个属于第二句,标 1)。
  4. 单句输入的特殊情况

    若仅输入单句(如文本分类、情感分析),token_type_ids所有位置均为0(因只有一个句子类型),部分框架(如 Hugging Face Transformers)在单句输入时会自动省略该张量,或生成全 0 的token_type_ids(不影响模型结果)。

  5. 形状:与input_idsattention_mask一致,即[batch_size, seq_len]

三者关系与总结表

张量名称 核心作用 关键特征 与文本的关联
input_ids 将 Token 映射为整数 ID,是文本的数值载体 包含[CLS]/[SEP],长度 = seq_len 直接对应 “分词后的文本 + 特殊 Token”
attention_mask 标记有效 Token / 填充 Token,控制注意力 1 = 有效、0 = 无效,与input_ids长度完全匹配 解决 “批量文本长度不一致” 的问题
token_type_ids 区分句子对中的不同句子 0 = 第一句、1 = 第二句,单句输入时全 0 仅用于 “句子对” 任务

简单来说:

  • input_ids 是 “文本的数字形式”,

  • attention_mask 是 “过滤无效信息的开关”,

  • token_type_ids是 “句子边界的区分器”,

    三者共同构成 BERT 的输入,确保模型能正确理解文本的 “内容、有效性和句子结构”,那么话说回来这些输入是从哪来的呢,就是来自我们的分词器,也就是BERT的tokenizer.encode()
    接下来我们来看一看具体的代码实战以及代码细节

    1.首先是基础调用示例

    # 单句输入时.token_type_ids会默认输出为0(因只有一个句子类型),代码示例:
    from transfomers import tokenizer
    # 首先先加载预训练的BERT Tokenizer(如bert-base-chinese)
    tokenizer = BertTokenizer.from_pretrained("bert-base-chinese")
    # 输入单句文本
    text = "我要成为一名合格的AI应用开发工程师"
    # 调用tokenizer处理文本
    outputs = tokenizer(
    text,             # 输入文本
    padding = "max_length" # 补全到最大输入长度(如512)
    truncation = True,         # 超过最大长度时截断
    return_tensors = "pt"  # 返回PyTorch张量(也可设为"tf"返回TensorFlow张量) 这个具体看用的哪个深度学习开发框架
    )
    # 最后就可以提取三个核心输出了
    print("input_ids:",outputs["input_ids"])         # 必输出:文本的数字编码
    print("attention_mask:",outputs["attention_mask"])    # 必输出:有效token掩码
    print("token_type_ids:",outputs["token_type_ids"])    # 输出0,单句无句子区分
    

    2.句子对输入示例(需区分句子边界)

      # 首先我们输入句子对
      token_pair = [“我想努力学习AI知识”,”然后当一个AI应用开发工程师“]
      # 处理句子对,token_type_ids会自动区分两句
      outputs = tokenizer(text_pair[0],
      text_pair[1], # 传入第二句(text_pair参数)
      padding = "max_length", # 补全到最大长度
      truncation = True,
      return_tensors = "pt"
      )
      # 此时token_type_ids会明确区分两句:第一句及首个[SEP]标0,第二句及第二个[SEP]标1
      print("token_type_ids:",outputs["token_type_ids"]
    

    3.参数的控制

    也就是说我怎样去控制它的输出
    默认情况下,tokenizer会强制输出input_ids和attention_mask(这是模型输入的"必须品"),而token_type_ids的输出与否,可通过return _token_type_ids参数控制

    • 若设为return_token_type_ids=True(默认值,尤其对 BERT 类模型):强制输出token_type_ids;
    • 若设为return_token_type_ids=False:仅输出input_ids和attention_mask(单句任务中可省略,不影响模型运行)。

好了,,经过上述的讨论,我们对BERT分词器的输出的三个参数,或者说BERT模型的输入已经有了比较合格的理解,希望文章可以帮助大家理解input_ids ,attention_mask,token_type_ids这三个核心张量

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐