%pip install gradio
Gradio
Suppose you’ve just built a fantastic machine-learning model. It crunched the numbers, learned from the data, and made impressive predictions. You’re excited and ready to harness its power, but there’s one problem — how to share it so everyone can easily test and use it?
This is where Gradio comes to the rescue!
Light Up Your Models With Gradio!
Gradio is an open-source Python library that lets you quickly whip up an efficient interface for your models. Yep, you heard it right! No more endless lines of code or complex setups. This library is all about simplicity and functionality, allowing you to interactively experiment with your models and share them effortlessly with others.
Enough Talk, Let’s Dive In!
Here’s your step-by-step guide to mastering Gradio and exploring its amazing features:
First, install Gradio using pip:
Let’s kick things off with a simple function greet.
def greet(name):
return "Hello " + name + "!"
Now, let’s put Gradio to work:
import gradio as gr
= gr.Interface(fn=greet, inputs="text", outputs="text")
iface # Let's launch the interface iface.launch()
Bam! You’ve just created an intuitive interface for your function. Users can provide their names in the interface and instantly see a personalized greeting message without coding chops!
But we’re just getting warmed up. Gradio is all about customization and versatility.
Inputs (required)
The inputs
parameter defines the input type, Gradio has a lot of input types, let’s try a few:
import gradio as gr
def plus_one(number):
return number + 1
= gr.Interface(fn=plus_one, inputs="slider", outputs="text")
iface iface.launch()
Outputs (required)
The outputs
parameter defines the output type
import gradio as gr
def plus_one(number):
return number + 1
= gr.Interface(fn=plus_one, inputs="slider", outputs="label")
iface iface.launch()
What if I want to change the input and it automatically changes the output? Unfortunately, Gradio does not support automatic output updates based on input changes without submission. This design ensures that resource-intensive functions are only called when the user is prepared to submit their input.
Here are some selected parameters that can be used as input or output in Gradio:
Input:
'textbox'
: A simple textbox for free text input.'image'
: Used when the input to the interface is an image file.'slider'
: Used to choose a single value between a range of values with a slider.- and more
Output:
'text'
: Simple text output.'image'
: Used for output which is an image file.'label'
: A simple text label.'json'
: When the output should be displayed as structured JSON data.- and more
These are just a few examples. For a full list, you can refer to the Gradio Interface API documentation.
fn (required)
The fn
parameter maps the inputs to the outputs.
from fastbook import *
'''
gv(inputs -> fn -> outputs
''')
import gradio as gr
def upper_case(text):
return text.upper()
= gr.Interface(fn=upper_case, inputs="text", outputs="text")
iface iface.launch()
Examples (optional)
To make our UI easier to understand, we can provide a sample of the input and output.
import gradio as gr
def upper_case(text):
return text.upper()
= gr.Interface(fn=upper_case, inputs="text", outputs="text", examples=[["hello world"], ["goodbye world"]])
iface iface.launch()
The examples will be rendered in the UI and can be clicked to quickly test the function.
Title and Description (optional)
Let’s add title and description to our interface so that users can understand what it does.
import gradio as gr
def upper_case(text):
return text.upper()
= gr.Interface(fn=upper_case, inputs="text", outputs="text", title="Uppercase Text", description="An interface for model that converts text to uppercase.")
iface iface.launch()
Flag
Notice that when the UI is rendered, there is a Flag button on the top right corner. This button allows users to record the input and output of the function and save it as a CSV file. Details can be seen here: https://www.gradio.app/docs/flagging
Exercise:
Student Identity
# @title #### Student Identity
= "" # @param {type:"string"}
student_id = "" # @param {type:"string"}
name = "" # @param {type:"string"} drive_link
%pip install rggrader
from rggrader import submit
# @title #### 00 Creating a "Mood Interpreter" with Gradio
# In this exercise, let's create a fun and simple Gradio application - a mood interpreter.
# The interface should take as input a user's mood (in text form) and return a fun interpretation of that mood.
# For example, if a user enters "happy", the interpreter might return, "Wow, you're shining brighter than the sun!"
# Here's a list of moods:
# "happy": "Wow, you're shining brighter than the sun!",
# "sad": "Oh no, it's little gloomy today, isn't it?",
# "excited": "Seems like someone's energy is through the roof!",
# "tired": "Ah, a good rest will work wonders.",
# "angry": "Uh oh, someone's a bit hot-headed today!"
# Put your code here:
import gradio as gr
def mood_interpreter(mood):
return None
= None
iface
# ---- End of your code ----
# Submit Method
= "00_gradio"
assignment_id = "00_gradio_mood_interpreter"
question_id str(mood_interpreter("happy")), question_id, drive_link) submit(student_id, name, assignment_id,
# @title #### 01 Creating a Palindrome Checker with Gradio
# A palindrome is a word, phrase, number, or other sequence of characters that reads the same backward as forward, ignoring spaces, punctuation, and capitalization.
# In this exercise, you will create a simple Gradio interface for a palindrome checker.
# The interface should take a word as input and return whether the input is a palindrome or not.
# put your code here:
import gradio as gr
def palindrome_checker(word):
return None
= None
iface
# ---- End of your code ----
# Submit Method
= "00_gradio"
assignment_id = "01_gradio_palindrome_checker"
question_id str(palindrome_checker("aditira")) question_id, drive_link) submit(student_id, name, assignment_id,
Level Up with Gradio!
Gradio comes with a variety of built-in components that you can leverage to customize your UI. The possibilities are endless, from sliders and dropdowns to checkboxes and radio buttons!
Gradio Component (Source: (www.gradio.app/docs/components))
Gradio includes pre-built components that can be used as inputs or outputs in your Interface with a single line of code.
From the previous examples, we assign values to the input
and output
parameters by providing a string value representing IOComponent
:
import gradio as gr
def calculate_area(length: int) -> str:
= length * length
area if area > 20:
return "Large area"
else:
return "Small area"
= gr.Interface(calculate_area,
iface ="slider", outputs="label")
inputs iface.launch()
But, what if we want to customize the minimum and maximum values of the slider? We can call IOComponent
in this example gr.inputs.Slider
and customize it there.
import gradio as gr
def calculate_area(length: int) -> str:
= length * length
area if area > 20:
return "Large area"
else:
return "Small area"
= gr.Interface(calculate_area,
iface = gr.inputs.Slider(minimum=0, maximum=40),
inputs = gr.outputs.Label())
outputs iface.launch()
Multiple Inputs
What if we want to have multiple inputs? We can call several IOComponent
in a list
for the value of the input.
The above function calculates the area of a rectangle, using two sliders to capture the length and width. Simple and interactive!
import json
import gradio as gr
def calculate_area(length: int, width: int) -> json:
= length * width
area if area > 20:
return {
"area": area,
"size": "Large area",
}else:
return {
"area": area,
"size": "Small area",
}
= gr.Interface(calculate_area,
iface = [gr.inputs.Slider(minimum=0, maximum=40), gr.inputs.Slider(minimum=0, maximum=100)], # Inputs with multiple values in a list
inputs = gr.outputs.JSON())
outputs iface.launch()
Note also that the value sent from the list in the input is read by the function that takes two parameters (adjusts to the list index) and we return the value in json form so that the output in Gradio using IOComponent
is gr.outputs.JSON()
What about multiple inputs with different components? Of course Gradio can also build this by adding radio buttons and drop-down menus in one input
example:
import gradio as gr
def greet(name, title):
return f"{title} {name}, nice to meet you!"
= gr.Interface(greet,
iface =["Mr.", "Ms.", "Dr.", "Prof."])],
[gr.inputs.Textbox(), gr.inputs.Dropdown(choices
gr.outputs.Textbox()) iface.launch()
Here we have a greeting function with a dropdown menu for users to select their title!
Multiple Output
What if you have a function that produces multiple outputs and you want to display all of them in the interface? Actually, Gradio can handle this perfectly. Let’s look at an example where a function calculates the area and perimeter of a square given the length of its side:
import gradio as gr
def calculate_area_and_perimeter(length: int):
= length * length
area = 4 * length
perimeter return area, perimeter
# To display multiple outputs, we use brackets `[...]` and list the types for each of the outputs. In this case, we have two numbers to display, so we have `outputs=["number", "number"]`.
= gr.Interface(calculate_area_and_perimeter,
iface =gr.inputs.Slider(1, 10, 1, label="Length"),
inputs=["number", "number"])
outputs iface.launch()
This will create a Gradio interface that allows the user to adjust the length of the square’s side using a slider, and then it will display both the area and the perimeter of the square.
Image Processing with Gradio
Gradio is not just about numbers and text. It also supports a variety of other types, including images! Let’s see an example where we create a Gradio interface that takes an image as input and outputs a grayscale version of the same image:
import gradio as gr
from PIL import Image
import numpy as np
def to_grayscale(input_image: gr.inputs.Image) -> gr.outputs.Image:
= Image.fromarray(input_image) # Convert the numpy array into a PIL Image object
pil_image = pil_image.convert('L') # Convert the image to grayscale
grayscale_image return np.array(grayscale_image) # Convert the PIL Image object back into a numpy array
= gr.Interface(fn=to_grayscale, inputs="image", outputs=gr.outputs.Image(type="numpy"))
iface iface.launch()
This Gradio interface allows the user to upload an image, then it processes the image to create a grayscale version, and finally displays the grayscale image.
As you can see, the sky’s the limit for Gradio. It provides an end-to-end solution for rapid UI creation, allowing you to focus more on your models and less on user interface challenges.
Understanding the Magic behind launch()
To start the Gradio app and bring your Gradio interface to life, we use the launch()
function. Here are some key parameters used with launch()
:
Debug
What if an error occurs in our Gradio application and we have to do debugging? Yes, Debugging can be a headache, especially when you are dealing with UIs. That’s where the debug
parameter comes into play. Setting this to True
will give you detailed error messages if something goes wrong while running the UI. By default, debug
is set to False
.
Let’s take a simple example where we unintentionally introduce an error into our function and see how to use the debug
parameter to help us fix it.
Consider the following function that should return the length of the input string. However, we’ve written it incorrectly, as it tries to get the length of an integer, which will result in a TypeError.
import gradio as gr
def string_length(text):
return len(5) # This will cause a TypeError: object of type 'int' has no len()
= gr.Interface(fn=string_length, inputs="text", outputs="text")
iface iface.launch()
This will fail silently because we haven’t enabled debugging yet. Let’s try it again, but this time with debug=True
.
import gradio as gr
def string_length(text):
return len(5) # This will cause a TypeError: object of type 'int' has no len()
= gr.Interface(fn=string_length, inputs="text", outputs="text")
iface =True) iface.launch(debug
Now you will see a detailed error trace in the console, which will help you debug the issue. Here’s the error trace:
TypeError: object of type 'int' has no len()
This message suggests there’s a TypeError because we’re trying to get the length of an integer. To correct it, we need to replace the integer with the text
parameter in the len function as below:
import gradio as gr
def string_length(text):
return len(text) # Correctly gets the length of the input string
= gr.Interface(fn=string_length, inputs="text", outputs="text")
iface =True) iface.launch(debug
Now, the interface should work as expected and return the length of the user’s input string.
Exercise
# @title #### 02 Name and Age Greetings App
# In this exercise, you are going to create a Gradio interface for an application that greets the user in a more personalized way.
# Your Gradio interface should take two inputs: the user's name and their age. The interface should return two outputs: a greeting that includes the user's name and a message based on the user's age.
# For example, if a user inputs "John" for the name and "25" for the age, the application might return, "Hello, John!" and "You're in the prime of your youth!"
# These are the rules for age_message:
# - If user is younger than 18 : "Enjoy your youth, life is an adventure waiting!"
# - If user is between 18 and 29 : "You're in the prime of your youth!"
# - If user is between 30 and 49 : "You are old enough to know better and still young enough to do it."
# - If user is 50 or older : "ge is just a state of mind!"
# Put your code here:
import gradio as gr
def personalized_greeting(name, age):
= ""
greetings = ""
age_message return greetings, age_message
= None
iface
# ---- End of your code ----
# Submit Method
= "00_gradio"
assignment_id = "02_gradio_personalized_greeting"
question_id str(personalized_greeting("John", 25)), question_id, drive_link) submit(student_id, name, assignment_id,
Now, the Fun Part - Building Mini Apps with Gradio!
Case 1: Age Predictor Mini-App
Suppose we have a machine learning model that predicts a person’s age based on their name (for the sake of simplicity, let’s define a dummy model here). We could build an intuitive user interface using Gradio:
import gradio as gr
def age_predictor(name):
# Let's pretend that our model predicts age 25 for every name
= 25
prediction return f"The predicted age for {name} is: {prediction}"
= gr.Interface(age_predictor, "text", "text")
iface iface.launch()
Voilà! Our app is ready to use. As usual, you just wrote a Python function, and Gradio transformed it into an interactive web-based app!
Case 2: Image Classifier Mini-App
Let’s tackle something a bit more complex now. Assume we have an image classification model to classify a given image into different categories. We want to expand our model’s use to those who understand machine learning or programming. So, let’s build a web-based app using Gradio:
def classify_image(inp):
# For the sake of simplicity, let's say our model always predicts 'cat'
return {'cat': 0.99, 'dog': 0.01, 'bird': 0.00}
= gr.inputs.Image(shape=(224, 224))
image = gr.outputs.Label(num_top_classes=3)
label
= gr.Interface(classify_image, image, label)
iface iface.launch()
That’s it! Any user can now upload an image and get an instant prediction from your image classification model without writing a single line of code!
Case 4: Text Translation Mini-App
Let’s consider a more advanced use case: text translation. If you have a text translation model that can translate English text into French (for example), Gradio can help bring it to life:
def translate_text(input):
# Here is a dummy translation function.
return "C'est un bel exemple de texte français."
= gr.Interface(translate_text, "text", "text")
iface iface.launch()
With Gradio, users can now test your text translation model interactively, making your model more accessible than ever!
Complex Gradio Interface: Recipe Finder Mini-App
Suppose we have a model that can recommend a possible dish and its recipe given a set of ingredients. Let’s build a web-based UI for our model using Gradio.
import gradio as gr
def suggest_recipe(ingredients, cuisine, vegetarian):
# Our function receives a list of ingredients, cuisine preference, and a vegetarian flag
# For simplicity, let's return a dummy recipe here
return "Recipe: Dummy Recipe"
# Multi-option input for ingredients, with autocomplete feature
= gr.inputs.Textbox(lines=5, label="Input Ingredients (comma-separated)")
ingredients_input
# Dropdown for cuisine preference
= gr.inputs.Dropdown(choices=["Italian", "Mexican", "Indian", "Chinese", "American"], label="Cuisine Preference")
cuisine_input
# Checkbox for vegetarian preference
= gr.inputs.Checkbox(label="Vegetarian")
vegetarian_input
= gr.Interface(suggest_recipe, [ingredients_input, cuisine_input, vegetarian_input], "text")
iface iface.launch()
Voila! We have created a more complex Gradio interface for our recipe-finding model. Users can input a list of ingredients, select their cuisine preference from a dropdown list, tick a checkbox if they want a vegetarian recipe, and our model will suggest a suitable recipe!
Combining different Gradio components allows you to build incredibly rich and interactive UIs for your machine-learning models. Not only does Gradio make your models more accessible to a broader audience, but it also enhances the overall user experience, making your models easier to understand and interact with!
Sentiment Analysis with Gradio & Hugging Face
Gradio allows easy creation of a web-based UI for our model. We’ll use Hugging Face’s pipeline to simplify loading the model and tokenizer.
%pip install transformers
# load the sentiment analysis pipeline
from transformers import pipeline
= pipeline('sentiment-analysis')
nlp_model
# function to be used in Gradio interface
def predict_sentiment(text):
= nlp_model(text)[0]
result return f"label: {result['label']}, with score: {round(result['score'], 4)}"
= gr.Interface(fn=predict_sentiment, inputs="textbox", outputs="text")
iface iface.launch()
This cell loads the sentiment analysis model using Hugging Face’s pipeline function and then sets up a Gradio interface for this model. The Gradio interface takes the text input, gets the model’s predictions, and shows the sentiment label and the respective score as output.
Voice Conversion App - Combining Interfaces
Gradio shines in building mini apps for various models and functions. One powerful feature is the ability to combine multiple interfaces into a single app using the TabbedInterface
function. This is especially useful when you want to showcase multiple related capabilities together. For instance, let’s build a mini app that houses both a text-to-speech (TTS) and a speech-to-text (STT) model:
import gradio as gr
= [
tts_examples "I love learning machine learning",
"How do you do?",
]
# Load the TTS model and interface
= gr.load(
tts_demo "huggingface/facebook/fastspeech2-en-ljspeech",
=None,
title=tts_examples,
examples="Give me something to say!",
description
)
# Load the STT model and interface
= gr.load(
stt_demo "huggingface/facebook/wav2vec2-large-960h",
=None,
title="mic",
inputs="Let me try to guess what you're saying!",
description
)
# Combine the two interfaces into a tabbed interface
= gr.TabbedInterface([tts_demo, stt_demo], ["Text-to-speech", "Speech-to-text"])
demo
if __name__ == "__main__":
=True) # Launch the mini app! demo.launch(debug
Now you have a mini app that capitalizes on Gradio’s power to deliver interactive and user-friendly experiences for model exploration! Details can be seen here: combining-interfaces
Personalized Welcome App - Blocks
Gradio’s Blocks
is a powerful feature that allows you to compose more complex interfaces with a variety of layout options, including rows and columns. Blocks can also contain other interface elements like markdown, inputs, outputs, and even buttons.
Let’s create a simple mini-app where user can input their name and get a personalized welcome message:
import gradio as gr
# This is the function that gets executed when the "Run" button is clicked.
def update(name):
return f"Welcome to Gradio, {name}!"
# With Blocks, we can create more complex Gradio interfaces.
with gr.Blocks() as demo:
"Start typing below and then click **Run** to see the output.")
gr.Markdown(with gr.Row(): # Adds a row to the interface
= gr.Textbox(placeholder="What is your name?")
inp = gr.Textbox()
out = gr.Button("Run") # Adds a button to the interface
btn =update, inputs=inp, outputs=out) # Attaches the 'update' function to the button
btn.click(fn
# Launches the mini app! demo.launch()
Let’s build a mini app with multiple rows and columns. This app will capture two users’ names and welcome message for them.
import gradio as gr
# This is the function that gets executed when the "Run" button is clicked.
def update(name1, name2):
return f"Welcome to Gradio, {name1} and {name2}!"
# We can create more complex Gradio interfaces with multiple rows and columns.
with gr.Blocks() as demo:
"Start typing below and then click **Run** to see the output.")
gr.Markdown(with gr.Row(): # Adds the first row to the interface
= gr.Textbox(placeholder="User 1, what is your name?")
inp1 = gr.Textbox()
out1 with gr.Row(): # Adds the second row to the interface
= gr.Textbox(placeholder="User 2, what is your name?")
inp2 = gr.Textbox()
out2 = gr.Button("Run") # Adds a button to the interface
btn =update, inputs=[inp1, inp2], outputs=[out1, out2]) # Attaches the 'update' function to the button
btn.click(fn
# Launches the mini app! demo.launch()
This mini app takes two users’ names as inputs in separate rows and provides personalized welcome messages for them. Details can be seen here: blocks and block-layouts.
Building Mini Apps with Gradio: Interactive Chatbot
Do you know ChatGPT? In Gradio, there is something called ChatInterface
and that is a powerful tool to create chatbox-style interfaces like ChatGPT.
Here, we’re going to build a very simple chatbot using Gradio. This chatbot doesn’t have any real understanding of the user’s input. Instead, it will randomly respond with either “Yes” or “No” whenever a new message is submitted.
import random
import gradio as gr
def random_response(message, history):
return random.choice(["Yes", "No"])
= gr.ChatInterface(random_response)
demo
if __name__ == "__main__":
demo.launch()
After launching this Gradio app, you’ll see a textbox where you can type your message. When you hit “submit”, the random_response function is called with your message, and the chatbot responds with either “Yes” or “No”. Since the responses are randomly selected, you’ll get different responses each time you send a message. It’s a very simple example, but it shows how easy it is to get started with a chat interface in Gradio!
What about the original model, for example GPT2?
In this example, we’re going to build a simple chatbot that uses the text-generation
pipeline from the Hugging Face transformers
library. This pipeline uses the GPT-2 model to generate text based on the user’s input.
import gradio as gr
from transformers import pipeline
# Instantiate a gpt2 text-generation pipeline
= pipeline('text-generation', model='gpt2')
generator
def gpt2_chatbot(message, history):
# Even though we're not using history in generating our response,
# it still needs to be a parameter in the function.
# Use the gpt2 model to generate a response. Let's limit it to 50 tokens.
= generator(message, max_length=50, temperature=0.7)[0]['generated_text']
generated_response
# Extract the generated text and return it.
= generated_response.split('\n')[-1]
bot_message return bot_message
# We create a ChatInterface, using the gpt2_chatbot function as the logic for the chatbot.
= gr.ChatInterface(fn=gpt2_chatbot, title="GPT-2 Chatbot")
demo demo.launch()
This code creates a chat interface using Gradio. The chat interface uses the GPT-2 model to generate responses to user input. When the user types a message and hits “submit”, the message is sent to the gpt2_chatbot function. That function uses the GPT-2 model to generate a response, and that response is displayed on the screen.
Wrapping Up
Gradio is a versatile tool that unlocks a sea of possibilities for your machine-learning models. It allows you to create user-friendly interfaces quickly, facilitating real-time interaction, sharing, and collaboration. The best part? It requires just a few lines of code. So, try Gradio and start building amazing apps for your models!