鸿泽思维
26-06-10 11:39 微博认证:头像本人

如何在AI时代管理我们的学习

学习最重要的是建立一套方法论,然后再去学习。学习分两个层面,懂不懂的先用起来,能跑起来。二是底层原理全部吃透。第一层相对来说比较容易,比如说AI,你训练一个模型让AI生成几百行代码就行了。至于代码是怎么动作的,那就不明白。第二层时,底层原理必须用方法论和死磕精神完成认知的迭代。这对大多数人来说,是非常难的,主要是他们没有学习的决心。

我用我学习AI的过程举一个例子。我在学习transformer的时候第一个认知门槛是LayerNorm层归一化。这东西到底在干什么?搞不清楚往后走就难了,也学不明白。我的方法是看看它具体做了什么事,再理解这件事的本质是什么。

结果上LayerNorm做了两个动作,一是将向量均值归0,二是将向量的方差归1。因此叫归一化层。现在,就不是编程的范畴了,而是数学的范畴,那我们就要回到数学思维。

对向量的均值归0,在数学意义上就是“线性平移”,啥叫线性平移?很简单,你有一个苹果,从餐桌的左边拿到餐桌的右边,这就叫线性平移。你这一次平移苹果变了吗?没有。所以均值归0不影响数据特征。

对向量方差归1,在数学意义上是缩放,以前咱们的正方形是4平米,通过方差归1直接缩放成1平方米,大小是变了,但是正方形的结构没变。

这两个动作下来相当于把数据挪了个位置,把大小缩放到一个合适的范围。这就相当于工厂的流水线,对原材料进行预处理,让它适合进行运算。你不归0向量没法以原点进行比较,你方差不归1有的向量大到把你脸给糊上了,有的小到显微镜都看不到,你看不清。

这段代码你就看明白了
layer_norm = torch.nn.LayerNorm(em_dim)
normed_input = layer_norm(input_vec)

但这段代码仍然是一个pytorch封装好的黑盒,这时我手搓了一个实现:
mean = x.mean(dim=-1, keepdim=True)
var = ((x - mean) ** 2).mean(dim=-1, keepdim=True)
x_norm = (x - mean) / torch.sqrt(var + eps)

第一行求x向量的均值,第二行求x向量的方差,第三行使用均值归0除以标准差使方差归1。这就完成了归一化的纯手工算法实现。AI的算法就是这么朴实无华。

但这并不是学习的结束,这时我思考到既然可以通过平移进行数据整形保持特征不变,然后计算向量倾角来得到下一个词。数轴的刻度就是一个虚拟的附加结构,所以我不平移,也可以算得出来。那么好了,这就进行了当前AI圈最核心的归一化算法RMSNorm的讨论范围了。

所以,我从对传统归一化LayerNorm的学习,三个小时以后自动推理出来了RMSNorm的核心算法:
rms = x / torch.sqrt(torch.mean(x ** 2, dim=-1, keepdim=True) + 1e-5)

RMSNorm做了一件什么事呢?既然数据平移特征不变,不平移特征就更不会不变,那就直接原地站撸,不做均值归0这个动作了,而是在初始化时基本保证数据的高斯分布,节省了均值计算的成本。这在AI训练过程中会有非常大的性能提升,因为归一化层会被反复调用,开销极大。

你们要知道整个AI界从LayerNorm到RMSNorm这简单的一小步用了三年时间,我用逻辑推理三个小时就搞出来了。这就是掌握底层原理以后的学习的追赶机制。

我为了确认工业界确实是用的这个算法,去github上验证了Meta公司的llama核心代码RMSNorm的实现:
return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps)
原地址:http://t.cn/AXXkHVn7

看明白llama与我手搓的差异了吗,如果你把这个底层都搞懂了,Meta的工程师为什么将算法改为乘平方根倒数,那么恭喜你,你可以吃AI算法这碗饭了。

发布于 北京