🚀 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
許可證。