Model Overview
Model Features
Model Capabilities
Use Cases
🚀 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},
}









