[具身智能-318]:分词 (Tokenization)原理和代码示例
分词Tokenization是大语言模型LLM的“第一公里”它的核心任务是将人类可读的自然语言文本转换为模型能够理解和处理的数字序列。简单来说分词器Tokenizer就是一个“翻译官”它通过一个预定义的“字典”词汇表将文本切分成一个个有意义的单元Token并给每个单元分配一个唯一的数字编号Token ID。 为什么需要分词大模型无法直接处理文字它们只能理解数字。分词就是这个从“文字”到“数字”的桥梁。按整词分词汇表会过于庞大且无法处理未见过的新词OOV问题。按字符分序列会过长模型难以学习词语级别的语义。按子词分 (Subword)这是目前的主流方案。它在词汇表大小和处理灵活性之间取得了最佳平衡能够将生僻词拆解为常见的子词单元。⚙️ 核心原理BPE (Byte Pair Encoding)BPE字节对编码是目前 GPT、Llama 等主流模型采用的分词算法。它的核心思想非常直观从字符开始反复合并出现频率最高的相邻单元直到词汇表达到预设的大小。这就像一个数据压缩过程常用的词如 hello会保持完整成为一个 Token而不常见的词如 unbelievable则会被拆解成有意义的子词如 un, believ, able。BPE 算法流程示例假设我们有一个极小的语料库包含以下单词及其出现次数hug: 10次pug: 5次pun: 12次bun: 4次hugs: 5次初始状态将每个单词拆分为单个字符。h u g: 10p u g: 5p u n: 12b u n: 4h u g s: 5统计与合并统计所有相邻字符对的频率找到最高频的一对进行合并。统计发现(u, g)这对组合出现了 20 次1055频率最高。于是我们将u和g合并成一个新的单元ug。词汇表更新为[h, u, g, p, n, b, s, ug]重复迭代用新的单元ug替换原文本中的u g然后再次统计。h ug: 10p ug: 5p u n: 12b u n: 4h ug s: 5接着可能会发现(h, ug)频率很高于是合并成hug。这个过程会不断重复直到词汇表大小满足要求。通过这种方式模型最终学会了一套高效的“拆分与合并”规则能够灵活地处理任何文本。 代码示例下面通过两种方式展示分词的实际应用一是使用业界标准的tiktoken库二是实现一个最基础的词级分词器来理解其底层逻辑。1. 使用tiktoken库 (GPT-4 同款)tiktoken是 OpenAI 开源的快速分词库GPT-4 就使用它进行分词。pythonimport tiktoken # 加载 GPT-4 使用的分词器 enc tiktoken.get_encoding(cl100k_base) text Large Language Models # 编码文本 - Token IDs token_ids enc.encode(text) print(fToken IDs: {token_ids}) # 输出示例: # 解码Token IDs - 文本 decoded_text enc.decode(token_ids) print(fDecoded text: {decoded_text}) # 输出: Large Language Models # 查看生僻词如何被拆分 rare_word_ids enc.encode(Unbelievable) print(fUnbelievable 的 Token IDs: {rare_word_ids}) # 输出示例: (被拆成了3个子词)2. 实现一个简易的词级分词器这个例子展示了分词器最基础的构建流程构建词汇表和编解码。pythonimport re class SimpleTokenizer: def __init__(self, texts): # 1. 构建词汇表 # 使用正则表达式切分文本并保留标点符号 preprocessed [] for text in texts: tokens re.split(r([,.:;?_!()\]|--|\s), text) preprocessed.extend([t for t in tokens if t.strip()]) # 去重、排序并为每个词元分配一个ID all_words sorted(set(preprocessed)) self.str_to_int {token: i for i, token in enumerate(all_words)} self.int_to_str {i: token for token, i in self.str_to_int.items()} def encode(self, text): # 2. 编码将文本转换为ID序列 tokens re.split(r([,.:;?_!()\]|--|\s), text) tokens [t for t in tokens if t.strip()] return [self.str_to_int[t] for t in tokens] def decode(self, ids): # 3. 解码将ID序列还原为文本 return .join([self.int_to_str[i] for i in ids]) # 使用示例 corpus [Hello, world!, Hello, AI!] tokenizer SimpleTokenizer(corpus) text Hello, world! ids tokenizer.encode(text) print(f原始文本: {text}) print(fToken IDs: {ids}) print(f还原文本: {tokenizer.decode(ids)})
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2501164.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!