如何在Hugging Face中切换为常规分词器而非子词分词器?
切换M-BERT为基于词的分词器实现方案
M-BERT默认通过AutoTokenizer.from_pretrained加载的是子词分词器(如WordPiece),要替换为基于词的分词器,可按以下两种方案实现:
方案一:自定义分词逻辑并适配Transformer接口
1. 实现基础词分词函数
根据任务语言编写分词逻辑,示例如下:
# 中文示例:用jieba做词分词 import jieba def word_based_tokenize(text): return list(jieba.cut(text)) # 英文示例:用nltk做词分词 # import nltk # nltk.download('punkt') # def word_based_tokenize(text): # return nltk.word_tokenize(text)
2. 包装为符合规范的Tokenizer类
为了和M-BERT模型兼容,需要将自定义分词逻辑包装成PreTrainedTokenizer的子类,核心实现_tokenize方法:
from transformers import PreTrainedTokenizer class WordBasedTokenizer(PreTrainedTokenizer): def __init__(self, vocab_file, **kwargs): super().__init__(**kwargs) # 加载M-BERT原生词表,确保和预训练模型一致 self.vocab = self._load_vocab(vocab_file) self.ids_to_tokens = {v: k for k, v in self.vocab.items()} def _tokenize(self, text): # 调用自定义词分词函数 return word_based_tokenize(text) def convert_tokens_to_ids(self, tokens): # 处理未登录词,映射为[UNK]的ID return [self.vocab.get(token, self.vocab.get("[UNK]")) for token in tokens] def convert_ids_to_tokens(self, ids): return [self.ids_to_tokens.get(id, "[UNK]") for id in ids] # 实现必须的抽象方法 def save_vocabulary(self, save_directory, filename_prefix=None): pass
3. 初始化自定义分词器
model_checkpoint = "bert-base-multilingual-cased" # 加载M-BERT的词表文件(可从预训练模型路径获取) vocab_file = f"{model_checkpoint}/vocab.txt" # 本地路径直接替换为对应位置 tokenizer = WordBasedTokenizer(vocab_file) # 补充特殊token配置,和M-BERT保持一致 tokenizer.add_special_tokens({ 'pad_token': '[PAD]', 'unk_token': '[UNK]', 'cls_token': '[CLS]', 'sep_token': '[SEP]' })
方案二:使用第三方适配的词级Tokenizer
部分第三方库提供了直接适配Transformer框架的词级分词器,比如针对中文场景的bert4keras内置词分词器,但如果需严格兼容Hugging Face生态,优先推荐方案一。
关键注意事项
- 未登录词处理:词级分词会产生更多不在M-BERT词表中的词汇,需提前通过替换为
[UNK]或扩展词表等方式处理。 - 模型性能适配:M-BERT预训练基于子词数据,切换词级分词后建议进行少量微调,让模型适配新的输入格式。
内容的提问来源于stack exchange,提问作者Jatayu Baxi
相关产品推荐
相关产品推荐

