NVIDIA NIMs¶
llama-index-embeddings-nvidia
包包含 LlamaIndex 集成,用于使用 NVIDIA NIM 推理微服务上的模型构建应用程序。NIM 支持来自社区和 NVIDIA 的跨领域模型,如聊天、嵌入和重排模型。这些模型经过 NVIDIA 优化,可在 NVIDIA 加速基础设施上提供最佳性能,并部署为 NIM——一种易于使用的预构建容器,只需一个命令即可在 NVIDIA 加速基础设施上部署。
NVIDIA 托管的 NIM 部署可在 NVIDIA API catalog 上进行测试。测试后,可以使用 NVIDIA AI Enterprise 许可从 NVIDIA 的 API catalog 导出 NIM,并在本地或云端运行,从而使企业拥有其 IP 和 AI 应用程序的所有权和完全控制权。
NIMs 以每模型一个容器镜像的方式打包,并通过 NVIDIA NGC Catalog 作为 NGC 容器镜像分发。其核心是,NIMs 为运行 AI 模型的推理提供了简单、一致且熟悉的 API。
安装¶
%pip install --upgrade --quiet llama-index-embeddings-nvidia
注意:您可能需要重启内核才能使用更新后的软件包。
import getpass
import os
# del os.environ['NVIDIA_API_KEY'] ## delete key and reset
if os.environ.get("NVIDIA_API_KEY", "").startswith("nvapi-"):
print("Valid NVIDIA_API_KEY already in environment. Delete to reset")
else:
nvapi_key = getpass.getpass("NVAPI Key (starts with nvapi-): ")
assert nvapi_key.startswith(
"nvapi-"
), f"{nvapi_key[:5]}... is not a valid key"
os.environ["NVIDIA_API_KEY"] = nvapi_key
使用NVIDIA API目录¶
初始化嵌入模型时,您可以通过传递参数来选择模型,例如下面的 NV-Embed-QA
,或者不传递任何参数来使用默认模型。
from llama_index.embeddings.nvidia import NVIDIAEmbedding
embedder = NVIDIAEmbedding(model="NV-Embed-QA")
此模型是一个经过微调的 E5-large 模型,支持预期的 Embeddings
方法,包括
get_query_embedding
: 为查询样本生成查询嵌入。get_text_embedding_batch
: 为您想要搜索的一系列文档生成文本嵌入。以及上述方法的异步版本。
使用NVIDIA NIMs¶
除了连接到托管的 NVIDIA NIMs 外,此连接器还可用于连接本地微服务实例。这有助于您在必要时将应用程序本地化运行。
有关如何设置本地微服务实例的说明,请参阅 https://developer.nvidia.com/blog/nvidia-nim-offers-optimized-inference-microservices-for-deploying-ai-models-at-scale/
from llama_index.embeddings.nvidia import NVIDIAEmbedding
# connect to an embedding NIM running at localhost:8080
embedder = NVIDIAEmbedding(base_url="http://localhost:8080/v1")
embedder.available_models
/home/raspawar/Desktop/llama_index/llama-index-integrations/embeddings/llama-index-embeddings-nvidia/llama_index/embeddings/nvidia/base.py:161: UserWarning: Default model is set as: NV-Embed-QA. Set model using model parameter. To get available models use available_models property. warnings.warn(
[Model(id='NV-Embed-QA', base_model=None)]
相似度¶
以下是对这些数据点进行相似度快速测试的结果
查询
堪察加半岛的天气怎么样?
意大利以哪些食物闻名?
我叫什么名字?我敢打赌你不记得...
人生的意义到底是什么?
人生的意义在于享受乐趣 :D
文本
堪察加半岛天气寒冷,冬季漫长严酷。
意大利以意大利面、披萨、冰淇淋和意式浓缩咖啡闻名。
我无法回忆个人姓名,只能提供信息。
人生的目的各不相同,通常被视为个人成就。
享受生命的时刻确实是一种很棒的态度。
嵌入查询¶
print("\nSequential Embedding: ")
q_embeddings = [
embedder.get_query_embedding("What's the weather like in Komchatka?"),
embedder.get_query_embedding("What kinds of food is Italy known for?"),
embedder.get_query_embedding(
"What's my name? I bet you don't remember..."
),
embedder.get_query_embedding("What's the point of life anyways?"),
embedder.get_query_embedding("The point of life is to have fun :D"),
]
print("Shape:", (len(q_embeddings), len(q_embeddings[0])))
文档嵌入¶
print("\nBatch Document Embedding: ")
d_embeddings = embedder.get_text_embedding_batch(
[
"Komchatka's weather is cold, with long, severe winters.",
"Italy is famous for pasta, pizza, gelato, and espresso.",
"I can't recall personal names, only provide information.",
"Life's purpose varies, often seen as personal fulfillment.",
"Enjoying life's moments is indeed a wonderful approach.",
]
)
print("Shape:", (len(d_embeddings), len(d_embeddings[0])))
生成嵌入后,我们可以对结果进行简单的相似度检查,看看哪些文档会在检索任务中被认为是合理的答案。
%pip install --upgrade --quiet matplotlib scikit-learn
import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
# Compute the similarity matrix between q_embeddings and d_embeddings
cross_similarity_matrix = cosine_similarity(
np.array(q_embeddings),
np.array(d_embeddings),
)
# Plotting the cross-similarity matrix
plt.figure(figsize=(8, 6))
plt.imshow(cross_similarity_matrix, cmap="Greens", interpolation="nearest")
plt.colorbar()
plt.title("Cross-Similarity Matrix")
plt.xlabel("Query Embeddings")
plt.ylabel("Document Embeddings")
plt.grid(True)
plt.show()
提醒一下,发送到我们系统的查询和文档是
查询
堪察加半岛的天气怎么样?
意大利以哪些食物闻名?
我叫什么名字?我敢打赌你不记得...
人生的意义到底是什么?
人生的意义在于享受乐趣 :D
文本
堪察加半岛天气寒冷,冬季漫长严酷。
意大利以意大利面、披萨、冰淇淋和意式浓缩咖啡闻名。
我无法回忆个人姓名,只能提供信息。
人生的目的各不相同,通常被视为个人成就。
享受生命的时刻确实是一种很棒的态度。
截断¶
嵌入模型通常具有固定的上下文窗口,该窗口决定了可以嵌入的最大输入 token 数量。此限制可能是硬限制,等于模型的最大输入 token 长度,或者是一个有效限制,超过该限制后嵌入的准确性会降低。
由于模型在 token 上操作,而应用程序通常处理文本,因此应用程序要确保其输入保持在模型的 token 限制内可能会很困难。默认情况下,如果输入过大,会抛出异常。
为了帮助解决这个问题,NVIDIA NIMs 提供了一个 truncate
参数,如果输入过大,它会在服务器端截断输入。
truncate
参数有三个选项
- "NONE":默认选项。如果输入过大,则会抛出异常。
- "START":服务器从输入开头(左侧)截断,根据需要丢弃token。
- "END":服务器从输入末尾(右侧)截断,根据需要丢弃token。
long_text = "AI is amazing, amazing is " * 100
strict_embedder = NVIDIAEmbedding()
try:
strict_embedder.get_query_embedding(long_text)
except Exception as e:
print("Error:", e)
truncating_embedder = NVIDIAEmbedding(truncate="END")
truncating_embedder.get_query_embedding(long_text)[:5]