Fuyu-8B是由Adept团队开源的一个多模态大语言模型,它用一个反常识的设计思路在多模态领域引起了广泛关注:完全抛弃视觉编码器,直接把原始图像块线性映射后送入解码器。这种像素级输入的方式让整个模型架构变得非常简洁,同时在图表理解、文档分析等任务上表现不俗。本文将从架构原理、核心机制、实际对比和使用方法几个方面,全面剖析这个以简单高效著称的模型。

一、Fuyu-8B的架构设计:为什么可以没有视觉编码器
要理解Fuyu-8B的特别之处,首先要回顾主流多模态模型的通行做法。以LLaVA、Qwen-VL等为代表的模型,通常采用视觉编码器加语言解码器的两段式结构:图像先经过一个预训练的视觉模型(如CLIP的ViT)提取特征,再将特征投影到语言模型的向量空间中参与后续生成。这种方式的好处是能复用成熟的视觉表征,但代价是引入了额外的组件、复杂的训练流程,以及一个致命的限制——视觉编码器的输入分辨率通常是固定的。
Fuyu-8B的做法则彻底简化了这一流程。它基于一个 decoder-only 的纯解码器架构(基于Persimmon-8B初始化),图像在进入模型前不需要经过任何视觉神经网络,而是直接被切成固定大小的patch,每个patch经过一个线性层投影成与词嵌入相同维度的向量,然后就当作普通的token与文本token拼接在一起送入解码器。也就是说,在Fuyu-8B看来,图像patch和文字token没有本质区别,都是序列中的输入单元。
这种设计带来一个直接的好处:模型可以原生处理任意分辨率的图像。传统方案遇到长图、大图时需要做切图、缩放或者低分辨率填充,而Fuyu-8B只需要按顺序把所有patch排进序列即可,分辨率越高,序列越长,模型结构本身完全不用改动。这对处理网页截图、长文档扫描件等实际业务场景非常友好。
二、图像线性映射与序列拼接的实现细节
具体到实现层面,Fuyu-8B的图像处理流程可以概括为三步:切分、投影、拼接。首先是切分,图像会被划分为固定尺寸的patch(在官方实现中,图像会先经过无损的patchify处理,每个patch对应一小块像素区域),同时模型会插入换行标记来保留图像的二维空间结构信息,让解码器能够感知patch之间的行列关系。
接下来是投影。每个图像patch的原始像素值会被展平,通过一个简单的线性层(Linear层)映射到与文本词嵌入一致的隐藏维度。这个线性层是模型中唯一专门为图像新增的参数,参数量极小。相比之下,传统方案中的视觉编码器往往有数亿参数,Fuyu-8B这部分的开销几乎可以忽略。
最后是拼接。图像patch的embedding序列会与文本token的embedding序列拼接成一个长序列,一起送入Transformer解码器进行自回归生成。用伪代码表示这一过程如下:
import torch
import torch.nn as nn
class FuyuImageEmbedding(nn.Module):
def __init__(self, patch_size=30, hidden_dim=4096):
super().__init__()
self.patch_size = patch_size
# 唯一为图像新增的参数:一个线性投影层
self.linear_proj = nn.Linear(patch_size * 3, hidden_dim)
def forward(self, image_patches):
# image_patches: 形状为 (num_patches, patch_size, 3)
# 展平每个patch的像素值后做线性投影
flattened = image_patches.reshape(image_patches.shape[0], -1)
embeddings = self.linear_proj(flattened)
return embeddings # 与文本token的embedding维度一致
这段代码虽然简化了很多工程细节,但核心思想一目了然:没有卷积、没有ViT、没有注意力池化,只有一个线性层。模型对图像的全部理解,都是在解码器内部的Transformer层中,通过与文本的联合训练逐渐学习出来的。
三、与主流多模态方案的对比分析
把Fuyu-8B和LLaVA类模型放在一起对比,能更清楚地看出两种技术路线的取舍。下面的表格总结了它们在几个关键维度上的差异:
| 对比维度 | Fuyu-8B | 视觉编码器方案(如LLaVA) |
|---|---|---|
| 架构组成 | 纯解码器+线性投影层 | 视觉编码器+投影层+语言模型 |
| 任意分辨率支持 | 原生支持,无需改动 | 需要切图或缩放适配 |
| 新增参数量 | 极小(一个线性层) | 较大(整个视觉编码器) |
| 训练复杂度 | 可从头联合训练 | 通常需要多阶段对齐训练 |
| 视觉表征上限 | 依赖解码器自身学习 | 可借助成熟视觉预训练成果 |
从表格可以看出,Fuyu-8B的优势集中在工程简洁性和灵活性上,而视觉编码器方案的优势在于能够站在成熟视觉预训练的肩膀上。这也解释了两者的适用场景差异:如果你的业务以文档、图表、UI截图这类结构化图像为主,且图像尺寸变化较大,Fuyu-8B的简单架构会带来明显的工程便利;如果任务更依赖细粒度的通用视觉理解(如自然场景识别、物体检测),借助视觉编码器的方案可能在效率与精度上更有优势。
另一个值得注意的点是推理效率。由于没有视觉编码器的前向计算,Fuyu-8B在处理图像时的额外开销主要体现在序列长度增长上。一张高分辨率图像可能产生数千个patch token,这对KV缓存和上下文长度提出了较高要求,部署时需要合理控制输入图像的分辨率,在精度和推理速度之间做权衡。
四、如何快速上手使用Fuyu-8B
Fuyu-8B已经在Hugging Face上开源,可以通过transformers库直接加载使用。需要注意的是,模型对提示词格式有一定要求,图像和文本需要按特定顺序组合。下面是一个基础的使用示例:
from transformers import FuyuProcessor, FuyuForCausalLM
from PIL import Image
import torch
# 加载模型和处理器
model_id = "adept/fuyu-8b"
processor = FuyuProcessor.from_pretrained(model_id)
model = FuyuForCausalLM.from_pretrained(
model_id, torch_dtype=torch.bfloat16, device_map="auto"
)
# 准备图像和提示文本
image = Image.open("chart.png")
text = "请描述这张图表的主要内容:\n"
# 构造模型输入
inputs = processor(text=text, images=image, return_tensors="pt").to(model.device)
# 生成回答
output = model.generate(**inputs, max_new_tokens=512)
result = processor.decode(output[0], skip_special_tokens=True)
print(result)
在使用过程中有几点实践建议值得参考。第一,图像分辨率要适中,过高的分辨率会导致序列长度爆炸,显著拖慢推理速度甚至超出上下文窗口限制;第二,Fuyu-8B的强项在图表、文档、界面截图的理解,如果用它来做开放场景的图像描述,效果可能不如专门的视觉编码器模型;第三,由于模型规模为8B参数,部署时建议使用半精度加载,普通消费级显卡可能需要借助量化手段才能流畅运行。
总体来看,Fuyu-8B用一个极简的架构验证了一个重要判断:多模态能力未必需要复杂的专用视觉模块,足够的语言模型容量加上端到端训练,同样可以涌现出图像理解能力。这种化繁为简的设计哲学,对后续多模态模型的演进产生了不小的影响,也为开发者提供了一个易于理解和改造的多模态基座。对于想在文档智能化、图表问答等方向做尝试的团队来说,Fuyu-8B是一个门槛友好的起点。