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:

%pip install gradio

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

iface = gr.Interface(fn=greet, inputs="text", outputs="text")
iface.launch()  # Let's launch the interface

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

iface = gr.Interface(fn=plus_one, inputs="slider", outputs="text")
iface.launch() 

Outputs (required)

The outputs parameter defines the output type

import gradio as gr

def plus_one(number):
    return number + 1

iface = gr.Interface(fn=plus_one, inputs="slider", outputs="label")
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()

iface = gr.Interface(fn=upper_case, inputs="text", outputs="text")
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()

iface = gr.Interface(fn=upper_case, inputs="text", outputs="text", examples=[["hello world"], ["goodbye world"]])
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()

iface = gr.Interface(fn=upper_case, inputs="text", outputs="text", title="Uppercase Text", description="An interface for model that converts text to uppercase.")
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
student_id = "" # @param {type:"string"}
name = "" # @param {type:"string"}
drive_link = ""  # @param {type:"string"}
%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

iface = None



# ---- End of your code ----

# Submit Method
assignment_id = "00_gradio"
question_id = "00_gradio_mood_interpreter"
submit(student_id, name, assignment_id, str(mood_interpreter("happy")), question_id, drive_link)
# @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

iface = None



# ---- End of your code ----

# Submit Method
assignment_id = "00_gradio"
question_id = "01_gradio_palindrome_checker"
submit(student_id, name, assignment_id, str(palindrome_checker("aditira")) question_id, drive_link)

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

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:
    area = length * length
    if area > 20:
        return "Large area"
    else:
        return "Small area"

iface = gr.Interface(calculate_area, 
    inputs="slider", outputs="label")
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:
    area = length * length
    if area > 20:
        return "Large area"
    else:
        return "Small area"

iface = gr.Interface(calculate_area, 
    inputs = gr.inputs.Slider(minimum=0, maximum=40),
    outputs = gr.outputs.Label())
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:
    area = length * width
    if area > 20:
        return {
            "area": area,
            "size": "Large area",
        }
    else:
        return {
            "area": area,
            "size": "Small area",
        }

iface = gr.Interface(calculate_area, 
    inputs = [gr.inputs.Slider(minimum=0, maximum=40), gr.inputs.Slider(minimum=0, maximum=100)], # Inputs with multiple values in a list
    outputs = gr.outputs.JSON())
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!"

iface = gr.Interface(greet, 
    [gr.inputs.Textbox(), gr.inputs.Dropdown(choices=["Mr.", "Ms.", "Dr.", "Prof."])],
    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):
    area = length * length
    perimeter = 4 * length
    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"]`.

iface = gr.Interface(calculate_area_and_perimeter, 
    inputs=gr.inputs.Slider(1, 10, 1, label="Length"), 
    outputs=["number", "number"])
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:
    pil_image = Image.fromarray(input_image)  # Convert the numpy array into a PIL Image object
    grayscale_image = pil_image.convert('L')  # Convert the image to grayscale
    return np.array(grayscale_image)  # Convert the PIL Image object back into a numpy array

iface = gr.Interface(fn=to_grayscale, inputs="image", outputs=gr.outputs.Image(type="numpy"))
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():

Share

What if you created a great Gradio interface and now you want to share it with others? The share parameter is your friend here. By setting this parameter to True, you can make your interface accessible via a public link. However, remember that your model needs to be hosted on a server or cloud that’s publicly accessible. You cannot share an interface running on your local machine. By default, share is set to False.

import gradio as gr

def upper_case(text):
    return text.upper()

iface = gr.Interface(fn=upper_case, inputs="text", outputs="text")
iface.launch(share=True)

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()

iface = gr.Interface(fn=string_length, inputs="text", outputs="text")
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()

iface = gr.Interface(fn=string_length, inputs="text", outputs="text")
iface.launch(debug=True)

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

iface = gr.Interface(fn=string_length, inputs="text", outputs="text")
iface.launch(debug=True)

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

iface = None



# ---- End of your code ----

# Submit Method
assignment_id = "00_gradio"
question_id = "02_gradio_personalized_greeting"
submit(student_id, name, assignment_id, str(personalized_greeting("John", 25)), question_id, drive_link)

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
    prediction = 25
    return f"The predicted age for {name} is: {prediction}"

iface = gr.Interface(age_predictor, "text", "text")
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}

image = gr.inputs.Image(shape=(224, 224))
label = gr.outputs.Label(num_top_classes=3)

iface = gr.Interface(classify_image, image, label)
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."

iface = gr.Interface(translate_text, "text", "text")
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
ingredients_input = gr.inputs.Textbox(lines=5, label="Input Ingredients (comma-separated)")

# Dropdown for cuisine preference
cuisine_input = gr.inputs.Dropdown(choices=["Italian", "Mexican", "Indian", "Chinese", "American"], label="Cuisine Preference")

# Checkbox for vegetarian preference
vegetarian_input = gr.inputs.Checkbox(label="Vegetarian")

iface = gr.Interface(suggest_recipe, [ingredients_input, cuisine_input, vegetarian_input], "text")
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
nlp_model = pipeline('sentiment-analysis')

# function to be used in Gradio interface
def predict_sentiment(text):
    result = nlp_model(text)[0]
    return f"label: {result['label']}, with score: {round(result['score'], 4)}"

iface = gr.Interface(fn=predict_sentiment, inputs="textbox", outputs="text")
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
tts_demo = gr.load(
    "huggingface/facebook/fastspeech2-en-ljspeech",
    title=None,
    examples=tts_examples,
    description="Give me something to say!",
)

# Load the STT model and interface
stt_demo = gr.load(
    "huggingface/facebook/wav2vec2-large-960h",
    title=None,
    inputs="mic",
    description="Let me try to guess what you're saying!",
)

# Combine the two interfaces into a tabbed interface
demo = gr.TabbedInterface([tts_demo, stt_demo], ["Text-to-speech", "Speech-to-text"])

if __name__ == "__main__":
    demo.launch(debug=True)  # Launch the mini app!

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:
    gr.Markdown("Start typing below and then click **Run** to see the output.")
    with gr.Row():  # Adds a row to the interface
        inp = gr.Textbox(placeholder="What is your name?")
        out = gr.Textbox()
    btn = gr.Button("Run")  # Adds a button to the interface
    btn.click(fn=update, inputs=inp, outputs=out)  # Attaches the 'update' function to the button

demo.launch()  # Launches the mini app!

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:
    gr.Markdown("Start typing below and then click **Run** to see the output.")
    with gr.Row():  # Adds the first row to the interface
        inp1 = gr.Textbox(placeholder="User 1, what is your name?")
        out1 = gr.Textbox()
    with gr.Row():  # Adds the second row to the interface
        inp2 = gr.Textbox(placeholder="User 2, what is your name?")
        out2 = gr.Textbox()
    btn = gr.Button("Run")  # Adds a button to the interface
    btn.click(fn=update, inputs=[inp1, inp2], outputs=[out1, out2])  # Attaches the 'update' function to the button

demo.launch()  # Launches the mini app!

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"])

demo = gr.ChatInterface(random_response)

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
generator = pipeline('text-generation', model='gpt2')

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.
    generated_response = generator(message, max_length=50, temperature=0.7)[0]['generated_text']
    
    # Extract the generated text and return it.
    bot_message = generated_response.split('\n')[-1]
    return bot_message

# We create a ChatInterface, using the gpt2_chatbot function as the logic for the chatbot.
demo = gr.ChatInterface(fn=gpt2_chatbot, title="GPT-2 Chatbot")
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!

Back to top