大模型分词的若干方法
1.基于字符的编码
基于字符的编码是将文本中的每个字符视为一个独立的单元,并为每个字符分配一个唯一的数字ID。
- 编码表/字符集: 实现的核心是一个“编码表”或“字符集”,它定义了字符与数字之间的映射关系。常见的字符集包括ASCII和Unicode。
- ASCII: 最初为英文字符设计,使用7位二进制数表示128个字符。
- Unicode: 是一个更全面的字符集,旨在包含世界上所有的字符。它为每个字符分配一个唯一的码点。
- 编码方案: Unicode可以通过不同的编码方案(如UTF-8、UTF-16)来实现。UTF-8是一种可变长度的编码方式,它使用1到4个字节来表示一个字符,并且与ASCII兼容。
- 过程: 在NLP模型中,会创建一个词汇表(Vocabulary),其中包含了数据集中所有出现过的唯一字符。每个字符会被映射到一个整数索引。例如,“你好世界”会被分为‘你’、‘好’、‘世’、‘界’四个单元。
存在的问题
- 丢失语义信息: 单个字符通常不具备完整的语义信息。例如,将“苹果”分成‘苹’和‘果’两个字符后,就丢失了“水果”或“公司”这一层面的完整词义。
- 序列过长: 由于每个字符都是一个单元,处理相同长度的文本,基于字符的方法会产生非常长的序列。 这会显著增加模型训练和推理所需的计算资源和时间。
- 学习难度大: 模型需要从非常长的字符序列中学习更高层次的语义概念(如词和短语),这使得学习过程更加困难。
2. 基于字节的分词
实现方式
基于字节的分词将文本视为原始的字节序列,并将每个字节作为一个单元。文本中的任何字符都可以通过UTF-8等编码方式转换为字节序列。
- 固定词汇表: 字节的取值范围是0到255,因此这种方法的词汇表大小是固定的256。
- 处理流程: 将文本首先通过UTF-8等编码为字节流,然后直接将这个字节流作为输入序列。例如,在UTF-8编码中,一个英文字母占1个字节,一个汉字通常占3个字节。
存在的问题
- 根本没有语义信息: 单个字节本身几乎不携带任何语义信息,比单个字符的语义更加稀疏。
- 序列变得极长: 这是所有方法中产生序列最长的一种。一个汉字会被拆分成3个字节单元,压缩率=1。
- 模型学习效率低: 模型需要从毫无语义的字节序列中学习语言模式,这比从字符或词的层面学习要困难得多。
3.基于词的分词
基于词的分词是将文本分割成独立的词语,这是最符合人类直觉的一种分词方式。
- 对于英文等语言:实现相对简单,通常可以直接根据空格和标点符号进行切分。
- 对于中文等语言:中文词语之间没有天然的分隔符,因此需要更复杂的算法来识别词语的边界。主要分为以下几类:
1. 基于词典的匹配 (Dictionary-based Matching)
这是最传统的方法,将待分词的文本与一个预先建立好的词典进行匹配。其核心原则是在所有可能的切分组合中,选择词语数量最少的那一种。
- 常见算法:最大匹配法(Maximum Matching),根据匹配方向分为:
-
正向最大匹配法 (Forward Maximum Matching, FMM):
- 从句子的开头向结尾扫描。设定一个最大词长(例如,词典中最长词的长度为5)。
- 从当前位置截取长度为5的字符串,查询词典。
- 如果查询不到,则将字符串长度减1(变为4),再次查询。
- 重复此过程,直到找到一个词或字符串长度变为1。将匹配到的词切分出来,然后从剩余文本的开头继续该过程。
-
逆向最大匹配法 (Backward Maximum Matching, BMM):扫描方向与正向相反,从句子的结尾向开头进行匹配。通常在处理中文偏正结构(中心词在后)的短语时,准确率略高于正向匹配。
-
双向最大匹配法 (Bidirectional Maximum Matching):同时执行正向和逆向匹配,然后根据规则(如总词数最少、单字最少等)选择更优的结果。
-
2. 基于统计的方法 (Statistics-based Methods)
这类方法将分词视为一个序列标注 (Sequence Labeling) 问题,利用大量标注好的人工分词语料库来训练模型。其核心思想是:一个句子最有可能的切分方式,就是切分后所有词语的联合概率最大的那一种。
-
标签集:为句子中的每个字赋予一个位置标签。最常用的
{B, M, E, S}标签体系如下:B(Begin): 词的开头字M(Middle): 词的中间字E(End): 词的结尾字S(Single): 单字成词
-
举例:
- 句子: “我爱北京天安门”
- 正确分词:
我/爱/北京/天安门 - 对应标签:
S/S/B E/B M E
-
模型目标:学习在给定一个汉字序列(句子)的情况下,如何预测出概率最大的一个标签序列。
-
常见模型:
- 隐马尔可夫模型 (HMM):一种生成模型,通过学习标签之间的转移概率和特定标签下生成某个字的发射概率来工作。
- 条件随机场 (CRF):一种判别模型,它克服了HMM的独立性假设缺陷。CRF在进行标签预测时,可以考虑到整个句子的全局信息,而不仅仅是当前字和它的前后标签。
- 特征:CRF可以引入非常丰富的、任意的上下文特征,例如:
- 当前字
C_i本身 - 前一个字
C_{i-1}和后一个字C_{i+1} - 当前字和前一个字的组合
C_{i-1}C_i
- 当前字
- 发展:在传统CRF中,这些上下文特征需要人类手动指定。后续的研究工作(如 BiLSTM-CRF 模型)通过引入深度学习网络,实现了特征的自动学习。
- 特征:CRF可以引入非常丰富的、任意的上下文特征,例如:
3. 混合分词 (Hybrid Segmentation)
混合分词旨在结合基于词典和基于统计两种方法的优点,取长补短,以达到最佳的分词效果。目前市面上绝大多数成熟的分词工具(如Jieba分词)都是采用这种策略。
-
实现方式:以统计为基础,以词典为补充
- 核心引擎:使用一个训练好的统计模型(如HMM、CRF或更先进的BiLSTM-CRF)来进行分词,得到一个初步结果。
- 词典干预:在分词过程中或分词后,使用一个用户自定义词典进行校正。例如,可以强制要求词典中的某些词必须被完整地切分出来,这对于处理特定领域的专有名词非常有效。
-
Jieba分词的例子:
- 首先基于前缀词典,构建一个包含句子中所有可能成词路径的有向无环图 (DAG)。
- 然后,利用动态规划算法,并结合词频信息(统计方法),在图中寻找一条概率最大(累积词频最高)的路径作为最终分词结果。
- 对于词典中没有的词(未登录词),启用一个基于HMM的模型来进行识别和切分。
- 同时,它也允许用户添加自定义词典来影响和优化最终的分词结果。
存在的问题
尽管基于词的分词非常直观,但它也面临着一些固有的挑战:
- 词汇量巨大:为了覆盖尽可能多的词语,词典会变得非常庞大,这不仅增加了内存消耗,也提高了计算复杂度。
- 未登录词 (Out-of-Vocabulary, OOV):对于词典中没有收录的新词、网络用语或专有名词(如“绝绝子”),模型将无法处理。通常会将其错误切分或标记为未知符号(如
[UNK]),从而丢失信息。 - **词形变化 **:对于英文等语言,该方法无法很好地处理词的形态变化。例如,"run", "running", "ran" 在词典中会被视为三个独立的词,模型难以捕捉它们之间共享的语义关联。
4.基于子词的分解方式
子词分词的核心思想是: 在词和字符之间找到一个中间地带。它试图将词汇量控制在合理范围内的同时,又能通过组合来表示任何词语,从而消除OOV问题。
字节对编码 (Byte Pair Encoding, BPE)
BPE 是最著名和最经典的子词算法之一,最初是一种数据压缩算法,后来被巧妙地应用到NLP领域。GPT系列模型就使用了BPE。
阶段一:学习(构建词汇表)
-
准备原料:
- 将所有文本拆分成最基础的单元:单个字符。
- 此时,词汇表里只有这些基础字符。
- 例如,
low lower newest->l o w,l o w e r,n e w e s t
-
迭代合并:
- 找:在所有文本中,统计出出现频率最高的相邻符号对。(假设,
ow可能是最高频的) - 合并:将这个最高频的符号对合并成一个新的、更大的符号。(
o 和w合并成ow`) - 更新:将这个新符号
ow添加到词汇表中。 - 重复:循环执行 “找” 和 “合并” 的步骤,直到达到预设的合并次数(比如10000次)或者词汇表大小(比如30000个)。
- 找:在所有文本中,统计出出现频率最高的相邻符号对。(假设,
最终产物:一个包含“单个字符”和“高频组合”(如 es, est, tion, ing)的词汇表。
阶段二:使用(分词新文本)
这就像是用已经做好的乐高积木来拼搭新模型。
-
拆分: 将新单词拆分成单个字符。例如,对新词
lowest进行分词 ->l o w e s t。 -
套用规则: 按照学习阶段的合并顺序,依次将新单词中的字符对进行合并。
- 规则1是合并
ow-> 应用后得到l ow e s t - 规则2是合并
low-> 应用后得到low e s t - 规则3是合并
est-> 应用后得到low est
- 规则1是合并
-
完成: 当没有更多可以套用的合并规则或者达到最大合并次数之后,分词结束。
lowest就被成功地分成了['low', 'est']。