说明文档
nomic-embed-text-v1: 一个可复现的长上下文 (8192) 文本嵌入模型
博客 | 技术报告 | AWS SageMaker | Atlas 嵌入与非结构化数据分析平台
nomic-embed-text-v1 是一个 8192 上下文长度的文本编码器,在短上下文和长上下文任务上都超越了 OpenAI text-embedding-ada-002 和 text-embedding-3-small 的性能。
性能基准测试
| 名称 | 序列长度 | MTEB | LoCo | Jina 长上下文 | 开放权重 | 开放训练代码 | 开放数据 |
|---|---|---|---|---|---|---|---|
| nomic-embed-text-v1 | 8192 | 62.39 | 85.53 | 54.16 | ✅ | ✅ | ✅ |
| jina-embeddings-v2-base-en | 8192 | 60.39 | 85.45 | 51.90 | ✅ | ❌ | ❌ |
| text-embedding-3-small | 8191 | 62.26 | 82.40 | 58.20 | ❌ | ❌ | ❌ |
| text-embedding-ada-002 | 8191 | 60.99 | 52.7 | 55.25 | ❌ | ❌ | ❌ |
激动人心的更新!:nomic-embed-text-v1 现在支持多模态了!nomic-embed-vision-v1 与 nomic-embed-text-v1 的嵌入空间对齐,这意味着任何文本嵌入都是多模态的!
使用方法
重要提示:文本提示必须包含一个任务指令前缀,用于指示模型正在执行的任务。
例如,如果您正在实现一个 RAG 应用程序,您需要将文档嵌入为 search_document: <text here>,将用户查询嵌入为 search_query: <text here>。
任务指令前缀
search_document
用途:将文本嵌入为数据集中的文档
此前缀用于将文本嵌入为文档,例如作为 RAG 索引的文档。
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("nomic-ai/nomic-embed-text-v1", trust_remote_code=True)
sentences = ['search_document: TSNE is a dimensionality reduction algorithm created by Laurens van Der Maaten']
embeddings = model.encode(sentences)
print(embeddings)
search_query
用途:将文本嵌入为待回答的问题
此前缀用于将文本嵌入为数据集文档可能解决的问题,例如作为 RAG 应用程序要回答的查询。
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("nomic-ai/nomic-embed-text-v1", trust_remote_code=True)
sentences = ['search_query: Who is Laurens van Der Maaten?']
embeddings = model.encode(sentences)
print(embeddings)
clustering
用途:嵌入文本以将它们分组到聚类中
此前缀用于嵌入文本,以便将它们分组到聚类中,发现共同主题或去除语义重复。
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("nomic-ai/nomic-embed-text-v1", trust_remote_code=True)
sentences = ['clustering: the quick brown fox']
embeddings = model.encode(sentences)
print(embeddings)
classification
用途:嵌入文本以进行分类
此前缀用于将文本嵌入为向量,这些向量将用作分类模型的特征。
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("nomic-ai/nomic-embed-text-v1", trust_remote_code=True)
sentences = ['classification: the quick brown fox']
embeddings = model.encode(sentences)
print(embeddings)
Sentence Transformers
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("nomic-ai/nomic-embed-text-v1", trust_remote_code=True)
sentences = ['search_query: What is TSNE?', 'search_query: Who is Laurens van der Maaten?']
embeddings = model.encode(sentences)
print(embeddings)
Transformers
import torch
import torch.nn.functional as F
from transformers import AutoTokenizer, AutoModel
def mean_pooling(model_output, attention_mask):
token_embeddings = model_output[0]
input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)
sentences = ['search_query: What is TSNE?', 'search_query: Who is Laurens van der Maaten?']
tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')
model = AutoModel.from_pretrained('nomic-ai/nomic-embed-text-v1', trust_remote_code=True)
model.eval()
encoded_input = tokenizer(sentences, padding=True, truncation=True, return_tensors='pt')
with torch.no_grad():
model_output = model(**encoded_input)
embeddings = mean_pooling(model_output, encoded_input['attention_mask'])
embeddings = F.normalize(embeddings, p=2, dim=1)
print(embeddings)
该模型原生支持将序列长度扩展到超过 2048 个标记。为此,
- tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')
+ tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased', model_max_length=8192)
- model = AutoModel.from_pretrained('nomic-ai/nomic-embed-text-v1', trust_remote_code=True)
+ model = AutoModel.from_pretrained('nomic-ai/nomic-embed-text-v1', trust_remote_code=True, rotary_scaling_factor=2)
Transformers.js
import { pipeline } from '@xenova/transformers';
// Create a feature extraction pipeline
const extractor = await pipeline('feature-extraction', 'nomic-ai/nomic-embed-text-v1', {
quantized: false, // Comment out this line to use the quantized version
});
// Compute sentence embeddings
const texts = ['search_query: What is TSNE?', 'search_query: Who is Laurens van der Maaten?'];
const embeddings = await extractor(texts, { pooling: 'mean', normalize: true });
console.log(embeddings);
Nomic API
使用 Nomic Embed 最简单的方式是通过 Nomic Embedding API。
使用 nomic Python 客户端生成嵌入非常简单:
from nomic import embed
output = embed.text(
texts=['Nomic Embedding API', '#keepAIOpen'],
model='nomic-embed-text-v1',
task_type='search_document'
)
print(output)
更多信息,请参阅 API 参考文档
训练
点击下方 Nomic Atlas 地图以可视化我们对比预训练数据的 500 万样本!
我们使用多阶段训练管道来训练我们的嵌入模型。从长上下文 BERT 模型 开始, 第一个无监督对比阶段在一个由弱相关文本对生成的数据集上进行训练,例如来自 StackExchange 和 Quora 等论坛的问答对、来自 Amazon 评论的标题-正文对,以及来自新闻文章的摘要。
在第二个微调阶段,利用更高质量的标记数据集,如来自网络搜索的搜索查询和答案。数据整理和困难样本挖掘在这一阶段至关重要。
更多详细信息,请参阅 Nomic Embed 技术报告 和相应的博客文章。
训练模型的数据集已完整发布。更多详细信息,请参阅 contrastors 代码仓库
加入 Nomic 社区
- Nomic: https://nomic.ai
- Discord: https://discord.gg/myY5YDR8z8
- Twitter: https://twitter.com/nomic_ai
引用
如果您发现这个模型、数据集或训练代码有用,请引用我们的工作
@misc{nussbaum2024nomic,
title={Nomic Embed: Training a Reproducible Long Context Text Embedder},
author={Zach Nussbaum and John X. Morris and Brandon Duderstadt and Andriy Mulyar},
year={2024},
eprint={2402.01613},
archivePrefix={arXiv},
primaryClass={cs.CL}
}
nomic-ai/nomic-embed-text-v1
作者 nomic-ai
创建时间: 2024-01-31 20:26:50+00:00
更新时间: 2025-03-31 17:40:51+00:00
在 Hugging Face 上查看