/images/avatar.png

vllbc

pack and unpack

pack

Packs several tensors into one. See einops tutorial for introduction into packing (and how it replaces stack and concatenation).

image.png ## unpack >Unpacks a single tensor into several by splitting over a selected axes. See einops tutorial for introduction into packing (and how it replaces stack and concatenation).

image.png

rearrange

einops.rearrange is a reader-friendly smart element reordering for multidimensional tensors. This operation includes functionality of transpose (axes permutation), reshape (view), squeeze, unsqueeze, stack, concatenate and other operations.

代替reshape,给维度命名。可以用…代表不想动的维度。 image.png image.png

repeat

einops.repeat allows reordering elements and repeating them in arbitrary combinations. This operation includes functionality of repeat, tile, and broadcast functions.

repeat是使维度增加,与reduce相反。 image.png image.png ## 应用 比如说repeat_kv函数就可以用einops.repeat很方便的实现

parse_shape

Parse a tensor shape to dictionary mapping axes names to their lengths.

# Use underscore to skip the dimension in parsing. 
>>> x = np.zeros([2, 3, 5, 7]) >>> parse_shape(x, 'batch _ h w') {'batch': 2, 'h': 5, 'w': 7} 
# `parse_shape` output can be used to specify axes_lengths for other operations: 
>>> y = np.zeros([700]) 
>>> rearrange(y, '(b c h w) -> b c h w', **parse_shape(x, 'b _ h w')).shape 
(2, 10, 5, 7)

也就是把维度的维数映射到对应的命名。与数据无关,只看得到维度。

gather和scatter

gather

参数:

  • input (Tensor) – the source tensor
  • dim (int) – the axis along which to index
  • index (LongTensor) – the indices of elements to gather
  • out (Tensor_,__optional_) – the destination tensor
  • sparse_grad (bool,optional) – If True, gradient w.r.t. input will be a sparse tensor. > gather操作是scatter操作的逆操作,如果说scatter是根据index和src求self(input),那么gather操作是根据self(input)和index求src。具体来说gather操作是根据index指出的索引,沿dim指定的轴收集input的值。
out[i][j][k] = input[index[i][j][k]][j][k]  # if dim == 0
out[i][j][k] = input[i][index[i][j][k]][k]  # if dim == 1
out[i][j][k] = input[i][j][index[i][j][k]]  # if dim == 2

对于gather操作来说,有三个约束需要满足:

llama系列

LLaMA介绍

LLaMA 是目前为止,效果最好的开源 LLM 之一。

论文的核心思想:相比于GPT,更小的模型+更多的训练数据**也可以获得可比的效果

基于更多 tokens 的训练集,在各种推理预算下,训练出性能最佳的一系列语言模型,称为 LLaMA,参数范围从 7B 到 65B 不等,与现有最佳 LLM 相比,其性能是有竞争力的。比如,LLaMA-13B 在大多数基准测试中优于 GPT-3,尽管其尺寸只有 GPT-3 的十分之一。作者相信,LLaMA 将有助于使 LLM 的使用和研究平民化,因为它可以在单个 GPU 上运行!在规模较大的情况下,LLaMA-65B 也具有与最佳大型语言模型(如 Chinchilla 或 PaLM-540B)相竞争的能力。

frequency_penalty&presence_penalty

image.png

LLM解码时采用的自回归采样,其过程如下:

  1. 小模型使用前缀作为输入,将输出结果处理+归一化成概率分布后,采样生成下一个token。
  2. 将生成的token和前缀拼接成新的前缀,重复执行1,直到生成EOS或者达到最大token数目。

将模型输出logits的转换成概率,有几种常用的采样方法,包括argmax、top-k和top-n等 # 贪心搜索 直接选择概率最高的单词。这种方法简单高效,但是可能会导致生成的文本过于单调和重复 # 随机采样 按照概率分布随机选择一个单词。这种方法可以增加生成的多样性,但是可能会导致生成的文本不连贯和无意义。 # beam search 维护一个大小为 k 的候选序列集合,每一步从每个候选序列的概率分布中选择概率最高的 k 个单词,然后保留总概率最高的 k 个候选序列。这种方法可以平衡生成的质量和多样性,但是可能会导致生成的文本过于保守和不自然。 # top-k image.png

rwkv

线性Transformer

\[V_i'=\frac{\sum_{j=1}^N sim(Q_i,K_j)V_j}{\sum_{j=1}^N sim(Q_i,K_j)}\] 注意下标i。 其中

\[sim(Q_{i},K_{j})=\phi(Q_{i},K_{j})\]

此时有:

\[V_{i}^{\prime}=\frac{\phi(Q_{i})\sum_{j=1}^{i}\phi(K_{j})^{T}V_{j}}{\phi(Q_{i})\sum_{j=1}^{i}\phi(K_{j})^{T}}\]

注意可以将\(\phi(Q_{i})\)提出来。

原始Transformer的计算复杂度随序列长N呈二次方增长,这是因为attention的计算包含两层for循环,外层是对于每一个Query,我们需要计算它对应token的新表征;内层for循环是为了计算每一个Query对应的新表征,需要让该Query与每一个Key进行计算。 所以外层是 for q in Queries,内层是 for k in Keys。Queries数量和Keys数量都是N,所以复杂度是 O(N^2) 。而Linear Transformer,它只有外层for q in Queries这个循环了。因为求和项的计算与i无关,所以所有的 Qi 可以共享求和项的值。换言之,求和项的值可以只计算一次,然后存在内存中供所有 Qi 去使用。所以Linear Transformer的计算复杂度是O(N) 。