在人工智能迅速发展的今天,多模态系统正成为推动视觉语言任务前沿发展的关键。CLIP(对比语言-图像预训练)作为其中的典范,通过将文本和视觉表示对齐到共享的特征空间,为图像-文本检索、分类和分割等任务带来了革命性突破。然而其文本编码器的局限性使其在处理复杂长文本和多语言任务时显得力不从心。
大型语言模型(LLM),如 GPT-4 和 LLaMA,则展示了卓越的语言理解和生成能力。这种强大的语言能力能否与 CLIP 结合,解决其文本编码器的短板?微软团队提出的 LLM2CLIP 框架便是这一创新的成果。
该论文提出了一种创新的方法,通过将 LLM 强大的语言知识与 CLIP 的视觉能力相结合,显著提升多模态任务的性能。通过整合 LLM 和 CLIP,LLM2CLIP 解决了传统 CLIP 在文本理解、语言支持和任务泛化方面的瓶颈。
方法创新
字幕对比微调(Caption Contrastive Fine-tuning)
- 核心问题:LLM 的原生文本特征缺乏区分性,难以直接用于多模态任务。
- 创新点:通过监督对比损失函数,将同一图像的字幕作为正样本,将其他字幕作为负样本,从而显著增强 LLM 的文本编码能力。
冻结 LLM 梯度
- 目的:保留 LLM 的开放世界知识,降低计算成本。
- 方法:仅微调适配器和投影层,实现多模态对齐。
高效训练策略
- 使用 LoRA 技术进行轻量级训练,在计算资源有限的情况下优化模型性能。
- 预提取文本特征,减少推理阶段的计算负担。
开放世界知识的利用
- LLM 的广泛训练语料使其能够处理复杂字幕,甚至支持多语言任务。
LLM2CLIP 的关键特性
- 增强文本理解:LLM2CLIP 能够处理超过 CLIP 原生限制的长文本和复杂描述。
- 跨语言支持:通过 LLM 的知识迁移,即使仅使用英语数据训练,仍可在中文等多语言任务中实现卓越表现。
- 高效计算:通过冻结梯度和轻量级适配器优化计算开销。
详细改进描述
处理长字幕和复杂文本: LLM 的更大的上下文窗口和更强的语言理解能力使得 LLM2CLIP 能够有效地处理长字幕和复杂文本,而无需像之前的工作那样进行文本截断或分段。
融入开放世界知识: LLM 在大规模文本语料库上进行预训练,因此拥有丰富的开放世界知识。LLM2CLIP 将这些知识融入到 CLIP 的视觉表示中,从而提高了其在各种下游任务中的性能。
跨语言能力: LLM2CLIP 的跨语言能力使其成为构建多语言多模态系统的强大工具,无需为每种语言单独训练模型。
高效训练: 通过冻结 LLM 的权重和预先提取文本特征,LLM2CLIP 的训练成本与微调原始 CLIP 模型相当。
实验结果
结果展示
LLM2CLIP 在多个基准测试中表现优异,在短文本、长文本以及跨语言任务中的性能显著提升,尤其在中文任务中,其表现甚至超越了专用中文数据集训练的模型。
- 图像-文本检索 (I2T 和 T2I): 在 Flickr30k、COCO、ShareGPT4V、Urban-1k 和 DOCCI 等数据集上进行评估。
- 跨语言图像-文本检索: 在 Flickr30K-CN 和 COCO-CN 数据集上进行评估。
- 视觉问答 (VQA): 使用 LLaVA 1.5 框架进行评估。
- 字幕检索准确率 (CRA): 用于评估文本模型区分字幕的能力。
如何开始使用 LLM2CLIP
以下是快速上手 LLM2CLIP 的完整代码教程:
1. 安装依赖环境
pip install llm2vec
git clone https://github.com/microsoft/LLM2CLIP.git && cd LLM2CLIP
pip install -r requirements.txt
2. 配置 Jupyter Notebook
如果需要交互式环境:
conda install -c conda-forge --override-channels notebook
conda install -c conda-forge --override-channels ipywidgets -y jupyter notebook
3. 导入必要库
from PIL import Image
from transformers import AutoModel, AutoConfig, AutoTokenizer
from transformers import CLIPImageProcessor
import torch
from llm2vec import LLM2Vec
4. 加载模型
# 图像处理器
processor = CLIPImageProcessor.from_pretrained("openai/clip-vit-large-patch14-336")
# 加载 CLIP 模型
model_name_or_path = "microsoft/LLM2CLIP-Openai-L-14-336"
model = AutoModel.from_pretrained(
model_name_or_path,
torch_dtype=torch.float16,
trust_remote_code=True
).to('cuda').eval()
# 加载微调后的 LLM 模型
llm_model_name = 'microsoft/LLM2CLIP-Llama-3-8B-Instruct-CC-Finetuned'
config = AutoConfig.from_pretrained(llm_model_name, trust_remote_code=True)
llm_model = AutoModel.from_pretrained(llm_model_name, config=config, trust_remote_code=True)
tokenizer = AutoTokenizer.from_pretrained(llm_model_name)
# 初始化 LLM2Vec
l2v = LLM2Vec(llm_model, tokenizer, pooling_mode="mean", max_length=512, doc_max_length=512)
5. 图像和字幕预处理
captions = ["a diagram", "a dog", "horses"]
image_path = "path_to_image/horses.png"
image = Image.open(image_path)
input_pixels = processor(images=image, return_tensors="pt").pixel_values.to('cuda')
6. 提取特征并匹配字幕
with torch.no_grad(), torch.cuda.amp.autocast():
image_features = model.get_image_features(input_pixels)
text_features = l2v.encode(captions, convert_to_tensor=True).to('cuda')
text_features = model.get_text_features(text_features)
# 归一化特征
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)
# 计算匹配概率
text_probs = (100.0 * image_features @ text_features.T).softmax(dim=-1)
print("匹配结果:", text_probs)
输入图像为上面的马照片时,输出为:
匹配结果: tensor([[3.425e-08, 1.0911e-06, 1.000e+00]], device='cuda:0')
这表明模型预测图像对应的字幕为“horses”,匹配概率为 100%。
再试一张更复杂的图片:
captions = ["a sunset over a mountain range", "a group of people hiking on a trail", "a peaceful lake surrounded by trees"]
image_path = "hiking_trail.jpg"
image = Image.open(image_path)
input_pixels = processor(images=image, return_tensors="pt").pixel_values.to('cuda')
with torch.no_grad(), torch.cuda.amp.autocast():
image_features = model.get_image_features(input_pixels)
text_features = l2v.encode(captions, convert_to_tensor=True).to('cuda')
text_features = model.get_text_features(text_features)
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)
text_probs = (100.0 * image_features @ text_features.T).softmax(dim=-1)
print("Label probs:", text_probs)
输出为:
匹配结果:: tensor([[1.122e-06, 9.998e-01, 1.243e-04]], device='cuda:0')
模型可以匹配出更准确的文字。
总结
LLM2CLIP 为多模态学习提供了一种新的范式,通过整合 LLM 的强大功能来增强 CLIP 模型。其在图像-文本检索、跨语言应用和长文本理解方面的出色性能,突显了其作为构建更强大、更通用的多模态系统的潜力。未来的研究可以进一步探索 LLM2CLIP 在更广泛的应用场景中的潜力,例如视频理解、多模态对话和具身智能。