欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

WordPiece是如何基于词表对文本进行切分的

发布时间:2023/12/16 编程问答 61 豆豆
生活随笔 收集整理的这篇文章主要介绍了 WordPiece是如何基于词表对文本进行切分的 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

本文从PaddleNLP源码入手,分析WordPiece是如何基于词表对输入的文本进行子词切分的。

为了更好地阅读本文,你需要知道子词切分tokenize相关的知识,可以参考我之前的文章:

  • tokenizer简介
  • tokenizers:BPE算法

WordPiece采用了一种贪心的最长匹配搜索算法来将原始文本切分成子词。

为简单起见,假设词表中只有三个子词:['un', 'aff', 'able'],我们要切分的单词是“unaffable”。具体做法是,初始化两个位置变量(start和end,分别表示最左侧字符的位置和最右侧字符的位置),然后将end逐个减1,每次移动后(包括初始时)都将从start到end的字符拼接起来,并查看它们是否在词表中。

另外,如果start不为0(即对应的字符不是开头的字符),那么需要在子词前面加上##。

本部分代码如下:

output_tokens = [] for token in whitespace_tokenize(text):# whitespace_tokenize是先将text按照空格切分,这对于输入一个句子的情况下有用# 接下来,把token想象成单词“unaffable”chars = list(token)if len(chars) > self.max_input_chars_per_word:# 这里做了一个限制:如果一个单词的长度超过了设定值(默认是100),那么便被标记为预先定义的字符,一般是`UNK`output_tokens.append(self.unk_token)continueis_bad = Falsestart = 0sub_tokens = []# 初始化了startwhile start < len(chars):end = len(chars)cur_substr = Nonewhile start < end:# 从最后一个字符逐个向左遍历,保证匹配到的子词是最长的substr = "".join(chars[start:end])if start > 0: # 添加特殊的连接符substr = "##" + substrif substr in self.vocab: # 姑且把vocab理解为一个列表或键为词表中单词的字典cur_substr = substrbreakend -= 1if cur_substr is None:# 这里是一个否决条件,如果end走了一遍仍没有找到合适的子词,那么说明当前从start到end组成的子词不在词表中is_bad = Truebreaksub_tokens.append(cur_substr)start = endif is_bad:# 只有有任意一部分不在词表中,那么当前token就被标记为`UNK`output_tokens.append(self.unk_token)else:output_tokens.extend(sub_tokens)

总结

以上是生活随笔为你收集整理的WordPiece是如何基于词表对文本进行切分的的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。