使用 Gradio 的過載模式快速構建 AI 應用

釋出於 2024 年 4 月 16 日
在 GitHub 上更新

在本文中,我將向您展示如何使用 Gradio 的過載模式快速構建一個功能強大的 AI 應用。但在我們開始之前,我想解釋一下過載模式的作用,以及為什麼 Gradio 要實現自己的自動過載邏輯。如果您已經熟悉 Gradio 並希望直接開始構建,請跳至第三部分

過載模式是做什麼的?

簡而言之,它可以在不重啟 Gradio 伺服器的情況下,從您的原始檔中載入最新的更改。如果這還不太好理解,請繼續閱讀。

Gradio 是一個用於建立互動式機器學習應用的熱門 Python 庫。Gradio 開發者完全在 Python 中宣告他們的 UI 佈局,並新增一些 Python 邏輯,這些邏輯會在發生 UI 事件時觸發。如果您瞭解基本的 Python,它就很容易學習。如果您還不熟悉 Gradio,請檢視這篇快速入門

Gradio 應用的啟動方式與任何其他 Python 指令碼一樣,只需執行 python app.py(包含 Gradio 程式碼的檔案可以任意命名)。這將啟動一個 HTTP 伺服器,用於渲染您的應用 UI 並響應使用者操作。如果您想對應用進行更改,您需要停止伺服器(通常使用 Ctrl + C),編輯原始檔,然後重新執行指令碼。

在開發應用時,不得不停止並重新啟動伺服器會帶來很多延遲。如果有一種方法可以自動載入最新的程式碼更改,讓您可以立即測試新想法,那就更好了。

這正是 Gradio 的過載模式所做的。只需執行 gradio app.py 而不是 python app.py,即可在過載模式下啟動您的應用!

為什麼 Gradio 要構建自己的過載器?

Gradio 應用使用 uvicorn 執行,這是一個用於 Python Web 框架的非同步伺服器。Uvicorn 已經提供了自動過載功能,但 Gradio 出於以下原因實現了自己的邏輯:

  1. 更快的過載:Uvicorn 的自動過載會關閉伺服器然後重新啟動。這比手動操作要快,但對於開發 Gradio 應用來說還是太慢了。Gradio 開發者在 Python 中構建他們的 UI,所以他們應該在做出更改後立即看到 UI 的外觀。這在 Javascript 生態系統中是標準做法,但在 Python 中是新鮮事物。
  2. 選擇性過載:Gradio 應用是 AI 應用。這意味著它們通常會將 AI 模型載入到記憶體中或連線到像向量資料庫這樣的資料儲存。在開發過程中重新啟動伺服器將意味著重新載入模型或重新連線資料庫,這在開發週期之間引入了太多的延遲。為了解決這個問題,Gradio 引入了一個 if gr.NO_RELOAD: 程式碼塊,您可以用它來標記不應被過載的程式碼。這隻有在 Gradio 實現自己的過載邏輯時才可能實現。

現在我將向您展示如何使用 Gradio 的過載模式快速構建一個 AI 應用。

構建一個文件分析應用

我們的應用將允許使用者上傳文件圖片並就其提問。他們將以自然語言獲得答案。我們將使用免費的 Hugging Face 推理 API,因此您應該可以在您的電腦上跟著操作。無需 GPU!

首先,我們來建立一個最基本的 gr.Interface。在一個名為 app.py 的檔案中輸入以下程式碼,並使用 gradio app.py 在過載模式下啟動它。

import gradio as gr

demo = gr.Interface(lambda x: x, "text", "text")

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

這將建立以下簡單的 UI。

Simple Interface UI

由於我想讓使用者在提問的同時上傳圖片檔案,我將把輸入元件切換為 gr.MultimodalTextbox()。注意 UI 是如何即時更新的!

Simple Interface with MultimodalTextbox

這個 UI 可以工作,但我認為如果輸入文字框在輸出文字框下面會更好。我可以使用 Blocks API 來實現這一點。我還透過新增佔位符文字來定製輸入文字框,以引導使用者。

Switch to Blocks

現在我對 UI 感到滿意了,我將開始實現 chat_fn 的邏輯。

由於我將使用 Hugging Face 的推理 API,我將從 huggingface_hub 包中匯入 InferenceClient(它隨 Gradio 預裝)。我將使用 impira/layouylm-document-qa 模型來回答使用者的問題。然後我將使用 HuggingFaceH4/zephyr-7b-beta LLM 以自然語言提供回應。

from huggingface_hub import InferenceClient

client = InferenceClient()

def chat_fn(multimodal_message):
    question = multimodal_message["text"]
    image = multimodal_message["files"][0]
    
    answer = client.document_question_answering(image=image, question=question, model="impira/layoutlm-document-qa")
    
    answer = [{"answer": a.answer, "confidence": a.score} for a in answer]
   
    user_message = {"role": "user", "content": f"Question: {question}, answer: {answer}"}
   
    message = ""
    for token in client.chat_completion(messages=[user_message],
                           max_tokens=200, 
                           stream=True,
                           model="HuggingFaceH4/zephyr-7b-beta"):
        if token.choices[0].finish_reason is not None:
           continue
        message += token.choices[0].delta.content
        yield message

這是我們的演示在執行中的樣子!

Demoing our App

我還會提供一個系統訊息,以便 LLM 保持答案簡短,並且不包含原始的置信度分數。為了避免在每次更改時重新例項化 InferenceClient,我將把它放在一個“不過載”的程式碼塊中。

if gr.NO_RELOAD:
    client = InferenceClient()

system_message = {
    "role": "system",
    "content": """
You are a helpful assistant.
You will be given a question and a set of answers along with a confidence score between 0 and 1 for each answer.
You job is to turn this information into a short, coherent response.

For example:
Question: "Who is being invoiced?", answer: {"answer": "John Doe", "confidence": 0.98}

You should respond with something like:
With a high degree of confidence, I can say John Doe is being invoiced.

Question: "What is the invoice total?", answer: [{"answer": "154.08", "confidence": 0.75}, {"answer": "155", "confidence": 0.25}

You should respond with something like:
I believe the invoice total is $154.08 but it can also be $155.
"""}

這是我們現在的演示!系統訊息確實有助於讓機器人的回答簡短,並且不含長串的小數。

Demo of app with system message

作為最後的改進,我將在頁面上新增一個 Markdown 標題。

Adding a Header

總結

在這篇文章中,我使用 Gradio 和 Hugging Face 推理 API 開發了一個可用的 AI 應用。當我開始開發時,我並不知道最終產品會是什麼樣子,因此 UI 和伺服器邏輯的即時過載讓我能非常迅速地迭代不同的想法。我花了大約一個小時就開發了整個應用!

如果您想檢視這個演示的完整程式碼,請檢視這個 空間

社群

註冊登入 發表評論

© . This site is unofficial and not affiliated with Hugging Face, Inc.