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

求助:如何加载用tokenizers训练的WordLevel分词器?Bert/Bart加载失败

问题描述

我用WordLevel编码方法构建了自定义词表,训练代码已成功运行,模型保存到my_word2_token文件夹下的vocab.json。训练代码如下:

import pandas as pd
from tokenizers import decoders, models, normalizers, pre_tokenizers, processors, trainers, Tokenizer
from transformers import BertTokenizerFast
from tokenizers.pre_tokenizers import Whitespace
import os
tokenizer = Tokenizer(models.WordLevel())
tokenizer.normalizer = normalizers.BertNormalizer(lowercase=True)
tokenizer.pre_tokenizer = pre_tokenizers.BertPreTokenizer()
special_tokens = ["[UNK]", "[PAD]", "[CLS]", "[SEP]", "[MASK]"]
trainer = trainers.WordLevelTrainer(vocab_size=1400, special_tokens=special_tokens)


tokenizer.train(files=["./data/material.txt"], trainer=trainer)
# 最终得到该语料的Tonkernize,查看下词汇大小
print("Trained vocab size: {}".format(tokenizer.get_vocab_size()))
# 保存训练的tokenizer
tokenizer.model.save('./my_word2_token/')

但加载时遇到两个问题:

  • 使用BertTokenizer分词结果全为[UNK]
  • 使用BartTokenizer报错:

ValueError: Calling BartTokenizer.from_pretrained() with the path to a single file or url is not supported for this tokenizer. Use a model identifier or the path to a directory instead.

需求是使用WordLevel编码而非BPE编码进行分词,需要解决加载问题。

解决方案

1. 正确保存和加载自定义WordLevel Tokenizer(适配Hugging Face Transformers)

你当前只保存了tokenizer的模型部分(vocab.json),但Hugging Face的BertTokenizer/BartTokenizer需要完整的tokenizer配置(比如预处理规则、特殊token映射等)。正确的做法是将训练好的tokenizers库的Tokenizer转换为BertTokenizerFast(它原生支持自定义WordLevel模型),再保存完整配置:

修改保存代码

在训练完成后,添加以下代码:

# 将tokenizers的Tokenizer转换为BertTokenizerFast
fast_tokenizer = BertTokenizerFast(tokenizer_object=tokenizer)
# 保存完整的tokenizer到目录
fast_tokenizer.save_pretrained('./my_word2_token/')

这会在my_word2_token目录下生成三个关键文件:vocab.json、tokenizer_config.json、special_tokens_map.json,包含了分词所需的所有规则和映射。

加载方式

之后用BertTokenizerFast加载整个目录即可:

from transformers import BertTokenizerFast

tokenizer = BertTokenizerFast.from_pretrained('./my_word2_token/')
# 测试分词
test_text = "你的测试文本内容"
print(tokenizer.tokenize(test_text))

这样就能避免全[UNK]的问题,因为加载后的tokenizer复用了训练时的所有预处理规则、特殊token配置,分词逻辑完全一致。

2. 关于BartTokenizer的问题

BartTokenizer默认基于BPE编码,且它的初始化依赖特定的模型目录结构和配置,不支持直接加载自定义WordLevel词表。如果一定要结合Bart模型架构使用WordLevel分词,建议:

  • 用上述方法训练并保存BertTokenizerFast(WordLevel)
  • 在加载Bart模型时,指定该tokenizer并调整嵌入层:
from transformers import BartForConditionalGeneration, BertTokenizerFast

tokenizer = BertTokenizerFast.from_pretrained('./my_word2_token/')
model = BartForConditionalGeneration.from_pretrained('facebook/bart-base')
# 匹配自定义词表大小
model.config.vocab_size = tokenizer.vocab_size
model.resize_token_embeddings(len(tokenizer))

注意:这种方式下,Bart的预训练权重是基于BPE的,替换词表后必须重新微调模型,否则效果会极差。如果只是需要WordLevel分词,优先使用BertTokenizerFast更直接高效。

3. 原加载方式全[UNK]的原因

你之前用BertTokenizer加载单个vocab.json时全[UNK],核心原因是:

  • BertTokenizer默认的预处理规则(大小写转换、预分词方式)和你训练WordLevel tokenizer时的规则不匹配
  • 没有加载特殊token的映射配置,导致tokenizer无法识别训练时定义的特殊token,进而打乱了整体分词逻辑

只有保存完整的tokenizer配置,才能保证加载后的分词逻辑和训练时完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 03:53:15