Capire la classe Interface
In questa sezione, daremo un’occhiata più da vicino alla classe Interface
e scopriremo i
parametri principali che si usano per crearne una.
Come creare una Interface
Si può notare che la classe Interface
(interfaccia) ha 3 parametri necessari:
Interface(fn, inputs, outputs, ...)
Questi parametri sono:
fn
: la funzione per le predizione chi viene utilizzata dall’interfaccia di Gradio. Questa funzione può accettare uno o più parametri e restituire uno o più valoriinputs
: il/i tipo/i dei componenti in input. Gradio fornisce molti componenti predefiniti, come"image"
(immagine) o"mic"
(microfono).outputs
: il/i tipo/i dei componenti in output. Anche in questo caso, Gradio fornisce molti componenti predefiniti, come"image"
o"label"
.
Per un elenco completo dei componenti, consultare la documentazione di Gradio. Ogni componente predefinito può essere personalizzato istanziando la classe corrispondente al componente.
Ad esempio, come abbiamo visto nella sezione precedente,
invece di passare "textbox"
al parametro inputs
, si può passare un componente Textbox(lines=7, label="Prompt")
per creare una casella di testo con 7 righe e un’etichetta.
Diamo un’occhiata a un altro esempio, questa volta con un componente Audio
.
Un semplice esempio con l’audio
Come detto in precedenza, Gradio fornisce molti input e output differenti.
Costruiamo perciò una Interface
che funziona con l’audio.
In questo esempio, svilupperemo una funzione da audio ad audio che prende un file audio e semplicemente lo inverte.
Per l’input utilizzeremo il componente Audio
. Quando si usa il componente Audio
,
si può specificare se si vuole che la source
(sorgente) dell’audio sia un file
caricato dall’utente o un microfono con cui l’utente può registrare la propria voce. In questo caso,
impostiamo "microphone"
. Per divertimento, aggiungeremo un’etichetta al nostro Audio
che dice
“Speak here…” (“Parla qui…”).
Inoltre, vorremmo ricevere l’audio come un numpy array, in modo da poterlo facilmente
“invertire”. Impostiamo quindi il "type"
come "numpy"
, che passa i dati in input
come una tupla di (sample_rate
, data
) alla nostra funzione.
Utilizzeremo anche il componente di output Audio
, il quale può convertire automaticamente
una tupla formata da una frequenza di campionamento e un numpy array di dati in un file audio riproducibile.
In questo caso, non abbiamo bisogno di fare alcuna personalizzazione, quindi useremo la stringa
"audio"
.
import numpy as np
import gradio as gr
def reverse_audio(audio):
sr, data = audio
reversed_audio = (sr, np.flipud(data))
return reversed_audio
mic = gr.Audio(source="microphone", type="numpy", label="Speak here...")
gr.Interface(reverse_audio, mic, "audio").launch()
Il codice precedente produrrà un’interfaccia come quella qui sotto (se il tuo browser non chiede il premesso per usare il microfono, apri il demo in una tab diversa.)
A questo punto potresti registrare la tua voce e di sentirti parlare al contrario - spaventoso 👻!
Lavorare con più input e output
Supponiamo di avere una funzione più complicata, con più input e output. Nell’esempio seguente, abbiamo una funzione che richiede un elenco a tendina, il valore di uno slider e un numero, e restituisce il campione audio di una nota musicale.
Osserva come si passa un elenco di componenti di input e di output, e vedi se riesci a seguire quello che succede.
La questione fondamentale è che quando si passa:
- un elenco di componenti di input, ogni componente corrisponde in ordine a un parametro.
- un elenco di componenti di output, ogni componente corrisponde a un valore restituito.
Lo snippet di codice qui sotto mostra come tre componenti di input si abbinano ai tre argomenti della funzione generate_tone()
:
import numpy as np
import gradio as gr
notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
def generate_tone(note, octave, duration):
sr = 48000
a4_freq, tones_from_a4 = 440, 12 * (octave - 4) + (note - 9)
frequency = a4_freq * 2 ** (tones_from_a4 / 12)
duration = int(duration)
audio = np.linspace(0, duration, duration * sr)
audio = (20000 * np.sin(audio * (2 * np.pi * frequency))).astype(np.int16)
return (sr, audio)
gr.Interface(
generate_tone,
[
gr.Dropdown(notes, type="index"),
gr.Slider(minimum=4, maximum=6, step=1),
gr.Textbox(type="number", value=1, label="Duration in seconds"),
],
"audio",
).launch()
Il metodo launch()
Per ora, abbiamo utilizzato il metodo launch()
per avviare l’interfaccia, ma
non abbiamo discusso realmente cosa fa.
Di default, il metodo launch()
avvia la demo in un web server che
che viene eseguito in locale. Se si esegue il codice in un Jupyter o Colab notebook,
Gradio incorporerà l’interfaccia grafica della demo nel notebook, così da poterla usare facilmente.
È possibile modificare il comportamento di launch()
attraverso diversi parametri:
inline
- per visualizzare l’interfaccia inline sui notebook di Python.inbrowser
- per avviare automaticamente l’interfaccia in una nuova scheda del browser di default.share
- per create un link pubblico per l’interfaccia da condividere dal proprio computer. Un po’ come un link di Google Drive!
Il parametro share
sarà trattato in modo molto più dettagliato nella prossima sezione!
✏️ Mettiamolo in pratica!
Costruiamo un’interfaccia che permetta di provare un modello di riconoscimento vocale. Per renderlo interessante, accetteremo un input qualisiasi tra un microfono o un file caricato.
Come al solito, caricheremo il nostro modello di riconoscimento vocale usando la funzione pipeline()
da 🤗 Transformers.
Se si ha bisogno di un ripasso veloce, si può tornare a quella sezione nel Capitolo 1. Quindi, implementeremo una funzione transcribe_audio()
che elabora l’audio e restituisce la sua trascrizione. Infine, avvolgeremo questa funzione in una Interface
con i componenti Audio
per gli input e solo testo per l’output. Il codice completo per questa applicazione è il seguente:
from transformers import pipeline
import gradio as gr
model = pipeline("automatic-speech-recognition")
def transcribe_audio(mic=None, file=None):
if mic is not None:
audio = mic
elif file is not None:
audio = file
else:
return "You must either provide a mic recording or a file"
transcription = model(audio)["text"]
return transcription
gr.Interface(
fn=transcribe_audio,
inputs=[
gr.Audio(source="microphone", type="filepath", optional=True),
gr.Audio(source="upload", type="filepath", optional=True),
],
outputs="text",
).launch()
Se il tuo browser non ti chiede i permessi per il microfono, apri la demo in una scheda separata.
Ecco fatto! Ora è possibile utilizzare questa interfaccia per trascrivere l’audio. Si osservi che
passando il parametro optional
come True
, si permette all’utente di
fornire o un microfono o un file audio (o nessuno dei due, ma questo restituirà un messaggio di errore).
Continua a leggere per scoprire come condividere la tua interfaccia con gli altri!