Gradio

言午日尧耳总發表於2024-08-08
  • BiliBili影片
  • 官網:https://www.gradio.app/
  • 為AI模型快速搭建互動式介面。根據AI模型需求,生成輸入和輸出元件,簡化使用者介面的構建過程。

起步

基礎

  • 安裝
pip install 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()
  • 預設訪問地址:http://127.0.0.1:7860
  • 按鈕
    • Clear:清空輸入資料
    • Submit:傳送請求
    • Flag:儲存當前結果,服務端會建立一個csv,Flag會儲存資料

部署

區域網

  • 在launch()方法中,增加引數設定
    • server_name: 伺服器名稱預設是"127.0.0.1",只能本機訪問。改成"0.0.0.0",即可在區域網內使用IP訪問
    • server_port: 服務埠預設7860,當部署多個時,可能需要單獨設定避免衝突
# 其他主機透過區域網訪問
demo.launch(server_name='0.0.0.0',server_port=7860)

釋出公網

  • 釋出公網藉助gradio的雲服務,將launch()方法的share設定為True
  • 第一次使用大機率不符合條件,控制檯會列印配置方式
    • 下載檔案
    • 重新命名檔案(完全一致,不要字尾名)
    • 移動到對應目錄(python環境的gradio目錄)
  • 配置完成重啟程式,即可返回一個公網連結,有效期為72小時
# share設定為True
demo.launch(share=True)
  • Windows列印內容如下
Running on local URL:  http://127.0.0.1:7860

Could not create share link. Missing file: C:\Users\xxc\.conda\envs\py-demo-3.11\Lib\site-packages\gradio\frpc_windows_amd64_v0.2. 

Please check your internet connection. This can happen if your antivirus software blocks the download of this file. You can install manually by following these steps: 

1. Download this file: https://cdn-media.huggingface.co/frpc-gradio-0.2/frpc_windows_amd64.exe
2. Rename the downloaded file to: frpc_windows_amd64_v0.2
3. Move the file to this location: C:\Users\xxc\.conda\envs\py-demo-3.11\Lib\site-packages\gradio
  • Linux列印內容如下
Running on local URL:  http://127.0.0.1:7860

Could not create share link. Missing file: /home/lds/miniconda3/envs/py-demo-3.11/lib/python3.11/site-packages/gradio/frpc_linux_amd64_v0.2. 

Please check your internet connection. This can happen if your antivirus software blocks the download of this file. You can install manually by following these steps: 

1. Download this file: https://cdn-media.huggingface.co/frpc-gradio-0.2/frpc_linux_amd64
2. Rename the downloaded file to: frpc_linux_amd64_v0.2
3. Move the file to this location: /home/lds/miniconda3/envs/py-demo-3.11/lib/python3.11/site-packages/gradio
  • 按列印內容配置後重啟,即成功釋出公網,並且列印內容如下
Running on local URL:  http://127.0.0.1:7860
Running on public URL: https://xxxxxxxxxxxxxxxx.gradio.live

This share link expires in 72 hours. For free permanent hosting and GPU upgrades, run `gradio deploy` from Terminal to deploy to Spaces (https://huggingface.co/spaces)

api呼叫

  • launch()方法有'show_api:bool'引數,預設為True
    • 即'demo.launch(show_api=True)'
    • 網頁左下方可開啟api請求方法
# 安裝gradio時已安裝,下面語句用於單獨安裝
pip install gradio_client
from gradio_client import Client

client = Client("http://127.0.0.1:7860/")
result = client.predict(
		name="Hello!!",
		intensity=0,
		api_name="/predict"
)

# 文字直接列印
# 圖片則自動儲存到快取,列印的是下載的圖片路徑
print(result)

介面

Inferface

  • 互動介面
  • 官網說明:https://www.gradio.app/docs/gradio/interface
引數 說明 型別 預設值 示例
fn 執行函式 Callable 必填
inputs 輸入 str | Component | list[str | Component] | None 必填 "text" | gr.Slider(0, 100) | ["text", gr.Slider(0, 100)]
outputs 輸出 str | Component | list[str | Component] | None 必填 "image" | gr.Image() | ["text", gr.Image()]
examples 輸入示例(和輸入元素一一對應) list[Any] | list[list[Any]] | str | None None [['張三', 1], ['李四', 2]]
title 標題(頁面上方居中) str | None None
description 描述(標題下方,左對齊) str | None None
api_name api介面路徑 str | Literal[False] | None "predict"
...


import gradio as gr


def greet(name, intensity):
    return "Hello, " + name + "!" * intensity


demo = gr.Interface(
    fn=greet,
    inputs=["text", gr.Slider(label="重複次數", value=2, minimum=1, maximum=10, step=1)],
    outputs=[gr.Textbox(label="greeting", lines=3)],
    examples=[["張三", 3], ["李四", 6]],
    title='Gradio的簡單示例',
    description='輸入名字和重複次數,得到歡迎語'
)

if __name__ == "__main__":
    demo.launch()

launch

  • 啟動互動介面
引數 說明 型別 預設值 說明
show_api 介面是否顯示api說明 bool True
server_name 服務地址 str | None None,即'127.0.0.1' '0.0.0.0',釋出到區域網使用
server_port 埠號 int | None None,即7860
auth 登入許可權 Callable | tuple[str, str] | list[tuple[str, str]] | None None,無需登入 ('admin','123456')
share 公共分享連結 bool | None None 連線到gradio.live
分享地址如:https://a23dsf231adb.gradio.live
...



import gradio as gr
demo = gr.Interface(...)

if __name__ == "__main__":
    demo.launch(
        server_name='0.0.0.0',
        server_port=1234,
        auth=('admin', '123456')
    )

ChatInterface

  • 聊天型別互動介面
  • 官網說明:https://www.gradio.app/docs/gradio/chatinterface
  • 介面按鈕
    • Retry: 重新傳送最後一條資訊
    • Undo: 刪除最後一條對話
    • Clear: 清空所有對話
引數 說明 型別 預設值 說明
fn 執行函式 Callable 必填
multimodal 多模態 bool False False則只能輸入文字;True則可以上傳音影片等檔案
examples 示例 list[str] | list[dict[str, str | list]] | list[list] | None None
title 標題 str | None None
...


import gradio as gr


# message為當前接收的訊息
def echo(message, history):
    print(history)  # history包含之前的所有對話,如:[['原神', '原神,啟動!'], ['LOL', 'LOL,啟動!']]
    return f'{message},啟動!'


demo = gr.ChatInterface(fn=echo,
                        multimodal=False,
                        examples=['原神', 'LOL', '黑神話'],
                        title="聊天機器人")
demo.launch()

TabbedInterface

  • Tab頁介面,多個介面放在tab頁當中
  • 官方說明:https://www.gradio.app/docs/gradio/tabbedinterface
引數 說明 型別 預設值 說明
interface_list 介面列表 list[Blocks] 必填
tab_names tab名稱列表 list[str] | None None ['計算器', '文生圖']
...


import gradio as gr


def hello(name):
    return f'Hello {name}'


def bye(x: int, y: int):
    return f'{x} + {y} = {x + y}'


hello_interface = gr.Interface(fn=hello, inputs="text", outputs="text", examples=[["張三"], ["李四"]])
bye_interface = gr.Interface(fn=bye, inputs=["number", "number"], outputs="text", examples=[[1, 1], [3, 4]])

demo = gr.TabbedInterface(interface_list=[hello_interface, bye_interface],
                          tab_names=['歡迎', '計算器'])

if __name__ == "__main__":
    demo.launch()

Blocks

  • 像搭積木一樣搭建介面
  • 官方文件:https://www.gradio.app/docs/gradio/blocks
import gradio as gr


def plus(x: int, y: int):
    return f"{x} + {y} = {x + y}"


with gr.Blocks() as demo:
    gr.Markdown("# 演示Block")
    gr.Markdown("像搭積木一樣,一行一行堆疊")
    
    # 新增行,裡面的元素橫向新增
    with gr.Row():
        inp_x = gr.Number(value=1)
        inp_y = gr.Slider()
        out = gr.Textbox()
    
    # 繼續下一行,新增按鈕
    btn = gr.Button("計算")
    btn.click(fn=plus, inputs=[inp_x, inp_y], outputs=out)

demo.launch()

render

  • 動態渲染
  • 官方文件:https://www.gradio.app/docs/gradio/render
import gradio as gr

with gr.Blocks() as demo:
    input_num = gr.Number()

    # 根據輸入值動態渲染
    @gr.render(inputs=input_num)
    def show_split(num):
        if num <= 0:
            gr.Markdown("## 輸入大於0的數字")
        else:
            for i in range(num):
                with gr.Row():
                    btn = gr.Button("點選")
                    text = gr.Textbox()
                    btn.click(lambda: 666, inputs=None, outputs=text)

demo.launch()

Accordion

  • 摺疊
  • 文件:https://www.gradio.app/docs/gradio/accordion
import gradio as gr

with gr.Blocks() as demo:
    # 摺疊元件
    with gr.Accordion("檢視詳情"):
        gr.Markdown("- 詳情1")
        gr.Markdown("- 詳情2")

demo.launch()

Row/Column

  • 行/列
  • 文件
    • https://www.gradio.app/docs/gradio/row
    • https://www.gradio.app/docs/gradio/column
import gradio as gr

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column(scale=1):
            text1 = gr.Textbox()
            text2 = gr.Textbox()
        with gr.Column(scale=4):
            btn1 = gr.Button("Button 1")
            btn2 = gr.Button("Button 2")

demo.launch()

Group

  • 分組
  • 文件:https://www.gradio.app/docs/gradio/group
import gradio as gr

with gr.Blocks() as demo:
    with gr.Group():
        gr.Textbox(label="First")
        gr.Textbox(label="Last")

demo.launch()

Tab

  • Tab頁
  • 文件:https://www.gradio.app/docs/gradio/tab
import gradio as gr

with gr.Blocks() as demo:
    with gr.Tab("計算器"):
        gr.Number(label="x")
        gr.Number(label="y")
        gr.Button("計算")
    with gr.Tab("圖生影片"):
        gr.Image()
        gr.Button("執行")

demo.launch()

元件

  • 內建元件非常豐富,目前有40+元件,介紹幾個常用的
  • 常見屬性
引數 型別 預設 說明
label str | None None 標籤,相當於表單說明
show_label bool | None None 是否顯示標籤
visible bool True 如果False,元件會隱藏
  • 常用元件
元件 簡稱 常用屬性 說明
Textbox "textbox" lines,placeholder 文字框
TextArea "textarea" lines,placeholder 多行文字框
Number "number" minimum,maximum,step 數字文字框
Slider "slider" minimum,maximum,step 滑塊
Radio "radio" choices 單選框
CheckboxGroup "checkboxgroup" choices 多選框
Audio "audio" format 音訊,需要安裝FFmpeg
Image "image" format,height,width,show_download_button 圖片
Video "video" format,height,width 影片,需要安裝FFmpeg
import gradio as gr
import time


def foo(textbox: str, textarea: str, number: int, slider: int, radio: str, checkboxes: list, ):
    return textbox, textarea, number, slider, radio, checkboxes


def multimedia_foo(audio, image, video):
    return audio, image, video


def chat_foo(message, history):
    return f'{message},啟動!'


def image_foo(text):
    time.sleep(1)
    return "example/image-1.webp"  # 虛擬碼,將提前準備的資源放在該路徑


def video_foo(text):
    time.sleep(1)
    return "example/video-1.mp4"  # 虛擬碼,將提前準備的資源放在該路徑


def audio_foo(text):
    time.sleep(1)
    return "example/audio-1.mp3"  # 虛擬碼,將提前準備的資源放在該路徑


components_interface = gr.Interface(
    fn=foo,
    inputs=[gr.Textbox(label="文字框"), gr.Number(label="數字文字框"), gr.Slider(label="滑塊"),
            gr.Radio(label="單選框", choices=["單選1", "單選2", "單選3"]),
            gr.CheckboxGroup(label="核取方塊", choices=["複選1", "複選2", "複選3"]), gr.TextArea(label="多行文字框")],
    outputs=[gr.Textbox(), gr.Number(), gr.Slider(), gr.Textbox(), gr.Textbox(), gr.TextArea()],
    examples=[["言午日堯耳總", 100, 6, "單選1", ["複選1", "複選2"], "Gradio演示"],
              ["耳總", 10086, 66, "單選2", [], "我的部落格:http://blog.xuxiiaocong.cn"]])

multimedia_interface = gr.Interface(
    fn=multimedia_foo,
    inputs=[gr.Audio(label="音訊"), gr.Image(label="圖片"), gr.Video(label="影片")],
    outputs=[gr.Audio(), gr.Image(), gr.Video()],
    examples=[["example/audio-1.mp3", "example/image-1.webp", "example/video-1.mp4"],
              ["example/audio-2.mp3", "example/image-2.webp", "example/video-2.mp4"],
              ["example/audio-3.mp3", "example/image-3.webp", "example/video-3.mp4"]]
)

chat_interface = gr.ChatInterface(fn=chat_foo, examples=['原神', 'LOL', '黑神話'])
text_2_image_interface = gr.Interface(fn=image_foo, inputs="text", outputs="image", examples=["小女孩抱著一隻貓"])
text_2_video_interface = gr.Interface(fn=video_foo, inputs="text", outputs="video", examples=["一個帥哥坐在椅子上"])
text_2_audio_interface = gr.Interface(fn=audio_foo, inputs="text", outputs="audio", examples=["創作一首歌"])

demo = gr.TabbedInterface(
    interface_list=[components_interface, multimedia_interface, chat_interface, text_2_image_interface,
                    text_2_video_interface, text_2_audio_interface],
    tab_names=["元件演示", "多媒體", "對話型", "文生圖", "文生影片", "文生音訊"])

demo.launch()

其他

安裝FFmpeg(Windows)

  • 處理音影片時,需要安裝FFmpeg
  • FFmpeg官網:https://ffmpeg.org/
  • 官網首頁點選"Download" > "More downloading options" > 選擇Windows圖示 > "Windows builds from gyan.dev"
  • 此時跳轉到gyan.dev > "release builds" > "ffmpeg-full.7z" 點選下載
  • 下載後解壓,將解壓後的資料夾新增到環境變數中,重啟命令列/IDE
ffmpeg -version

Gradio其他內容

  • Helpers: 互動事件,如點選事件,選擇事件
  • Modals: 彈窗
  • Routes: 掛載到FastApi應用
  • Other: 標記(Flagging)、主題(Themes)等