视频链接:
基于PyTorch从零构建多模态(视觉)大模型 by Umar Jamil
从头编写一个视觉语言模型:PloyGamma,是谷歌的一个模型
1:原始图像
2:视觉编码器(本文是viT),通过对比学习进行训练。这个对比学习最开始是CLIP,后来被谷歌改成了SigLIP
3:线性投影层
4:如何将图像tokens的嵌入与文本token的嵌入结合起来
5:文本提示
6:Tokenizer
7:语言模型本身,基于transformer
8:如何利用条件生成输出
接下来的内容:
1)Vision Transformer
2)对比学习(CLIP、SigLip)
3)多模态语言模型(Gemma):如何把视觉和文本结合起来
4)KV-cache:希望这个模型用于推理,希望以优化的方式来实现,最佳方法就是使用KV-cache
5)旋转位置编码:
6)归一化Normalization(batch Normalization,layer Normalization,RMS Normalization)
1. 对比学习
1.1 CLIP
CLIP:文本编码器与图像编码器对应的嵌入表示的内积应该最大。这个完全可以用交叉熵损失来实现。关于交叉熵可以参考我的另外一篇文章:关于交叉熵损失函数以及几个类似的损失函数
CLIP伪代码如下:
1.2 CLIP的问题
问题就是:使用了交叉熵损失函数,交叉熵损失函数需要使用softmax,而softmax函数需要用到指数函数。如果logits很大,那么其指数就会变的非常巨大,可能32位来表示这个数字是不够的。所以需要softmax数值稳定(让数字在32位或者16位范围内可以被表示)
办法就是让每个logits减去最大的logit,(相当于分子分母同时乘以一个常数)解释如上图所示。
交叉熵损失函数涉及到大量的计算,并行化也比较困难,使得没法使用很大的batch size。而且因为softmax的非对称性,normalization需要在图片上和文本上执行两次。
1.3 Siglip
总之,clip的softmax计算很昂贵。这就是为什么在SigLIP论文种提意用sigmoid损失替换交叉熵损失。
SigLIP做的是如下步骤:
1)计算点积,不把损失当作行或者列的分布来处理,而是将其作为一个二分类问题,使用sigmoid损失。每个点积都彼此独立处理。表格里的每一项,不是0就是1.
2)把每个点积通过sigmoid函数,标签位1或者0.每一个点积变成了独立的二分类问题。
3)这样batch size可以扩大的很大,可以并行处理
1.4 为什么要使用对比视觉编码器
不仅希望这些嵌入可以捕捉图像的信息,而且可以与文本嵌入对齐
2. ViT
一个图片,分成16个patch,每个patch用卷积,然后展平成16个embeddings,然后加上16个位置编码,16个位置编码是学习的。transformer对嵌入做上下文化处理,输出是上下文处理后的嵌入,也就是每个嵌入捕捉了其他patch的信息,也捕捉了它在图像中的呈现方式,希望每个嵌入也包含了他的位置信息,由位置编码给出。
有一个tokens列表代表整个图片的信息,每个token是代表对应的一个patch,但是同时通过注意力机制也包含了其他patch信息。(40:30)
2.1. 位置编码【TO DO】
2.2. Layer Norm
存在问题协变量偏移:
不同的输入,范围变化很大,导致输出范围变化很大,导致loss范围变化很大,导致反向传播不稳定,要花很长时间去学习这个变化,效率低。
2.2.1 Batch Normalization
针对每个特征维度,在batch这个维度上做标准化,也就是减去均值,除以标准差
缺点:当Batch size很小的时候,这个均值和标准差变化也很大,所以并没有完全解决协变量平移的问题。
2.2.2 Layer Normalization
Layer Normalization 是在所有特征上进行标准化,不会出现随着batch变化而出现很大变化的情况