Large Language-and-Vision Assistant
一个开源的端到端多模态大模型,让大语言模型"看懂"图像
LLaVA(Large Language-and-Vision Assistant)是 2023 年由 威斯康星大学麦迪逊分校、微软研究院和哥伦比亚大学的研究者共同提出的 开源多模态大语言模型。它是首批将 GPT-4 级别的视觉指令微调 (Visual Instruction Tuning)思路落地到开源模型上的工作之一。
它的核心思想非常简洁:把一个视觉编码器(看图)和一个 大语言模型(说话)用一个投影层连接起来, 让模型能够根据图像内容回答问题、执行指令,实现图文对话。
LLaVA 的意义在于:它证明了仅用极简的架构和少量公开数据, 就能训出在多模态基准上接近 GPT-4V 表现的开源模型,极大地推动了多模态开源生态的发展。
LLaVA 的架构可以用一句话概括:图像 → 视觉编码器 → 投影层 → 大语言模型 → 文本输出。 它没有设计复杂的交互模块,而是用最直接的方式把视觉特征"翻译"成语言模型能理解的"词"。
<image> 占位 token
LLM 只认文本 token,图像要进入它的输入序列,靠的是一个特殊占位 token——在 prompt 模板里写成 <image>。它干两件事:给 LLM 词表扩一个新"词"并初始化 embedding;在序列里占个位置,等视觉特征备好后,把这个占位符替换成一串视觉 token。
USER: <image> 这张图里有什么? ASSISTANT:
336×336 的图,ViT-L/14(patch 14)切成 24×24 = 576 个 patch,每个经编码 + 投影层映射成 1 个视觉 token,整体替换掉那个 <image>。这就是上面"投影层"说的"建立视觉 token → 语言空间的映射"。
<image> 这个 special token 本身不是加速手段,它只是"接口 / 对齐"机制。真正的性能负担,恰恰是替换进去的那 576 个视觉 token——自注意力是 O(n²),序列暴涨算力平方级上升;每个视觉 token 都要在每层存 K/V,KV Cache 显存随长度线性涨。一张图 576 token,往往比文字 prompt 还长,成了延迟和显存的大头。
从视觉编码到训练优化,LLaVA 站在了一系列成熟技术的肩膀上。
OpenAI 的 CLIP 视觉 Transformer,将图像编码为视觉 token 序列。LLaVA 使用其 ViT-L/14 变体(输入 336×336),在训练中通常冻结权重,只取其强大的图像表征能力。
语言解码器。早期 LLaVA 使用 Vicuna(基于 LLaMA 在 ShareGPT 对话数据上微调的对话模型),后续版本也接入了 LLaMA-3、Mistral、Qwen 等更强的基础模型作为后端。
连接视觉与语言的桥梁。LLaVA-v1 用单层 Linear,LLaVA-1.5 升级为两层 MLP(多层感知机),把视觉特征映射到 LLM 的词嵌入维度,相当于给模型装上"视觉词汇表"。
用 GPT-4 基于 COCO 图像的描述和边界框,自动生成多模态指令数据(详细描述、对话、复杂推理三类),无需人工逐条标注,高效构建了 15 万条视觉指令数据集。
参数高效微调技术。通过在注意力层旁路注入低秩矩阵,只训练极少参数(通常 <1%),让普通 GPU 也能微调大模型,显著降低显存和算力门槛。
微软的深度学习优化库,LLaVA 用它做分布式训练与显存优化(ZeRO 切分、混合精度、激活检查点),是训练大模型背后的"加速引擎"。详见下文。
基于 HuggingFace Transformers 和 PyTorch 实现,配合 DeepSpeed 与 Flash Attention 加速,构成了完整的训练与推理栈。
IO 感知的注意力实现,减少 GPU HBM 读写,在长上下文和长图像 token 序列场景下显著降低显存、提升速度。
"从零"在这里指从零开始组装并训练自己的多模态模型(视觉编码器和 LLM 通常复用预训练权重)。 整个流程分为数据准备 → 阶段一对齐预训练 → 阶段二指令微调 → 评估四步。
选好两个预训练模型作为"地基",并准备图文对齐数据。
目标是让投影层学会把视觉特征"翻译"成语言模型能理解的表示。
让模型学会根据图像执行指令、回答问题,具备对话与推理能力。
在多模态基准上评测,根据结果迭代数据和训练策略。
典型的训练启动命令(伪代码示意):
DeepSpeed 是微软开源的深度学习训练优化库, 专为训练超大模型设计。它和 PyTorch 配合使用,能在显存、速度、规模三个维度上 "榨干"硬件性能,是大模型训练的事实标准之一。LLaVA 的多卡训练就依赖它。
Zero Redundancy Optimizer,把优化器状态、梯度、参数切分到多卡上,消除数据并行的冗余,让单卡能训更大的模型。
支持 BF16/FP16,在几乎不损失精度的前提下减半显存、近乎翻倍速度。
用时间换空间,丢弃中间激活值、反向时重算,大幅降低显存峰值,能训更长序列。
无缝扩展到多 GPU、多节点,配合 ZeRO-3 可训练数百亿参数模型。
ZeRO 通过逐步切分更多内容,用更多通信换更少显存:
| 阶段 | 切分内容 | 显存节省 | 通信开销 |
|---|---|---|---|
| ZeRO-1 | 优化器状态(Optimizer States) | ~4× | 与普通数据并行相当 |
| ZeRO-2 | 优化器状态 + 梯度(Gradients) | ~8× | 略增 |
| ZeRO-3 | 优化器状态 + 梯度 + 参数(Parameters) | ~N×(N 为卡数) | 显著增加 |
zero3.json)即可切换策略,无需改动训练代码。
LLaVA 用 DeepSpeed 完成训练,那训好之后如何让模型推理更高效? SwiftKV 正是 DeepSpeed 作者团队(Samyam Rajbhandari、Yuxiong He 等,现于 Snowflake AI Research) 把优化思路从"训练"延伸到"推理"的代表作。它专门解决企业级场景(RAG、长文档摘要、代码生成)中 长 prompt 带来的 prefill 计算瓶颈。
用前面某一层的输出,直接预填充后面若干层的 KV Cache,让 prompt token 跳过这些后层。 prompt 不必每层都跑一遍 Transformer,通过层间复用省掉大量 prefill 计算。
跳层会改变模型行为,所以用一套轻量蒸馏把原模型能力迁移过来,让变换后的模型精度几乎不掉。 这是"无痛跳层"的关键--光跳层质量会崩,蒸馏才稳。
天然兼容 KV Cache 压缩(低显存场景进一步省内存),可与 token 裁剪、量化等方法叠加, 在显存受限时进一步提升推理表现。
| 指标 | 提升 |
|---|---|
| Prefill 计算量 | 降低 25% ~ 50% |
| 端到端聚合吞吐 | 最高 2× |
| 单 token 生成时间 | 降低 60% |
| Llama-3.1-70B 推理速度 | 16K tokens/s(560 TFlops/GPU) |
📄 论文:SwiftKV: Fast Prefill-Optimized Inference with Knowledge-Preserving Model Transformation(arXiv:2410.03960,2024-10) ·
🔗 开源:github.com/snowflakedb/arctictraining
LLaVA = CLIP 视觉编码器 + 投影层 + 大语言模型 + 视觉指令微调
它用最简洁的架构证明了:把现成的"眼睛"(CLIP)和"大脑"(LLM)用一个可训练的"桥梁"(投影层) 连起来,再用 GPT-4 生成的指令数据做两阶段微调(先对齐、再对话),就能得到一个强大的开源多模态助手。 而训练这一切的"加速引擎",就是 DeepSpeed——它通过 ZeRO 切分、混合精度、激活检查点, 把显存和算力压榨到极致,让普通人也能在多卡上训出自己的大模型。 而训完之后要让模型推理更快,同一拨人又拿出了 SwiftKV--用跨层 KV 预填充 + 蒸馏, 把长 prompt 的 prefill 计算砍掉 25~50%。从训练到推理,一条完整的优化链路。