🚀 GME-VARCO-VISION-Embedding
GME-VARCO-VISION-Embedding
是一个多模态嵌入模型,可在高维嵌入空间中计算文本、图像和视频之间的语义相似度。该模型尤其专注于视频检索,相较于图像检索,视频检索需要更高的复杂度和上下文理解能力。它在各种场景下,如基于场景的搜索、基于描述的搜索和基于问答的搜索,都能实现高检索准确率和强大的泛化性能。
🚀 快速开始
模型信息
属性 |
详情 |
模型类型 |
多模态嵌入模型 |
基础模型 |
Qwen/Qwen2-VL-7B-Instruct |
库名称 |
transformers |
标签 |
多模态、视频嵌入、ncsoft、ncai、varco |
任务类型 |
特征提取 |
许可证 |
cc-by-nc-4.0 |
演示视频
查看展示我们多模态嵌入模型实际应用的演示视频:
这些演示展示了我们的嵌入模型如何与AI智能体协同工作,根据用户查询搜索相关视频,并利用检索到的视频内容生成响应。
✨ 主要特性
模型架构与训练方法
GME-VARCO-VISION-Embedding
基于 Qwen/Qwen2-VL-7B-Instruct
,并使用了 Alibaba-NLP/gme-Qwen2-VL-7B-Instruct
的参数来提高模型的通用检索能力。
1. 在视频偏好数据集上进行微调(对比学习)
为了高效地微调模型,我们使用了 ShareGPTVideo的17k视频偏好数据集,该数据集包含提示、视频、标准答案和选择-拒绝文本对。我们将提示和视频视为查询,将拒绝响应作为标准答案的硬负样本。每个查询都使用InfoNCE损失与批内负样本以及一个硬负样本一起进行训练。模型在8个A100 GPU上以批量大小为8进行了两个周期的全量微调,仅需几个小时即可完成训练。
2. 添加检索向量
为了弥补训练实例的不足并增强微调模型的泛化能力,我们通过从 Alibaba-NLP/gme-Qwen2-VL-7B-Instruct
(一个基于Qwen2-VL的图像文本检索模型)的权重中减去原始 Qwen/Qwen2-VL-7B-Instruct
模型的权重,计算出一个检索向量 𝜏。这种方法受到了Chat Vector的启发,Chat Vector是一种通过添加从基础模型与其聊天优化版本之间的权重差异获得的向量,使预训练语言模型具备新语言聊天能力的方法。
性能
截至2025年7月,我们的模型在MultiVENT2.0数据集上实现了 最先进(SOTA)的零样本性能。详细结果请查看 官方排行榜。
💻 使用示例
GME-VARCO-VISION-Embedding
采用了 Qwen/Qwen2-VL-7B-Instruct
的推理管道。
基础用法
图像-文本检索
import torch
import requests
from PIL import Image
from transformers import Qwen2VLForConditionalGeneration, AutoProcessor
from qwen_vl_utils import process_vision_info
model_name = "NCSOFT/GME-VARCO-VISION-Embedding"
model = Qwen2VLForConditionalGeneration.from_pretrained(
model_name,
torch_dtype=torch.bfloat16,
attn_implementation="flash_attention_2",
device_map="auto",
)
processor = AutoProcessor.from_pretrained(model_name)
tokenizer = processor.tokenizer
device = model.device
qry_msg = [
{
"role": "user",
"content": [
{"type": "text", "text": "Find a photo of a cat."},
],
},
]
qry_txt = processor.apply_chat_template(
qry_msg, tokenize=False, add_generation_prompt=True
) + tokenizer.eos_token
qry_input = processor(
text=[qry_txt],
padding=True,
return_tensors="pt",
).to(device)
img_msg = [
{
"role": "user",
"content": [{
"type": "image",
"image": "image"
}]
}
]
img_txt = processor.apply_chat_template(
img_msg, tokenize=False, add_generation_prompt=True
) + tokenizer.eos_token
candidate_imgs= [
{
"role": "user",
"content": [{
"type": "image",
"image": "http://images.cocodataset.org/val2017/000000039769.jpg"}]
},
{
"role": "user",
"content": [{
"type": "image",
"image": "https://farm1.staticflickr.com/116/290755713_a5de6c1079_z.jpg"}]
},
{
"role": "user",
"content": [{
"type": "image",
"image": "http://farm3.staticflickr.com/2418/2193688811_d9f5e23bbd_z.jpg"}]
},
{
"role": "user",
"content": [{
"type": "image",
"image":"http://farm7.staticflickr.com/6049/6329686751_997c68fff9_z.jpg"}]
},
]
candidate_images, _ = process_vision_info(candidate_imgs)
image_inputs = processor(
text=[img_txt] * len(candidate_images),
images=candidate_images,
padding=True,
return_tensors="pt",
).to(device)
with torch.inference_mode():
qry_emb = model(
**qry_input, output_hidden_states=True, return_dict=True
).hidden_states[-1][:, -1, :]
img_emb = model(
**image_inputs, output_hidden_states=True, return_dict=True
).hidden_states[-1][:, -1, :]
qry_emb = F.normalize(qry_emb, dim=-1)
img_emb = F.normalize(img_emb, dim=-1)
score = qry_emb @ img_emb.t()
高级用法
视频嵌入
vid_message = [
{
"role": "user",
"content": [{
"type": "video",
"video": video_path,
"max_pixels": 262144,
"fps": 2.0,}]
}
]
video_text = processor.apply_chat_template(
vid_message, tokenize=False, add_generation_prompt=True
) + tokenizer.eos_token
image_input, video_input = process_vision_info(vid_message)
video_input = processor(
text=[video_text],
images=image_input,
videos=video_input,
padding=True,
return_tensors="pt",
).to(device)
with torch.inference_mode():
video_emb = model(
**video_input, output_hidden_states=True, return_dict=True
).hidden_states[-1][:, -1, :]
video_emb = F.normalize(video_emb, dim=-1)
📄 许可证
本项目采用 cc-by-nc-4.0
许可证。