NVIDIA NIMs¶
llama-index-llms-nvidia
软件包包含与 NVIDIA NIM 推理微服务模型构建应用的 LlamaIndex 集成。NIM 支持跨领域的模型,包括来自社区及 NVIDIA 的聊天、嵌入和重排序模型。这些模型经过 NVIDIA 优化,可在 NVIDIA 加速基础设施上提供最佳性能,并部署为 NIM——一种易于使用的预构建容器,通过单一命令即可在 NVIDIA 加速基础设施上随处部署。
可通过 NVIDIA API 目录 测试 NVIDIA 托管的 NIM 部署。测试完成后,企业可使用 NVIDIA AI Enterprise 许可证从 NVIDIA API 目录导出 NIM,并在本地或云端运行,从而完全掌控其知识产权和 AI 应用。
NIM 按模型打包为容器镜像,并通过 NVIDIA NGC 目录作为 NGC 容器镜像分发。NIM 的核心功能是为 AI 模型推理提供简单、一致且熟悉的 API。
NVIDIA 的 LLM 连接器¶
本示例演示了如何使用 LlamaIndex 与公开可访问的 AI Foundation 端点交互,并开发基于 LLM 的系统。
通过此连接器,您可以连接并生成兼容模型,这些模型作为托管 NVIDIA NIM 提供,例如:
- Google 的 gemma-7b
- Mistal 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 NIM 微服务¶
除了连接托管的 NVIDIA NIM 服务外,该连接器还可用于连接本地微服务实例。这使您能够在必要时将应用程序部署到本地环境。
有关如何设置本地微服务实例的说明,请参阅: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
对象关联的模型。
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()
方法¶
现在我们可以尝试使用 .chat()
方法实现同样的功能。该方法需要接收一个聊天消息列表作为参数——因此我们将使用之前创建好的消息列表。
在示例中我们将使用 mistralai/mixtral-8x7b-instruct-v0.1
模型。
chat_llm = NVIDIA(model="mistralai/mixtral-8x7b-instruct-v0.1")
现在我们需要做的就是在 ChatMessages
列表上调用 .chat()
方法并观察响应结果。
您还会注意到,我们可以传入一些额外的关键字参数来影响生成过程——在这个例子中,我们使用了 seed
参数来控制生成内容,并通过 stop
参数指定模型在遇到特定标记时停止生成!
注意:您可以通过查阅所选模型的 API 文档了解该模型端点支持哪些额外 kwargs 参数。例如 Mixtral 模型的文档位于此处!
chat_llm.chat(messages, seed=4, stop=["cat", "cats", "Cat", "Cats"])
如预期所示,我们收到了一个 ChatResponse
作为响应。
异步聊天:(achat
)¶
我们还提供了 .chat()
方法的异步实现,可通过以下方式调用。
await chat_llm.achat(messages)
流式传输:.stream_chat()
¶
我们同样可以使用 build.nvidia.com
上的模型来实现流式应用场景!
让我们选择另一个模型来观察这种特性。本次任务将使用谷歌的 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'
这一步我们需要一个嵌入模型!我们将使用英伟达的 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 上各类模型以及本地 NIM 的集成方案。但请注意,并非所有这些模型都针对工具调用进行过训练。请务必选择确实具备工具调用能力的模型进行实验和应用开发。
您可以通过以下方式获取已知支持工具调用的模型列表:
注意:
更多示例请参阅: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))