news 2026/9/7 18:24:03

Transformers 中的 BertJapanese:基于 MeCab/Sudachi 等分词的日语 BERT 分词器全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Transformers 中的 BertJapanese:基于 MeCab/Sudachi 等分词的日语 BERT 分词器全解析

Transformers 中的 BertJapanese:基于 MeCab/Sudachi 等分词的日语 BERT 分词器全解析

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

本文导读:日语文本没有空格分词,无法直接套用标准 BERT 的 WordPiece 流程。本篇技术指南以官方文档 docs/source/en/model_doc/bert-japanese.md 为主体,系统讲解 Transformers 仓库中BertJapaneseTokenizer的分层分词架构、四种词级分词器与三种子词级分词器的选型与参数,并给出可一键复现的推理代码、底层源码证据与测试用例验证。读完你既能用一行代码跑通cl-tohoku/bert-base-japanese系列模型,也能按业务需求定制 MeCab/Sudachi/JumanPP 等日文形态素解析方案。

一、BertJapanese 是什么

在日语 BERT 场景中,模型结构本身与标准 BERT完全一致,唯一的关键差异在于分词方式。日语通常不空格分词,因此必须借助形态素解析器(Morphological Analyzer)先将句子切分为“单词”,再喂给子词切分器。文档与源码都反复强调这一点:"This implementation is the same as BERT, except for tokenization method"(模型 API 参考直接沿用 BERT,见 BERT 文档)。

该功能由贡献者 cl-tohoku(东北大学乾研究室发布的cl-tohoku/bert-japanese系列模型作者)于 2020-11-16 引入本仓库。仓库内实现位于两个文件:

  • 分词器实现:src/transformers/models/bert_japanese/tokenization_bert_japanese.py
  • 单元测试:tests/models/bert_japanese/test_tokenization_bert_japanese.py

文档最初描述了两类分词模型,但从当前源码(以及 测试文件 的用例矩阵)看,可用的组合已扩展到远不止两种:

层级可选实现说明
词级分词(word_tokenizer_typebasic/mecab/sudachi/jumanpp把日文切分为“单词”
子词级分词(subword_tokenizer_typewordpiece/character/sentencepiece把单词进一步切分为可入词表的子词

下文将逐一说明每种组合如何配置、背后的分词器类如何工作。

二、安装与依赖

文档明确说明:使用 MeCab 词级分词需要额外安装形态素解析相关依赖:

# 从 PyPI 安装时 pip install transformers["ja"] # 从源码安装(clone 仓库后)时 pip install -e .["ja"]

这里"ja"extra 的具体内容定义在 setup.py 的extras["ja"]中(第 208-210 行):

extras["ja"] = deps_list("fugashi", "ipadic", "unidic_lite", "unidic", "rhoknp") if PYTHON_MINOR_VERSION < 14: extras["ja"] += deps_list("sudachipy", "sudachidict_core")

其中各包对应关系(依赖版本声明见 src/transformers/dependency_versions_table.py):

  • fugashi(>=1.0):MeCab 的 Python 封装,MecabTokenizer的必需依赖;
  • ipadic(>=1.0.0,<2.0):IPA 词典;
  • unidic_lite(>=1.0.7)与unidic(>=1.0.2):UNIDIC 词典(轻量版 / 完整版,完整版需额外执行python -m unidic download下载,体积较大);
  • rhoknp:Juman++ 的 Python 封装,JumanppTokenizer的必需依赖;
  • sudachipy(>=0.6.6)与sudachidict_core:SudachiPy 分词器及其核心词典,SudachiTokenizer的必需依赖(注意当前 setup.py 将其限定在 Python < 3.14 的环境下安装)。

如果只使用 Character 字符级或 Basic 词级切分(无形态素解析),则无需这些额外依赖。若遗漏安装,源码会抛出明确的提示:例如MecabTokenizer.__init__中捕获ModuleNotFoundError并提示 "You need to install fugashi to use MecabTokenizer"(见 tokenization_bert_japanese.py)。

三、快速上手:两种经典用法

3.1 MeCab + WordPiece(cl-tohoku/bert-base-japanese)

MeCab 与 WordPiece 的组合是cl-tohoku/bert-base-japanese的默认配置。文档给出了如下可直接运行示例(注意原文档中的变量笔误,model.device已修正为bertjapanese.device):

import torch from transformers import AutoModel, AutoTokenizer bertjapanese = AutoModel.from_pretrained("cl-tohoku/bert-base-japanese", device_map="auto") tokenizer = AutoTokenizer.from_pretrained("cl-tohoku/bert-base-japanese") ## 输入日语文本 line = "吾輩は猫である。" inputs = tokenizer(line, return_tensors="pt").to(bertjapanese.device) print(tokenizer.decode(inputs["input_ids"][0])) # [CLS] 吾輩 は 猫 で ある 。 [SEP] outputs = bertjapanese(**inputs)

可以看到,句子先被 MeCab 按词法切分为吾輩 / は / 猫 / で / ある / 。六个“单词”,词与词之间有明确的空格边界。由于吾輩等词整体存在于 BERT 词表中,因此此处 WordPiece 未发生二次切分。

3.2 Character 字符级切分(cl-tohoku/bert-base-japanese-char)

若使用字符级切分模型,则完全不依赖形态素解析器,输出效果是逐字展开:

bertjapanese = AutoModel.from_pretrained("cl-tohoku/bert-base-japanese-char", device_map="auto") tokenizer = AutoTokenizer.from_pretrained("cl-tohoku/bert-base-japanese-char") ## 输入日语文本 line = "吾輩は猫である。" inputs = tokenizer(line, return_tensors="pt").to(bertjapanese.device) print(tokenizer.decode(inputs["input_ids"][0])) # [CLS] 吾 輩 は 猫 で あ る 。 [SEP] outputs = bertjapanese(**inputs)

两种模型在仓库中的注册名均为BertJapaneseTokenizer。在 src/transformers/models/auto/tokenization_auto.py 中通过("bert-japanese", "BertJapaneseTokenizer")映射,因此AutoTokenizer.from_pretrained会根据 checkpoint 的tokenizer_class自动路由到正确实现——这一点由 test_tokenizer_bert_japanese 直接验证(assertIsInstance(tokenizer, BertJapaneseTokenizer))。

四、BertJapaneseTokenizer 构造参数全解

BertJapaneseTokenizer继承自 [PreTrainedTokenizer],构造签名与参数在源码(tokenization_bert_japanese.py)中可查:

参数类型默认值说明
vocab_filestr必填每行一个 WordPiece 词条的词表文件(vocab.txt
spm_filestrNoneSentencePiece 模型文件(.spm/.model),仅当subword_tokenizer_type="sentencepiece"时必填并校验存在性
do_lower_caseboolFalse是否在 basic/mecab/sudachi 阶段转小写
do_word_tokenizeboolTrue是否执行词级切分;置False则整句作为单个输入
do_subword_tokenizeboolTrue是否执行子词切分;置False则词级结果直接作为 token
word_tokenizer_typestr"basic"词级分词器,取值["basic", "mecab", "sudachi", "jumanpp"]
subword_tokenizer_typestr"wordpiece"子词分词器,取值["wordpiece", "character", "sentencepiece"]
mecab_kwargsdictNone透传给MecabTokenizer的关键字参数
sudachi_kwargsdictNone透传给SudachiTokenizer的关键字参数
jumanpp_kwargsdictNone透传给JumanppTokenizer的关键字参数
never_split/unk_token/sep_token/pad_token/cls_token/mask_token-[UNK]/[SEP]/[PAD]/[CLS]/[MASK]沿袭标准 BERT 的特殊 token 约定

词表相关常量在源码第 33 行定义:VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt", "spm_file": "spiece.model"},即 WordPiece/Character 模式依赖vocab.txt,SentencePiece 模式依赖spiece.model,二者通过subword_tokenizer_type切换使用。

BertJapaneseTokenizer还设定了token_type_ids_pattern="bert_style"token_type_ids_include_special_tokens=Truespecial_tokens_pattern="cls_sep",因此它与 BERT 一样:单句编码为[CLS] ... [SEP],句对编码为[CLS] A [SEP] B [SEP],每条 token 都附带 token_type_ids——这与 test_sequence_builders 的断言行为一致。

五、核心流水线:两段式_tokenize

理解BertJapaneseTokenizer的关键是它的两段式切分流水线(源码_tokenize,见 tokenization_bert_japanese.py):

def _tokenize(self, text): if self.do_word_tokenize: tokens = self.word_tokenizer.tokenize(text, never_split=self.all_special_tokens) else: tokens = [text] if self.do_subword_tokenize: split_tokens = [sub_token for token in tokens for sub_token in self.subword_tokenizer.tokenize(token)] else: split_tokens = tokens return split_tokens

流水线可概括为:

  1. 词级切分:由word_tokenizer把整句切成一串日语“单词”(形态素);
  2. 子词切分:对第 1 步输出的每一个词,再调用subword_tokenizer做二次切分(如 WordPiece 把词典外长词拆成##前缀子词);
  3. 特殊 token([CLS]/[SEP]等)在all_special_tokens的保护下不被切开。

在构造函数中,word_tokenizer_type决定实例化BasicTokenizer/MecabTokenizer/SudachiTokenizer/JumanppTokenizer中的哪一个,subword_tokenizer_type决定实例化WordpieceTokenizer/CharacterTokenizer/SentencepieceTokenizer中的哪一个,非法取值会抛出ValueError

一个值得注意的工程细节:当词级分词器为mecab/sudachi/jumanpp时,底层持有不可序列化的解析器对象,因此类实现了__getstate__(pickle 时删除word_tokenizer)与__setstate__(反序列化时依据保存的 kwargs 重建解析器),确保模型可被pickle与多进程分发(见 tokenization_bert_japanese.py)。

六、词级分词器(word tokenizer)逐一分析

6.1 BasicTokenizer(basic,默认)

即标准 BERT 的BasicTokenizerBertJapaneseTokenizer在构造它时强制传入tokenize_chinese_chars=False(见 tokenization_bert_japanese.py)。这是因为对日语启用中文逐字切分会把汉字拆得过碎,破坏后续形态素/子词处理;仓库中的 BasicTokenizer 完整保留了对 CJK 区间(含扩展区)判定的_is_chinese_char逻辑(第 737-759 行),但在此处被显式关闭。它同时完成 Unicode NFKC/NFC 归一化、空白清理、标点拆分与小写化。

6.2 MecabTokenizer(mecab)

通过fugashi封装 MeCab 完成形态素解析(构造逻辑见 tokenization_bert_japanese.py),其mecab_kwargs支持:

参数默认值说明
do_lower_caseFalse是否对非never_splittoken 做小写化
normalize_textTrue切分前是否对文本做 Unicode NFKC 归一化(用于把全角/半角统一,如アップルアップル8
mecab_dic"unidic_lite"使用的词典:"ipadic"(IPA)、"unidic_lite"(轻量 UNIDIC)、"unidic"(完整 UNIDIC,需python -m unidic download),若使用系统词典则传None并改用mecab_option
mecab_optionNone直接传给 MeCab 构造器的原始选项字符串

设置mecab_dic后,源码会拼出-d "{dic_dir}" -r "{mecabrc}"再附加用户自定义的mecab_option,实现词典路径与配置的自动定位。tokenize对 MeCab 输出的每个词取word.surface作为 token,并按需做小写化。

测试对三种词典均给出预期(见 test_tokenization_bert_japanese.py):同一输入"アップルストアでiPhone8 が 発売された 。",使用ipadic输出アップルストア一词,而使用unidic_lite/unidic输出アップル+ストア两词——这正是不同词典粒度差异的直观体现,实践选型时应保持“训练用词典 = 推理用词典”。

6.3 SudachiTokenizer(sudachi)

基于 SudachiPy 的三粒度形态素解析器(构造见 tokenization_bert_japanese.py),其sudachi_kwargs关键参数:

参数默认值说明
normalize_textTrueNFKC 归一化开关
trim_whitespaceFalse是否剔除并 trim 空白/tab/换行 token
sudachi_split_mode"A"切分粒度:A(最细)、B(中)、C(不切分)
sudachi_dict_type"core"词典类型:small/core/full
sudachi_config_path/sudachi_resource_dirNoneSudachiPy 配置与资源目录
sudachi_projectionNone词投影模式,如surface/normalized/reading/normalized_nouns等(需要 sudachipy>=0.6.8)

projection是 Sudachi 的特色能力。测试 test_sudachi_tokenizer_projection 展示了投影前后的差异:输入"これはねこです。",在sudachi_split_mode="A"+sudachi_projection="normalized_nouns"下被切分为此れ / は / 猫 / です / 。,其中これ此れねこ即为词典投影把平假名口语还原为规范表记的结果。

SplitMode 三档差异同样有测试佐证(test_tokenization_bert_japanese.py):对"外国人参政権",A/B/C 三种模式分别输出外国/人/参政/権外国人/参政権外国人参政権。将其接入完整分词器时(如测试中的word_tokenizer_type="sudachi", sudachi_kwargs={"sudachi_split_mode": "B"}),会进一步得到带##的 WordPiece 子词外国/##人/参政/##権

6.4 JumanppTokenizer(jumanpp)

基于rhoknp调用 Juman++(构造见 tokenization_bert_japanese.py)。jumanpp_kwargs支持do_lower_casenormalize_text(默认True)、trim_whitespace(默认False)。其tokenize通过self.juman.apply_to_sentence(text).morphemes逐个取词素文本。测试 test_jumanpp_full_tokenizer_with_jumanpp_kwargs_trim_whitespace 验证了它也能与 WordPiece 正常衔接。Juman++ 由京都大学 Kurohashi 实验室维护,擅长长距离依存与未知语处理,适合作为 MeCab/Sudachi 之外的高精度备选。

七、子词级分词器(subword tokenizer)逐一分析

7.1 WordpieceTokenizer(wordpiece,默认)

标准的 BERT WordPiece 实现(源码见 tokenization_bert_japanese.py),采用最长匹配优先的贪心算法:对每个词从最长子串开始向词表查询,非词首子词一律加##前缀;子串超过max_input_chars_per_word=100或无法切分时输出[UNK]。解码时通过" ".join(tokens).replace(" ##", "")还原(convert_tokens_to_string)。测试 test_wordpiece_tokenizer 展示了核心行为:こんばんはこん/##ばんは

7.2 CharacterTokenizer(character)

逐字切分(源码见 tokenization_bert_japanese.py)。先做 NFKC 归一化,再对每个字符查词表:こんにちはこ/ん/に/ち/は;词表外的字符(如测试中的)映射为[UNK](见 test_character_tokenizer)。由于该模式不需要词级分词器配合形态素解析,是文档所述“第二种经典用法”的底层实现。

7.3 SentencepieceTokenizer(sentencepiece)

subword_tokenizer_type="sentencepiece"时,构造器要求spm_file指向spiece.model,词表与 id 映射改由 SentencePiece 的sp_model提供(vocab_size_convert_token_to_id/_convert_id_to_token都会切换到 SP 模型路径)。其实现参考了 Albert 分词器(见类注释及 tokenization_bert_japanese.py),输出采用前缀标记词首。注意:此时主切分器仍然先由word_tokenizer(通常配 sudachi/jumanpp)产出词序列,再交给 SentencePiece。这类组合实际存在于社区模型中,例如测试使用的nlp-waseda/roberta-base-japanese-with-auto-jumanpp(Jumanpp 词级 + SentencePiece 子词级),其预期输出如▁国境 ▁の ▁長い ...(见 test_sentencepiece_tokenizer)。

八、解码与词表读写行为

  • 解码:WordPiece/Character 模式下,convert_tokens_to_string以空格拼接 token 并去掉##粘连;SentencePiece 模式下直接调用 SP 模型的decode(见 tokenization_bert_japanese.py)。
  • 词表加载load_vocab按行读取vocab.txt构造OrderedDict(token → id),并同步维护反向ids_to_tokens(第 38-46、124-125 行)。
  • 保存save_vocabulary按配置分别写出vocab.txt或 SP 模型的序列化 proto 到spiece.model(第 263-293 行)。
  • 词表扩展get_vocab在基础词表之上合并added_tokens_encoder中未冲突的新增 token。

九、参数组合速查与选型建议

综合上述实现,可将完整组合归纳如下:

词级分词器子词分词器典型搭配场景
basicwordpiece简单位切分(无形态学信息),仅适合预切好的空格文本
mecabwordpiece/character经典cl-tohoku/bert-base-japanese/-char路线,词典选ipadicunidic_lite
sudachiwordpiece/sentencepiece需要 split_mode A/B/C 粒度控制或规范化投影
jumanppwordpiece/sentencepiece追求更高精度的形态素切分

选型要点

  1. 推理必须与训练一致do_lower_casenormalize_text、MeCab 的mecab_dic、Sudachi 的sudachi_split_mode/sudachi_dict_type等任何一项不一致,都会改变 token id,导致下游模型结果漂移;
  2. 字符级 vs 词法级:Character 模式实现简单、无需外部词典且对未知词友好,但序列更长、信息粒度更细;词法级模式序列更短、语义单元更完整,但引入外部解析器依赖与词典;
  3. normalize_text 影响显著:NFKC 会把半角片假名与全角数字统一后再切分。若关闭(normalize_text=False),测试显示アップル会保持原样(见 test_mecab_tokenizer_no_normalize),对依赖原始表记的任务可能更合适;
  4. 切分粒度对比测试可参考仓库测试:同一句" \tアップルストアでiPhone8 が \n 発売された 。 "在 tests/models/bert_japanese/test_tokenization_bert_japanese.py 中被 ipadic(アップルストア一体)与 unidic_lite(アップル/ストア拆分)解析出不同结果,直接展示了词典差异对下游词表覆盖的影响。

十、延伸阅读

  • 模型结构 API(与 BERT 完全一致):BERT 模型文档
  • 分词器完整源码:tokenization_bert_japanese.py
  • 行为验证用例:test_tokenization_bert_japanese.py
  • 日语 extra 依赖声明:setup.py
  • AutoTokenizer 路由注册:tokenization_auto.py
  • 本文对应的英文原文文档:docs/source/en/model_doc/bert-japanese.md,另有日文、韩文译版

如果你手头的任务恰好是处理无空格书写的日语文本,那么基于BertJapaneseTokenizer的词法级(MeCab/Sudachi/Juman++)+ 子词级(WordPiece/Character/SentencePiece)两段式流水线,就是与预训练权重对齐度最高、也最值得在生产中复用的分词方案。

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 18:23:40

品牌企业内容分发全链路自动化方案

![企业战略会议](https://images.pexels.com/photos/7109316/pexels-photo-7109316.jpeg?autocompress&cstinysrgb&w1080)*图源&#xff1a;Pexels tiger-lily&#xff08;免费商用授权&#xff09;* 品牌方的内容营销普遍存在一个尴尬的断层&#xff1a;创意端越来越…

作者头像 李华
网站建设 2026/9/7 18:23:12

2026年9月西安 GEO 优化和抖音推广哪个效果好?对比分析

西安商家在选择推广方式时&#xff0c;常会问&#xff1a;西安 GEO 优化和抖音推广哪个效果好&#xff1f;简单说&#xff0c;GEO 优化更像“让 AI 在回答问题时想起你”&#xff0c;抖音推广更像“主动把内容推到用户面前”。前者偏长期搜索与信任积累&#xff0c;后者偏短期曝…

作者头像 李华
网站建设 2026/9/7 18:20:55

地下管线数字化管理的政策与技术路径

随着城市更新行动深入推进&#xff0c;燃气安全、地下管网等城市基础设施的数字化管理成为数字政府建设的重要议题。政府工作报告明确提出“扎实开展城市更新”“开展燃气、电动自行车等安全隐患全链条专项整治”&#xff0c;为地下管线数字化管理提供了政策依据。面对日益复杂…

作者头像 李华
网站建设 2026/9/7 18:20:45

青龙面板Docker版本升级:解决重启后回退旧版本的完整教程

青龙面板Docker版本升级&#xff1a;解决重启后回退旧版本的完整教程 【免费下载链接】qinglong 支持 Python3、JavaScript、Shell、Typescript 的定时任务管理平台&#xff08;Timed task management platform supporting Python3, JavaScript, Shell, Typescript&#xff09;…

作者头像 李华
网站建设 2026/9/7 18:19:02

广告算法竞赛中的dataset.py设计与特征工程实战

我这两年打各种广告算法比赛&#xff0c;有个特别深的体会&#xff1a;很多队伍不是死在模型上&#xff0c;而是死在数据上。腾讯广告算法大赛这类比赛&#xff0c;数据量大、字段杂、线上线下分布差异明显&#xff0c;谁先把 dataset.py 写明白&#xff0c;谁就赢了一半。这次…

作者头像 李华