跳转到内容

CohereAI 嵌入

Cohere Embed 是首个原生支持浮点、int8、二进制和超二进制嵌入的嵌入模型。

  1. v3 模型支持所有嵌入类型,而 v2 模型仅支持 float 嵌入类型。
  2. 默认的 embedding_type 是带有 LlamaIndexfloat。您可以使用参数 embedding_type 为 v3 模型进行自定义。

在本笔记本中,我们将演示使用 Cohere Embeddings 配合不同的 modelsinput_typesembedding_types

请参考他们的主要博客文章了解有关Cohere int8和二进制嵌入的更多详细信息。

如果您在 Colab 上打开这个笔记本,您可能需要安装 LlamaIndex 🦙。

%pip install llama-index-llms-cohere
%pip install llama-index-embeddings-cohere
!pip install llama-index
# Initilise with your api key
import os
cohere_api_key = "YOUR COHERE API KEY"
os.environ["COHERE_API_KEY"] = cohere_api_key

With latest embed-english-v3.0 embeddings.

Section titled “With latest embed-english-v3.0 embeddings.”
  • input_type=“search_document”:将此用于您想要存储在向量数据库中的文本(文档)

  • input_type=“search_query”:用于搜索查询,以在您的向量数据库中找到最相关的文档

默认的 embedding_typefloat

from llama_index.embeddings.cohere import CohereEmbedding
# with input_typ='search_query'
embed_model = CohereEmbedding(
api_key=cohere_api_key,
model_name="embed-english-v3.0",
input_type="search_query",
)
embeddings = embed_model.get_text_embedding("Hello CohereAI!")
print(len(embeddings))
print(embeddings[:5])
1024
[-0.041931152, -0.022384644, -0.07067871, -0.011886597, -0.019210815]
# with input_type = 'search_document'
embed_model = CohereEmbedding(
api_key=cohere_api_key,
model_name="embed-english-v3.0",
input_type="search_document",
)
embeddings = embed_model.get_text_embedding("Hello CohereAI!")
print(len(embeddings))
print(embeddings[:5])
1024
[-0.03074646, -0.0029201508, -0.058044434, -0.015457153, -0.02331543]
embed_model = CohereEmbedding(
api_key=cohere_api_key,
model_name="embed-english-v3.0",
input_type="search_query",
embedding_type="int8",
)
embeddings = embed_model.get_text_embedding("Hello CohereAI!")
print(len(embeddings))
print(embeddings[:5])
1024
[-54, -29, -90, -16, -25]
embed_model = CohereEmbedding(
api_key=cohere_api_key,
model_name="embed-english-v3.0",
input_type="search_query",
embedding_type="binary",
)
embeddings = embed_model.get_text_embedding("Hello CohereAI!")
print(len(embeddings))
print(embeddings[:5])
128
[-127, -38, 66, 83, 89]

使用旧的 embed-english-v2.0 嵌入。

Section titled “With old embed-english-v2.0 embeddings.”

v2 模型默认支持 float 嵌入类型。

embed_model = CohereEmbedding(
api_key=cohere_api_key, model_name="embed-english-v2.0"
)
embeddings = embed_model.get_text_embedding("Hello CohereAI!")
print(len(embeddings))
print(embeddings[:5])
4096
[0.65771484, 0.7998047, 2.3769531, -2.3105469, -1.6044922]

现在使用最新的 embed-english-v3.0 嵌入模型,

Section titled “Now with latest embed-english-v3.0 embeddings,”

让我们使用

  1. input_type=search_document 用于构建索引
  2. input_type=search_query 以获取相关上下文。

我们将试验 int8 嵌入类型。

import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.llms.cohere import Cohere
from llama_index.core.response.notebook_utils import display_source_node
from IPython.display import Markdown, display
INFO:matplotlib.font_manager:generated new fontManager
generated new fontManager
!mkdir -p 'data/paul_graham/'
!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'
--2024-03-27 13:02:13-- https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.111.133, 185.199.109.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 75042 (73K) [text/plain]
Saving to: ‘data/paul_graham/paul_graham_essay.txt’
data/paul_graham/pa 100%[===================>] 73.28K --.-KB/s in 0.02s
2024-03-27 13:02:14 (2.96 MB/s) - ‘data/paul_graham/paul_graham_essay.txt’ saved [75042/75042]
documents = SimpleDirectoryReader("./data/paul_graham/").load_data()

使用 input_type = 'search_document' 构建索引

Section titled “Build index with input_type = ‘search_document’”
llm = Cohere(model="command-nightly", api_key=cohere_api_key)
embed_model = CohereEmbedding(
api_key=cohere_api_key,
model_name="embed-english-v3.0",
input_type="search_document",
embedding_type="int8",
)
index = VectorStoreIndex.from_documents(
documents=documents, embed_model=embed_model
)

使用 input_type = 'search_query' 构建检索器

Section titled “Build retriever with input_type = ‘search_query’”
embed_model = CohereEmbedding(
api_key=cohere_api_key,
model_name="embed-english-v3.0",
input_type="search_query",
embedding_type="int8",
)
search_query_retriever = index.as_retriever()
search_query_retrieved_nodes = search_query_retriever.retrieve(
"What happened in the summer of 1995?"
)
for n in search_query_retrieved_nodes:
display_source_node(n, source_length=2000)

节点ID: 0f821a16-5242-4284-86ba-23b16069e071
相似度: 0.30740912992211505
文本: 我们将以我在剑桥拥有的建筑作为总部。我们每周二会在那里共进晚餐——因为我已经在周四为周四的用餐者准备晚餐——晚餐后我们会邀请初创企业专家来进行讲座。

我们知道本科生那时正在决定暑期工作,所以几天之内我们就草拟了一个名为夏季创始人计划的项目,我在我的网站上发布了一则公告,邀请本科生申请。我从未想过写文章会成为获取"交易流"的方式——正如投资者所称——但事实证明这是完美的来源。[15] 我们收到了225份夏季创始人计划的申请,惊讶地发现其中许多申请者已经毕业,或即将在当年春季毕业。这个SFP项目已经开始变得比我们预想的更加严肃。

我们从225个团队中邀请了约20个进行现场面试,并从中挑选了8个进行资助。他们是一个令人印象深刻的群体。第一批成员包括reddit、Justin Kan和Emmett Shear(后来共同创立了Twitch)、Aaron Swartz(当时已参与撰写RSS规范,几年后成为开放获取的殉道者),以及Sam Altman(后来成为YC的第二任主席)。我认为第一批团队如此优秀并非完全靠运气。当时必须相当大胆才会选择参加像"夏季创始人计划"这样新奇的项目,而不是去微软或高盛这类正规公司做暑期工作。

针对初创企业的交易条款,是基于我们与朱利安达成的协议(1万美元换取10%股权)以及罗伯特提到的麻省理工研究生暑期项目条件(6000美元)综合制定的。我们为每位创始人投资6000美元,在典型的双创始人情况下总计1.2万美元,换取6%的股权。这条件必须公平,因为它比我们当初接受的条款优厚两倍。此外,在那个异常炎热的第一个夏天,杰西卡还为创始人们免费提供了空调。[16]

很快我就意识到我们偶然发现了……

节点ID: 15e1050d-38f1-4c7c-a169-ef9fe4ab1249
相似度: 0.3000104724138056
文本: 一家只有几名员工的公司会显得很不专业。所以我们直到1998年夏天雅虎收购我们时才实现盈亏平衡。这也意味着在整个公司存续期间,我们都受制于投资者。由于我们和投资者都是初创领域的新手,结果即使按初创公司的标准来看也是一团糟。

当雅虎收购我们时,这真是一个巨大的解脱。原则上,我们的Viaweb股票很有价值。这是一家盈利且快速增长企业的股份。但对我来说,它感觉并不那么有价值;我不知道如何评估一家企业的价值,但我非常清楚地意识到,我们似乎每隔几个月就会经历一次濒临死亡的经历。自从我们开始以来,我的研究生生活方式也没有显著改变。所以当雅虎收购我们时,感觉就像从赤贫变成了富有。既然我们要去加利福尼亚,我买了一辆车,一辆黄色的1998年大众GTI。我记得当时在想,单是它的皮革座椅就远比我拥有的任何东西都奢华。

接下来的一年,从1998年夏天到1999年夏天,大概是我人生中效率最低的时期。当时我并未意识到,但运营Viaweb带来的精力消耗和精神压力已让我精疲力竭。初到加利福尼亚时,我曾试图延续自己惯常的编程到凌晨三点的工作模式,但疲惫感加上雅虎早衰的企业文化,以及圣克拉拉办公室令人压抑的格子间,逐渐将我拖垮。几个月后,那种不安的感觉竟如同重回Interleaf工作一般。

雅虎在收购我们时给了我们很多期权。当时我认为雅虎估值过高,最终会一文不值,但令我惊讶的是,其股价在次年上涨了5倍。我坚持到第一批期权归属,然后在1999年夏天离开了。距离我上次绘画已经太久,以至于我几乎忘记了自己这么做的初衷。整整四年间,我的大脑完全被软件和男士衬衫占据。但我做这一切本就是为了致富,所以...

使用 input_type = 'search_document' 构建索引

Section titled “Build index with input_type = ‘search_document’”
llm = Cohere(model="command-nightly", api_key=cohere_api_key)
embed_model = CohereEmbedding(
api_key=cohere_api_key,
model_name="embed-english-v3.0",
input_type="search_document",
embedding_type="float",
)
index = VectorStoreIndex.from_documents(
documents=documents, embed_model=embed_model
)

使用 input_type = 'search_query' 构建检索器

Section titled “Build retriever with input_type = ‘search_query’”
embed_model = CohereEmbedding(
api_key=cohere_api_key,
model_name="embed-english-v3.0",
input_type="search_query",
embedding_type="float",
)
search_query_retriever = index.as_retriever()
search_query_retrieved_nodes = search_query_retriever.retrieve(
"What happened in the summer of 1995?"
)
for n in search_query_retrieved_nodes:
display_source_node(n, source_length=2000)

节点ID: cff8a942-2e1a-4921-ac08-8355b49fde85
相似度: 0.3051793987443398
文本: 我们将以我在剑桥拥有的建筑作为总部。我们每周二会在那里共进晚餐——因为我已经在周四为周四的用餐者做饭——晚餐后我们会邀请创业专家来进行讲座。

我们知道本科生那时正在决定暑期工作,所以几天之内我们就草拟了一个名为夏季创始人计划的项目,我在我的网站上发布了一则公告,邀请本科生申请。我从未想过写文章会成为获取"交易流"的方式——正如投资者所称——但事实证明这是完美的来源。[15] 我们收到了225份夏季创始人计划的申请,惊讶地发现其中许多申请者已经毕业,或即将在当年春季毕业。这个SFP项目已经开始变得比我们预想的更加严肃。

我们从225个团队中邀请了约20个进行现场面试,并从中挑选了8个进行资助。他们是一个令人印象深刻的群体。第一批成员包括reddit、Justin Kan和Emmett Shear(后来共同创立了Twitch)、Aaron Swartz(当时已参与撰写RSS规范,几年后成为开放获取的殉道者),以及Sam Altman(后来成为YC的第二任主席)。我认为第一批团队如此优秀并非完全靠运气。当时必须相当大胆才会选择参加像"夏季创始人计划"这样新奇的项目,而不是去微软或高盛这类正规公司做暑期工作。

针对初创企业的交易条款,是基于我们与朱利安达成的协议(1万美元换取10%股权)以及罗伯特提到的麻省理工研究生暑期项目条件(6000美元)综合制定的。我们为每位创始人投资6000美元,在典型的双创始人情况下总计1.2万美元,换取6%的股权。这条件必须公平,因为它比我们当初接受的条款优厚两倍。此外,在那个异常炎热的第一个夏天,杰西卡还为创始人们免费提供了空调。[16]

很快我就意识到我们偶然发现了……

节点ID: 1810afad-3817-447c-a194-859601437923
相似度: 0.2959499578848539
文本: 一家只有几名员工的公司会显得很不专业。所以我们直到1998年夏天雅虎收购我们时才实现盈亏平衡。这意味着在公司整个生命周期中我们都受制于投资者。由于我们和投资者都是初创领域的新手,即使按照初创公司的标准,结果也是一团糟。

当雅虎收购我们时,这真是一个巨大的解脱。原则上,我们的Viaweb股票很有价值。这是一家盈利且快速增长企业的股份。但对我来说,它感觉并不那么有价值;我不知道如何评估一家企业的价值,但我非常清楚地意识到,我们似乎每隔几个月就会经历一次濒临死亡的经历。自从我们开始以来,我的研究生生活方式也没有显著改变。所以当雅虎收购我们时,感觉就像从赤贫变成了富有。既然我们要去加利福尼亚,我买了一辆车,一辆黄色的1998年大众GTI。我记得当时在想,单是它的皮革座椅就远比我拥有的任何东西都奢华。

接下来的一年,从1998年夏天到1999年夏天,大概是我人生中效率最低的时期。当时我并未意识到,但运营Viaweb带来的精力消耗和精神压力已让我精疲力竭。初到加利福尼亚时,我曾试图延续自己惯常的编程到凌晨三点的工作模式,但疲惫感加上雅虎早衰的企业文化,以及圣克拉拉办公室令人压抑的格子间,逐渐将我拖垮。几个月后,那种不安的感觉竟如同重回Interleaf工作一般。

雅虎在收购我们时给了我们很多期权。当时我认为雅虎估值过高,最终会一文不值,但令我惊讶的是,其股价在次年上涨了5倍。我坚持到第一批期权归属,然后在1999年夏天离开了。距离我上次绘画已经太久,以至于我几乎忘记了自己这么做的初衷。整整四年间,我的大脑完全被软件和男士衬衫占据。但我做这一切本就是为了致富,所以...

使用 input_type = 'search_document' 构建索引

Section titled “Build index with input_type = ‘search_document’”
embed_model = CohereEmbedding(
api_key=cohere_api_key,
model_name="embed-english-v3.0",
input_type="search_document",
embedding_type="binary",
)
index = VectorStoreIndex.from_documents(
documents=documents, embed_model=embed_model
)

使用 input_type = 'search_query' 构建检索器

Section titled “Build retriever with input_type = ‘search_query’”
embed_model = CohereEmbedding(
api_key=cohere_api_key,
model_name="embed-english-v3.0",
input_type="search_query",
embedding_type="binary",
)
search_query_retriever = index.as_retriever()
search_query_retrieved_nodes = search_query_retriever.retrieve(
"What happened in the summer of 1995?"
)
for n in search_query_retrieved_nodes:
display_source_node(n, source_length=2000)

节点ID: fd8e185d-7c9e-40de-8d3e-09a76ae85e18
相似度: 0.3498979255746315
文本: 在当时,这个编辑器是最优秀的通用网站构建工具之一。我保持代码简洁,除了与Robert和Trevor的软件集成外,无需整合其他任何软件,因此开发过程相当有趣。如果当时我只需要专注于这个软件,接下来的三年本会是我人生中最轻松的时光。不幸的是,我还需要处理许多其他事务,这些事务都是我不如编程擅长的领域,结果接下来的三年反而成了压力最大的时期。

90年代后半期涌现了许多开发电商软件的初创公司。我们决心成为微软Word那样的产品,而非Interleaf。这意味着要易于使用且价格实惠。幸运的是我们当时很穷,这促使我们将Viaweb定价得比我们意识到的更加低廉。小型店铺每月收费100美元,大型店铺每月300美元。这个低价极具吸引力,也始终是竞争对手的眼中钉,但这并非源于我们有什么精明的定价策略。我们根本不清楚企业愿意为软件支付多少费用。每月300美元在我们看来已经是巨款。

我们无意中做对了很多事情。例如,我们做了现在被称为“做那些无法规模化的事”,尽管当时我们会将其描述为“如此无能,以至于被迫采取最绝望的措施来获取用户”。其中最普遍的做法就是为他们搭建店铺。这似乎特别丢脸,因为我们软件存在的全部理由就是让人们可以用它来创建自己的店铺。但为了获取用户,我们愿意做任何事。

我们了解了比我们想知道的更多的零售知识。例如,如果只能展示男士衬衫的小图(按照当时的标准所有图片都很小),那么展示领口的特写比展示整件衬衫的图片效果更好。我记得学到这一点的原因是,这意味着我必须重新扫描大约30张男士衬衫的图片。我最初扫描的那批图片效果还特别出色。

汝…

节点ID: b013216a-1c23-46b6-ba78-aaeed21b2fe2
相似度: 0.3376224194936838
文本: 但在夏季过半时,我意识到自己其实并不想经营公司——尤其不想经营大公司,而当时的情况看起来必须如此。我创办Viaweb仅仅是因为需要钱。既然现在不再需要钱了,为什么还要继续做这件事?如果这个愿景必须通过公司形式实现,那我宁愿放弃这个愿景。我会构建一个可以作为开源项目实现的子集。

令我非常惊讶的是,我花在这些事情上的时间终究没有白费。在我们创立Y Combinator之后,我经常遇到致力于构建这种新架构各个组成部分的初创公司,而花费大量时间思考甚至尝试编写其中部分内容变得非常有用。

我打算作为开源项目构建的子集是新的Lisp语言——如今我甚至无需隐藏它的括号。许多Lisp黑客都梦想构建新的Lisp变体,部分原因是这门语言的显著特征在于它拥有多种方言,另一部分原因(我认为)是我们心中存有现有方言都未能企及的柏拉图式Lisp理想形态。我当然也怀揣这样的理想。因此那年夏天结束时,我和丹转而开始在我剑桥购置的宅邸中研发这种新的Lisp方言,我将其命名为Arc。

次年春天,闪电降临。我受邀在一个Lisp会议上发表演讲,于是分享了我们在Viaweb使用Lisp的经验。随后我将这份演讲的附言文件上传至多年前通过Viaweb创建却从未使用的个人网站paulgraham.com。短短一天内,该页面获得了30,000次浏览量。究竟发生了什么?来源链接显示有人将其发布到了Slashdot网站。[10]

哇,我想,原来有观众啊。如果我写了东西放到网上,任何人都能读到。这在现在看来可能显而易见,但在当时却令人惊讶。在印刷时代,通往读者的渠道很狭窄,由被称为编辑的凶猛怪兽把守着。让你写的任何东西获得读者的唯一途径就是获...

floatint8 相比,使用 binary 嵌入类型检索到的文本块确实有所不同。在您的RAG流水线中使用 float/int8/binary/ubinary 嵌入进行检索评估将会很有意思。
Section titled “The retrieved chunks are certainly different with binary embedding type compared to float and int8. It would be interesting to do retrieval evaluation for your RAG pipeline in using float/int8/binary/ubinary embeddings.”

Cohere 现在支持多模态嵌入模型,其中文本和图像处于同一嵌入空间。

from PIL import Image
import matplotlib.pyplot as plt
img = Image.open("../data/images/prometheus_paper_card.png")
plt.imshow(img)
<matplotlib.image.AxesImage at 0x2c7323af0>

png

from llama_index.embeddings.cohere import CohereEmbedding
embed_model = CohereEmbedding(
api_key=cohere_api_key,
model_name="embed-english-v3.0",
)
embeddings = embed_model.get_image_embedding(
"../data/images/prometheus_paper_card.png"
)
print(len(embeddings))
print(embeddings[:5])
1024
[0.01171875, -0.014503479, 0.014205933, -0.022949219, -0.040374756]
embeddings = embed_model.get_text_embedding("prometheus evaluation model")
print(len(embeddings))
print(embeddings[:5])
1024
[0.0044403076, 0.01737976, -0.023345947, 0.028182983, -0.036499023]