NVIDIA NIMs¶
llama-index-embeddings-nvidia
软件包包含与 NVIDIA NIM 推理微服务模型构建应用的 LlamaIndex 集成组件。NIM 支持来自社区及 NVIDIA 的跨领域模型,包括对话、嵌入和重排序模型。这些模型经过 NVIDIA 优化,可在 NVIDIA 加速基础设施上实现最佳性能,并部署为 NIM——一种易于使用的预构建容器,通过单条命令即可在 NVIDIA 加速基础设施上随处部署。
用户可通过 NVIDIA API catalog 测试 NVIDIA 托管的 NIM 部署方案。测试完成后,企业可凭借 NVIDIA AI Enterprise 许可证从 NVIDIA API 目录导出 NIM,在本地或云端运行,从而完全掌控自身知识产权和 AI 应用。
NIM 按模型打包为容器镜像,通过 NVIDIA NGC 目录以 NGC 容器镜像形式分发。其核心价值在于为 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
文本内容:
堪察加半岛气候寒冷,冬季漫长而严酷。
意大利以意大利面、披萨、意式冰淇淋和浓缩咖啡著称。
我无法记住个人姓名,仅能提供信息咨询。
生命的意义因人而异,常被视为个人价值的实现。
享受生活点滴确实是种美好的处世态度。
截断处理¶
嵌入模型通常具有固定的上下文窗口,这决定了能够被嵌入的最大输入令牌数量。该限制可能是硬性限制(等于模型的最大输入令牌长度),也可能是有效限制(超出后嵌入精度会下降)。
由于模型处理的是令牌而应用程序通常处理的是文本,应用程序要确保其输入保持在模型的令牌限制内可能具有挑战性。默认情况下,如果输入过大,系统会抛出异常。
为解决此问题,NVIDIA NIMs 提供了 truncate
参数,当输入过大时可在服务器端进行截断处理。
truncate
参数提供三个选项:
- "NONE":默认选项。若输入过大则抛出异常。
- "START":服务器从起始位置(左侧)截断输入,按需丢弃令牌。
- "END":服务器从末尾位置(右侧)截断输入,按需丢弃令牌。
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]