如何获取transformers库BertTokenizer分词生成的子词位置标识
BertTokenizer子词定位方法
实现逻辑
HuggingFace 提供的 BertTokenizer 对超出词表的长词做拆分时,除首个子词外,其余后续子词都会统一添加##前缀,我们可以直接通过这个前缀特征判断子词类型:
- 不带
##前缀的token为原词的首个token,标记为0 - 带
##前缀的token为长词拆分出的后续子词,标记为1
代码实现
版本1:传入token字符串列表(适配你给出的调用习惯)
from transformers import BertTokenizer def locate_subwords(token_str_list): return [1 if token.startswith('##') else 0 for token in token_str_list] # 测试用例 t = BertTokenizer.from_pretrained('bert-base-uncased') # 先把编码结果转为token字符串列表 token_list = t.convert_ids_to_tokens(t('word embeddings', add_special_tokens=False).input_ids) location = locate_subwords(token_list) print(location) # 输出:[0, 1, 1, 1, 1] print(token_list) # 输出:['word', 'em', '##bed', '##ding', '##s']
版本2:直接传入分词器返回的Encoding对象
如果不想单独做转换,也可以把转换逻辑封装到函数内:
def locate_subwords(tokenizer, encoding): token_str_list = tokenizer.convert_ids_to_tokens(encoding.input_ids) return [1 if token.startswith('##') else 0 for token in token_str_list] # 调用示例 t = BertTokenizer.from_pretrained('bert-base-uncased') encoding = t('word embeddings', add_special_tokens=False) location = locate_subwords(t, encoding)
补充说明
- 如果开启
add_special_tokens=True,返回的<[BOS_never_used_51bce0c785ca2f68081bfa7d91973934]>、[SEP]等特殊标记会被标记为0,符合其作为独立标记的属性,无需额外调整。 - 如果你使用其他类型的分词器(如RoBERTa、ALBERT等),只需要把判断条件替换为对应分词器的子词前缀规则,即可复用这套逻辑。
内容的提问来源于stack exchange,提问作者namespace-Pt
相关产品推荐
相关产品推荐

