- 作者
-
-
- 姓名
- Amit Shekhar
- 发布于
-
视觉语言模型(VLM)是一种 AI 模型,它可以同时查看图像并阅读文本,然后以文本形式回答。它的工作原理是将图像转换成一串数字,这些数字在语言模型看来就像词元(token)一样,因此语言模型可以像阅读我们的问题一样“阅读”图像。
在这篇博客中,我们将学习视觉语言模型(VLM)是如何工作的。我们还将了解计算机如何将图像视为数字、视觉编码器如何将图像切分成图块并理解它们、CLIP 如何连接图像和文本、投影器如何将图像图块转换为 LLM 可以读取的词元、VLM 是如何训练的,以及 VLM 在哪些场景表现出色、在哪些场景会失败。
我们将涵盖以下内容:
- 什么是视觉语言模型?
- 计算机如何看待图像?
- 核心问题:图像不是文字
- VLM 的三个组成部分
- 第 1 部分:视觉编码器
- CLIP 是如何让图像和文本学会同一种语言的?
- 第 2 部分:投影器
- 第 3 部分:语言模型
- 用代码实现 VLM
- VLM 是如何训练的?
- 连接视觉与语言的其他方法
- VLM 在哪些场景表现出色、在哪些场景会失败
我是 Amit Shekhar,Outcome School 的创始人。我曾指导和培养过许多开发者,他们的努力为他们赢得了高薪的技术工作,帮助许多科技公司解决了各自的独特问题,并创建了众多被顶级公司使用的开源库。我热衷于通过开源、博客和视频分享知识。
我在 Outcome School 教授 AI 和机器学习。
让我们开始吧。
什么是视觉语言模型?
视觉语言模型(VLM)是一种 AI 模型,它同时接收图像和文本作为输入,将它们放在一起理解,并输出文本。
假设我们给 VLM 一张厨房的照片,并问它:“用这张桌子上的东西我能做什么菜?”。VLM 看着照片,看到鸡蛋、西红柿和洋葱,然后回答:“你可以用西红柿和洋葱做一个煎蛋卷。”
我们每天都在使用 VLM。当我们向 ChatGPT、Claude 或 Gemini 上传照片并就照片提问时,正是 VLM 在完成这项工作。
VLM 是一种能够处理多种类型数据的模型。我们有一篇关于多模态 AI的详细博客,端到端地介绍了这个更大的模型家族。
VLM 的一些常见任务:
- 描述照片中的内容。
- 回答关于图像的问题。
- 从截图、账单或文档中读取文本。
- 理解图表和示意图。
现在,要理解 VLM 是如何工作的,我们必须首先理解计算机是如何看待图像的。
计算机如何看待图像?
计算机看到的并不是猫或树。它看到的只是数字。
图像是由称为像素的微小彩色点组成的网格。每个像素有三个数字:它含有多少红(Red)、绿(Green)、蓝(Blue)光。每个数字的范围是 0 到 255。
例如,纯红色像素是
[255, 0, 0]
,而白色像素是
[255, 255, 255]
.
因此,一张 336 x 336 像素的图像就是一个包含 336 x 336 = 112,896 个像素的大网格,每个像素有 3 个数字。总共有 338,688 个数字。
A cat photo (what we see)
↓
What the computer sees:
[[ [120, 85, 60], [122, 88, 61], ... ],
[ [118, 84, 59], [121, 86, 60], ... ],
... ]这些原始数字并不能直接表示“猫”。必须有什么东西把这些原始数字转化为意义。
核心问题:图像不是文字
LLM 会把文本拆分成称为token 的小片段,并把每个 token 转换成一个称为嵌入 的数字列表。LLM 只理解这些嵌入的序列,并且一次预测一个 token 来生成答案。而图像是像素的网格。这是两种完全不同的数据形式。
让我们用一个类比来理解。假设一位作家只懂英语。我们给这位作家看一幅画,并请他据此写一个故事。但这位作家看不懂画,只能阅读英文文本。我们该怎么办?
我们雇两个帮手:
- 一位绘画专家,他观察这幅画,并用自己的私人笔记记录下画的细节。
- 一位翻译,他把这些私人笔记转换成作家能读懂的英文句子。
现在,作家阅读这些英文笔记加上我们的问题,然后写出故事。
这正是 VLM 的工作方式。问题是:我们如何把图像转换成看起来像文字 token 的东西?答案就是 VLM 的三个组成部分。
VLM 的三个组成部分
大多数流行的 VLM 由三个部分组成:
Image Text question
↓ ↓
[ Vision Encoder ] ↓
(painting expert) ↓
↓ ↓
patch vectors ↓
↓ ↓
[ Projector ] ↓
(translator) ↓
↓ ↓
visual tokens text tokens
↓ ↓
+-----------------+----------------+
↓
[ Language Model ]
(writer)
↓
Text answer在这里,我们有:
- 视觉编码器: 理解图像并将其转换为一组向量,向量就是数字列表。
- 投影器: 把这些向量转换成与 LLM 的词嵌入相同的“语言”。
- 语言模型: 一起读取图像 token 和文本 token,并写出答案。
现在,让我们逐一理解每个部分。
第 1 部分:视觉编码器
最常见的视觉编码器是Vision Transformer,也称为 ViT。Transformer 与 LLM 内部使用的架构相同。ViT 将它用于图像。
第 1 步: 图像被切成称为图块(patch)的小方块。例如,一张 336 x 336 的图像按 14 x 14 像素的图块切分,每边得到 24 个图块。也就是 24 x 24 = 576 个图块。
+----+----+----+----+ | P1 | P2 | P3 | P4 | +----+----+----+----+ | P5 | P6 | P7 | P8 | +----+----+----+----+ | ... | +-------------------+
在这里,每个方块就是一个图块。这些图块按顺序逐行读取,就像句子中的词语一样。
第 2 步: 每个图块被转换成一个向量。每个 14 x 14 的图块有 14 x 14 x 3 = 588 个数字。这些数字被排成一个长列表,并通过一个学习到的层把它们转换成向量。现在,每个图块就像图像中的一个“词”。
第 3 步:模型为每个图像块添加一个位置嵌入,这样它就知道该图像块在图像中的位置。如果没有这一步,模型就无法判断天空图像块是在顶部还是底部。
第 4 步:这些图像块经过许多层 Transformer。在每一层中,通过一个称为注意力的步骤,每个图像块都会关注其他所有图像块。显示耳朵的图像块会关注显示眼睛的图像块和显示毛发的图像块,它们共同理解出“这是一张猫脸”。
最后,我们为每个图像块得到一个向量。此时每个向量都承载着含义,而不仅仅是原始颜色。这些就是我们绘画专家的私人笔记。
计划转型进入 AI 领域?
无论你今天在哪个技术领域工作,只要付出努力,你都可以转型到以下这些角色:
- AI 工程师
- 前沿部署工程师
- AI Agent 工程师
- Harness 工程师
- 语音 AI 工程师
- AI 架构师
- LLM 工程师
- LLM 推理工程师
- 生成式 AI 工程师
- MLOps 工程师
- 机器学习工程师
- 深度学习工程师
Outcome School 的 AI 与机器学习课程将带你抵达那里。
现在,下一个重要的问题是:视觉编码器是如何学会识别事物的?这就轮到 CLIP 登场了。
CLIP 是如何让图像和文本学会同一种语言的?
许多 VLM 使用的视觉编码器来自一个名为 CLIP 的模型,该模型由 OpenAI 于 2021 年发布。CLIP 是 Contrastive Language-Image Pre-training(对比语言-图像预训练)的缩写。
CLIP 在大约 4 亿对从互联网收集的图像及其说明文字上进行了训练。例如,一张狗的照片配上说明文字“一只棕色的狗在公园里玩耍”。
CLIP 有两个部分:图像编码器和文本编码器。其训练过程如下:
- 取一批图像及其说明文字。
- 将每张图像转换为一个向量,将每条说明文字转换为一个向量。
- 让每张图像的向量与其对应说明文字的向量接近。
- 让它与该批次中所有其他说明文字的向量远离。
这被称为对比学习,因为模型是通过将正确匹配与错误匹配进行对比来学习的。
经过这种训练后,CLIP 的图像编码器产生的向量承载着关于图像的真实含义,而且这种含义已经与语言建立了联系。这就是为什么它非常适合充当 VLM 的绘画专家。
第 2 部分:投影器
现在,我们有了来自视觉编码器的图像块向量。但它们仍然使用视觉编码器自己的私有语言。LLM 无法直接读取它们。
例如,视觉编码器产生的向量大小为 1,024,而 LLM 期望的嵌入大小为 4,096。甚至每个数字的含义也不相同。
于是,投影器前来救场了。
投影器是一个小型神经网络,它将每个图像块向量转换为一个对 LLM 而言看起来像词嵌入的向量。
投影器可以非常简单。在流行的模型 LLaVA 中,第一版使用了一个单独的线性层,也就是乘以一个学习到的数字表。下一版 LLaVA-1.5 则使用了一个名为 MLP 的小型两层网络,MLP 是多层感知机(Multi-Layer Perceptron)的缩写。
经过投影器之后,每个图像块就变成了一个视觉 token。对 LLM 来说,视觉 token 看起来和词 token 一模一样,尽管它来自图像。这就是我们的翻译器在工作。
给你的一点小提示
无论你在哪个技术领域工作,都请熟悉以下这些主题:
- LLM
- RAG
- MCP
- Agent
- 微调
- 量化
我们把它们全部整合在一个视频中:
AI 工程详解:LLM、RAG、MCP、Agent、微调与量化
不必停下阅读——把它收藏起来,等有空时再看。未来的你会感谢现在的你。
现在,让我们回到正题。
第 3 部分:语言模型
现在,LLM 接收到一个长序列:
[visual token 1] [visual token 2] ... [visual token 576] [What] [is] [in] [this] [image] [?]
LLM 读取这个序列的方式与读取普通文本完全相同。通过注意力机制,文本 token 会关注视觉 token。“this”这个词会关注视觉 token,并找到猫的图像块。
然后,LLM 生成答案,一次生成一个 token:
"This is an orange cat sleeping on a blue sofa."
这就是我们的写作者在工作。LLM 从不接触像素,它只看到 token。有些 token 来自文字,有些则来自图像。
用代码实现 VLM
让我们用 Python 和 NumPy 看看数据流经 VLM 时的形状代码。我们使用随机数,只是为了理解数据流。
import numpy as np
image = np.random.rand(336, 336, 3) # height, width, 3 colors (RGB)
patch = 14 # each patch is 14 x 14 pixels
patches_per_side = 336 // patch # 24
num_patches = patches_per_side ** 2 # 576
print("Patches:", num_patches)
vision_dim, llm_dim = 1024, 4096
patch_vectors = np.random.rand(num_patches, vision_dim) # output of the vision encoder
projector = np.random.rand(vision_dim, llm_dim) # learned during training
visual_tokens = patch_vectors @ projector
print("Visual tokens:", visual_tokens.shape)
text_tokens = np.random.rand(8, llm_dim) # "What is in this image?"
llm_input = np.concatenate([visual_tokens, text_tokens])
print("LLM input:", llm_input.shape)在这里,我们有:
- image 是一张 336 x 336 的图片,每个像素有 3 个颜色数值。
- 我们把它切成 14 x 14 的图像块,得到 24 x 24 = 576 个图像块。
- patch_vectors 代表视觉编码器的输出:每个图像块对应一个大小为 1,024 的向量。
- projector 是一个学习到的表。@ 符号表示矩阵乘法。它将每个大小为 1,024 的向量转换为大小为 4,096 的向量,即 LLM 所期望的大小。
- text_tokens 代表我们 8 个问题 token 的嵌入。
- np.concatenate 将视觉 token 和文本 token 连接成一个序列。
这将打印出以下内容:
Patches: 576 Visual tokens: (576, 4096) LLM input: (584, 4096)
在这里,我们可以看到 LLM 接收到 584 个 token:576 个来自图像,8 个来自文本。它们的大小都相同,因此 LLM 可以一起读取它们。
注意: 这里一张图像使用了 576 个 token,远多于我们 8 个 token 的问题。这就是为什么图像会使 VLM 比纯文本更慢、成本更高。
保持更新: 订阅我们的新闻通讯,将最新的 AI 和机器学习博客直接发送到您的收件箱。
VLM 是如何训练的?
现在,让我们来理解这三个部分是如何学会协同工作的。LLaVA 是一个很好的例子,因为它的方法很简单。
我们从两个已经训练好的部分开始:来自 CLIP 的视觉编码器和一个已经掌握语言的 LLM。只有投影器是新的。
步骤 1: 我们训练翻译器。视觉编码器和 LLM 被冻结,也就是说它们的参数不更新。只有投影器在大量图像-描述对上进行训练。任务是看图并生成对应的描述。这让投影器学会将图像向量转换为 LLM 的语言。
步骤 2: 我们教模型遵循指令。模型在带有问题和优质回答的图像示例上进行训练。例如,一张街道的图片,配上问题“过马路安全吗?”以及一个有用的回答。在这一步,投影器和 LLM 都参与训练。视觉编码器通常保持冻结。这让 VLM 学会围绕图像进行有用的对话。
| 部分 | 步骤 1 | 步骤 2 |
|---|---|---|
| 视觉编码器 | 冻结 | 冻结 |
| 投影器 | 训练 | 训练 |
| LLM | 冻结 | 训练 |
这就是通过复用已经擅长各自工作的部分,来低成本训练 VLM 的方法。
要深入学习多模态 AI、微调和大语言模型(LLM),请查看 Outcome School 的 AI 与机器学习项目。
连接视觉与语言的其他方法
投影器设计是最常见的,但并不是唯一的。让我用表格列出主要的设计,以便你更好地理解。
| 设计 | 如何连接图像 | 示例 |
|---|---|---|
| 投影器 | 将每个图块转换为视觉 token,并放在文本前面 | LLaVA |
| 基于查询的连接器 | 一小组可学习的查询从图像中提取重要信息,产生更少的 token | BLIP-2 (Q-Former) |
| 交叉注意力 | 图像不作为 token 加入。LLM 内部的额外层在阅读文本时查看图像 | Flamingo |
| 原生多模态 | 模型从一开始就在图像和文本 token 上一起训练 | Chameleon |
这里我们可以注意到其中的权衡。投影器设计简单且保留所有细节,但使用很多 token。基于查询的设计使用更少的 token,但可能丢失细小细节。
Flamingo 设计建立在交叉注意力之上,文本在 LLM 内部查看图像。我们有一篇关于 Transformer 中的交叉注意力的详细博客,解释了它的工作原理。
VLM 在哪些场景表现出色、在哪些场景会失败
擅长的场景:
- 描述照片并回答关于照片的一般问题。
- 读取截图、收据和文档中的文字。
- 理解图表、表格和示意图。
- 帮助低视力人群了解周围环境。
失效的场景:
- 幻觉: VLM 可能会描述图像中不存在的东西。例如,桌上明明没有杯子,它却说桌上有一个杯子。一个主要原因是 LLM 从文本中养成了很强的习惯。杯子通常放在厨房的桌子上,所以它会用通常存在的东西来填补空缺。
- 计数和精确位置: 像“天上有几只鸟?”或“钥匙在手机的左边吗?”这类问题经常被答错。
- 微小细节: 当大图像被缩小以适应视觉编码器时,小文本和小物体会变得模糊。许多较新的 VLM 通过将大图像切成多个图块并分别编码每个图块来解决这个问题,但这会使用更多的 token。
- 成本: 每张图像会增加数百甚至数千个 token,这会使模型更慢、更昂贵。
现在我们应该已经理解了视觉语言模型(VLM)是如何工作的。
常见问题
VLM 内部的语言模型能看到图像的像素吗?
不能。语言模型永远看不到像素,只能看到 token。视觉编码器将图像块转换为向量,投影器将这些向量转换为看起来像词 token 的视觉 token。然后语言模型将视觉 token 和文本 token 作为一个序列一起读取。
为什么向 VLM 发送图像比发送文本成本更高?
一张图像会为输入增加数百甚至数千个 token。例如,一张 336 x 336 的图像切成 14 x 14 的图像块会产生 576 个视觉 token,远多于一个只有 8 个 token 的简短问题。更多的 token 会使模型更慢、更昂贵。
为什么 VLM 难以读取大图像中的小文本?
当大图像被缩小以适应视觉编码器时,小文本和小物体会变得模糊。许多较新的 VLM 通过将大图像切成多个图块并分别编码每个图块来解决这个问题。这保留了小细节,但会使用更多的 token。
构建 VLM 时,视觉编码器会被重新训练吗?
通常不会。在像 LLaVA 这样的简单方案中,视觉编码器来自 CLIP,并且已经训练好了。它保持冻结,先训练投影器,然后将投影器和 LLM 一起在带有问题和正确答案的图像上进行训练。正是这种复用使 VLM 的训练成本保持在较低水平。
今天就到这里。
谢谢
Amit Shekhar Outcome School 创始人
你可以通过以下方式与我联系:
关注 Outcome School: