Gradio 是一个开源的Python package,允许快速的对于机器学习模型、API、或Python function构建build demo或web application。然后将构建的链接进行share。支持与Jupyter notebook、Google Colab、在任何编辑器中编辑的Python进行集成,还是非常好用的。
安装
pip install --upgrade gradio
构建应用
import gradio as gr
def greet(name, intensity):
return "Hello, " + name + "!" * int(intensity)
demo = gr.Interface(
fn=greet,
inputs=["text", "slider"],
outputs=["text"],
)
demo.launch()
直接运行就可以了 python app.py
。
这里比较重要的就是Interface
这个Class了。
Interface class
,设计用于接受one or more inputs,返回one or more outputs。接受三个核心参数:
- fn:包装了user interface的function;
- inputs:Gradio components(用于input),number of components,需要和 number of arguments匹配;
- outputs:类似上面的inputs。
后面还会看到,Gradio包含了超过30个built-in components(比如:gr.Textbox(), gr.Image(),gr.HTML())等components,设计用于机器学习。
上面这个代码运行之后呢,可以在本地浏览器进行预览:http://127.0.0.1:7860。
不过让我比较吃惊的是,它竟然可以做到发布到公网中:
demo.launch(share=True) # Share your demo with just 1 extra parameter 🚀
还是很强的。
使用 gr.Blocks 定制 Demos
具备较强的定制化功能,可以控制components在page中的位置,处理多个data flows,以及复杂的交互。
示例如下:
import gradio as gr
def greet(name):
return "Hello " + name + "!"
with gr.Blocks() as demo:
name = gr.Textbox(label="Name")
output = gr.Textbox(label="Output Box")
greet_btn = gr.Button("Greet")
greet_btn.click(fn=greet, inputs=name, outputs=output, api_name="greet")
demo.launch()
也可以采用装饰器:
import gradio as gr
with gr.Blocks() as demo:
name = gr.Textbox(label="Name")
output = gr.Textbox(label="Output Box")
greet_btn = gr.Button("Greet")
@greet_btn.click(inputs=name, outputs=output)
def greet(name):
return "Hello " + name + "!"
demo.launch()
不管是否用了装饰器,上面的核心还是定义了一个Button,并且绑定了事件在Button上面。
也可以不用Button,比如:Textbox,它支持 change() event,如下:
import gradio as gr
def welcome(name):
return f"Welcome to Gradio, {name}!"
with gr.Blocks() as demo:
gr.Markdown(
"""
# Hello World!
Start typing below to see the output.
""")
inp = gr.Textbox(placeholder="What is your name?")
out = gr.Textbox()
inp.change(welcome, inp, out)
demo.launch()
这里可以看到每个Component相关的event listeners。Docs。
聊天机器人(gr.ChatInterface)
这里要介绍的 gr.ChatInterface 就更高级了,专为Chatbot而设计,如果做Chatbot,可能更加方便,这里做详细介绍:
介绍
能够很方便的构建LLM,与别人共享。支持multimodal chatbots。
定义chat function
首先需要定义chat function,chat function支持两个参数:message,history。
- message: 字符串类型,表示最近的message
- history: openai-style风格的dictionaries,具有 role、content keys, 表示聊天历史
如:
[
{"role": "user", "content": "What is the capital of France?"},
{"role": "assistant", "content": "Paris"}
]
你的chat function需要返回:字符串类型,它是chatbot response。
import random
def random_response(message, history):
return random.choice(["Yes", "No"])
import gradio as gr
gr.ChatInterface(
fn=random_response)
.launch()
流式的chatbots
在你的chat function中,可以使用yield生成partial response
,这个时候用streaming chatbot
比较好。
import time
import gradio as gr
def slow_echo(message, history):
for i in range(len(message)):
time.sleep(0.3)
yield "You typed: " + message[: i+1]
gr.ChatInterface(
fn=slow_echo)
.launch()
定制Chat UI
- 还可以增加title,description参数
- 使用theme,css
- 增加examples
- 定制化chatbot(高度、占位符等) or textbox
import gradio as gr
def yes_man(message, history):
if message.endswith("?") or message.endswith("?"):
return "是的"
else:
return "可以问我任何问题!"
gr.ChatInterface(
yes_man,
chatbot=gr.Chatbot(placeholder="chatbot里面的占位符", height=300),
textbox=gr.Textbox(placeholder="我是占位符我怕谁,哈哈哈", container=False, scale=7),
title="这里是标题",
description="描述信息,放在最上方",
theme="ocean",
examples=["例子1", "例子2", "例子3"],
cache_examples=True,
).launch()
效果如下:
多模态的chat interface
有时候想上传图片、files(在chatbot里面),怎么办?直接传参 multimodal=True 就行了。
这里我们先考虑输出还是字符串的情况,但是对于function的first parameter则有点不一样了,因为它包含了文字、图片/文件:
{
"text": "user input",
"files": [
"updated_file_1_path.ext",
"updated_file_2_path.ext",
...
]
}
示例代码:
import gradio as gr
def yes_man(message, history):
print(message)
if message["text"].endswith("?") or message["text"].endswith("?"):
return "是的"
else:
return "可以问我任何问题!"
gr.ChatInterface(
yes_man,
chatbot=gr.Chatbot(placeholder="chatbot里面的占位符", height=300),
textbox=gr.MultimodalTextbox(file_count="multiple", file_types=["image"]),
title="这里是标题",
description="描述信息,放在最上方",
theme="ocean",
examples=[
{"text": "No files", "files": []}
],
cache_examples=True,
multimodal=True
).launch()
返回复杂的Responses
上面介绍的还都是返回字符串,称之为chatbot中的text,也可以返回更加复杂的结构:
- gr.Image
- gr.Plot
- gr.Audio
- gr.HTML
- gr.Video
- gr.Gallery
import gradio as gr
def music(message, history):
if message.strip():
return gr.Audio("https://github.com/gradio-app/gradio/raw/main/test/test_files/audio_sample.wav")
else:
return "Please provide the name of an artist"
gr.ChatInterface(
music,
textbox=gr.Textbox(placeholder="Which artist's music do you want to listen to?", scale=7),
).launch()
这个再结合音乐的API是不是会很有趣?
有了这些知识,我们可以对接真实的API,比如和讯飞星火、智谱AI对接。