You need to enable JavaScript to run this app. 如何在HuggingFace预训练分词器中启用WordPiece前缀适配BERT序列标注
优惠活动
大模型
产品
解决方案
定价
更多

如何在HuggingFace预训练分词器中启用WordPiece前缀适配BERT序列标注

HuggingFace BERT分词器输出WordPiece子词前缀的实现

核心场景说明

基于BERT做序列标注任务时,需要识别WordPiece拆分的子词标记,通过求和/平均聚合同一原词的所有子词嵌入,完成子词和原始单词的标签对齐。实际使用中会遇到的共性问题:

  • 早期教程里BERT拆分的子词会带可识别的##前缀,比如New~york会被拆为New、##~、##york;但当前版本的HuggingFace分词器默认输出的解码结果里看不到这类前缀
  • 调整WordPiece前缀参数后,调用decode方法得到的文本依然没有前缀标记,无法直接区分独立词和拆分的子词

常见操作误区

之前尝试的代码看不到前缀,本质是两个操作逻辑不对:

  1. 混淆了decode和原始token提取方法的功能

    注意:decode方法的设计目标是把token序列还原成人类可读的自然句子,内置了自动剥离子词##前缀、拼接相邻子词的逻辑,不管怎么配置分词器参数,只要调用decode,就会把所有子词标记隐藏掉,这是方法本身的固定行为,不是参数没生效。

  2. 快速版分词器的初始化方式错误
    直接用本地vocab文件路径初始化BertTokenizerFast时,没有加载完整的预训练分词器配置,传入的wordpieces_prefix参数不会真正作用到分词逻辑上,自然得不到预期的输出。

具体实现方法

完全不需要自行训练自定义分词器,按下面的步骤操作就能拿到带前缀标记的子词列表,满足序列标注的对齐需求:

  1. 用convert_ids_to_tokens提取原始带标记的子词
    不要依赖decode的输出,拿到input_ids之后,用分词器自带的ID转token方法获取原始子词列表,这个方法会完整保留WordPiece的##前缀:

    from transformers import BertTokenizer
    
    tokenizer = BertTokenizer.from_pretrained('bert-base-cased')
    batch_sentences = ["hello, i'm testing this efauenufefu"]
    inputs = tokenizer(batch_sentences, return_tensors="pt")
    
    # 输出的token列表会保留所有##前缀的子词标记
    token_list = tokenizer.convert_ids_to_tokens(inputs["input_ids"][0])
    print(token_list)
    

    对应你之前测试的无意义长字符串拆分结果,实际输出的token列表为:

    ['[CLS]', 'hello', ',', 'i', "'", 'm', 'testing', 'this', 'e', '##fa', '##uen', '##ufe', '##fu', '[SEP]']
    

    可以清晰看到拆分出的子词都带##前缀,满足子词识别需求。

  2. 正确配置快速版分词器的WordPiece前缀
    如果使用BertTokenizerFast,不要直接读本地vocab文件初始化,要从预训练模型加载完整配置后再调整前缀参数:

    from transformers import BertTokenizerFast
    
    # 从预训练源加载完整分词器配置,再传入前缀参数
    tokenizer_fast = BertTokenizerFast.from_pretrained(
        'bert-base-cased',
        wordpieces_prefix="##"
    )
    inputs = tokenizer_fast(
        ["hello, i'm testing this efauenufefu"],
        return_tensors="pt"
    )
    
    # 同样用convert_ids_to_tokens拿原始带标记的子词
    token_list = tokenizer_fast.convert_ids_to_tokens(inputs["input_ids"][0])
    print(token_list)
    
  3. 序列标注对齐的更优方案
    做子词和原词对齐时,甚至不需要手动识别##前缀:快速版分词器自带get_word_ids()方法,会直接返回每个子词对应的原始单词索引,相同原词拆分出的所有子词会共享同一个word id,直接按id分组聚合嵌入,比手动判断前缀更稳定。

    # 获取当前批次每个子词对应的原词索引
    word_ids = tokenizer_fast.get_word_ids(batch_index=0)
    print(word_ids)
    # 同一原词拆分的所有子词会返回相同的id值,可直接用于嵌入聚合和标签对齐
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 12:36:05