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

自定义特殊标记[SP][EMPTY]未被Bert分词器识别的技术问题

解决BertWordPieceTokenizer训练的特殊标记被BertTokenizer识别为[UNK]的问题

问题根源

你遇到的问题有两个核心原因:

  1. 用tokenizers库训练时虽然把[SP]、[EMPTY]加入了词汇表,但transformers的BertTokenizer加载单独的vocab.txt文件时,不会自动把这些自定义标记注册为特殊标记,只会默认识别官方的那几个,所以自定义标记会被当成未知字符输出[UNK]。
  2. 你输入句子里的[CLS]、[SEP]被当成了普通文本,tokenizer把它们拆成了转义后的\[CLS\],而不是识别为特殊标记。

两种解决办法

办法1:加载时手动指定特殊标记

在创建BertTokenizer的时候,通过additional_special_tokens参数把自定义标记传进去,同时同步训练时的配置(比如do_lower_case=False):

from tokenizers import BertWordPieceTokenizer
from transformers import BertTokenizer

vocab_size=50_000
path = '/content/drive/MyDrive/text.txt'

# 训练tokenizer
special_tokens = ['[PAD]', '[UNK]', '[CLS]', '[SEP]', '[MASK]', '[SP]', '[EMPTY]']
tokenizer = BertWordPieceTokenizer(clean_text=True, handle_chinese_chars=False, strip_accents=False, lowercase=False)
tokenizer.train(files=path, vocab_size=vocab_size, min_frequency=5, limit_alphabet=1000, wordpieces_prefix='##', special_tokens=special_tokens)
tokenizer.save_model('/content/drive/MyDrive/', 'new')

# 加载时手动传入自定义特殊标记
tokenizer = BertTokenizer.from_pretrained(
    '/content/drive/MyDrive/new-vocab.txt',
    additional_special_tokens=['[SP]', '[EMPTY]'],
    do_lower_case=False,
    strip_accents=False
)

# 正确使用特殊标记:用tokenizer的属性,不要直接写字符串
sen = f"{tokenizer.cls_token} تم اجتياز الامتحان بنجاح {tokenizer.additional_special_tokens[0]} {tokenizer.additional_special_tokens[1]} {tokenizer.sep_token}"
print(tokenizer.tokenize(sen))

办法2:保存完整tokenizer配置(更省心)

不要只存词汇表,直接保存tokenizers训练好的完整tokenizer文件,再用transformers的BertTokenizerFast加载,这样会自动保留所有配置,包括特殊标记:

from tokenizers import BertWordPieceTokenizer
from transformers import BertTokenizerFast

vocab_size=50_000
path = '/content/drive/MyDrive/text.txt'

# 训练tokenizer
special_tokens = ['[PAD]', '[UNK]', '[CLS]', '[SEP]', '[MASK]', '[SP]', '[EMPTY]']
tokenizer = BertWordPieceTokenizer(clean_text=True, handle_chinese_chars=False, strip_accents=False, lowercase=False)
tokenizer.train(files=path, vocab_size=vocab_size, min_frequency=5, limit_alphabet=1000, wordpieces_prefix='##', special_tokens=special_tokens)

# 保存完整的tokenizer配置文件
tokenizer.save('/content/drive/MyDrive/new_tokenizer.json')

# 直接加载完整配置
tokenizer = BertTokenizerFast.from_pretrained('/content/drive/MyDrive/new_tokenizer.json')

# 用tokenizer属性构建句子,避免转义问题
sen = f"{tokenizer.cls_token} تم اجتياز الامتحان بنجاح {tokenizer.additional_special_tokens[0]} {tokenizer.additional_special_tokens[1]} {tokenizer.sep_token}"
print(tokenizer.tokenize(sen))

重要提醒

别直接在输入句子里写[CLS]这种字符串,要用tokenizer自带的属性(比如tokenizer.cls_token),这样才能保证被识别成特殊标记,不会被转义拆分。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:03:17