Cours
L’utilité des modèles d’IA actuels est fortement limitée sans interfaces utilisateur accessibles. Avec Gradio, une bibliothèque open source de web UI pour Python, vous pouvez combler l’écart entre les LLM et les utilisateurs finaux non techniques. Elle vous permet de créer rapidement des prototypes pour vos projets d’IA et d’en simplifier le déploiement auprès d’un public plus large.
Ce tutoriel s’adresse aux ingénieurs en apprentissage automatique qui n’ont en général aucune expérience en développement web. Il couvre les bases et concepts clés de Gradio, la création d’interfaces pour différents types de modèles d’IA, des fonctionnalités avancées pour l’UX et l’interactivité, ainsi que les bonnes pratiques de déploiement et de partage.
C’est parti.
Premiers pas avec Gradio
Installation
Nous allons commencer par créer un environnement virtuel (de préférence Conda) :
$ conda create -n gradio_tutorial python=3.9 -y
$ conda activate gradio_tutorial
Ensuite, utilisez PIP pour installer Gradio et ses dépendances :
$ pip install gradio ipykernel
Nous avons également installé le paquet ipykernel afin d’afficher des interfaces Gradio directement dans les notebooks Jupyter. Ce processus nécessite d’ajouter l’environnement virtuel créé comme noyau dans Jupyter Lab. Voici la commande à exécuter :
$ ipython kernel install --user --name=gradio_tutorial
$ jupyter lab # Start the lab
Vous pouvez ainsi créer un notebook avec un noyau où Gradio est installé. Pour vérifier, importez-le sous son alias standard et affichez sa version :
import gradio as gr
print(gr.__version__)
4.37.1
Concepts et terminologie de base
Plongeons dans Gradio en apprenant ses notions clés via un exemple « Hello World » :
def greet(name):
return f"Hello, {name}!"
demo = gr.Interface(
fn=greet,
inputs=['text'],
outputs="text",
)
demo.launch()
En exécutant ce code dans une cellule, vous obtenez une petite interface interactive qui renvoie un message d’accueil personnalisé :

Gradio s’articule autour de quelques concepts clés :
- Interface : la classe centrale pour créer des UI.
- Composants : éléments d’entrée et de sortie comme des zones de texte, des images et de l’audio. Il existe aujourd’hui plus de 30 composants intégrés.
- Fonctions : fonctions Python qui traitent les informations issues des composants d’entrée et retournent les résultats à afficher via les composants de sortie.
- Launch : la méthode pour démarrer votre application Gradio.
Ci-dessus, nous avons créé une fonction greet qui prend un texte en entrée et renvoie un texte en sortie. C’est pourquoi les composants d’entrée et de sortie sont spécifiés comme text dans la classe Interface.
Enfin, nous appelons la méthode launch, qui démarre un serveur local. Pour rendre l’interface accessible à tous, vous pouvez définir le paramètre share à True. Cela ouvre un tunnel SSH et déploie l’application Gradio sur une page web publique partageable :
demo.launch(share=True)
Running on public URL: https://d638ed5f2ce0044296.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)
Composants Gradio
Lors de la création d’applications Gradio, vous passerez l’essentiel de votre temps à explorer les composants et leur disposition sur la page. Voyons de plus près ce dont vous disposez.
Composants d’entrée et de sortie
Gradio propose un large éventail de composants pour construire des interfaces interactives. Ces composants se répartissent généralement en deux catégories : entrée et sortie.
Les composants d’entrée permettent aux utilisateurs de fournir des données au processeur sous-jacent (il peut s’agir de n’importe quelle fonction Python). Parmi les entrées les plus courantes :
- Textbox
- Image
- Audio
- Slider
- Dropdown
Voici une interface factice qui utilise certains des composants ci-dessus :
def process_inputs(text, image, audio, number, option):
# Process inputs and return results
return f"Processed: {text}, {number}, {option}"
demo = gr.Interface(
fn=process_inputs,
inputs=[
gr.Textbox(label="Enter text"),
gr.Image(label="Upload image"),
gr.Audio(label="Upload audio"), # Uncomment this line to add audio input
gr.Slider(0, 100, label="Choose a number"),
gr.Dropdown(["Streamlit", "Taipy", "Gradio"], label="Select a UI library"),
],
outputs="text",
)
demo.launch()
Dans cet exemple, la fonction process_inputs attend cinq paramètres. Nous devons donc créer cinq composants d’entrée et les passer à inputs. Si le nombre de composants d’entrée doit correspondre au nombre de paramètres requis par la fonction, ce n’est pas une règle absolue. Pour éviter erreurs et avertissements, définissez des valeurs par défaut pour les paramètres qui ne nécessitent pas d’entrée utilisateur via l’UI.

Remarquez que nous utilisons la classe Textbox pour définir le composant d’entrée plutôt qu’une simple chaîne text comme dans le premier exemple. Il est recommandé d’utiliser les classes dédiées pour définir les composants d’entrée et de sortie afin de pouvoir les personnaliser. Par exemple, toutes les classes de composants disposent d’un attribut utile label, tandis que Slider et Dropdown proposent des arguments pour définir la plage et les options disponibles.
Beaucoup de composants d’entrée peuvent aussi servir à afficher la sortie. Voici des cas courants :
- Label : pour afficher du texte ou des résultats de classification
- Image : pour montrer des images traitées ou générées
- Audio : pour lire de l’audio traité ou généré
- Plot : pour afficher des graphiques
Comme pour les entrées, le nombre de composants de sortie doit correspondre au nombre de valeurs renvoyées par la fonction de traitement.
Personnaliser l’apparence des composants
Gradio vous permet d’adapter l’apparence de vos composants à vos besoins. Voici un exemple avec des zones de texte personnalisées :
demo = gr.Interface(
fn=lambda x: int(x) ** 7,
inputs=gr.Textbox(
lines=5,
placeholder="Enter any number...",
label="Custom textbox",
info="This is a customized textbox component to raise any number to the power of 7.",
),
outputs=gr.Textbox(label="And the number is...", show_copy_button=True),
)
demo.launch()

Dans cet exemple, nous avons personnalisé les composants Textbox en définissant le nombre de lignes, un texte d’espace réservé et d’info, et en ajoutant un bouton de copie pour la sortie.
Expérimentez différents composants et leurs propriétés pour créer des interfaces adaptées aux exigences de votre application d’IA. Pour connaître les propriétés modifiables d’un composant, consultez sa documentation, ou mieux encore, utilisez l’opérateur ? dans Jupyter Lab après le nom de sa classe :

Créer des interfaces pour les LLM
Mettons en pratique ce que nous avons vu en créant deux interfaces réelles basées sur du texte et sur l’image, propulsées par des LLM.
Nous allons d’abord bâtir un traducteur de l’anglais vers le turc, l’espagnol ou le chinois :
import openai # pip install openai
def translate_text(api_key, text, target_language):
openai.api_key = api_key # Set openai API key
language_map = {
"Turkish": "Turkish",
"Spanish": "Spanish",
"Chinese": "Chinese (Simplified)",
}
prompt = f"Translate the following English text to {language_map[target_language]}:\n\nEnglish: {text}\n\n{target_language} translation:"
try:
response = openai.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "You are a professional translator."},
{"role": "user", "content": prompt},
],
)
translation = response.choices[0].message.content.strip()
return translation
except Exception as e:
return f"Error: {str(e)}"
Nous définissons d’abord une fonction translate_text. En son sein, nous configurons la clé d’API OpenAI et créons une table de correspondance des langues. Puis nous construisons l’invite de traduction. Ensuite, dans un bloc try-except, nous envoyons une requête au point de terminaison ChatCompletion avec un message système. Enfin, nous renvoyons le premier choix.
Nous pouvons maintenant construire l’interface :
iface = gr.Interface(
fn=translate_text,
inputs=[
gr.Textbox(
placeholder="Enter your OpenAI API key",
type="password",
label="OpenAI API Key",
),
gr.Textbox(
lines=4,
placeholder="Enter English text to translate...",
label="English Text",
),
gr.Dropdown(choices=["Turkish", "Spanish", "Chinese"], label="Target Language"),
],
outputs=gr.Textbox(label="Translation", show_copy_button=True),
title="English to Turkish/Spanish/Chinese Translator",
description="Translate English text to Turkish, Spanish, or Chinese using OpenAI's GPT-4 model. Enter your OpenAI API key, the text you want to translate, and select the target language.",
)
iface.launch(share=True)
Le code reste simple, comme dans les interfaces précédentes, mais nous introduisons deux nouvelles propriétés :
- L’argument type des zones de texte transforme le champ texte en champ mot de passe et masque la saisie.
- Les arguments title et description de la classe Interface ajoutent un titre H1 et un sous-titre en haut de la page.
Voici le résultat :

Vous vous demandez peut-être pourquoi nous demandons la clé d’API de l’utilisateur dans l’application plutôt que de fournir la nôtre. La raison tient à la façon dont Gradio déploie les interfaces.
Si nous fournissions notre propre clé d’API via une variable d’environnement (pratique standard), la version publique partageable de l’application ne fonctionnerait pas, car elle n’y aurait pas accès. Dans la section déploiement, nous verrons comment résoudre cela en hébergeant nos apps sur les Spaces de HuggingFace.
Créons maintenant une autre interface pour générer des images :
def generate_surrealist_art(api_key, prompt):
surrealist_prompt = f"Create a surrealist artwork based on the following concept: {prompt}. The artwork should be dreamlike, with unexpected juxtapositions and a sense of the uncanny."
client = OpenAI(api_key=api_key)
response = client.images.generate(
model="dall-e-3",
prompt=surrealist_prompt,
size="1024x1024",
)
image_url = response.data[0].url
return image_url
Nous créons une fonction nommée generate_surrealist_art qui envoie une requête à dall-e-3 et renvoie l’URL de l’image générée à partir d’une invite surréaliste. Nous passons ensuite cette fonction à une nouvelle instance de la classe Interface :
iface = gr.Interface(
fn=generate_surrealist_art,
inputs=[
gr.Textbox(
placeholder="Enter your OpenAI API key",
type="password",
label="OpenAI API Key",
),
gr.Textbox(
lines=2,
placeholder="Describe your surrealist concept...",
label="Concept Description",
),
],
outputs=gr.Image(value="str"),
title="Surrealist Artwork Generator",
description="Generate surrealist artwork based on your prompts using DALL-E. Enter your OpenAI API key and describe your concept.",
)
iface.launch(share=True)
Nous définissons deux entrées : la clé d’API et le concept à matérialiser en image surréaliste. Puis nous créons un composant de sortie pour l’image générée avec la classe Image. En définissant son argument value à str, le composant peut télécharger et afficher des images depuis des URL — exactement ce qu’il nous faut.
Et voici le résultat :

Créer des interfaces pour des modèles de ML classiques
Construisons maintenant une interface pour un modèle de régression tabulaire classique. Nous utiliserons le jeu de données Diamonds, disponible dans Seaborn.
Créez d’abord un nouveau répertoire de travail et un script nommé app.py à l’intérieur. Collez ensuite le code depuis ce gist GitHub qui charge les données, les traite avec un Pipeline Scikit-learn et entraîne un modèle RandomForestRegression.

L’étape suivante consiste à créer une fonction de traitement qui accepte autant d’entrées qu’il y a de variables dans le jeu de données Diamonds :
# Create the Gradio interface
def predict_price(carat, cut, color, clarity, depth, table, x, y, z):
input_data = pd.DataFrame(
{
"carat": [carat],
"cut": [cut],
"color": [color],
"clarity": [clarity],
"depth": [depth],
"table": [table],
"x": [x],
"y": [y],
"z": [z],
}
)
prediction = model.predict(input_data)[0]
return f"Predicted Price: ${prediction:.2f}"
La fonction convertit ces entrées en DataFrame et les passe à la méthode .predict() du pipeline de modèle entraîné. Enfin, elle renvoie une chaîne avec le prix prédit.
La classe Interface doit alors refléter la signature de cette fonction : neuf composants d’entrée pour les caractéristiques et un composant de sortie pour afficher le prix prédit :
iface = gr.Interface(
fn=predict_price,
inputs=[
gr.Slider(
minimum=diamonds["carat"].min(),
maximum=diamonds["carat"].max(),
label="Carat",
),
gr.Dropdown(["Fair", "Good", "Very Good", "Premium", "Ideal"], label="Cut"),
gr.Dropdown(["D", "E", "F", "G", "H", "I", "J"], label="Color"),
gr.Dropdown(
["I1", "SI2", "SI1", "VS2", "VS1", "VVS2", "VVS1", "IF"], label="Clarity"
),
gr.Slider(
minimum=diamonds["depth"].min(),
maximum=diamonds["depth"].max(),
label="Depth",
),
gr.Slider(
minimum=diamonds["table"].min(),
maximum=diamonds["table"].max(),
label="Table",
),
gr.Slider(minimum=diamonds["x"].min(), maximum=diamonds["x"].max(), label="X"),
gr.Slider(minimum=diamonds["y"].min(), maximum=diamonds["y"].max(), label="Y"),
gr.Slider(minimum=diamonds["z"].min(), maximum=diamonds["z"].max(), label="Z"),
],
outputs="text",
title="Diamond Price Predictor",
description="Enter the characteristics of a diamond to predict its price.",
)
iface.launch(share=True)
Dans la classe, nous créons trois menus déroulants pour les variables catégorielles. Les options sont remplies avec les catégories uniques de chaque variable. Nous créons également six curseurs pour les variables numériques. Les plages des curseurs sont déterminées par les valeurs minimale et maximale de chaque variable.
Il ne reste plus qu’à exécuter le script pour lancer et déployer l’application :
$ python app.py
Voici le résultat :

Pour les bonnes pratiques et conseils d’optimisation, rendez-vous directement à la section Bonnes pratiques ci-dessous.
Déployer des applications Gradio
Nous avons déjà vu à quel point il est facile de déployer des apps Gradio en activant un seul argument. L’inconvénient de cette méthode est toutefois que les démos expirent au bout de 72 heures. La méthode recommandée consiste donc à déployer via HuggingFace Spaces. HuggingFace a acquis Gradio en 2021, rendant l’intégration entre les deux plateformes très fluide.
Pour ce tutoriel, ou pour toute application future créée avec Gradio, inscrivez-vous à un compte gratuit sur huggingface.co puis allez dans Settings > Tokens pour générer un jeton d’accès :

Le jeton n’apparaît qu’une seule fois, veillez donc à le conserver en lieu sûr.
Avec ce jeton, vous pouvez déployer autant d’applications Gradio que vous le souhaitez avec un hébergement permanent sur Spaces. À titre d’exemple, nous allons déployer le modèle de prédiction du prix des diamants de la section précédente — vous verrez, c’est étonnamment simple.
Il vous suffit d’ouvrir le répertoire contenant le script d’interface et d’exécuter gradio deploy dans le terminal :

L’assistant en ligne de commande vous guide pour convertir votre script en un Space fonctionnel sur HuggingFace. Il vous demande notamment :
- Le jeton d’accès que vous avez généré
- Le titre du Space : il fera partie de l’URL après déploiement
- Le nom du script contenant le code de l’UI Gradio (app.py par défaut)
- Le matériel du Space ; laissez vide pour n’utiliser que des CPU (gratuit)
- Les variables d’environnement utilisées par le script (endroit sûr pour stocker les clés d’API et secrets)
- Les dépendances — saisissez-les une par une en appuyant sur Entrée
Vous obtenez ensuite un lien vers le Space déployé. Voici à quoi cela ressemble :

Autre avantage de cette méthode de déploiement : Gradio convertit automatiquement la démo en API REST opérationnelle. Les instructions d’accès et d’appel sont toujours disponibles en bas de page :

En une seule opération, vous disposez donc à la fois d’un hébergement UI permanent pour vos utilisateurs non techniques et d’une API REST pour vos collègues et amis développeurs.
Pour plus d’options de déploiement et de partage, comme l’intégration de démos dans des pages web, l’ajout d’une authentification Google, etc., consultez la section « Sharing Your App » de la documentation Gradio.
Bonnes pratiques et conseils Gradio
En développant des interfaces avec Gradio, suivre des bonnes pratiques améliore nettement l’expérience utilisateur et la maintenabilité de votre application. Voici quelques recommandations clés :
1. Utiliser des scripts pour l’organisation et la maintenabilité
Organisez vos applications Gradio dans des scripts Python pour faciliter le contrôle de version, la collaboration et le déploiement.
2. Optimiser l’allocation de l’espace pour les composants
Utilisez des outils de dimensionnement et de mise en page adaptés (par ex. gr.Column(), gr.Row()) pour garantir une interface équilibrée et responsive.
3. Fournir des informations complètes
Exploitez les attributs « info » et « label » pour donner des consignes claires et du contexte à chaque composant.
4. Gérer efficacement de grands ensembles de variables
Pour les modèles à nombreuses variables, utilisez des entrées de fichiers (CSV, JSON) afin d’activer des prédictions par lot et de simplifier l’interface.
5. Gérer correctement les variables d’environnement
Utilisez python-dotenv en local et définissez les variables dans Hugging Face Spaces lors du déploiement.
6. Implémenter la gestion des erreurs et la validation
Validez les entrées, fournissez des messages d’erreur clairs et utilisez des blocs try-except pour gérer les erreurs avec élégance.
7. Optimiser les performances
Mettez en place du caching, le chargement paresseux pour les gros modèles et utilisez gr.LoadingStatus() pour les tâches longues.
8. Concevoir pour l’accessibilité
Assurez un contraste élevé, fournissez du texte alternatif pour les images et permettez la navigation au clavier pour tous les éléments interactifs.
9. Mettre en œuvre une divulgation progressive
Utilisez des accordéons ou des onglets pour organiser les interfaces complexes et dévoiler les options avancées au besoin.
10. Mettre à jour et maintenir régulièrement
Tenez les dépendances à jour, surveillez les bugs et améliorez en continu sur la base des retours utilisateurs.
11. Tirer parti des ressources HuggingFace
Exploitez les outils et ressources HuggingFace pour une intégration fluide avec Gradio, notamment les dépôts de modèles et les jeux de données.
12. Héberger de grands modèles sur HuggingFace Hub
Pour les grands modèles tabulaires, chargez-les sur HuggingFace Hub et importez-les directement dans votre script Gradio pour améliorer les performances et réduire le stockage local.
13. Utiliser les jeux de données HuggingFace
Pour les gros jeux de données, importez-les sur HuggingFace Hub et accédez-y directement dans votre application Gradio afin de simplifier la gestion et d’accélérer le chargement.
Conclusion et ressources complémentaires
Dans cet article, nous avons vu les bases de la création d’interfaces utilisateur pour des applications d’IA avec Gradio. Nous n’avons fait qu’effleurer le sujet, car Gradio offre bien d’autres fonctionnalités pour bâtir des interfaces complexes. Par exemple, interface state permet à votre app de mémoriser des sorties d’un appel de fonction à l’autre. Les interfaces réactives modifient dynamiquement l’UI dès que l’entrée utilisateur change. Avec les Blocks, vous pouvez créer des apps avec des mises en page et des designs personnalisés.
Dans le même esprit, découvrez ces ressources associées pour aller plus loin :