#
Comprendre la classe Interface

Dans cette section, nous allons examiner de plus près la classe `Interface`, et comprendre les principaux paramètres utilisés pour en créer une.

##
Comment créer une interface

Vous remarquerez que la classe `Interface` a 3 paramètres obligatoires :

`Interface(fn, inputs, outputs, ...)`

Ces paramètres sont :

- `fn`: la fonction de prédiction qui est enveloppée par l’interface Gradio. Cette fonction peut prendre un ou plusieurs paramètres et retourner une ou plusieurs valeurs.
- `inputs`: le(s) type(s) de composant(s) d’entrée. Gradio fournit de nombreux composants préconstruits tels que`"image"` ou `"mic"`.
- `outputs`: le(s) type(s) de composant(s) de sortie. Encore une fois, Gradio fournit de nombreux composants pré-construits, par ex. `"image"` ou `"label"`.

Pour une liste complète des composants, jetez un coup d’œil à la documentation de Gradio. Chaque composant préconstruit peut être personnalisé en instanciant la classe correspondant au composant.

Par exemple, comme nous l’avons vu dans la section précédente, au lieu de passer le paramètre `inputs` par `"textbox"`, vous pouvez passer un composant `Textbox(lines=7, label="Prompt")` pour créer une zone de texte avec 7 lignes et un label.

Voyons un autre exemple, cette fois avec un composant `Audio`.

##
Un exemple simple avec audio

Comme mentionné précédemment, Gradio fournit de nombreuses entrées et sorties différentes. Construisons donc une `Interface` qui fonctionne avec l’audio.

Dans cet exemple, nous allons construire une fonction audio-vers-audio qui prend un fichier audio et l’inverse simplement.

Nous utiliserons comme entrée le composant `Audio`. Lorsque vous utilisez le composant `Audio`, vous pouvez spécifier si vous voulez que la `source` de l’audio soit un fichier que l’utilisateur télécharge ou un microphone avec lequel l’utilisateur enregistre sa voix. Dans ce cas, nous allons choisir un microphone. Juste pour le plaisir, nous allons ajouter une étiquette à notre `Audio` qui dit « Speak here… » (Parler ici).

De plus, nous aimerions recevoir l’audio sous la forme d’un tableau numpy afin de pouvoir facilement l’inverser. Nous allons donc définir le `"type"` comme étant `"numpy"`, ce qui permet de passer les données d’entrée comme un tuple de (`sample_rate`, `data`) dans notre fonction.

Nous utiliserons également le composant de sortie `Audio` qui peut automatiquement rendre un tuple avec un taux d’échantillonnage et un tableau numpy de données comme un fichier audio lisible. Dans ce cas, nous n’avons pas besoin de faire de personnalisation, donc nous utiliserons le raccourci de la chaîne `"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()

Le code ci-dessus produira une interface comme celle qui suit (si votre navigateur ne vous demande pas l’autorisation pour accéder au microphone, ouvrez la démo dans un onglet séparé).

Vous devriez maintenant être capable d’enregistrer votre voix et de vous entendre parler à l’envers. Effrayant 👻 !

##
Gérer les entrées et sorties multiples

Imaginons que nous ayons une fonction plus compliquée, avec plusieurs entrées et sorties. Dans l’exemple ci-dessous, nous avons une fonction qui prend un index de liste déroulante, une valeur de curseur et un nombre, et renvoie un échantillon audio d’une tonalité musicale.

Regardez comment nous passons une liste de composants d’entrée et de sortie, et voyez si vous pouvez suivre ce qui se passe.

La clé ici est que lorsque vous passez :

- une liste de composants d’entrée, chaque composant correspond à un paramètre dans l’ordre.
- une liste de composants de sortie, chaque composant correspond à une valeur retournée.

L’extrait de code ci-dessous montre comment trois composants d’entrée correspondent aux trois arguments de la fonction `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()

###
La méthode `launch()`

Jusqu’à présent, nous avons utilisé la méthode `launch()` pour lancer l’interface, mais nous n’avons pas vraiment discuté de ce qu’elle fait.

Par défaut, la méthode `launch()` lancera la démo dans un serveur web qui tourne localement. Si vous exécutez votre code dans un notebook Jupyter ou Colab, Gradio va intégrer l’interface graphique de la démo dans le notebook afin que vous puissiez l’utiliser facilement.

Vous pouvez personnaliser le comportement de `launch()` à travers différents paramètres :

- `inline` : si vous voulez afficher l’interface en ligne sur les notebooks Python.
- `inbrowser` : pour lancer automatiquement l’interface dans un nouvel onglet du navigateur par défaut.
- `share` : si vous voulez créer un lien public partageable depuis votre ordinateur pour l’interface. Un peu comme un lien Google Drive !

Nous couvrirons le paramètre `share` plus en détail dans la section suivante !

##
✏️ Appliquons ça !

Construisons une interface qui vous permette de faire la démonstration d’un modèle de reconnaissance vocale. Pour rendre la chose intéressante, nous accepterons soit une entrée micro, soit un fichier téléchargé.

Comme d’habitude, nous allons charger notre modèle de reconnaissance vocale en utilisant la fonction `pipeline()` de 🤗 Transformers. Si vous avez besoin d’un rafraîchissement rapide, vous pouvez revenir à cette section du chapitre 1. Ensuite, nous allons implémenter une fonction `transcribe_audio()` qui traite l’audio et retourne la transcription (en anglais). Enfin, nous allons envelopper cette fonction dans une `Interface` avec les composants `Audio` pour les entrées et juste le texte pour la sortie. Au total, le code de cette application est le suivant :

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

Si votre navigateur ne vous demande pas l’autorisation pour accéder au microphone, ouvrez la démo dans un onglet séparé.

Voilà, c’est fait ! Vous pouvez maintenant utiliser cette interface pour transcrire de l’audio. Remarquez ici qu’en passant le paramètre `optional` à `True`, nous permettons à l’utilisateur de soit fournir un microphone ou un fichier audio (ou aucun des deux, mais cela retournera un message d’erreur).

Continuez pour voir comment partager votre interface avec d’autres !