模型概述
模型特點
模型能力
使用案例
🚀 Jina CLIP v2:文本和圖像的多語言多模態嵌入
Jina CLIP v2 是由 Jina AI 訓練的嵌入集,是一款通用的多語言多模態嵌入模型,可用於文本和圖像的處理。它打破了語言障礙,實現了更準確的跨模態理解和檢索,讓多模態搜索和檢索更強大、更易訪問。
由 Jina AI 訓練的嵌入集。
Jina CLIP v2:文本和圖像的多語言多模態嵌入
該模型基於論文 jina-clip-v2: Multilingual Multimodal Embeddings for Text and Images 構建。
🚀 快速開始
博客 | 技術報告 | Azure | AWS SageMaker | Google Cloud Platform | API
✨ 主要特性
jina-clip-v2
是一款通用的多語言多模態文本和圖像嵌入模型。多模態嵌入通過統一的表示方式,實現了跨不同模態的數據搜索和理解,是神經信息檢索和多模態生成式人工智能應用的核心。
基於 jina-clip-v1
和最近發佈的 jina-embeddings-v3
,jina-clip-v2
有以下顯著改進:
- 性能提升:在文本 - 圖像和文本 - 文本檢索任務中,v2 比 v1 的性能提升了 3%。與 v1 類似,v2 的文本編碼器可作為有效的多語言長上下文密集檢索器,性能與前沿模型
jina-embeddings-v3
相當(目前是 MTEB 上參數少於 1B 的最佳多語言嵌入模型)。 - 多語言支持:文本塔採用與
jina-embeddings-v3
相同的主幹,jina-clip-v2
支持 89 種語言的多語言 - 圖像檢索,在多語言圖像檢索任務中,比nllb-clip-large-siglip
最多提升 4%。 - 更高的圖像分辨率:v2 現在支持 512x512 的輸入圖像分辨率,相比 v1 的 224x224 有了顯著提升。更高的分辨率能夠更好地處理細節豐富的圖像,改進特徵提取,更準確地識別細粒度的視覺元素。
- 嵌套式表示:v2 允許用戶將文本和圖像嵌入的輸出維度從 1024 截斷至 64,在保持強大性能的同時,減少存儲和處理開銷。
jina-clip-v2
擁有 0.9B 參數,結合了兩個強大的編碼器:
- 文本編碼器
Jina-XLM-RoBERTa
(jina-embeddings-v3
的主幹) - 視覺編碼器
EVA02-L14
(由 BAAI 開發的高效視覺 Transformer)
屬性 | 詳情 |
---|---|
基礎模型 | 文本編碼器:Jina-XLM-RoBERTa;圖像編碼器:EVA02-L |
參數 | 文本編碼器:561M;圖像編碼器:304M |
輸入規格 | 文本:最多 8,192 個標記;圖像:512×512 像素 |
最小輸出維度 | 文本:64;圖像:64 |
最大輸出維度 | 文本:1,024;圖像:1,024 |
層數 | 文本:24;圖像:24 |
注意力機制 | 文本:FlashAttention2;圖像:xFormers |
池化策略 | 文本:平均池化;圖像:CLS 池化 |
附加特性 | 文本:支持 89 種語言;圖像:補丁大小 14x14 |
這些編碼器經過聯合訓練,以創建圖像和文本的對齊表示。
類似 CLIP 的模型已成為通用多模態應用的核心。藉助 jina-clip-v2
,我們將這些能力提升到了新的高度,打破語言障礙,實現更準確的跨模態理解和檢索。我們相信,這一版本將使多模態搜索和檢索更強大,也讓全球開發者更容易使用。
📚 詳細文檔
訓練、數據和參數
模型和訓練的詳細信息請參考 jina-clip-v2 的技術報告。 jina-clip-v1 的技術報告
更快的推理:FA2、XFormers 和 bf16
在支持 CUDA 的 PyTorch 環境中,模型默認採用 torch.bfloat16
精度。強烈建議安裝 FlashAttention 和 xFormers,以利用它們高效的注意力機制實現。
💻 使用示例
基礎用法
通過 Jina AI 嵌入 API
curl https://api.jina.ai/v1/embeddings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer [JINA_AI_API_TOKEN]" \
-d @- <<EOFEOF
{
"model": "jina-clip-v2",
"dimensions": 1024,
"task": "retrieval.query",
"normalized": true,
"embedding_type": "float",
"input": [
{
"text": "غروب جميل على الشاطئ"
},
{
"text": "海灘上美麗的日落"
},
{
"text": "A beautiful sunset over the beach"
},
{
"text": "Un beau coucher de soleil sur la plage"
},
{
"text": "Ein wunderschöner Sonnenuntergang am Strand"
},
{
"text": "Ένα όμορφο ηλιοβασίλεμα πάνω από την παραλία"
},
{
"text": "समुद्र तट पर एक खूबसूरत सूर्यास्त"
},
{
"text": "Un bellissimo tramonto sulla spiaggia"
},
{
"text": "浜辺に沈む美しい夕日"
},
{
"text": "해변 위로 아름다운 일몰"
},
{
"image": "https://i.ibb.co/nQNGqL0/beach1.jpg"
},
{
"image": "https://i.ibb.co/r5w8hG8/beach2.jpg"
}
]
}
EOFEOF
通過 transformers
# !pip install transformers einops timm pillow
from transformers import AutoModel
# Initialize the model
model = AutoModel.from_pretrained('jinaai/jina-clip-v2', trust_remote_code=True)
# Corpus
sentences = [
'غروب جميل على الشاطئ', # Arabic
'海灘上美麗的日落', # Chinese
'Un beau coucher de soleil sur la plage', # French
'Ein wunderschöner Sonnenuntergang am Strand', # German
'Ένα όμορφο ηλιοβασίλεμα πάνω από την παραλία', # Greek
'समुद्र तट पर एक खूबसूरत सूर्यास्त', # Hindi
'Un bellissimo tramonto sulla spiaggia', # Italian
'浜辺に沈む美しい夕日', # Japanese
'해변 위로 아름다운 일몰', # Korean
]
# Public image URLs or PIL Images
image_urls = ['https://i.ibb.co/nQNGqL0/beach1.jpg', 'https://i.ibb.co/r5w8hG8/beach2.jpg']
# Choose a matryoshka dimension, set to None to get the full 1024-dim vectors
truncate_dim = 512
# Encode text and images
text_embeddings = model.encode_text(sentences, truncate_dim=truncate_dim)
image_embeddings = model.encode_image(
image_urls, truncate_dim=truncate_dim
) # also accepts PIL.Image.Image, local filenames, dataURI
# Encode query text
query = 'beautiful sunset over the beach' # English
query_embeddings = model.encode_text(
query, task='retrieval.query', truncate_dim=truncate_dim
)
# Text to Image
print('En -> Img: ' + str(query_embeddings @ image_embeddings[0].T))
# Image to Image
print('Img -> Img: ' + str(image_embeddings[0] @ image_embeddings[1].T))
# Text to Text
print('En -> Ar: ' + str(query_embeddings @ text_embeddings[0].T))
print('En -> Zh: ' + str(query_embeddings @ text_embeddings[1].T))
print('En -> Fr: ' + str(query_embeddings @ text_embeddings[2].T))
print('En -> De: ' + str(query_embeddings @ text_embeddings[3].T))
print('En -> Gr: ' + str(query_embeddings @ text_embeddings[4].T))
print('En -> Hi: ' + str(query_embeddings @ text_embeddings[5].T))
print('En -> It: ' + str(query_embeddings @ text_embeddings[6].T))
print('En -> Jp: ' + str(query_embeddings @ text_embeddings[7].T))
print('En -> Ko: ' + str(query_embeddings @ text_embeddings[8].T))
通過 sentence-transformers
# !pip install sentence-transformers einops timm pillow
from sentence_transformers import SentenceTransformer
# Choose a matryoshka dimension
truncate_dim = 512
# Initialize the model
model = SentenceTransformer(
'jinaai/jina-clip-v2', trust_remote_code=True, truncate_dim=truncate_dim
)
# Corpus
sentences = [
'غروب جميل على الشاطئ', # Arabic
'海灘上美麗的日落', # Chinese
'Un beau coucher de soleil sur la plage', # French
'Ein wunderschöner Sonnenuntergang am Strand', # German
'Ένα όμορφο ηλιοβασίλεμα πάνω από την παραλία', # Greek
'समुद्र तट पर एक खूबसूरत सूर्यास्त', # Hindi
'Un bellissimo tramonto sulla spiaggia', # Italian
'浜辺に沈む美しい夕日', # Japanese
'해변 위로 아름다운 일몰', # Korean
]
# Public image URLs or PIL Images
image_urls = ['https://i.ibb.co/nQNGqL0/beach1.jpg', 'https://i.ibb.co/r5w8hG8/beach2.jpg']
# Encode text and images
text_embeddings = model.encode(sentences, normalize_embeddings=True)
image_embeddings = model.encode(
image_urls, normalize_embeddings=True
) # also accepts PIL.Image.Image, local filenames, dataURI
# Encode query text
query = 'beautiful sunset over the beach' # English
query_embeddings = model.encode(
query, prompt_name='retrieval.query', normalize_embeddings=True
)
通過 transformers.js
⚠️ 重要提示
JinaCLIP 是在 Transformers.js v3.1.0 中添加的,因此請確保使用兼容的版本!更多信息請參閱 發佈說明。
如果尚未安裝,可以使用以下命令從 NPM 安裝 Transformers.js JavaScript 庫:
npm i @huggingface/transformers
import { AutoModel, AutoProcessor, RawImage, matmul } from "@huggingface/transformers";
// Load processor and model
const model_id = "jinaai/jina-clip-v2";
const processor = await AutoProcessor.from_pretrained(model_id);
const model = await AutoModel.from_pretrained(model_id, { dtype: "q4" /* e.g., "fp16", "q8", or "q4" */ });
// Prepare inputs
const urls = ["https://i.ibb.co/nQNGqL0/beach1.jpg", "https://i.ibb.co/r5w8hG8/beach2.jpg"];
const images = await Promise.all(urls.map(url => RawImage.read(url)));
const sentences = [
"غروب جميل على الشاطئ", // Arabic
"海灘上美麗的日落", // Chinese
"Un beau coucher de soleil sur la plage", // French
"Ein wunderschöner Sonnenuntergang am Strand", // German
"Ένα όμορφο ηλιοβασίλεμα πάνω από την παραλία", // Greek
"समुद्र तट पर एक खूबसूरत सूर्यास्त", // Hindi
"Un bellissimo tramonto sulla spiaggia", // Italian
"浜辺に沈む美しい夕日", // Japanese
"해변 위로 아름다운 일몰", // Korean
];
// Encode text and images
const inputs = await processor(sentences, images, { padding: true, truncation: true });
const { l2norm_text_embeddings, l2norm_image_embeddings } = await model(inputs);
// Encode query (text-only)
const query_prefix = "Represent the query for retrieving evidence documents: ";
const query_inputs = await processor(query_prefix + "beautiful sunset over the beach");
const { l2norm_text_embeddings: query_embeddings } = await model(query_inputs);
// Compute text-image similarity scores
const text_to_image_scores = await matmul(query_embeddings, l2norm_image_embeddings.transpose(1, 0));
console.log("text-image similarity scores", text_to_image_scores.tolist()[0]); // [0.29530206322669983, 0.3183615803718567]
// Compute image-image similarity scores
const image_to_image_score = await matmul(l2norm_image_embeddings[0], l2norm_image_embeddings[1]);
console.log("image-image similarity score", image_to_image_score.item()); // 0.9344457387924194
// Compute text-text similarity scores
const text_to_text_scores = await matmul(query_embeddings, l2norm_text_embeddings.transpose(1, 0));
console.log("text-text similarity scores", text_to_text_scores.tolist()[0]); // [0.5566609501838684, 0.7028406858444214, 0.582255482673645, 0.6648036241531372, 0.5462006330490112, 0.6791588068008423, 0.6192430257797241, 0.6258729100227356, 0.6453716158866882]
通過 ONNX Runtime
# !pip install transformers onnxruntime pillow
import onnxruntime as ort
from transformers import AutoImageProcessor, AutoTokenizer
# Load tokenizer and image processor using transformers
tokenizer = AutoTokenizer.from_pretrained('jinaai/jina-clip-v2', trust_remote_code=True)
image_processor = AutoImageProcessor.from_pretrained(
'jinaai/jina-clip-v2', trust_remote_code=True
)
# Corpus
sentences = [
'غروب جميل على الشاطئ', # Arabic
'海灘上美麗的日落', # Chinese
'Un beau coucher de soleil sur la plage', # French
'Ein wunderschöner Sonnenuntergang am Strand', # German
'Ένα όμορφο ηλιοβασίλεμα πάνω από την παραλία', # Greek
'समुद्र तट पर एक खूबसूरत सूर्यास्त', # Hindi
'Un bellissimo tramonto sulla spiaggia', # Italian
'浜辺に沈む美しい夕日', # Japanese
'해변 위로 아름다운 일몰', # Korean
]
# Public image URLs or PIL Images
image_urls = ['https://i.ibb.co/nQNGqL0/beach1.jpg', 'https://i.ibb.co/r5w8hG8/beach2.jpg']
# Tokenize input texts and transform input images
input_ids = tokenizer(sentences, return_tensors='np')['input_ids']
pixel_values = image_processor(image_urls)['pixel_values']
# Start an ONNX Runtime Session
session = ort.InferenceSession('jina-clip-v2/onnx/model.onnx')
# Run inference
output = session.run(None, {'input_ids': input_ids, 'pixel_values': pixel_values})
# Keep the normalised embeddings, first 2 outputs are un-normalized
_, _, text_embeddings, image_embeddings = output
📄 許可證
該模型根據 CC BY - NC 4.0 許可進行下載和運行。可通過 Jina 嵌入 API、AWS、Azure 和 GCP 進行商業使用。如需商業使用下載,請 聯繫我們。
📞 聯繫我們
加入我們的 Discord 社區,與其他社區成員交流想法。
📚 引用
如果您在研究中發現 jina-clip-v2
很有用,請引用以下論文:
@misc{koukounas2024jinaclipv2multilingualmultimodalembeddings,
title={jina-clip-v2: Multilingual Multimodal Embeddings for Text and Images},
author={Andreas Koukounas and Georgios Mastrapas and Bo Wang and Mohammad Kalim Akram and Sedigheh Eslami and Michael Günther and Isabelle Mohr and Saba Sturua and Scott Martens and Nan Wang and Han Xiao},
year={2024},
eprint={2412.08802},
archivePrefix={arXiv},
primaryClass={cs.CL},
url={https://arxiv.org/abs/2412.08802},
}









