NVIDIA NIMs¶
`llama-index-llms-nvidia` 包包含 LlamaIndex 集成,用于使用 NVIDIA NIM 推理微服务上的模型构建应用程序。NIM 支持来自社区和 NVIDIA 的模型,涵盖聊天、嵌入和重排序等领域。这些模型经过 NVIDIA 优化,可在 NVIDIA 加速基础设施上提供最佳性能,并部署为 NIM,这是一种易于使用、预构建的容器,可在 NVIDIA 加速基础设施上通过单个命令部署到任何地方。
NVIDIA 托管的 NIM 部署可在 NVIDIA API 目录上进行测试。测试后,可使用 NVIDIA AI Enterprise 许可将 NIM 从 NVIDIA API 目录导出,并在本地或云端运行,使企业能够拥有并完全控制其 IP 和 AI 应用程序。
NIMs 按模型打包为容器镜像,并通过 NVIDIA NGC 目录作为 NGC 容器镜像分发。其核心在于,NIMs 为在 AI 模型上运行推理提供了简单、一致且熟悉的 API。
NVIDIA 的 LLM 连接器¶
本示例介绍了如何使用 LlamaIndex 通过公共可用的 AI Foundation 端点与 LLM 驱动的系统进行交互和开发。
使用此连接器,您将能够连接到作为托管 NVIDIA NIMs 提供的兼容模型并从中进行生成,例如:
- Google 的 gemma-7b
- Mistral AI 的 mistral-7b-instruct-v0.2
- 还有更多!
安装¶
%pip install --upgrade --quiet llama-index-llms-nvidia llama-index-embeddings-nvidia llama-index-readers-file
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
# llama-parse is async-first, running the async code in a notebook requires the use of nest_asyncio
import nest_asyncio
nest_asyncio.apply()
使用 NVIDIA API 目录¶
from llama_index.llms.nvidia import NVIDIA
from llama_index.core.llms import ChatMessage, MessageRole
llm = NVIDIA()
messages = [
ChatMessage(
role=MessageRole.SYSTEM, content=("You are a helpful assistant.")
),
ChatMessage(
role=MessageRole.USER,
content=("What are the most popular house pets in North America?"),
),
]
llm.chat(messages)
使用 NVIDIA NIMs¶
除了连接到托管的 NVIDIA NIMs,此连接器还可用于连接到本地微服务实例。这有助于您在必要时将应用程序本地化。
关于如何设置本地微服务实例的说明,请参阅 https://developer.nvidia.com/blog/nvidia-nim-offers-optimized-inference-microservices-for-deploying-ai-models-at-scale/
from llama_index.llms.nvidia import NVIDIA
# connect to an chat NIM running at localhost:8080, spcecifying a specific model
llm = NVIDIA(
base_url="http://localhost:8080/v1", model="meta/llama3-8b-instruct"
)
# default model
llm = NVIDIA()
llm.model
我们可以通过检查 .model
属性来验证这是否是预期的默认模型。
llm = NVIDIA(model="mistralai/mistral-7b-instruct-v0.2")
llm.model
每个示例我们将遵循相同的基本模式
- 我们将把我们的
NVIDIA
LLM 指向我们期望的模型 - 我们将研究如何使用端点来完成所需的任务!
completion_llm = NVIDIA()
我们可以通过检查 .model
属性来验证这是否是预期的默认模型。
completion_llm.model
让我们在模型上调用 .complete()
,输入字符串 "Hello!"
,并观察响应。
completion_llm.complete("Hello!")
正如 LlamaIndex 所预期的那样 - 我们收到了一个 CompletionResponse
作为响应。
异步补全:.acomplete()
¶
还有一个异步实现,可以以相同的方式使用!
await completion_llm.acomplete("Hello!")
聊天:.chat()
¶
现在我们可以使用 .chat()
方法尝试做同样的事情。这个方法需要一个聊天消息列表作为输入 - 所以我们将使用上面创建的那个。
本示例我们将使用 mistralai/mixtral-8x7b-instruct-v0.1
模型。
chat_llm = NVIDIA(model="mistralai/mixtral-8x7b-instruct-v0.1")
现在我们只需要对我们的 ChatMessages
列表调用 .chat()
并观察响应。
您还会注意到,我们可以传入一些额外的关键字参数来影响生成 - 在此示例中,我们使用了 seed
参数来影响生成,并使用了 stop
参数来指示模型在达到某个特定 token 后停止生成!
注意:您可以通过参考所选模型的 API 文档来查找有关模型端点支持哪些额外关键字参数的信息。Mixtral 的 API 文档示例位于此处!
chat_llm.chat(messages, seed=4, stop=["cat", "cats", "Cat", "Cats"])
正如预期,我们收到了一个 ChatResponse
作为响应。
异步聊天:(achat
)¶
我们也有流式传输的等效异步方法,其用法与同步实现类似。
await chat_llm.achat(messages)
流式传输:.stream_chat()
¶
我们还可以使用 build.nvidia.com
上找到的模型进行流式传输用例!
让我们选择另一个模型并观察这种行为。我们将使用 Google 的 gemma-7b
模型来完成此任务。
stream_llm = NVIDIA(model="google/gemma-7b")
让我们使用 .stream_chat()
调用我们的模型,该方法同样需要一个 ChatMessage
对象列表作为输入,并捕获响应。
streamed_response = stream_llm.stream_chat(messages)
streamed_response
如我们所见,响应是一个包含流式响应的生成器。
一旦生成完成,让我们看看最终的响应。
last_element = None
for last_element in streamed_response:
pass
print(last_element)
异步流式传输:.astream_chat()
¶
我们也有流式传输的等效异步方法,其用法与同步实现类似。
streamed_response = await stream_llm.astream_chat(messages)
streamed_response
last_element = None
async for last_element in streamed_response:
pass
print(last_element)
加载数据¶
首先创建一个目录来存放我们的数据。
!mkdir -p 'data/hhgttg'
我们将从上述来源下载数据。
!wget 'https://web.eecs.utk.edu/~hqi/deeplearning/project/hhgttg.txt' -O 'data/hhgttg/hhgttg.txt'
这一步我们需要一个嵌入模型!我们将使用 NVIDIA NV-Embed-QA
模型来实现,并将其保存在我们的 Settings
中。
from llama_index.embeddings.nvidia import NVIDIAEmbedding
from llama_index.core import Settings
embedder = NVIDIAEmbedding(model="NV-Embed-QA", truncate="END")
Settings.embed_model = embedder
现在我们可以加载文档并利用上述内容创建一个索引。
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
documents = SimpleDirectoryReader("data/hhgttg").load_data()
index = VectorStoreIndex.from_documents(documents)
现在我们可以创建一个简单的查询引擎,并将 streaming
参数设置为 True
。
streaming_qe = index.as_query_engine(streaming=True)
让我们向查询引擎发送一个查询,然后流式传输响应。
streaming_response = streaming_qe.query(
"What is the significance of the number 42?",
)
streaming_response.print_response_stream()
工具调用¶
从 v0.2.1 版本开始,NVIDIA 支持工具调用。
NVIDIA 提供了与 build.nvidia.com 上的多种模型以及本地 NIMs 的集成。并非所有这些模型都经过工具调用训练。请务必选择一个支持工具调用的模型用于您的实验和应用。
您可以通过以下方式获取已知支持工具调用的模型列表:
注意:
更多示例请参考:nvidia_agent.ipynb
tool_models = [
model
for model in NVIDIA().available_models
if model.is_function_calling_model
]
使用一个支持工具的模型,
from llama_index.core.tools import FunctionTool
def multiply(a: int, b: int) -> int:
"""Multiple two integers and returns the result integer"""
return a * b
multiply_tool = FunctionTool.from_defaults(fn=multiply)
def add(a: int, b: int) -> int:
"""Add two integers and returns the result integer"""
return a + b
add_tool = FunctionTool.from_defaults(fn=add)
llm = NVIDIA("meta/llama-3.1-70b-instruct")
from llama_index.core.agent import FunctionCallingAgentWorker
agent_worker = FunctionCallingAgentWorker.from_tools(
[multiply_tool, add_tool],
llm=llm,
verbose=True,
)
agent = agent_worker.as_agent()
response = agent.chat("What is (121 * 3) + 42?")
print(str(response))