Saltar a contenido

Gradio

Gradio es una herramienta que facilita el prototipado de demos para modelos de ML mediante un interfaz web amigable, de manera que con unas pocas líneas de código Python tengamos un interfaz gráfico que nos evite tener que desarrollar toda una aplicación web para comprobar el funcionamiento de nuestros modelos de IA, sin necesidad de saber JavaScript ni CSS para hacer un diseño responsive.

Alternativas

Las alternativas actuales son Streamlit para prototipado y creación de cuadros de mandos de forma programativa y ágil, y si ya dejamos el prototipado y nos centramos en entornos de producción, las herramientas más empleados son Flask y Django, pero requiriendo un mayor dominio de estás tecnologías al estar centradas en el desarrollo web y no en el prototipado para modelos ML.

Gradio se resume, principalmente, en tres elementos:

  • Interfaz: la clase principal para crear interfaces de usuario.
  • Componentes: tanto de entrada como de salida (por ejemplo, cuadros de texto, imágenes, audio, etc...). Actualmente hay más de 30 componentes incorporados.
  • Funciones: funciones Python que procesan la información de los componentes de entrada y devuelven los resultados para mostrarlos con componentes de salida.
Elementos Gradio
Elementos Gradio

Hola Gradio

A continuación, vamos a ver cómo, con unas pocas líneas, creamos un diálogo para un introducir texto como entrada y una caja para mostrar el resultado:

hello-gradio.py
import gradio as gr

def saluda(nombre):
    return "Hola " + nombre + "!"

demo = gr.Interface(fn=saluda, inputs="text", outputs="text")
demo.launch()

Al ejecutar el script, ya sea mediante python hello-gradio.py o mejor con gradio hello-gradio.py (ya que permite la edición en caliente), se publicará la aplicación en una URL privada, normalmente en http://127.0.0.1:7860, donde podemos ver cómo ha creado un diálogo de tipo texto con nombre para introducir la entrada, y otro output, para mostrar la salida:

Hola gradio!
Hola gradio!

Tras introducir una frase de entrada, aparece el resultado de ejecutar la función saluda:

Hola gradio! - response
Hola gradio! - response

Para crear una URL pública, cambiaremos la última línea de nuestro script con:

demo.launch(share=True)

Si volvemos a ejecutar el script, ahora nos mostrará tanto la URL local como la remota para poder acceder a nuestra demo durante 72 horas de forma gratuita (mediante la conexión remota sólo se realiza una pasarela con nuestro ordenador local, de manera que tanto el modelo de IA como toda la computación se realiza en nuestra máquina local, con lo que, si la detenemos, ya no funcionará):

(venv) % gradio hello-gradio.py 
Watching: '/Users/aitormedrano/sandbox/hf' '/Users/aitormedrano/sandbox/hf'

Running on local URL:  http://127.0.0.1:7860
Running on public URL: https://e7f052359229ef0ed8.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)

Gradio ❤️ HuggingFace

Gradio y HuggingFace van de la mano, de manera que podemos desplegar nuestras aplicaciones Gradio en Spaces de HuggingFace para ofrecer una solución rápida para probar nuestros modelos desplegados.

Al final de la ejecución nos recomienda el uso de Spaces. Así pues, si queremos desplegar el modelo en Spaces, el primer paso será hacer login con las credenciales de Hugging Face.

La clase Interface

La clase Interface es la clase de más alto nivel, y permite crear el IU de nuestros modelos ML.

Del ejemplo anterior, hemos visto que la clase Interface recibe tres parámetros: Interface(fn=funcion, inputs=entradas, outputs=salidas, ...):

  • fn: función que invoca al modelo ML o realiza la funcionalidad deseada. La función acepta al menos un parámetro y devuelve uno o más valores.
  • inputs: define el tipo del componente de entrada (o los tipos de los componentes si tenemos varias entradas). Gradio ofrece varios componentes predefinidos, como de tipo texto, imagen, micrófono, etc... La cantidad de componentes de entrada debe coincidir con el número de parámetros indicados en la función fn. Si asociamos None a inputs, sólo se muestran los componentes de salida.
  • outputs: igual que el caso anterior, define el tipo del componente de salida (o los tipos de los componentes si tenemos varias salidas). Gradio ofrece varios componentes predefinidos, como de tipo texto, imagen, etiqueta, etc... La cantidad de componentes de salida debe coincidir con el número de valores devueltos por la función fn. Si asociamos None a outputs, sólo se muestran los componentes de entrada.

Tipos de componentes

Aunque los estudiaremos más adelante en esta sesión, podemos indicar los tipos de componentes mediante una cadena de texto (por ejemplo, "text", "textbox", "image", "audio", etc...) o como una instancia de la clase ( gr.TextBox(), gr.Image(), gr.Audio(), etc...)

En el caso de crear varios interfaces, Gradio ofrece tanto las clases TabbedInterface como Blocks para combinar interfaces (en versiones anteriores a la 3.0 se utilizaban tanto Parallel como Series)

Por ejemplo, a modo de aplicación de bienvenida, podemos definir una serie de funciones que muestren al usuario diferentes mensajes y utilizar un TabbedInterface para combinarlos mediante el uso de pestañas:

gradio-tabbed.py
import gradio as gr

#app 1
def saluda(nombre):
    return "¡Hola " + nombre + "! 😎"

app1 =  gr.Interface(fn = saluda, inputs="text", outputs="text")

#app 2
def mensaje(accion):
    return "Hoy vamos a " + accion + " con Gradio"

app2 =  gr.Interface(fn = mensaje, inputs="text", outputs="text")

demo = gr.TabbedInterface([app1, app2], ["Bienvenid@", "¿Qué hacemos?"], "Uso de pestañas")

demo.launch()

Fíjate en la siguiente imagen en la creación de las pestañas, y el nombre de cada etiqueta:

Uso de pestañas en Gradio
Uso de pestañas en Gradio

Personalizando el interfaz

Además de los controles, podemos configurar ciertos elementos, como el título o la descripción, así como cambiar el tema visual (colores, fuente, etc...) de todo el interfaz.

Para ello, cuando definimos el interfaz, además de la función y los componentes de entrada y salida, tenemos disponibles los parámetros:

  • title: título, se muestra en la parte superior y como título de la página.
  • description: acepta tanto texto como Markdown o HTML, y se coloca debajo del título.
  • article: acepta tanto texto como Markdown o HTML, y se coloca debajo del interfaz.
  • theme: mediante gr.Theme() podemos cambiar toda la apariencia visual. Tenemos un conjunto de temas disponibles, o podemos crear los nuestros propios, tanto a nivel de colores o fuentes como de tamaños de los componentes. También podemos utilizar temas creados por terceros mediante gr.Theme.from_hub().
  • css: además del tema, podemos modificar propiedades CSS.
  • fill_witdh: con el valor True, permite anular el padding y ocupar todo el ancho.

Así pues, si cogemos nuestro ejemplo inicial y lo personalizamos con algunas propiedades, veremos su apariencia modificada:

hello-gradio-custom.py
import gradio as gr

def saluda(nombre):
    return "Hola " + nombre + "!"


titulo = "Hola Gradio"
descripcion = """Con Gradio podemos crear prototipos visuales para probar nuestros <strong>modelos de IA</strong>

<br />

<figure style="display: flex; justify-content: center; align-items: center;">
    <img src="https://aitor-medrano.github.io/iabd/images/logoIABD3.png" alt=Logo IABD" width="100px">
</figure>
"""
articulo = "En este caso, sólo debes escribir tu *nombre* y pulsar sobre **enviar**"

demo = gr.Interface(fn=saluda, inputs="text", outputs="text", title=titulo, description=descripcion, article=articulo, theme="glass", submit_btn="enviar", fill_width=True)
demo.launch()

Obteniendo:

Personalizando el interfaz con Gradio
Personalizando el interfaz con Gradio

La clase Blocks

La clase Blocks es la API de bajo nivel de Gradio que nos permite controlar el flujo de datos, la disposición y agrupación de los componentes y los eventos que disparan la ejecución de las funciones de las aplicaciones Gradio, como si fueran bloques.

El uso básico de Blocks es el siguiente: tras crear un objeto Blocks, lo usaremos como contexto (mediante la sentencia with) y definiremos los diseños, componentes o eventos dentro del contexto Blocks. Finalmente, llamaremos al método launch() para lanzar el gradio.

Veamos un ejemplo sencillo, donde combinamos componentes como Markdown, botones o cajas de texto interactivas:

gradio-blocks.py
import gradio as gr

def modifica(nombre):
    return f"¡Bienvenido a Gradio, {nombre}!"

with gr.Blocks() as demo:
    gr.Markdown("Escribe debajo y pulsa *Ejecuta* para ver la salida")
    with gr.Row():
        inp = gr.Textbox(placeholder="¿Cómo te llamas?", label="Entrada")
        out = gr.Textbox(label="Salida")
    btn = gr.Button("Ejecuta")
    btn.click(fn=modifica, inputs=inp, outputs=out)

demo.launch()

Tras lanzar el Gradio, veremos el siguiente interfaz, el cual captura el evento click del botón (con una firma similar a la de Interface) y concatena el nombre en la salida:

Uso de Blocks
Uso de Blocks

Usando decoradores

También podemos usar decoradores para simplificar el código utilizando el nombre del componente que maneja el evento:

gradio-blocks-decorator.py
import gradio as gr

with gr.Blocks() as demo:
    gr.Markdown("Escribe debajo y pulsa *Ejecuta* para ver la salida")
    with gr.Row():
        inp = gr.Textbox(placeholder="¿Cómo te llamas?", label="Entrada")
        out = gr.Textbox(label="Salida")
    btn = gr.Button("Ejecuta")

    @btn.click(inputs=inp, outputs=out)
    def modifica(nombre):
        return f"¡Bienvenido a Gradio, {nombre}!"

demo.launch()

Sobre este ejemplo, vamos a quitar el botón, y asociar el manejador a un cambio en la entrada, capturando el evento change:

gradio-blocks-change-py
import gradio as gr

def modifica(nombre):
    return f"¡Bienvenido a Gradio, {nombre}!"

with gr.Blocks() as demo:
    gr.Markdown("Escribe debajo y comprueba la salida")
    with gr.Row():
        inp = gr.Textbox(placeholder="¿Cómo te llamas?", label="Entrada")
        out = gr.Textbox(label="Salida")

    inp.change(fn=modifica, inputs=inp, outputs=out)

demo.launch()

De esta manera, cada vez que escribimos, se actualizará la salida:

Uso de Blocks con evento change
Uso de Blocks con evento change

Dependiendo del componente, tendremos diferentes manejadores de eventos. Acabamos de ver que el componente gradio.Textbox() ofrece el manejador change() que se dispara al cambiar el texto al teclear. Otro ejemplo sería el componente gradio.Video() que ofrece el manejador play(), el cual se dispara cuando un usuario pulsa play.

Múltiples flujos

Es común que nuestros prototipos contengan varios de datos de entrada y que dependiendo de las elecciones, luego utilicemos unos u otros valores. Es más, puede que hasta tengamos varios lanzadores para la aplicación.

Vamos a darle una vuelta de tuerca a nuestra aplicación que saluda, para que nos permita saludar o despedirnos, teniendo en cuenta el valor de un campo numérico. Así como datos de entrada, usaremos una caja de texto y un número, y como salida una caja de texto, pero con dos botones para saludar o despedirse:

gradio-flows.py
import gradio as gr

def saludar(nombre, hora):
    texto_hora = "¡Buenos días!" if int(hora) <= 12 else "¡Buenas tardes!" 
    return f"{texto_hora} ¡Bienvenido a Gradio, {nombre}!"

def despedir(nombre, hora):
    texto_hora = "¡A disfrutar!" if int(hora) <= 12 else "¡Mañana más!"
    return f"{texto_hora} ¡Hasta la próxima con Gradio, {nombre}!"


with gr.Blocks() as demo:
    nombre = gr.Textbox(placeholder="¿Cómo te llamas?", label="Nombre")
    hora = gr.Number(label="Hora", value="8")
    out = gr.Textbox(label="Salida")

    btnSaluda = gr.Button("Saludar")
    btnSaluda.click(fn=saludar, inputs=[nombre, hora], outputs=out)

    btnDespide = gr.Button("Despedir")
    btnDespide.click(fn=despedir, inputs=[nombre, hora], outputs=out)

demo.launch()

De esta manera, cada botón tiene su manejador y cada función su propia lógica:

Uso de flujos con Blocks
Uso de flujos con Blocks

Disposición

La disposición (layout) de los bloques de una aplicación se pueden personalizar mediante clases como gr.Row(), gr.Columns(), gr.Tab() o gr.Accordion().

  • Filas


    Por ejemplo, podemos utilizar filas dentro de los bloques mediante gr.Row(), de manera que todos los hijos de nuestra aplicación se renderizan horizontalmente:

    gradio-rows.py
    import gradio as gr
    
    with gr.Blocks() as demo:
        with gr.Row():
            gr.Text(placeholder="Uno")
            gr.Text(placeholder="Dos")
            gr.Text(placeholder="Tres")
    
    demo.launch()
    

    Uso de Row
    Uso de Row

  • Columnas


    En cambio, con gr.Column() renderizamos los hijos verticalmente. Podemos indicar la anchura de las columnas mediante los atributos scale y min_width:

    gradio-columns.py
    import gradio as gr
    
    with gr.Blocks() as demo:
        with gr.Row():
            with gr.Column(scale=2):
                btn1 = gr.Button("Botón 1")
                btn2 = gr.Button("Botón 2")
            with gr.Column(scale=1):
                text1 = gr.Textbox(placeholder="A")
                text2 = gr.Textbox(placeholder="B")
    
    demo.launch()
    

    Uso de Columns
    Uso de Columns

  • Pestañas


    También podemos organizar los componentes en forma de pestañas utilizando gradio.Tab(). Los componentes de una pestaña concreta se mostrarán cuando un usuario navegue a la pestaña correspondiente. A cada pestaña se le asigna una etiqueta.

    gradio-tab.py
    import gradio as gr
    
    with gr.Blocks() as demo:
        with gr.Tab(label="Botones"):
            btn1 = gr.Button("Botón 1")
            btn2 = gr.Button("Botón 2")
        with gr.Tab(label="Cajas"):
            text1 = gr.Textbox(placeholder="Uno")
            text2 = gr.Textbox(placeholder="Dos")
    
    demo.launch()
    

    Uso de Tab
    Uso de Tab

  • Acordeón


    Definimos un acordeón mediante gradio.Accordion(), el cual permite mostrar u ocultar los elementos contenidos:

    gradio-accordion.py
    import gradio as gr
    
    with gr.Blocks() as demo:
        with gr.Accordion("Muestra detalles", open=False):
            gr.Markdown("IABD - *Aitor Medrano*")
    
    demo.launch()
    

    Uso de Accordion
    Uso de Accordion

Visibilidad

Normalmente, la función que pasamos a la clase Interface o Block devuelve un valor, ya sea el resultado de un cálculo o de la inferencia a algún modelo de ML.

Pero también podemos devolver otro componente que modifique las propiedades de los componentes de salida, como pueden ser el número de líneas de un Textbox o la visibilidad de un Image.

El siguiente ejemplo, donde la función ya no devuelve un valor sino un componente, muestra como modificamos tanto el tamaño como la visibilidad (mediante la propiedad visible) de un componente de texto:

gradio-visibilidad.py
import gradio as gr

def updateTextbox(eleccion):
    if eleccion == "Pequeño":
        return gr.Textbox(lines=1, visible=True)
    elif eleccion == "Grande":
        return gr.Textbox(lines=6, visible=True)
    else:
        return gr.Textbox(visible=False)

demo = gr.Interface(
    updateTextbox,
    gr.Radio(
        ["Pequeño", "Grande", "Sin mensaje"], label="¿Qué tipo de mensaje quieres enviar?"
    ),
    gr.Textbox(lines=2)
)

demo.launch()

Y un ejemplo de su uso:

Modificando la visibilidad
Modificando la visibilidad

Componentes básicos

Gradio dispone de un conjunto de componentes predefinidos para varias funciones, ya sea desde trabajar con texto o multimedia como audios, imágenes y vídeo como gráficos mediante Matplotlib o Seaborne.

Texto

Podemos mostrar textos mediante el componente Textbox. Cada método ofrece una area de texto para introducir una cadena de entrada o mostrar una cadena de salida. A la hora de pasarle el componente al Interface, podemos indicar el componente o la cadena text, tanto para la entrada como para la salida.

gradio-text.py
import gradio as gr

def muestraTexto(frase):
    return frase

demo = gr.Interface(muestraTexto, gr.TextBox(), "text")

demo.launch()

Código fuente

También podemos mostrar código fuente utilizando un Textbox:

gradio-code.py
import gradio as gr

code = '''def calMedia(numeros):
    suma = 0
    for n in numeros:
        suma = suma + n          

    media = suma / len(numeros)
    return media'''

with gr.Blocks() as demo:
    gr.Textbox(code)

demo.launch()

Datos

Para mostrar datos, podemos emplear diferentes tipos como str, number, bool, date o markdown. Por defecto, tendremos un DataFrame de Pandas.

Para obtener otros tipos de datos, hemos de indicarlo en la salida. Por ejemplo, podemos obtener un array de NumPy indicando numpy, y array si queremos un array de Python.

import gradio as gr

def mostrarDatos(datos):
    return datos

demo = gr.Interface(mostrarDatos, gr.Dataframe(), "dataframe")
demo.launch()

Multimedia

En Gradio podemos mostrar elementos como imágenes, así como transformar las imágenes aplicando un filtro como, por ejemplo, el sepia o el azul. Para ello, en la entrada podemos pasar componentes de tipo Image, Video, Audio o File.

El siguiente ejemplo muestra cómo visualizar una imagen después de aplicar un filtro de tono azul.

import numpy as np
import gradio as gr

def blueHue(inputImg):
    # definimos el filtro
    blueHueFilter = np.array([
            [0.272, 0.534, 0.131], 
            [0.349, 0.686, 0.168],
            [0.393, 0.769, 0.189]])

    blueHueImg = inputImg.dot(blueHueFilter.T)
    blueHueImg /= blueHueImg.max()
    return blueHueImg

demo = gr.Interface(blueHue, gr.Image(height=300, width=200), "image")
demo.launch()
Componente Image
Componente Image

De forma similar, podemos mostrar vídeos sin ningún procesamiento:

import gradio as gr

def mostrarVideo(datos):
    return datos

demo = gr.Interface(mostrarVideo, gr.Video(), "video")
demo.launch()

Gráficos

Los elementos gráficos se muestran en Gradio mediante el componente gradio.Plot(). Después de crear el gráfico, puede especificar fn = funcionDibujaGrafico, input = None y output = gradio.Plot().

Ya existen una serie de gráficos ya predefinidos, como BarPlot,

import gradio as gr

def createBarPlot():
    x = ["Manzanas", "Plátanos", "Naranjas"]  # Etiquetas del eje X
    y = [10, 15, 7]  # Valores para cada barra

    # Devolver los datos en el formato adecuado para gr.BarPlot
    return {
        "labels": x,       # Etiquetas del eje X
        "data": [y],       # Los datos, como una lista de listas
        "title": "Frutas más vendidas",  # Título del gráfico
        "x": "Frutas",     # Etiqueta para el eje X
        "y": "Cantidad"    # Etiqueta para el eje Y
    }

demo = gr.Interface(fn=createBarPlot, inputs=None, outputs=gr.BarPlot())

demo.launch()

Componentes interactivos

A continuación, vamos a estudiar algunos de los componentes interactivos que ofrece Gradio.

Botón

Mediante gradio.Button() podemos definir un botón de envío nuestras aplicaciones especificando value="Enviar" y añadiendo un evento gradio.Button.click():

gradio-button.py
import gradio as gr

def combinar(a, b):
    return "¡Hola " + a + " " + b + '!\n'+ " Bienvenido a IABD"

with gr.Blocks() as demo:  
    txtIn1 = gr.Textbox(label="Nombre", lines=2)
    txtIn2 = gr.Textbox(label="Apellidos")
    txtOut = gr.Textbox(value="", label="Salida")
    btn = gr.Button(value="Enviar")

    btn.click(combinar, inputs=[txtIn1, txtIn2], outputs=[txtOut])

demo.launch()

Y su resultado sería:

Componente Button
Componente Button

Checkbox

Cuando tenemos varios valores para elegir, podemos utilizar un gradio.Checkbox() o un gradio.CheckboxGroup() para mostrar una caja con las opciones posibles:

gradio-checkbox.py
import gradio as gr

def crearFrase(tipo, listaActividades):
    return f"Se agradece un café {"cargado" if tipo else "suave"} acompañado de {" y ".join(listaActividades)}"

demo = gr.Interface(
    crearFrase,
    [
        gr.Checkbox(label="Cargado"),
        gr.CheckboxGroup(label="Café con...", choices=["tostadas", "galletas", "magdalenas", "las noticias"]),
    ],
    "text")

demo.launch()

Y su resultado sería:

Componentes Checkbox
Componentes Checkbox

Fechas

Podemos utilizar el componente gradio.DateTime para mostrar un componente que muestre la fecha.

gradio-datetime.py
import gradio as gr

with gr.Blocks() as demo:
    gr.DateTime()
    gr.DateTime(label="Solo fecha", include_time=False)

demo.launch()

Slider

Mediante gradio.Slider() crearemos un deslizador entre un rango de valores con un tamaño de pasos. La posición por defecto la indicaremos mediante el valor.

En el siguiente ejemplo, combinamos los componentes vistos anteriormente con un deslizador y un campo de tipo fecha:

gradio-slider.py
import gradio as gr
import time

def crearFrase(fecha, cantidad, tipo, listaActividades):
    return f"A las {cantidad} me {"tomé" if fecha < time.time() else "tomaré"} un café {"cargado" if tipo else "suave"} acompañado de {" y ".join(listaActividades)}"

demo = gr.Interface(
    crearFrase,
    [
        gr.DateTime(label="Fecha...", include_time=False),
        gr.Slider(label="Hora...", minimum=2, maximum=24, value=8, step=2),
        gr.Checkbox(label="Cargado"),
        gr.CheckboxGroup(label="Café con...", choices=["tostadas", "galletas", "magdalenas", "las noticias"])
    ],
    "text")

demo.launch()

Desplegable

Mediante gradio.Dropdown() podemos indicar un elemento de una lista de posibilidades mediante un componente desplegable:

gradio-dropdown
import gradio as gr
import time

def crearFrase(fecha, cantidad, tipo, listaActividades, media):
    return f"A las {cantidad} me {"tomé" if fecha < time.time() else "tomaré"} un café {"cargado" if tipo else "suave"} acompañado de {" y ".join(listaActividades)} o ver {media}"

demo = gr.Interface(
    crearFrase,
    [
        gr.DateTime(label="Fecha...", value="now", include_time=False),
        gr.Slider(label="Hora...", minimum=2, maximum=24, value=8, step=2),
        gr.Checkbox(label="Cargado"),
        gr.CheckboxGroup(label="Café con...", choices=["tostadas", "galletas", "magdalenas", "las noticias"]),
        gr.Dropdown(["una serie", "una película", "un documental", "un concierto"])
    ],
    "text")

demo.launch()
Componentes Slider, DateTime y Dropdown
Componentes Slider, DateTime y Dropdown

Más componentes

Como puedes imaginar, hay muchos más componentes que puedes consultar en la documentación oficial.

Flagging

Gradio nos permite marcar las ejecuciones (flag) para recopilar datos sobre los usuarios que utilizan nuestras aplicaciones o modelos, especialmente puntos de datos en los que la aplicación se comporta de forma inesperada.

Para ello, en toda interfaz aparece el botón Flag, con el cual el usuario puede enviar datos al lugar donde se está ejecutando la aplicación.

Gradio permite cuatro parámetros en el componente gradio.Interface() que definen cómo funciona:

  • allow_flagging: por defecto está activo (si no queremos que aparezca el botón, lo ponemos a False)
  • flagging_options: listad de diferentes botones a mostrar
  • flagging_dir: indica donde se almacenan los datos de las ejecuciones
  • flagging_callback: función a invocar al pulsar sobre cada flag.

Veamos su uso con un ejemplo de una calculadora:

gradio-flagging.py
import gradio as gr

def calcula(num1, operacion, num2):
    if operacion == "suma":
        return num1 + num2
    elif operacion == "resta":
        return num1 - num2
    elif operacion == "producto":
        return num1 * num2
    elif operacion == "división":
        return num1 / num2


demo = gr.Interface(
    calcula,
    ["number", gr.Radio(["suma", "resta", "producto", "división"]), "number"],
    "number",
    flagging_mode="manual",
    flagging_options=["signo incorrecto", "división por cero", "otro"]
)

demo.launch()

En la siguiente imagen podéis observar cómo se visualizan diferentes botones para marcar las ejecuciones, con las etiquetas marcadas en el parámetro flagging_options:

Flagging en Gradio
Flagging en Gradio

Si probamos diferentes operaciones, veremos que nos crea el archivo .gradio/flagged/output/dataset1.csv con los valores de entrada marcados, la salida, el botón pulsado y el timestamp:

dataset1.csv
num1,operacion,num2,output,flag,timestamp
3,resta,'-2,5,división por cero,2024-10-13 19:12:45.842902
3,división,2.234532414213453e+63,1.3425627576120835e-63,otro,2024-10-13 19:13:06.604335

Preparando datos

Añadir ejemplos a un Gradio es tan fácil como proporcionar una lista de listas con el parámetro examples. Cada sublista es una muestra de datos, donde cada elemento corresponde a una entrada de la función de predicción. Las entradas deben estar ordenadas en el mismo orden en que las espera la función de predicción.

Si nuestro interfaz sólo tiene un componente de entrada, podemos proporcionar los ejemplos como una lista normal en lugar de una lista de listas:

gradio-examples.py
import gradio as gr

def saluda(nombre):
    return "Hola " + nombre + "!"

demo = gr.Interface(fn=saluda, inputs="text", outputs="text", examples=["Aitor", "IABD", "¿Qué tal?"])
demo.launch()

Como puede observarse, los ejemplos se muestran en la parte inferior de los componentes de entrada:

Datos de ejemplo como entradas en Gradio
Datos de ejemplo como entradas en Gradio

Desde una carpeta

También podemos especificar una ruta a un directorio que contenga los ejemplos. Si nuestro interfaz sólo acepta un único tipo de archivo de entrada, por ejemplo, un clasificador de imágenes, simplemente pasaremos la ruta de un directorio al argumento examples, y la interfaz cargará las imágenes del directorio como ejemplos. En el caso de entradas múltiples, este directorio debe contener un archivo log.csv con los valores de los ejemplos.

En el contexto de la demo de la calculadora vista en el apartado anterior, podemos establecer examples='/demo/examples' y en ese directorio incluimos el siguiente fichero log.csv:

log.csv
num1,operacion,num2
5,"suma",3
4,"producto",2
5,"resta",3

Referencias

Actividades

  1. (RAPIA.3 / CEPIA.3b, CEPIA.3c / 2p) Mediante Gradio y a partir de la siguiente imagen, crea el interfaz de usuario del prototipo para probar el proyecto Lara:

    Gradio de Lara
    Gradio de Lara

    Debes tener en cuenta que como entradas tienes que configurar tanto un fichero de sonido, como un desplegable con diferentes nombres de modelos, y como salida, una caja de texto.

    En sesiones posteriores introduciremos el modelo Whisper para transcribir de audios a texto y hacer el prototipo funcional. Por lo tanto, en esta actividad sólo necesitamos crear el interfaz gráfico.

  2. (RAPIA.3 / CEPIA.3b, CEPIA.3c / 2p) Crea un prototipo mediante Gradio haciendo uso de Blocks que permita traducir entre dos idiomas (por ejemplo, de castellano a inglés y viceversa), haciendo uso de algún control que te facilite decidir el sentido de la traducción (y por tanto el modelo a emplear). Para ello, emplea los modelos opus-mt-xx-yy de traducción que necesites de Helsinki-NLP.

  3. (RAPIA.3 / CEPIA.3b, CEPIA.3c, CEPIA.3d / opcional) Investiga como puedes añadir una autenticación básica a Gradio, y modifica tu prototipo de traductor para permitir su uso únicamente al usuario iabd y contraseña iabd.