Gradio: applicazioni web in python per AI [parte 3]

Con Gradio è possibile creare applicazioni web per i nostri modelli di machine learning e AI in poche righe di codice. Mediante alcuni esempi, vedremo le funzionalità avanzate disponibili, quali l'autenticazione, il caching e l'elaborazione dei file in ingresso. Costruiremo anche un chatbot e un classificatore di immagini partendo da modelli pre-addestrati. Infine discuteremo come distribuire il nostro progetto in pochi semplici passi.

Share

Reading time: 6 minutes

Negli articoli precedenti, Gradio: applicazioni web in python per AI [parte1] e Gradio: applicazioni web in python per AI [parte2], abbiamo visto un’introduzione a Gradio e come personalizzare le nostre applicazioni per renderle più reattive e adatte alle nostre esigenze. In questo articolo affronteremo degli argomenti più avanzanti per completare il quadro delle funzionalità messe a disposizione dalla libreria. In particolare, vedremo come gestire la cache, il flagging, l’autenticazione, gli stati e il caricamento dei dati mediante file. Verranno anche mostrati due esempi di applicazioni reali per comprendere a pieno le potenzialità di Gradio. Infine, forniremo alcune informazioni su come distribuire i nostri progetti.

Configurazioni

Le applicazioni Gradio sono configurate nel processo launch(). Tuttavia, è possibile effettuare alcune configurazioni attraverso le variabili d’ambiente.

Per rendere l’applicazione accessibile sulla rete locale, è necessario impostare il valore “0.0.0.0” nel parametro server_name in gradio.Interface.launch() . Questo valore può essere impostato anche attraverso la variabile d’ambiente GRADIO_SERVER_NAME. Se non viene passato nessun parametro, verrà utilizzato il valore 127.0.0.1 per impostazione predefinita.

Flagging

Il flagging consente di raccogliere dati sugli utenti che utilizzano la vostra applicazione/modello, in particolare i punti in cui l’applicazione si comporta in modo inaspettato. Gradio dispone di un metodo di flagging semplice.

Includendo un pulsante Flag in ogni interfaccia, l’utente può inviare i dati alla posizione in cui l’applicazione è in esecuzione.

Gradio consente quattro parametri nel componente gradio.Interface() che definiscono il funzionamento del flagging. I parametri includono allow_flagging, flagging_options, flagging_dir e flagging_callback.

allow_flagging è manuale per impostazione predefinita e i campioni vengono contrassegnati quando l’utente fa clic sul pulsante Flag. È possibile utilizzare flagging_dir = “path/to/store”, specificando la directory per la memorizzazione dei dati di log. Altrimenti, i registri saranno memorizzati in una nuova cartella nella posizione in cui viene lanciata l’applicazione.

Possiamo aggiungere il flagging all’applicazione di visualizzazione Altair, come mostrato di seguito.

				
					import numpy as np
import pandas as pd

import gradio as gr
import altair as alt

from math import log
import numpy as np
import pandas as pd


def gdp_change(r, year, country, smoothen):
    years = ['1850', '1900', '1950', '2000', '2050']
    m = years.index(year)
    start_day = 1* m
    final_day = 1* (m + 1)
    x = np.arange(start_day, final_day + 1)
    pop_count = {"USA": 350, "Canada": 40, "Mexico": 300, "UK": 120}
    if smoothen:
        r = log(r)
    df = pd.DataFrame({'day': x})
    df[country] = ( x ** (r) * (pop_count[country] + 1))
    df['country'] = df[country].values

    return alt.Chart(df).mark_bar().encode(
            x='day',
            y= 'country').properties(width=550)

inputs = [
        gr.Slider(0.1, 1, 0.3,step = 0.001, label="R"),
        gr.Dropdown(['1850', '1900', '1950', '2000', '2050'], label="year"),
        gr.Radio(["USA", "Canada", "Mexico", "UK"], label="Countries", ),
        gr.Checkbox(label="Log of GDP Growth Rate?"),
    ]
outputs = gr.Plot()


demo = gr.Interface(fn=gdp_change, inputs=inputs, outputs=outputs, allow_flagging="manual", flagging_options=["No plot shown", "Wrong axis", "Other"])

demo.launch()

				
			

Per le opzioni dei parametri, consultare la documentazione di Gradio.

Caching

Ogni volta che l’applicazione viene aggiornata, si perderanno gli esempi dal server. È possibile specificare cache_examples = True nell’interfaccia principale di Gradio, cioè gradio.Interface() dopo aver definito gli esempi.

				
					import gradio as gra
def user_greeting(name):
    return "Hi! " + name + " Welcome to your first Gradio application!😎"

app =  gra.Interface(fn = user_greeting, inputs="text", outputs="text", examples = ["Zenith", "Antoinne", "Amelia", "Johanna"], cache_examples = True)
app.launch()

				
			

Autenticazione delle applicazioni

Quando si lancia un’applicazione Gradio, è possibile definire un metodo di autenticazione specificando il parametro auth. Se viene passato auth, saranno richiesti un nome utente e una password (o un elenco di tuple nome utente-password) per accedere all’interfaccia.

Si può anche aggiungere un auth_message per guidare l’utente su cosa includere.

				
					import gradio as gr

def data_display(input_img):
    return input_img

demo = gr.Interface(data_display, gr.Dataframe(), "matrix")
demo.launch(auth=("gradio", "test@1234"), auth_message="Try this")


				
			

Aggiungere lo stato alle applicazioni

La statefullness in Gradio può essere realizzata sia in stati globali che in stati di sessione.

Stato globale

Lo stato globale nei blocchi ha una funzionalità simile a quella dell’interfaccia. Qualsiasi variabile o dato definito al di fuori di una funzione è accessibile a tutte le funzioni.

Nell’esempio track_gdp qui sotto, la variabile gdps è condivisa da tutti gli utenti. Gli utenti che accedono all’applicazione vedranno i loro punteggi aggiunti all’elenco.

				
					import gradio as gr

gdps = []

def track_gdp(gdp):
    gdps.append(gdp)
    top_gdps = sorted(gdps, reverse=True)[:3]
    return top_gdps

demo = gr.Interface(
    track_gdp, 
    gr.Number(label="gdp"), 
    gr.JSON(label="Top gdps")
)
demo.launch()
				
			

Stato di sessione

Gradio supporta anche lo stato di sessione, in cui i dati persistono tra più invii all’interno di una sessione di pagina e nelle applicazioni a blocchi. Per lo stato di sessione:

 

  1. Definire un oggetto gradio.State().
  2. Inserire l’oggetto State nell’ascoltatore di eventi, come input e output.
  3. Nella funzione dell’event listener, includere la variabile nel parametro di input e nel valore di ritorno.

Per dimostrare lo stato di sessione di un’applicazione, utilizzeremo il gioco dell’impiccato.

				
					import gradio as gr
import random

secret_word = "machine"

with gr.Blocks() as demo:    
    used_letters_var = gr.State([])
    with gr.Row() as row:
        with gr.Column():
            input_letter = gr.Textbox(label="Enter letter")
            btn = gr.Button("Guess Letter")
        with gr.Column():
            hangman = gr.Textbox(
                label="Hangman",
                value="_"*len(secret_word)
            )
            used_letters_box = gr.Textbox(label="Used Letters")

    def guess_letter(letter, used_letters):
        used_letters.append(letter)
        answer = "".join([
            (letter if letter in used_letters else "_")
            for letter in secret_word
        ])
        return {
            used_letters_var: used_letters,
            used_letters_box: ", ".join(used_letters),
            hangman: answer
        }
    btn.click(
        guess_letter, 
        [input_letter, used_letters_var],
        [used_letters_var, used_letters_box, hangman]
        )
demo.launch()

				
			

Si noterà che la sessione persiste all’interno della pagina, ma se si carica l’app in una nuova scheda o si aggiorna l’applicazione, questa non condividerà la cronologia “indovinata”.

Caricamento ed elaborazione di file

Moltissime applicazioni richiedono che l’utente fornisca delle informazioni sotto forma di file. In Gradio è possibile caricare e visualizzare qualsiasi tipologia di file, oltre che elaborare in modo opportuno il loro contenuto.

Caricamento di un singolo file

Vediamo un esempio di caricamento di un’immagine.

				
					import numpy as np
import gradio as gr

def upload_image(input_img):

    return input_img

demo = gr.Interface(upload_image, gr.Image(width=400, height=300), "image")
demo.launch()
				
			

gradio.File() consente anche di caricare file generici come i file zip.

				
					from zipfile import ZipFile

import gradio as gr
from zipfile import ZipFile

def upload_file(file_obj):
    files = []
    with ZipFile(file_obj.name) as zfile:
        for zinfo in zfile.infolist():
            files.append(
                {
                    "name": zinfo.filename,
                }
            )
    return files


demo = gr.Interface(upload_file, "file", "json")

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

Caricamento di più file

Per caricare più file, aggiungere un parametro file_count, che specifica il numero di file che è possibile caricare in una singola sessione. In questo esempio creeremo un input per caricare più file che verranno utilizzati per creare un file zip.

				
					import os
from zipfile import ZipFile

import gradio as gr

def zip_files(files):
    with ZipFile("tmp.zip", "w") as zipObj:
        for idx, file in enumerate(files):
            zipObj.write(file.name, "file" + str(idx))
    return "tmp.zip"

demo = gr.Interface(
    zip_files,
    gr.File(file_count="multiple"),
    "file"
)

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

Caricamento ed elaborazione dei dati

Durante il caricamento dei file, è possibile definire una funzione che pre-elabora i dati e restituisce un output del file pre-elaborato. Ad esempio, è possibile modificare la tonalità dei dati delle immagini.

				
					import numpy as np
import gradio as gr

def sepia_hue(input_img):
    sepia_filter = np.array([[.393, .769, .189],
                         [.349, .686, .168],
                         [.272, .534, .131]])
    sepia_hue_img = input_img.dot(sepia_filter.T)
    sepia_hue_img /= sepia_hue_img.max()
    return sepia_hue_img

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

Costruire un classificatore di immagini

I transformers offrono API e strumenti per scaricare e addestrare rapidamente modelli pre-addestrati all’avanguardia. Come mostrato di seguito, è possibile creare facilmente un’applicazione di classificazione utilizzando i transformers per le immagini. Useremo un modello pre-addestrato da Google per classificare un paio di immagini.

				
					import gradio as gr
#load your preffered model
demo = gr.load("google/vit-base-patch16-224", src="huggingface")

#launch
demo.launch()
				
			

Per altri modelli di trasformatori, consultare la documentazione di Huggingface.

Utilizzare Huggingface per sviluppare un chatbot

La creazione di un chatbot è semplificata dall’uso dei modelli pre-addestrati di Hugging face. È necessario un tokenizer e un modello conversazionale pre-addestrato, come DialoGPT.

				
					from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
#set up the model (large version of DialoGPT)
tokenizer = AutoTokenizer.from_pretrained("microsoft/DialoGPT-large")
model = AutoModelForCausalLM.from_pretrained("microsoft/DialoGPT-large")

#Defining a predict function

def predict(input, history=[]):
    # tokenize the new input sentence
    new_user_input_ids = tokenizer.encode(input + tokenizer.eos_token, return_tensors='pt')

    # append the new user input tokens to the chat history
    bot_input_ids = torch.cat([torch.LongTensor(history), new_user_input_ids], dim=-1)

    # generate a response 
    history = model.generate(bot_input_ids, max_length=1000, pad_token_id=tokenizer.eos_token_id).tolist()

    # convert the tokens to text, and then split the responses into lines
    response = tokenizer.decode(history[0]).split("<|endoftext|>")
    response = [(response[i], response[i+1]) for i in range(0, len(response)-1, 2)]  # convert to tuples of list
    return response, history

#creating a gradio interface

import gradio as gr

demo = gr.Interface(fn=predict,
             inputs=["text", "state"],
             outputs=["chatbot", "state"])

demo.launch()
				
			

Distribuzione delle applicazioni

Il pacchetto Gradio semplifica la creazione di un’interfaccia grafica condivisibile e di un link pubblico per il modello. Questo è vero finché il modello viene eseguito nel vostro ambiente locale. Ma quando si ha bisogno di una soluzione ospitata a lungo termine, è necessario rivolgersi altrove.

È qui che entrano in gioco servizi di hosting come Heroku e HuggingFace spaces.

Heroku

La distribuzione di un’applicazione Gradio in Heroku segue cinque fasi:

  1. Creare l’applicazione (app.py) e memorizzarla in una nuova directory.
  2. Scrivere il file requirements.txt

Avrete bisogno, ovviamente, di un account Heroku e, facoltativamente, per comodità, della Heroku CLI. Create un account Heroku e scaricate la CLI, se non l’avete già fatto:

  1. Creare un file setup.sh. Affinché l’applicazione venga eseguita correttamente, assicurarsi che venga servita sull’URL e sulla porta corretti. Aggiungere export GRADIO_SERVER_NAME=0.0.0.0 e export GRADIO_SERVER_PORT=”$PORT” al file setup.sh.
  2. Creare un Procfile. Il file Procfile specifica i comandi da eseguire per avviare l’applicazione Gradio. Ci sono solo due comandi: l’esecuzione dello script bash e l’avvio dell’applicazione. Quindi il vostro Procfile Heroku assomiglia al web: source setup.sh && python app.py
  3. Distribuite! Una volta fatto questo, si può procedere con il consueto processo di deploy su Heroku.

Huggingface

Create un account utente su https://huggingface.co/. Andate su Spaces nella barra di navigazione e creare un nuovo spazio. Fornite tutte le informazioni necessarie.

A questo punto verrà creato un collegamento con un repo. Copiare il link nel prompt dei comandi. Ad esempio, potreste ottenere un collegamento come mostrato di seguito, ma potrebbe essere diverso a seconda dei vostri dettagli.

				
					git clone https://huggingface.co/spaces/alefiori82/Gradio_machine_learning
				
			

Verrà creata una nuova cartella (Gradio_machine_learning).

  1. Fate una copia dei file necessari per l’esecuzione dell’applicazione Gradio, come app.py, requirements.txt in questa nuova cartella.
  2. Nel terminale, eseguire i seguenti comandi, sostituendo i rispettivi nomi con quelli del proprio spazio di lavoro.
				
					cd Gradio_Machine_Learning
git add .
git commit -m "first commit"
git push
				
			

Verrà richiesto di inserire le credenziali di Huggingface. Se avete soddisfatto tutti i requisiti, andate nei vostri spazi e fate clic sul vostro spazio. Dovreste vedere l’applicazione in esecuzione.

More To Explore

Python

Pandas: analisi dati con Python [parte 1]

I data scientists necessitano continuamente di leggere, manipolare e analizzare i dati. In molti casi si utilizzano dei tools specifici, ma a volte è necessario sviluppare il proprio codice. Per far ciò la libreria Pandas ci viene in aiuto. Scopriamo le sue strutture dati, come possiamo leggere i dati da diversi fonti e manipolarli per ii nostri scopi.

Intelligenza artificiale

Gradio: applicazioni web in python per AI [parte 3]

Con Gradio è possibile creare applicazioni web per i nostri modelli di machine learning e AI in poche righe di codice. Mediante alcuni esempi, vedremo le funzionalità avanzate disponibili, quali l’autenticazione, il caching e l’elaborazione dei file in ingresso. Costruiremo anche un chatbot e un classificatore di immagini partendo da modelli pre-addestrati. Infine discuteremo come distribuire il nostro progetto in pochi semplici passi.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Progetta con MongoDB!!!

Acquista il nuovo libro che ti aiuterà a usare correttamente MongoDB per le tue applicazioni. Disponibile ora su Amazon!

Design with MongoDB

Design with MongoDB!!!

Buy the new book that will help you to use MongoDB correctly for your applications. Available now on Amazon!