语言基础与文本表示:字符编码、分词技术与子词分词
聊到多语言NLP,我第一个想跟你聊的,其实是那些最基础、最容易被忽略的东西。字符编码、分词、子词——这些听起来像“体力活”的环节,往往决定了你整个系统的天花板。
我见过太多团队,模型选得花里胡哨,结果在编码上翻了车。嗯,咱们今天就把这块地基打牢。
字符编码:Unicode 与 UTF-8
先说编码。你想想看,计算机只认0和1,但人类有几千种语言、几十万个字符。怎么让机器理解“你好”和“Hello”其实是同一个意思?
答案就是 Unicode。它给每个字符分配了一个唯一的数字编号,比如“中”的编号是 U+4E2D。但问题来了:这个编号怎么存?
我早期做项目时,有个同事直接拿 UTF-32 存文本。每个字符固定4字节,简单粗暴。结果一个1GB的语料库,硬生生膨胀到4GB。训练速度直接腰斩。
所以实际工程中,UTF-8 是绝对的主流。它用变长编码,英文1字节,中文3字节,兼顾了空间和效率。
核心要点:
- Unicode 是字符集,只负责编号
- UTF-8 是编码方式,负责存储和传输
- 多语言场景下,UTF-8 是默认选择
我个人的习惯是:所有文本处理的第一步,先统一转成 UTF-8。别问为什么,问就是踩过坑。
分词技术:从规则到神经网络
分词,说白了就是把一句话切成有意义的单元。中文没有空格,所以分词尤其头疼。
基于规则的分词
最早的做法是查词典。比如“我爱北京天安门”,词典里有“北京”、“天安门”,那就切出来。实现起来简单,但遇到“长春药店”这种歧义句就傻了——是“长春/药店”还是“长/春药/店”?
我记得有一次做新闻分类,规则分词把“美国会”切成了“美国/会”,结果“美国会通过法案”被理解成“美国”和“会”两个词。嗯,后来我加了个词性标注才勉强解决。
基于统计的分词
规则搞不定,那就让数据说话。统计分词的核心是:看哪些字经常一起出现。比如“机器”和“学习”经常挨着,那“机器学习”就应该是一个词。
常用的算法有 HMM(隐马尔可夫模型)和 CRF(条件随机场)。说白了,就是给每个字打标签:B(词首)、M(词中)、E(词尾)、S(单字词)。
我建议你试试 jieba 分词,它背后就是统计模型。虽然现在看起来有点老,但作为 baseline 依然能打。
基于神经网络的分词
最近几年,大家都用 LSTM 或 Transformer 来做分词。把句子输入网络,直接输出每个字的标签。准确率比统计方法高不少,但需要大量标注数据。
你想想看,标注一个分词语料库有多贵?中文一个句子平均20个字,标10万句就是200万个标签。所以很多团队干脆用子词分词绕过了这个问题。
子词分词:BPE、WordPiece、SentencePiece
子词分词,是当前 NLP 的事实标准。它不把词当作最小单位,而是把词拆成更小的子词单元。
比如“unbelievable”可以拆成“un”、“believe”、“able”。这样即使遇到生词“unhappiness”,模型也能通过“un”、“happy”、“ness”猜出意思。
BPE(字节对编码)
BPE 的思路很简单:从单个字符开始,不断合并出现频率最高的相邻字符对。
举个例子:假设语料里有“low”、“lower”、“new”。初始词表是 {l, o, w, e, r, n}。然后统计发现“lo”出现最多,合并成“lo”。接着“low”出现最多,再合并。最终词表里会有“low”、“lower”、“new”这些子词。
我曾在机器翻译项目里用过 BPE。当时中英翻译,中文这边切词后词表有5万,英文那边有3万。用 BPE 压缩到各1万,模型大小直接减半,翻译质量反而提升了。
小技巧:BPE 的合并次数是个超参数。我一般从 8000 开始试,看验证集上的困惑度变化。合并太多会丢失信息,太少又切得太碎。
WordPiece
WordPiece 和 BPE 很像,但合并标准不同。BPE 看频率,WordPiece 看互信息——也就是两个字符一起出现带来的信息增益。
BERT 用的就是 WordPiece。它有个特殊标记“##”,表示这个词是前一个词的延续。比如“playing”会被切成“play”和“##ing”。
我个人觉得 WordPiece 比 BPE 更优雅,但实现起来复杂一点。如果你用 HuggingFace 的 transformers 库,它已经帮你封装好了。
SentencePiece
SentencePiece 是 Google 出的,它最大的特点是:不依赖预分词。直接把原始文本(包括空格)当作输入,自己学出分词规则。
这意味着你不需要先做中文分词,也不需要处理日语、韩语这些没有空格的语言。SentencePiece 一视同仁。
我曾经在做一个多语言翻译系统时,用了 SentencePiece。输入是 100 种语言的混合文本,输出是统一的子词序列。效果出奇的好,因为模型学会了跨语言的共享子词。
注意:SentencePiece 有两种模式:unigram 和 BPE。unigram 模式基于语言模型,效果更好但训练更慢。我建议小语料用 BPE,大语料(>10GB)用 unigram。
三种子词方法对比
| 方法 | 核心思想 | 典型应用 | 我的评价 |
|---|---|---|---|
| BPE | 按频率合并字符对 | GPT、RoBERTa | 简单粗暴,够用 |
| WordPiece | 按互信息合并 | BERT | 更精细,但实现复杂 |
| SentencePiece | 不依赖预分词 | T5、XLNet | 多语言场景首选 |
最后说一句:别纠结选哪个。我建议你从 SentencePiece 开始,因为它最通用。等遇到具体问题再换也不迟。
好了,这一章就到这里。下一章咱们聊聊词向量和预训练模型——那才是真正有意思的部分。
公众号:蓝海资料掘金营,微信deep3321