在前文,我们通过NVIDIA NIM,可以用最少的代码,使用大模型了
【 从零开始NIM及大语言模型和RAG使用入门
但是好像还不够,这好像只能给技术人员使用,那么真正的使用者,还是需要UI界面来提供方便,如果能语音交互,当然更好了,今天带来通过gradio,实现基本的web页面交互和语音交互。
UI和语音交互的代码见下面参考资料地址,非常详细,就不重复拷贝了。这里补充说明几个遇到的问题和处理,并展示效果:
1、找不到麦克风问题
处理方式: 此问题是浏览器权限问题,需要使用https方式,解决方法有两种,一种是通过打开share参数,使用第二个外网域名的地址https,需要有”网络条件“,第二种是生成本地证书,使用https访问,这种方式在jupyter中不能打开页面。
1 demo.launch(share=True,debug=True)
2 demo.launch(debug=True, server_port=5000, server_name="192.168.100.110",ssl_certfile="/tmp/cert.pem", ssl_keyfile="/tmp/key.pem")
需要先生产证书文件,注意证书文件的路径引用正确。
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes
运行效果展示
启动服务后,通过浏览器,可以通过文字、语音进行交互,例子还可以将回答转换为语音文件,自动播放,只是目前例子语音只能用英文。
2、运行环境:
例子的运行过程,还遇到有一些错误,需要安装以下安装包
pip install gradio
pip install openai-whisper==20231117
pip install ffmpeg==1.4
conda install ffmpeg -y
pip install edge-tts
pip install transformers
pip install openai
#补充
pip install mpv
conda install pyaudio
pip install ipywidgets
3、多模态图片文件路径问题:
多模态处理图片,需要将文字转为base64编码:
# 使用全局变量 table 来存储数据
table = None
# 将要处理的图像转换成base64格式
image_b64 = image2b64("economic-assistance-chart.png")
#展示读取的图片
from PIL import Image
display(Image.open("economic-assistance-chart.png"))
输出路径错误,会导致程序运行不下去,要确定输出路径存在,并且有读写权限:
global img_path
#img_path = '/home/nvidia/2024_summer_bootcamp/day3/'+'image.png' //错误代码
img_path = '/tmp/'+'image.png'
print(img_path)
将多模态智能体封装进Gradio
def chart_agent_gr(image_b64, user_input, table):
image_b64 = image2b64(image_b64)
# Chart reading Runnable
chart_reading = ChatNVIDIA(model="microsoft/phi-3-vision-128k-instruct")
chart_reading_prompt = ChatPromptTemplate.from_template(
'Generate underlying data table of the figure below, : <img src="data:image/png;base64,{image_b64}" />'
)
chart_chain = chart_reading_prompt | chart_reading
# Instruct LLM Runnable
# instruct_chat = ChatNVIDIA(model="nv-mistralai/mistral-nemo-12b-instruct")
# instruct_chat = ChatNVIDIA(model="meta/llama-3.1-8b-instruct")
#instruct_chat = ChatNVIDIA(model="ai-llama3-70b")
instruct_chat = ChatNVIDIA(model="meta/llama-3.1-405b-instruct")
instruct_prompt = ChatPromptTemplate.from_template(
"Do NOT repeat my requirements already stated. Based on this table {table}, {input}" \
"If has table string, start with 'TABLE', end with 'END_TABLE'." \
"If has code, start with '```python' and end with '```'." \
"Do NOT include table inside code, and vice versa."
)
instruct_chain = instruct_prompt | instruct_chat
# 根据“表格”决定是否读取图表
chart_reading_branch = RunnableBranch(
(lambda x: x.get('table') is None, RunnableAssign({'table': chart_chain })),
(lambda x: x.get('table') is not None, lambda x: x),
lambda x: x
)
# 根据需求更新table
update_table = RunnableBranch(
(lambda x: 'TABLE' in x.content, save_table_to_global),
lambda x: x
)
execute_code = RunnableBranch(
(lambda x: '```python' in x.content, execute_and_return_gr),
lambda x: x
)
# 执行绘制图表的代码
chain = (
chart_reading_branch
| RunnableLambda(print_and_return)
| instruct_chain
| RunnableLambda(print_and_return)
| update_table
| execute_code
)
return chain.invoke({"image_b64": image_b64, "input": user_input, "table": table})
打开一个Gradio的服务, 我们可以利用Gradio的页面与构建好的智能体对话
import gradio as gr
multi_modal_chart_agent = gr.Interface(fn=chart_agent_gr,
inputs=[gr.Image(label="Upload image", type="filepath"), 'text'],
outputs=['image'],
title="Multi Modal chat agent",
description="Multi Modal chat agent",
allow_flagging="never")
multi_modal_chart_agent.launch(debug=True, share=False, show_api=False, server_port=5001, server_name="192.168.100.110")
运行效果展示:
参考资料
https://github.com/gradio-app/gradio/pull/3872
https://github.com/kinfey/Microsoft-Phi-3-NvidiaNIMWorkshop/blob/main/Phi-3-Voice.ipynb