並獲得增強文件體驗
開始使用
Gradio 模組簡介
在前面的章節中,我們已經探索並建立了使用 Interface 類的演示。在本節中,我們將介紹我們**新開發的**低階 API,稱為 gradio.Blocks。
那麼,Interface 和 Blocks 之間有什麼區別呢?
⚡
Interface:一個高階 API,允許您只需提供輸入和輸出列表即可建立完整的機器學習演示。🧱
Blocks:一個低階 API,允許您完全控制應用程式的資料流和佈局。您可以使用Blocks(如“構建塊”)構建非常複雜的多步驟應用程式。
為什麼選擇 Blocks 🧱?
正如我們在前面的章節中看到的,Interface 類允許您只需幾行程式碼即可輕鬆建立功能齊全的機器學習演示。Interface API 非常易於使用,但缺乏 Blocks API 提供的靈活性。例如,您可能希望
- 將相關的演示組合為一個 Web 應用程式中的多個選項卡
- 更改演示的佈局,例如指定輸入和輸出的位置
- 具有多步驟介面,其中一個模型的輸出成為下一個模型的輸入,或者具有更靈活的資料流
- 根據使用者輸入更改元件的屬性(例如,下拉列表中的選項)或其可見性
我們將在下面探討所有這些概念。
使用 Blocks 建立簡單的演示
安裝 Gradio 後,將以下程式碼作為 Python 指令碼、Jupyter Notebook 或 Colab Notebook 執行。
import gradio as gr
def flip_text(x):
return x[::-1]
demo = gr.Blocks()
with demo:
gr.Markdown(
"""
# Flip Text!
Start typing below to see the output.
"""
)
input = gr.Textbox(placeholder="Flip this text")
output = gr.Textbox()
input.change(fn=flip_text, inputs=input, outputs=output)
demo.launch()以上這個簡單的示例介紹了 Blocks 的 4 個核心概念
Blocks 允許您構建 Web 應用程式,這些應用程式可以結合 Markdown、HTML、按鈕和互動式元件,只需在
with gradio.Blocks上下文中例項化 Python 物件即可。🙋如果您不熟悉 Python 中的 `with` 語句,我們建議您檢視 Real Python 提供的優秀的[教程](https://realpython.com/python-with-statement/)。閱讀完後請回到這裡 🤗例項化元件的順序很重要,因為每個元素都按照建立的順序渲染到 Web 應用程式中。(更復雜的佈局將在下面討論)您可以在程式碼中的任何位置定義常規 Python 函式,並使用
Blocks透過使用者輸入執行它們。在我們的示例中,我們有一個簡單的函式來“翻轉”輸入文字,但您可以編寫任何 Python 函式,從簡單的計算到處理機器學習模型的預測。您可以為任何
Blocks元件分配事件。這將在單擊、更改等元件時執行您的函式。當您分配事件時,您會傳遞三個引數:fn:應呼叫的函式,inputs:輸入元件的(列表),以及outputs:應呼叫的輸出元件的(列表)。在上面的示例中,當名為輸入
input的Textbox中的值發生更改時,我們執行flip_text()函式。該事件讀取input中的值,將其作為名稱引數傳遞給flip_text(),然後該函式返回一個值,該值被分配給名為output的第二個Textbox。要檢視每個元件支援的事件列表,請參閱 Gradio 的文件。
Blocks 會根據您定義的事件觸發器自動確定元件是否應該具有互動性(接受使用者輸入)。在我們的示例中,第一個文字框是互動式的,因為它的值被
flip_text()函式使用。第二個文字框不是互動式的,因為它的值從未用作輸入。在某些情況下,您可能希望覆蓋此行為,您可以透過將布林值傳遞給元件的interactive引數來實現(例如gr.Textbox(placeholder="Flip this text", interactive=True))。
自定義演示的佈局
我們如何使用 Blocks 來自定義演示的佈局?預設情況下,Blocks 會在一列中垂直渲染您建立的元件。您可以透過建立額外的列 with gradio.Column(): 或行 with gradio.Row(): 並在這些上下文中建立元件來更改這一點。
您需要注意以下幾點:在 Column 下建立的任何元件(這也是預設設定)都將垂直佈局。在 Row 下建立的任何元件都將水平佈局,類似於Web 開發中的 flexbox 模型。
最後,您還可以使用 with gradio.Tabs() 上下文管理器為您的演示建立選項卡。在此上下文中,您可以透過指定 with gradio.TabItem(name_of_tab): 子項來建立多個選項卡。在 with gradio.TabItem(name_of_tab): 上下文中建立的任何元件都將顯示在該選項卡中。
現在讓我們向演示中新增一個 flip_image() 函式,並新增一個翻轉影像的新選項卡。下面是一個包含 2 個選項卡並使用 Row 的示例
import numpy as np
import gradio as gr
demo = gr.Blocks()
def flip_text(x):
return x[::-1]
def flip_image(x):
return np.fliplr(x)
with demo:
gr.Markdown("Flip text or image files using this demo.")
with gr.Tabs():
with gr.TabItem("Flip Text"):
with gr.Row():
text_input = gr.Textbox()
text_output = gr.Textbox()
text_button = gr.Button("Flip")
with gr.TabItem("Flip Image"):
with gr.Row():
image_input = gr.Image()
image_output = gr.Image()
image_button = gr.Button("Flip")
text_button.click(flip_text, inputs=text_input, outputs=text_output)
image_button.click(flip_image, inputs=image_input, outputs=image_output)
demo.launch()您會注意到,在這個示例中,我們還在每個選項卡中建立了一個 Button 元件,併為每個按鈕分配了一個單擊事件,這實際上是執行函式的操作。
探索事件和狀態
就像您可以控制佈局一樣,Blocks 使您可以對觸發函式呼叫的事件進行細粒度的控制。每個元件和許多佈局都支援特定的事件。
例如,Textbox 元件有兩個事件:change()(當文字框內的值發生變化時)和 submit()(當用戶在聚焦於文字框時按下 Enter 鍵時)。更復雜的元件可以有更多的事件:例如,Audio 元件還分別具有音訊檔案播放、清除、暫停等的事件。請參閱每個元件支援的事件的文件。
您可以將事件觸發器附加到這些事件中的零個、一個或多個事件。您可以透過將元件例項上的事件名稱作為函式呼叫來建立事件觸發器,例如 textbox.change(...) 或 btn.click(...)。該函式接收三個引數,如上所述
fn:要執行的函式inputs:一個(或多個)元件,其值應作為輸入引數提供給函式。每個元件的值按順序對映到相應的函式引數。如果函式不接受任何引數,則此引數可以為 None。outputs:一個(或多個)元件,其值應根據函式返回的值進行更新。每個返回值按順序設定相應元件的值。如果函式不返回任何內容,則此引數可以為 None。
您甚至可以使輸入和輸出元件成為同一個元件,就像我們在使用 GPT 模型進行文字補全的示例中所做的那樣
import gradio as gr
api = gr.Interface.load("huggingface/EleutherAI/gpt-j-6B")
def complete_with_gpt(text):
# Use the last 50 characters of the text as context
return text[:-50] + api(text[-50:])
with gr.Blocks() as demo:
textbox = gr.Textbox(placeholder="Type here and press enter...", lines=4)
btn = gr.Button("Generate")
btn.click(complete_with_gpt, textbox, textbox)
demo.launch()建立多步驟演示
在某些情況下,您可能希望使用一個多步驟演示,其中您將一個函式的輸出重新用作下一個函式的輸入。使用 Blocks 執行此操作非常簡單,因為您可以將一個元件用作一個事件觸發器的輸入,但用作另一個事件觸發器的輸出。請檢視下面示例中的文字元件,其值是語音到文字模型的結果,但也傳遞給情感分析模型
from transformers import pipeline
import gradio as gr
asr = pipeline("automatic-speech-recognition", "facebook/wav2vec2-base-960h")
classifier = pipeline("text-classification")
def speech_to_text(speech):
text = asr(speech)["text"]
return text
def text_to_sentiment(text):
return classifier(text)[0]["label"]
demo = gr.Blocks()
with demo:
audio_file = gr.Audio(type="filepath")
text = gr.Textbox()
label = gr.Label()
b1 = gr.Button("Recognize Speech")
b2 = gr.Button("Classify Sentiment")
b1.click(speech_to_text, inputs=audio_file, outputs=text)
b2.click(text_to_sentiment, inputs=text, outputs=label)
demo.launch()更新元件屬性
到目前為止,我們已經瞭解瞭如何建立事件來更新另一個元件的值。但是,如果您想更改元件的其他屬性,例如文字框的可見性或單選按鈕組中的選項,該怎麼辦?您可以透過從函式返回元件類的 update() 方法而不是常規返回值來實現此目的。
這用一個例子最容易說明
import gradio as gr
def change_textbox(choice):
if choice == "short":
return gr.Textbox.update(lines=2, visible=True)
elif choice == "long":
return gr.Textbox.update(lines=8, visible=True)
else:
return gr.Textbox.update(visible=False)
with gr.Blocks() as block:
radio = gr.Radio(
["short", "long", "none"], label="What kind of essay would you like to write?"
)
text = gr.Textbox(lines=2, interactive=True)
radio.change(fn=change_textbox, inputs=radio, outputs=text)
block.launch()我們剛剛探索了 Blocks 的所有核心概念!就像使用 Interfaces 一樣,您可以透過在 launch() 方法中使用 share=True 或部署在 Hugging Face Spaces 上來建立可以共享的酷炫演示。