一、SentencePiece 简介SentencePiece 在大模型领域主要用于文本的 分词 和 编码。1、分词是将文本分割成一个个独立的词语或符号。传统的中文分词方法，例如 BMM 分词、隐马尔可夫(H M M ) 分词，都是基于规则的，需要人工制定分词规则。而 SentencePiece 则是基于 无监督学习 的，它可以自动学习文本的语义和结构，并根据学习结果进行分词。2、编码是将分词后的词语或符号转换为数字形式，以便计算机能够处理。SentencePiece 使用了一种称为 字节对编码 的方法，它可以将每个词语或符号编码成一个或多个字节。字节对编码的优点是能够有效地利用空间，并且可以将词语或符号之间的关系编码到编码中。3、优势：SentencePiece 在大模型领域具有以下优势：分词效果好，能够准确地识别词语和符号的边界。编码效率高，能够节省空间。能够将词语或符号之间的关系编码到编码中，有利于模型学习。因此，SentencePiece 已经被广泛应用于各大模型，例如 Google 的 BERT、GPT-3，以及阿里巴巴的 M6 等。简单来说，SentencePiece 就是大模型领域的一个 分词和编码工具。它可以帮助大模型更好地理解和处理文本。4、自监督训练原理SentencePiece 的自监督训练模型原理是通过 无监督学习 的方式，学习文本的语义和结构，并根据学习结果进行分词和编码。具体来说，SentencePiece 的训练过程可以分为以下几个步骤：数据准备：首先需要准备一个文本语料库，语料库中的文本可以是任何类型，例如新闻文章、书籍、代码等。模型训练：使用无监督学习算法训练 SentencePiece 模型，模型的输入是文本语料库，输出是分词后的文本。模型评估：使用评估指标评估模型的性能，例如分词准确率、召回率等。SentencePiece 使用的无监督学习算法是一种称为 Masked Language Modeling (MLM) 的算法。MLM 的基本思想是：将文本中的部分词语或符号进行遮蔽，然后让模型预测被遮蔽的词语或符号。通过这种方式，模型可以学习文本的语义和结构。在 SentencePiece 中，MLM 的具体实现如下：随机选择文本中的部分词语或符号进行遮蔽。将被遮蔽的词语或符号替换为一个特殊符号，例如 [MASK]。将处理后的文本输入模型，让模型预测被遮蔽的词语或符号。通过这种方式，模型可以学习到被遮蔽词语或符号与周围词语或符号之间的关系，从而提高分词和编码的准确性。SentencePiece 的自监督训练模型具有以下优势：不需要人工制定分词规则，能够自动学习文本的语义和结构。分词效果好，能够准确地识别词语和符号的边界。编码效率高，能够节省空间。SentencePiece 的自监督训练模型已经被广泛应用于各大模型，例如 Google 的 BERT、GPT-3，以及阿里巴巴的 M6 等。二、TikToken 简介Tiktoken 的功能与 SentencePiece 类似，都是用于文本的 分词 和 编码。Tiktoken 是一个基于 BPE 算法的 快速分词器，它专门针对 GPT-4 和 ChatGPT 等大模型进行了优化。Tiktoken 的主要特点如下：速度快：Tiktoken 的分词速度比 SentencePiece 快很多，可以满足大模型训练和推理的需求。效果好：Tiktoken 的分词效果与 SentencePiece 相当，能够准确地识别词语和符号的边界。易用性：Tiktoken 提供了简单的 API 接口，方便使用。Tiktoken 与 SentencePiece 的主要区别 如下：分词算法：Tiktoken 使用 BPE 算法进行分词，而 SentencePiece 使用的是无监督学习算法。速度：Tiktoken 的分词速度比 SentencePiece 快很多。模型：Tiktoken 专门针对 GPT-4 和 ChatGPT 等大模型进行了优化，而 SentencePiece 则是通用的。速度探究所以大家一定对为什么这么快很好奇，查阅tictoken的源码得知，tictoken对CoreBPE类进行了基于RUST的重写，包括真·多线程，regex，缓存caching，哈希各个方面的优化，具体的下面逐一解释：3.1 regex优化正则是耗时的大头，解决办法是用一些不那么花哨的方法，比如用 regex crate可解析的形式的regex要比寻常方法快3倍以上。一旦明确了使用crate可解析的regex，可以选择用regex crate 或者 fancy_regex crateregex crate 和 fancy_regex crate也有相互关系，fancy_regex使用的re.find_it会竞争re的可变缓存空间，造成性能下降，而regex的find_iter有不同的代码路径，不会造成这个问题。为此，通过给绝大部分的regex线程做一个克隆线程来避免。3.2 threadingrayon并没有比python自带的threads和释放GIL的情况下快，所以直接用python线程计数等来完成threads这里我多说一下，python自带的GIL是指如果没有额外操作，只是使用了类似：3.3 cachingtokenizer中使用LRU cache是很有必要的，可以加速查找速度，作者使用了RWLock来保护cache安全，对于RWLock，全称是"reader-writer spin lock"，和普通的spinlock不同，它对"read"和"write"的操作进行了区分。如果当前没有writer，那么多个reader可以同时获取这个rwlock。如果当前没有任何的reader，那么一个writer可以获取这个rwlock。3.4 hash作者使用了FxHashMap替代传统的HashMap达到了一定的性能提升，简单说明一下，FxHashMap的散列算法质量不高，但速度非常快，特别是对整数键而言，并且发现它的性能优于rustc内的所有其他散列算法。以上就是tictoken进行的性能优化。
一、点乘（Dot Product）、点积 内积点乘也称为标量积或内积，是两个等长向量之间的运算。它将两个向量的对应元素相乘，然后将乘积相加，得到一个标量值。点乘只适用于向量。点积是点乘的另一种说法，通常在数学和物理学中使用，但在深度学习中，点乘和点积可以互换使用。内积通常指的是点乘，是两个向量之间的运算，得到一个标量值。内积的概念也可以扩展到矩阵，称为矩阵乘法，但矩阵乘法的结果是一个矩阵，而不是一个标量。1、对应元素相乘，求和dot：只能张量中向量(一维)操作，结果是一个标量。比如两个embedding求相似度。import torch x = torch.tensor([1,2,3]) y = torch.tensor([1,1,2]) z = torch.dot(x,y) print(z) ## 结果：tensor(9) k = x*y m = torch.mul(x,y) print(k) print(m) 2、 对应元素相乘，不求和*和 mul 操作是一样的，要求x,y具有相同的维度(一维向量，二维矩阵都可以)import torch x = torch.tensor([[3,3],[3,3]]) y = torch.tensor([[1,2],[3,4]]) k = x*y m = torch.mul(x,y) #x.mul(x) print(k) print(m) ## tensor([[ 3, 6], [ 9, 12]]) ## tensor([[ 3, 6], [ 9, 12]]) 3、 矩阵相乘@和torch.mm和torch.matmul 作用一样矩阵相乘有torch.mm和torch.matmul两个函数。其中前一个是针对二维矩阵，后一个是高维。当torch.mm用于大于二维时将报错。a = [B,E]b = [E,B]c = torch.mm(a,b)C 维度是[B,B]4、torch.matmul重点解读matmul 有广播机制(1)两个 1 维，向量内积a = torch.ones(3) b = torch.ones(3) print(torch.matmul(a,b)) # tensor(3.) (2)两个 2 维，矩阵相乘a = torch.ones(3,4) b= torch.ones(4,3) print(torch.matmul(a,b)) # tensor([[4., 4., 4.], # [4., 4., 4.], # [4., 4., 4.]])(3)一个 1 维，二个 2 维，矩阵和向量相乘注意：相靠近的那个维数要相同，比如（7）和（7,8,5)，又比如（7,8,5）和（5）a = torch.ones(3) b= torch.ones(3,4) print(torch.matmul(a,b)) # tensor([3., 3., 3., 3.]) a = torch.ones(3,4) b = torch.ones(4) print(torch.matmul(a,b)) # tensor([4., 4., 4.]) (4)、高维情况i）其中一个1维，另一个N维（N>2): 类似3），即需要靠近的那个维数相同，比如（7，）和（7,8,11），又比如（7,8,11）和（11，）ii）都高于2维，那么除掉最后两个维度之外（两个数的维数满足矩阵乘法，即，(m,p)和(p,n)），剩下的纬度满足pytorch的广播机制。a=torch.ones(5,3,4,1) b=torch.ones( 3,1,1) print(torch.matmul(a,b))