0


AI原来如此的简单,使用NIM平台3步亲手搭建基于NVIDIA NIM 平台的知识问答系统实践

Nvidia NIM 提供了强大的工具和灵活的部署选项,让生成式 AI 模型的开发和应用变得更加高效和便捷。无论你是初学者还是资深开发者,NIM 都能轻松应对 AI 推理的复杂挑战,加速创新与落地。

NVIDIA AI 是非常先进的生成式 AI 平台,深受多家创新前沿企业组织的信赖。该平台专为企业设计并不断更新,让您可以放心将生成式 AI 应用大规模部署到任何地方的生产环境中,人工智能数据和技术基础架构等在内的全新混合式AI解决方案及服务,以高效、便捷和专业的方式,充分帮助企业实现AI技术落地到业务中的商业价值。

在这里插入图片描述

NIM 代表 NVIDIA 推理微服务,这意味着它是一种用于对生成式 AI 模型进行推理的服务。在宣布推出时,NIM 仅作为 一套面向开发者的 API 提供。NIM 也是 NVIDIA AI Enterprise 的一部分,该平台建立在 VMware 和 Red Hat 的基础设施软件之上。

在这里插入图片描述
打开官网可以看到,NVIDIA NIM 平台支持了很多的模型,比如我们常见的llama这里会有很多个版本,可以用来选择:
在这里插入图片描述
点击第一个模型进去后,可以看到这个模型的一些介绍,然后还有一些是不同语言如何来实现这个大模型:

在这里插入图片描述
从ptyhon的代码来分析,可以看到以下这段代码非常的简洁,基本上分为3步:

    1. 定义OpenAI的参数,里面的base_url是写死的,api_key是动态生成的,需要自已去获取
    1. client.chat实例化一个chat的会话,里面传了一些参数,使用content来表示自己的提示
    1. 通过返回的消息completion,这里因为是流式返回,所以,就使用了for循环来接受
from openai import OpenAI

client =OpenAI(
  base_url ="https://integrate.api.nvidia.com/v1",
  api_key ="$API_KEY_REQUIRED_IF_EXECUTING_OUTSIDE_NGC")

completion = client.chat.completions.create(
  model="nvidia/llama-3.1-nemotron-70b-instruct",
  messages=[{"role":"user","content":"Write a limerick about the wonders of GPU computing."}],
  temperature=0.5,
  top_p=1,
  max_tokens=1024,
  stream=True
)for chunk in completion:if chunk.choices[0].delta.content is not None:print(chunk.choices[0].delta.content, end="")

那这里提到的key在哪里去获取呢?点击下图的Get api keys即可进行获取,还是非常简单的:

在这里插入图片描述
将图中的api_key替换自己的key即可,这里提示一下,不要泄露出去:

在这里插入图片描述
通过执行这个python的文件,可以得到以下的结果:

在这里插入图片描述
可以看到不到3分钟就可以得到一个基于NVIDIA NIM 平台的知识问答系统实践,非常的神奇!


上面描述了一个简单的python代码即可实现一个AI应用,总不能将代码提供给别人吧?

1. 如何通过web页面将一个AI应用分享给其它人使用:

把下面的代码复制粘贴到一开始创建的 Python 文件中,例如“nim_test.py”:

# -*- coding: utf-8-*-

# 导入必要的库
from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings, ChatNVIDIA
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores importFAISSfrom langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import chain
import os
import gradio as gr
from datetime import datetime
# Even if you do not know the full answer, generate a one-paragraph hypothetical answer to the below question in Chinese
# 定义假设性回答模板
hyde_template ="""Even if you do not know the full answer, generate a one-paragraph hypothetical answer to the below question:{question}"""

# 定义最终回答模板
template ="""Answer the question based only on the following context:{context}

Question:{question}"""

# 定义函数来处理问题
def process_question(url, api_key, model_name, question):
    # 初始化加载器并加载数据
    loader =WebBaseLoader(url)
    docs = loader.load()

    # 设置环境变量
    os.environ['NVIDIA_API_KEY']= api_key

    # 初始化嵌入层
    embeddings =NVIDIAEmbeddings()
    text_splitter =RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
    documents = text_splitter.split_documents(docs)
    vector =FAISS.from_documents(documents, embeddings)
    retriever = vector.as_retriever()

    # 初始化模型
    model =ChatNVIDIA(model=model_name)

    # 创建提示模板
    hyde_prompt = ChatPromptTemplate.from_template(hyde_template)
    hyde_query_transformer = hyde_prompt | model |StrOutputParser()

    # 定义检索函数
    @chain
    def hyde_retriever(question):
        hypothetical_document = hyde_query_transformer.invoke({"question": question})return retriever.invoke(hypothetical_document)

    # 定义最终回答链
    prompt = ChatPromptTemplate.from_template(template)
    answer_chain = prompt | model |StrOutputParser()

    @chain
    def final_chain(question):
        documents = hyde_retriever.invoke(question)
        response =""for s in answer_chain.stream({"question": question,"context": documents}):
            response += s
        return response

    # 调用最终链获取答案
    returnstr(datetime.now())+final_chain.invoke(question)

# 定义可用的模型列表
models =["mistralai/mistral-7b-instruct-v0.2","meta/llama-3.1-405b-instruct"]

# 启动Gradio应用
iface = gr.Interface(
    fn=process_question,
    inputs=[
        gr.Textbox(label="输入需要学习的网址"),
        gr.Textbox(label="NVIDIA API Key"),
        gr.Dropdown(models, label="选择语言模型"),
        gr.Textbox(label="输入问题")],
    outputs="text",
    title="网页知识问答系统")

# 启动Gradio界面
iface.launch()

这段代码是一个基于Gradio的网页知识问答系统,它使用了NVIDIA的AI模型和LangChain库来处理自然语言问题。以下是代码的详细解释:

    1. 导入必要的库:
from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings, ChatNVIDIA:导入NVIDIA的嵌入层和聊天模型。
from langchain_community.document_loaders import WebBaseLoader:导入网页加载器。
from langchain_community.vectorstores importFAISS:导入FAISS向量存储库。
from langchain_text_splitters import RecursiveCharacterTextSplitter:导入文本分割器。
from langchain_core.prompts import ChatPromptTemplate:导入聊天提示模板。
from langchain_core.output_parsers import StrOutputParser:导入字符串输出解析器。
from langchain_core.runnables import chain:导入链运行器。
import os:导入操作系统库。
import gradio as gr:导入Gradio库。
from datetime import datetime:导入日期时间库。
    1. 定义假设性回答模板:
    1. hyde_template:即使你不知道完整的答案,也要根据以下问题生成一段假设性的回答。 定义最终回答模板:
    1. template:仅根据以下上下文回答问题。 定义函数来处理问题:
    1. process_question:该函数接受网址、API密钥、模型名称和问题作为输入,并返回问题的答案。
    1. 定义可用的模型列表:
    1. models:包含可用的NVIDIA AI模型名称。
    1. 启动Gradio应用,iface:使用Gradio的Interface类创建一个界面,该界面包含输入组件(网址、API密钥、模型选择、问题)和输出组件(文本)。 iface.launch():启动Gradio界面。

安装所需要的依赖项,输入下方命令:

pip install langchain_nvidia_ai_endpoints langchain-community langchain-text-splitters faiss-cpu gradio==3.50.0 setuptools beautifulsoup4

在这里插入图片描述

在这里插入图片描述


3. 如何使用其它的AI模型:

可以看到以下提供了很多类型的模型:

    1. 大语言模型 Phi-3 LLMs
    1. 生成代码 Granite Code
    1. 生成文本向量 Generate Embeddings for Text Retrieval (agent-blueprints)
    1. 视觉语义分割ChangeNet
    1. 光学字符检测OCDRNet
    1. 统计图表理解deplot(agent-blueprints)

在我们的工作中,其实有许多统计图表理解的需求,今天来尝试一下:

应用场景

识别发票/账单金额,并转存为格式化数据,对图片中的文字进行识别,并与图片存储在一起,便于后期图片信息检索

申请地址

https://build.nvidia.com/google/google-deplot?snippet_tab=Python

模型介绍

将统计图表转换为数据结构json格式

应用场景

对图片转换为表格数据库/csv/json形式存储,结合generate code生成Sql或者结合大预言模型,进行分析给出总结

# 导入requests库和base64编码库
import requests, base64

# 设置推理URL和流式传输标志
invoke_url ="https://ai.api.nvidia.com/v1/vlm/google/deplot"
stream = True

# 以二进制模式打开图像文件并进行base64编码
withopen("economic-assistance-chart.png","rb")as f:
    image_b64 = base64.b64encode(f.read()).decode()

# 确保编码后的图像大小小于180,000字节,否则需要使用资产API
assert len(image_b64)<180_000, \
  "To upload larger images, use the assets API (see docs)"

# 准备请求头,需要API密钥进行身份验证
headers ={"Authorization":"Bearer $API_KEY_REQUIRED_IF_EXECUTING_OUTSIDE_NGC","Accept":"text/event-stream"if stream else"application/json"}

# 准备请求负载,包含用户消息、最大令牌数、温度等参数
payload ={"messages":[{"role":"user","content": f'Generate underlying data table of the figure below: <img src="data:image/png;base64,{image_b64}" />'}],"max_tokens":1024,"temperature":0.20,"top_p":0.20,"stream": stream
}

# 发送POST请求到指定的推理URL
response = requests.post(invoke_url, headers=headers, json=payload)

# 根据是否开启流式传输,处理响应
if stream:for line in response.iter_lines():if line:print(line.decode("utf-8"))else:print(response.json())

这段代码的主要功能是使用NVIDIA的AI模型进行图像分析,并生成图像的底层数据表。以下是代码的详细解释:

1. 导入必要的库:

import requests, base64:导入requests库用于发送HTTP请求,导入base64库用于进行base64编码。
设置推理URL和流式传输标志:

2. 以二进制模式打开图像文件并进行base64编码:

  • with open(“economic-assistance-chart.png”, “rb”) as f::以二进制模式打开名为economic-assistance-chart.png的图像文件。
  • image_b64 = base64.b64encode(f.read()).decode():将图像文件读取为字节流,然后进行base64编码,并将结果转换为字符串。

3. 确保编码后的图像大小小于180,000字节:

  • assert len(image_b64) < 180_000, “To upload larger images, use the assets API (see docs)”:确保编码后的图像大小小于180,000字节,否则需要使用资产API。

4. 准备请求头:

  • headers = {…}:准备请求头,需要API密钥进行身份验证。
  • 准备请求负载:
  • payload = {…}:准备请求负载,包含用户消息、最大令牌数、温度等参数。
  • 发送POST请求到指定的推理URL:
  • response = requests.post(invoke_url, headers=headers, json=payload):发送POST请求到指定的推理URL。 根据是否开启流式传输,处理响应:
  • if stream::如果开启了流式传输,则逐行处理响应。
  • else::如果没有开启流式传输,则直接打印响应的JSON格式。

总的来说,这段代码通过发送HTTP请求到NVIDIA的AI模型,对图像进行分析并生成底层数据表。

在这里插入图片描述
可以得到以下的结果:
在这里插入图片描述

# 提取content字段
contents =[item['content']for item in data if'content'in item]

# 打印提取到的content字段
for content in contents:print(content)

在这里插入图片描述
那么试一下识别图片文本呢?看看是什么效果:
在这里插入图片描述
可以看出好像打印英文没有问题,中文识别还是有点小小距离的:
在这里插入图片描述
更换英文的图片进行识别:
在这里插入图片描述
好像识别不出来,试试其它的模型呢?
在这里插入图片描述

OcdrNet

申请地址

https://build.nvidia.com/nvidia/ocdrnet?snippet_tab=Python

模型介绍

用于光学字符检测和识别的预训练模型

import os
import sys
import uuid
import zipfile

import requests

# NVCFAPI 的OC DRNet模型端点
nvai_url ="https://ai.api.nvidia.com/v1/cv/nvidia/ocdrnet"

# 授权头,需要API key,如果在NGC之外执行
header_auth = f"Bearer $API_KEY_REQUIRED_IF_EXECUTING_OUTSIDE_NGC"

def _upload_asset(input, description):"""
    上传一个资产到NVCFAPI。
    
    :param input: 要上传的二进制资产
    :param description: 资产的描述
    :return: 资产ID(UUID对象)
    """
    assets_url ="https://api.nvcf.nvidia.com/v2/nvcf/assets"
    
    # 设置请求头
    headers ={"Authorization": header_auth,"Content-Type":"application/json","accept":"application/json",}
    
    # 设置S3请求头
    s3_headers ={"x-amz-meta-nvcf-asset-description": description,"content-type":"image/jpeg",}
    
    # 设置请求负载
    payload ={"contentType":"image/jpeg","description": description}
    
    # 发送POST请求以获取上传URL和资产ID
    response = requests.post(assets_url, headers=headers, json=payload, timeout=30)
    response.raise_for_status()
    
    asset_url = response.json()["uploadUrl"]
    asset_id = response.json()["assetId"]
    
    # 发送PUT请求上传资产
    response = requests.put(
        asset_url,
        data=input,
        headers=s3_headers,
        timeout=300,)
    response.raise_for_status()
    
    # 返回资产IDreturn uuid.UUID(asset_id)if __name__ =="__main__":"""
    上传一张自选图片到NVCFAPI,并向光学字符检测和识别模型发送请求。
    响应保存到本地目录。
    
    注意:必须设置环境变量NGC_PERSONAL_API_KEY。
    """
    
    # 检查命令行参数数量
    iflen(sys.argv)!=3:print("Usage: python test.py <image> <output_dir>")
        sys.exit(1)
    
    # 上传资产并获取资产ID
    asset_id =_upload_asset(open(sys.argv[1],"rb"),"Input Image")
    
    # 设置请求负载
    inputs ={"image": f"{asset_id}","render_label": False}
    
    # 设置资产列表
    asset_list = f"{asset_id}"
    
    # 设置请求头
    headers ={"Content-Type":"application/json","NVCF-INPUT-ASSET-REFERENCES": asset_list,"NVCF-FUNCTION-ASSET-IDS": asset_list,"Authorization": header_auth,}
    
    # 发送POST请求到OC DRNet模型
    response = requests.post(nvai_url, headers=headers, json=inputs)
    
    # 保存响应内容到本地ZIP文件
    withopen(f"{sys.argv[2]}.zip","wb")as out:
        out.write(response.content)
    
    # 解压ZIP文件到输出目录
    with zipfile.ZipFile(f"{sys.argv[2]}.zip","r")as z:
        z.extractall(sys.argv[2])
    
    # 输出保存目录和目录内容
    print(f"Output saved to {sys.argv[2]}")print(os.listdir(sys.argv[2]))

在这里插入图片描述

标签: 人工智能

本文转载自: https://blog.csdn.net/2401_86049470/article/details/143100444
版权归原作者 2401_86049470 所有, 如有侵权,请联系我们删除。

“AI原来如此的简单,使用NIM平台3步亲手搭建基于NVIDIA NIM 平台的知识问答系统实践”的评论:

还没有评论