diff --git a/chapters/en/chapter1/1.mdx b/chapters/en/chapter1/1.mdx index a2a11c2d9..c29d1fa5c 100644 --- a/chapters/en/chapter1/1.mdx +++ b/chapters/en/chapter1/1.mdx @@ -47,6 +47,8 @@ About the authors: [**Dawood Khan**](https://huggingface.co/dawoodkhan82) is a Machine Learning Engineer at Hugging Face. He's from NYC and graduated from New York University studying Computer Science. After working as an iOS Engineer for a few years, Dawood quit to start Gradio with his fellow co-founders. Gradio was eventually acquired by Hugging Face. +[Sasha Luccioni](https://huggingface.co/sasha) is a researcher at Hugging Face, where she works on the ethical and societal impacts of machine learning models. + [**Merve Noyan**](https://huggingface.co/merve) is a developer advocate at Hugging Face, working on developing tools and building content around them to democratize machine learning for everyone. [**Lucile Saulnier**](https://huggingface.co/SaulLu) is a machine learning engineer at Hugging Face, developing and supporting the use of open source tools. She is also actively involved in many research projects in the field of Natural Language Processing such as collaborative training and BigScience. diff --git a/chapters/fr/_toctree.yml b/chapters/fr/_toctree.yml index c042be25d..15742477a 100644 --- a/chapters/fr/_toctree.yml +++ b/chapters/fr/_toctree.yml @@ -190,6 +190,45 @@ title: Quiz de fin de chapitre quiz: 9 +- title: 10. Obtenir des jeux de données de grande qualité + new: true + subtitle: Comment utiliser Argilla pour créer des jeux de données exceptionnels ? + sections: + - local: chapter10/1 + title: Introduction à Argilla + - local: chapter10/2 + title: Configurez votre instance Argilla + - local: chapter10/3 + title: Chargez votre jeu de données dans Argilla + - local: chapter10/4 + title: Annoter votre jeu de données + - local: chapter10/5 + title: Utilisez votre jeu de données annoté + - local: chapter10/6 + title: Argilla, coché ! + - local: chapter10/7 + title: Quiz de fin de chapitre + quiz: 10 + +- title: 11. Finetuner des LLM + subtitle: Utiliser le finetuning supervisé et LoRA pour spécialiser un LLM + sections: + - local: chapter11/1 + title: Introduction + - local: chapter11/2 + title: Gabarits de chat + - local: chapter11/3 + title: Finetuning avec SFTTrainer + - local: chapter11/4 + title: LoRA (Low-Rank Adaptation) + - local: chapter11/5 + title: Évaluation + - local: chapter11/6 + title: Conclusion + - local: chapter11/7 + title: Examen ! + quiz: 11 + - title: Evènements liés au cours sections: - local: events/1 diff --git a/chapters/fr/chapter1/1.mdx b/chapters/fr/chapter1/1.mdx index c631bce23..4365d731f 100644 --- a/chapters/fr/chapter1/1.mdx +++ b/chapters/fr/chapter1/1.mdx @@ -46,6 +46,8 @@ Après avoir terminé ce cours, nous vous recommandons de suivre la [Spécialisa [**Dawood Khan**](https://huggingface.co/dawoodkhan82) est un ingénieur en apprentissage automatique chez Hugging Face. Il vient de New York et est diplômé en informatique de l’Université de New York. Après avoir travaillé comme ingénieur iOS pendant quelques années, Dawood a quitté son poste pour créer Gradio avec ses cofondateurs. Gradio a finalement été acquis par Hugging Face. +[Sasha Luccioni](https://huggingface.co/sasha) est chercheuse chez Hugging Face, où elle travaille sur les impacts éthiques et sociétaux des modèles d'apprentissage automatique. + [**Merve Noyan**](https://huggingface.co/merve) est développeuse *advocate* chez Hugging Face et travaille à la création d'outils et de contenus visant à démocratiser l'apprentissage machine pour tous. [**Lucile Saulnier**](https://huggingface.co/SaulLu) est ingénieure en apprentissage machine chez Hugging Face et travaille au développement et à l'implémentation de nombreux outils *open source*. Elle est également activement impliquée dans de nombreux projets de recherche dans le domaine du NLP comme l'entraînement collaboratif de modèles et le projet [BigScience](https://bigscience.huggingface.co/). diff --git a/chapters/fr/chapter10/1.mdx b/chapters/fr/chapter10/1.mdx new file mode 100644 index 000000000..3720b2ce3 --- /dev/null +++ b/chapters/fr/chapter10/1.mdx @@ -0,0 +1,26 @@ +# Introduction à Argilla[[introduction-to-argilla]] + + + +Dans le chapitre 5, vous avez appris à construire un jeu de données en utilisant la bibliothèque 🤗 Datasets et dans le chapitre 6, vous avez exploré comment finetuner modèles pour certaines tâches courantes de NLP. Dans ce chapitre, vous allez apprendre à utiliser [Argilla](https://argilla.io) pour **annoter et nettoyer des jeux de données** que vous pouvez utiliser pour entraîner et évaluer vos modèles. + +La clé pour entraîner des modèles performants est de disposer de données de haute qualité. Bien qu'il existe sur le Hub des jeux de données de qualité que vous pouvez utiliser pour entraîner et évaluer vos modèles, il se peut qu'ils ne soient pas pertinents pour votre application ou votre cas d'utilisation spécifique. Dans ce cas, vous voudrez peut-être construire votre propre jeu de données. Argilla vous aidera à le faire efficacement. + +Argilla sign in page. + +Avec Argilla, vous pouvez : + +- transformer des données non structurées en **données structurées** pour les utiliser dans des tâches de NLP. +- nettoyer un jeu de données pour passer d'un jeu de données de faible qualité à un jeu de données de **haute qualité**. +- recueillir des **retours humains** pour les LLM et les modèles multimodaux. +- inviter des experts à collaborer avec vous dans Argilla, ou crowdsourcer des annotations ! + +Voici quelques-unes des choses que vous apprendrez dans ce chapitre : + +- Comment configurer votre propre instance Argilla. +- Comment charger un jeu de données et le configurer en fonction de tâches de NLP populaires. +- Comment utiliser l'interface utilisateur d'Argilla pour annoter votre jeu de données. +- Comment utiliser votre jeu de données annoté et l'exporter vers le Hub. \ No newline at end of file diff --git a/chapters/fr/chapter10/2.mdx b/chapters/fr/chapter10/2.mdx new file mode 100644 index 000000000..a8d230f00 --- /dev/null +++ b/chapters/fr/chapter10/2.mdx @@ -0,0 +1,56 @@ +# Configurez votre instance Argilla[[set-up-your-argilla-instance]] + + + +Pour commencer à utiliser Argilla, vous devrez d'abord mettre en place votre propre instance. Ensuite, vous devrez installer le SDK Python afin de pouvoir gérer Argilla avec Python. + +## Déployer l'interface utilisateur d'Argilla + +La façon la plus simple de créer votre instance Argilla est de passer par Hugging Face Spaces. Pour créer votre Space Argilla, suivez simplement [ce formulaire](https://huggingface.co/new-space?template=argilla%2Fargilla-template-space). Si vous avez besoin de plus de conseils, consultez la page [« Argilla quickstart »](https://docs.argilla.io/latest/getting_started/quickstart/). +Space configuration form. + +>[!WARNING] +> ⚠️ Vous pouvez activer le **stockage persistant** pour que les données ne soient pas perdues si l'espace est interrompu ou redémarré. +> Vous pouvez le faire à partir des paramètres de votre Space. + +Une fois qu'Argilla est opérationnel, vous pouvez vous connecter avec vos identifiants. + +## Install and connect the Python SDK + +Vous pouvez maintenant aller dans votre environnement Python ou votre notebook et installer la bibliothèque argilla : +`!pip install argilla` + +Connectons-nous à notre instance Argilla. Pour ce faire, vous aurez besoin des informations suivantes : + +- **Votre URL API** : Il s'agit de l'URL où Argilla s'exécute. Si vous utilisez un Space, vous pouvez ouvrir le Space, cliquer sur les trois points dans le coin supérieur droit, puis « Embed this Space » et copier l'**URL directe**. Cela devrait ressembler à `https://..hf.space`. +- **Votre clé API** : Pour obtenir votre clé, connectez-vous à votre instance Argilla et allez dans « My Settings », puis copiez la clé API. +- **Votre token HF** : Si votre Space est privé, vous aurez besoin d'un *Access Token* dans votre compte Hugging Face Hub avec des permissions d'écriture. + +```python +import argilla as rg + +HF_TOKEN = "..." # uniquement pour les spaces privés + +client = rg.Argilla( + api_url="...", + api_key="...", + headers={"Authorization": f"Bearer {HF_TOKEN}"}, # uniquement pour les spaces privés +) +``` + +Pour vérifier que tout fonctionne correctement, nous allons appeler `me`. Cela devrait nous renvoyer notre utilisateur : + +```python +client.me +``` + +Si cela fonctionne, votre instance Argilla est opérationnelle et vous y êtes connecté ! Félicitations ! + +Nous pouvons maintenant commencer à charger notre premier jeu de données dans Argilla. \ No newline at end of file diff --git a/chapters/fr/chapter10/3.mdx b/chapters/fr/chapter10/3.mdx new file mode 100644 index 000000000..04211d6bc --- /dev/null +++ b/chapters/fr/chapter10/3.mdx @@ -0,0 +1,110 @@ +# Chargez votre jeu de données dans Argilla[[load-your-dataset-to-argilla]] + + + +En fonction de la tâche NLP sur laquelle vous travaillez et du cas d'utilisation/votre application spécifique, vos données et la tâche d'annotation se présenteront différemment. Pour cette partie du cours, nous utiliserons [un jeu de données collectant des actualités](https://huggingface.co/datasets/SetFit/ag_news) pour réaliser deux tâches : de la classification indiquant le thème de chaque texte et de la reconnaissannce d'entités nommées pour identifier les entités mentionnées. + + + +Il est possible d'importer des jeux de données depuis le Hub en utilisant directement l'interface utilisateur Argilla, mais nous utiliserons le SDK pour apprendre à modifier les données si nécessaire. + +## Configurez votre jeu de données + +La première étape consiste à se connecter à notre instance Argilla comme nous l'avons fait dans la section précédente : + +```python +import argilla as rg + +HF_TOKEN = "..." # uniquement pour les spaces privés + +client = rg.Argilla( + api_url="...", + api_key="...", + headers={"Authorization": f"Bearer {HF_TOKEN}"}, # uniquement pour les spaces privés +) +``` + +Nous pouvons maintenant réfléchir aux paramètres de notre jeu de données dans Argilla. Ceux-ci représentent la tâche d'annotation que nous allons effectuer sur nos données. Tout d'abord, nous pouvons charger le jeu de données depuis le Hub et inspecter ses caractéristiques, afin de nous assurer que nous le configurons correctement. + +```python +from datasets import load_dataset + +data = load_dataset("SetFit/ag_news", split="train") +data.features +``` + +Voici les caractéristiques de notre jeu de données : + +```python out +{'text': Value(dtype='string', id=None), + 'label': Value(dtype='int64', id=None), + 'label_text': Value(dtype='string', id=None)} +``` + +Il contient un `text` ainsi que des labels pour la tâche de classification. Nous les ajouterons à nos paramètres de jeu de données avec une question `spans` pour les entités nommées : + +```python +settings = rg.Settings( + fields=[rg.TextField(name="text")], + questions=[ + rg.LabelQuestion( + name="label", title="Classifier le texte :", labels=data.unique("label_text") + ), + rg.SpanQuestion( + name="entities", + title="Surligner toutes les entités présentes dans le texte :", + labels=["PERSON", "ORG", "LOC", "EVENT"], + field="text", + ), + ], +) +``` + +Voyons un peu plus en détail ce que signifient ces paramètres. Tout d'abord, nous avons défini les **champs**, qui contiennent les informations que nous allons annoter. Dans ce cas, nous n'avons qu'un seul champ et il se présente sous la forme d'un texte, nous avons donc choisi un `TextField`. + +Ensuite, nous définissons des **questions** qui représentent les tâches que nous voulons effectuer sur nos données : + +- Pour la tâche de classification de texte, nous avons choisi une `LabelQuestion` et nous avons utilisé les valeurs uniques de la colonne `label_text` comme nos labels, pour s'assurer que la question est compatible avec ceux qui existent déjà dans le jeu de données. +- Pour la tâche de classification de *tokens*, nous aurons besoin d'une `SpanQuestion`. Nous avons défini un ensemble de labels que nous utiliserons pour cette tâche, ainsi que le champ sur lequel nous surlignerons les entités. + +Pour en savoir plus sur tous les types de champs et de questions disponibles et sur d'autres paramètres avancés, tels que les métadonnées et les vecteurs, consultez la [documentation](https://docs.argilla.io/latest/how_to_guides/dataset/#define-dataset-settings). + +## Charger le jeu de données + +Maintenant que nous avons défini quelques paramètres, nous pouvons créer le jeu de données : + +```python +dataset = rg.Dataset(name="ag_news", settings=settings) + +dataset.create() +``` + +Le jeu de données apparaît maintenant dans notre instance Argilla, mais vous verrez qu'il est vide : + +Screenshot of the empty dataset. + +Nous devons maintenant ajouter les enregistrements que nous allons annoter, c'est-à-dire les lignes de notre jeu de données. Pour ce faire, nous devons simplement saisir les données en tant qu'enregistrements et fournir une correspondance pour les éléments qui n'ont pas le même nom dans les jeux de données du Hub et d'Argilla : + +```python +dataset.records.log(data, mapping={"label_text": "label"}) +``` + +Dans notre correspondance, nous avons spécifié que la colonne `label_text` dans le jeu de données devrait être associée à la question avec le nom `label`. De cette façon, nous utiliserons les étiquettes existantes dans le jeu de données comme pré-annotations afin de pouvoir annoter plus rapidement. + +Pendant que les enregistrements continuent à être consignés, vous pouvez déjà commencer à travailler avec votre jeu de données dans l'interface utilisateur d'Argilla. A ce stade, cela devrait ressembler à ceci : + +Screenshot of the dataset in Argilla. + +Notre jeu de données est maintenant prêt à être annoté ! \ No newline at end of file diff --git a/chapters/fr/chapter10/4.mdx b/chapters/fr/chapter10/4.mdx new file mode 100644 index 000000000..cb41d356b --- /dev/null +++ b/chapters/fr/chapter10/4.mdx @@ -0,0 +1,44 @@ +# Annoter votre jeu de données[[annotate-your-dataset]] + + + +Maintenant, il est temps de commencer à travailler à partir de l'interface utilisateur d'Argilla pour annoter notre jeu de données. + +## Alignez votre équipe sur les règles d'annotation à respecter + +Avant de commencer à annoter votre jeu de données, il est toujours bon de rédiger quelques lignes directrices, surtout si vous travaillez en équipe. Cela vous aidera à vous aligner sur la tâche et l'utilisation des différentes étiquettes, et à résoudre les questions ou les conflits lorsqu'ils surviennent. + +Dans Argilla, vous pouvez aller sur la page des paramètres de votre jeu de données dans l'interface utilisateur et modifier les directives et les descriptions de vos questions pour faciliter l'alignement. + +Screenshot of the Dataset Settings page in Argilla. + +Si vous souhaitez approfondir la question de la rédaction de bonnes règles, nous vous recommandons de lire [cet article de blog](https://argilla.io/blog/annotation-guidelines-practices) ainsi que les références bibliographiques qui y sont mentionnées. + +## Répartir la tâche + +Dans la page des paramètres du jeu de données, vous pouvez également modifier les paramètres de distribution du jeu de données. Cela vous permettra d'annoter plus efficacement lorsque vous travaillez en équipe. La valeur par défaut du nombre minimum de réponses soumises est de 1, ce qui signifie que dès qu'un enregistrement a une réponse soumise, il est considéré comme complet et compte dans la progression du traitement de votre jeu de données. + +Parfois, vous souhaitez avoir plus d'une réponse soumise par enregistrement. Par exemple, si vous voulez analyser l'accord inter-annotateurs dans votre tâche. Dans ce cas, assurez-vous de changer ce paramètre à un nombre plus élevé, mais toujours inférieur ou égal au nombre total d'annotateurs. Si vous travaillez seul sur la tâche, ce paramètre doit être égal à 1. + +## Annoter les enregistrements + +>[!TIP] +>💡 Si vous déployez Argilla dans un Space, tous les membres de l'équipe pourront se connecter en utilisant le Hugging Face OAuth. Sinon, vous devrez peut-être créer des comptes utilisateurs pour eux en suivant [ce guide](https://docs.argilla.io/latest/how_to_guides/user/). + +Lorsque vous ouvrirez votre jeu de données, vous vous rendrez compte que la première question est déjà remplie avec quelques étiquettes suggérées. C'est parce que dans la section précédente nous avons associé notre question appelée `label` à la colonne `label_text` dans le jeu de données, de sorte qu'il nous suffit de revoir et de corriger les étiquettes déjà existantes : + +Screenshot of the dataset in Argilla. + +Pour la classification de *tokens*, nous devrons ajouter toutes les étiquettes manuellement, car nous n'avons pas inclus de suggestions. Voici à quoi cela pourrait ressembler après l'ajout des annotations : + +Screenshot of the dataset in Argilla with spans annotated. + +Au fur et à mesure que vous parcourez les différents dossiers, vous pouvez entreprendre différentes actions : +- soumettre vos réponses, une fois que vous avez terminé l'enregistrement. +- les sauvegarder comme brouillon, au cas où vous voudriez y revenir plus tard. +- les écarter, si l'enregistrement ne doit pas faire partie du jeu de données ou si vous ne voulez pas y répondre. + +Dans la section suivante, vous apprendrez comment exporter et utiliser ces annotations. \ No newline at end of file diff --git a/chapters/fr/chapter10/5.mdx b/chapters/fr/chapter10/5.mdx new file mode 100644 index 000000000..5d730f696 --- /dev/null +++ b/chapters/fr/chapter10/5.mdx @@ -0,0 +1,69 @@ +# Utilisez votre jeu de données annoté[[use-your-annotated-dataset]] + + + +Nous allons maintenant apprendre à exporter et à utiliser les données annotées que nous avons dans Argilla. + +## Charger le jeu de données + +Tout d'abord, nous devons nous assurer que nous sommes connectés à notre instance Argilla comme dans les étapes précédentes : + +```python +import argilla as rg + +HF_TOKEN = "..." # uniquement pour les spaces privés + +client = rg.Argilla( + api_url="...", + api_key="...", + headers={"Authorization": f"Bearer {HF_TOKEN}"}, # uniquement pour les spaces privés +) +``` + +Nous allons maintenant charger le jeu de données avec lequel nous allons travailler : + +```python +dataset = client.datasets(name="ag_news") +``` + +Charger le jeu de données et appeler ses enregistrements avec `dataset.records` est suffisant pour commencer. Cependant, nous allons également apprendre à effectuer quelques opérations optionnelles, comme filtrer les enregistrements et exporter votre jeu de données vers le Hub d'Hugging Face. + +## Filtrer le jeu de données + +Il arrive que l'on ne veuille utiliser que les enregistrements qui ont été effectués. Nous allons donc commencer par filtrer les enregistrements de notre jeu de données en fonction de leur statut : + +```python +status_filter = rg.Query(filter=rg.Filter([("status", "==", "completed")])) + +filtered_records = dataset.records(status_filter) +``` + +>[!TIP] +>⚠️ Notez que les enregistrements avec le statut `completed` (c'est à dire les enregistrements qui atteignent le minimum de réponses soumises configuré dans les paramètres de distribution des tâches) peuvent avoir plus d'une réponse et que chaque réponse peut avoir n'importe quel statut parmi `submitted`, `draft` ou `discarded`. + +Pour en savoir plus sur le requêtage et le filtrage des enregistrements, consultez la [documentation](https://docs.argilla.io/latest/how_to_guides/query/). + +## Exportation vers le Hub + +Nous pouvons maintenant exporter nos annotations vers le Hub d'Hugging Face, afin de pouvoir les partager avec d'autres personnes. Pour ce faire, nous devrons convertir les enregistrements en un objet Dataset puis le pousser vers le Hub : + +```python +filtered_records.to_datasets().push_to_hub("argilla/ag_news_annotated") +``` + +Il est également possible d'exporter directement le jeu de données Argilla complet (y compris les enregistrements en attente) de la manière suivante : + +```python +dataset.to_hub(repo_id="argilla/ag_news_annotated") +``` + +C'est un choix intéressant au cas où d'autres personnes voudraient ouvrir le jeu de données dans leurs instances Argilla, car les paramètres sont automatiquement sauvegardés et ils peuvent simplement importer le jeu de données complet en utilisant une seule ligne de code : + +```python +dataset = rg.Dataset.from_hub(repo_id="argilla/ag_news_annotated") +``` \ No newline at end of file diff --git a/chapters/fr/chapter10/6.mdx b/chapters/fr/chapter10/6.mdx new file mode 100644 index 000000000..9f9ca28dc --- /dev/null +++ b/chapters/fr/chapter10/6.mdx @@ -0,0 +1,19 @@ +# Argilla, coché ![[argilla-check]] + + + +C'est tout ! Félicitations ! 👏 + +Dans ce chapitre, vous avez appris les étapes de base pour : +- configurer Argilla. +- annoter pour améliorer la qualité de votre jeu de données. +- adapter un jeu de données existant et le réutiliser pour une tâche de NLP différente. +- partager votre jeu de données annoté avec la communauté dans le Hub d'Hugging Face. + +## Que faire ensuite ? +- Consultez d'autres tutoriels étape par étape pour d'autres tâches populaires de NLP dans la [page des tutoriels](https://docs.argilla.io/latest/tutorials/). +- Vous pouvez également explorer d'autres exemples de jeux de données dans cette [démo](https://demo.argilla.io/sign-in?auth=ZGVtbzoxMjM0NTY3OA==). +- Si vous souhaitez continuer à en apprendre davantage sur Argilla et ses fonctionnalités avancées, consultez la [documentation](https://docs.argilla.io/latest/). \ No newline at end of file diff --git a/chapters/fr/chapter10/7.mdx b/chapters/fr/chapter10/7.mdx new file mode 100644 index 000000000..bb02385e9 --- /dev/null +++ b/chapters/fr/chapter10/7.mdx @@ -0,0 +1,186 @@ + + +# Quiz de fin de chapitre[[end-of-chapter-quiz]] + + + +Testons ce que nous avons appris dans ce chapitre ! + +### 1. A quoi peut servir Argilla ? + + + +### 2. Argilla fonctionne UNIQUEMENT dans les Spaces d'Hugging Face et avec 🤗 Datasets. + + + +### 3. Vous avez besoin d'un token Hugging Face pour connecter le SDK Python à votre serveur Argilla. + + + +### 4. Que sont les **champs** dans Argilla ? Combien de champs pouvez-vous utiliser ? + + + +### 5. Quel est le meilleur type de question pour une tâche de classification de tokens ? + + + +### 6. À quoi sert le bouton « Save as draft » ? + + +### 7. Argilla ne propose pas automatiquement des étiquettes suggérées, vous devez fournir ces données vous-même. + + + +### 8. Sélectionnez toutes les étapes nécessaires pour exporter un jeu de données Argilla dans son intégralité vers le Hub : + +client= rg.Argilla(api_url='...', api_key='...')", + explain: "Oui, pour interagir avec votre serveur, vous devez d'abord l'instancier.", + correct: true + }, + { + text: "Importer le jeu de données depuis le Hub : dataset = rg.Dataset.from_hub(repo_id='argilla/ag_news_annotated')", + explain: "Non. Il s'agit d'importer un jeu de données du Hub dans votre instance Argilla.", + }, + { + text: "Charger le jeu de données : dataset = client.datasets(name='my_dataset')", + explain: "Oui, vous en aurez besoin pour la suite des opérations.", + correct: true + }, + { + text: "Convertir le jeu de données Argilla en un jeu de données Datasets : dataset = dataset.to_datasets()", + explain: "Ceci n'est pas nécessaire si vous exportez le jeu de données complet. Argilla s'en chargera pour vous. Cependant, vous pouvez en avoir besoin si vous travaillez avec un sous-ensemble d'enregistrements." + }, + { + text: "Utiliser la méthode to_hub pour exporter le jeu de données : dataset.to_hub(repo_id='my_username/dataset_name')", + explain: "Ceci poussera le jeu de données vers l'identifiant du repo indiqué, et créera un nouveau repo s'il n'existe pas.", + correct: true + }, + ]} +/> diff --git a/chapters/fr/chapter11/1.mdx b/chapters/fr/chapter11/1.mdx new file mode 100644 index 000000000..4f5a4a562 --- /dev/null +++ b/chapters/fr/chapter11/1.mdx @@ -0,0 +1,32 @@ +# Finetuning supervisé + +Dans [la section 2 du chapitre 2](/course/fr/chapter2/2), nous avons vu que les modèles de langage génératifs peuvent être finetunés sur des tâches spécifiques telles que le résumé et la réponse aux questions. Cependant, de nos jours, il est beaucoup plus courant de finetuner les modèles de langage sur un large éventail de tâches simultanément ; une méthode connue sous le nom de *finetuning* supervisé (SFT pour *supervised fine-tuning*). Ce processus permet aux modèles de devenir plus polyvalents et capables de gérer divers cas d'utilisation. La plupart des grands modèles de langage avec lesquels les individus interagissent sur des plateformes telles que ChatGPT ont été soumis à un SFT afin de les rendre plus utiles et de les aligner sur les préférences humaines. Ce chapitre est divisé en quatre sections : + +## 1️⃣ Gabarits de chat (*chat template*) + +Les gabarits de chat structurent les interactions entre les utilisateurs et les modèles d'IA, garantissant des réponses cohérentes et appropriées. Ils comprennent des éléments tels que les instructions (*prompts* en anglais) du système et des balises attribuant les tours de rôle. + +## 2️⃣ *Finetuning* supervisé + +Le *finetuning* supervisé est un processus essentiel pour adapter les modèles de langage pré-entraînés à des tâches spécifiques. Il s'agit d'entraîner le modèle sur un jeu de données spécifique à la tâche avec des exemples étiquetés. Pour un guide détaillé sur le *finetuning*, y compris les étapes clés et les meilleures pratiques, voir [la section sur le *finetuning* supervisé de la documentation de la bibliothèque *TRL*](https://huggingface.co/docs/trl/en/sft_trainer). + +## 3️⃣ *Low Rank Adaptation* (LoRA) + +*Low Rank Adaptation* (LoRA) est une technique de *finetuning* ajoutant des matrices de rangs inférieurs aux couches du modèle de langage. Cela permet un *finetuning* efficace tout en préservant les connaissances pré-entraînées du modèle. L'un des principaux avantages de la méthode LoRA réside dans les économies de mémoire considérables qu'elle offre, ce qui permet de finetuner des modèles de grande taille sur des ressources matérielles limitées. + +## 4️⃣ Évaluation + +L'évaluation est une étape cruciale du processus de *finetuning*. Elle nous permet de mesurer les performances du modèle sur un jeu de données spécifique à une tâche. + + +⚠️ Afin de bénéficier de toutes les fonctionnalités disponibles du Hub d'Hugging Face et de 🤗 Transformers, nous recommandons la création d'un compte. + +## Réferences + +- [La documentation de *Transformers* sur les gabarits de chat](https://huggingface.co/docs/transformers/main/en/chat_templating) +- [Script pour le *finetuning* supervisé dans *TRL*](https://github.com/huggingface/trl/blob/main/trl/scripts/sft.py) +- [`SFTTrainer` dans *TRL*](https://huggingface.co/docs/trl/main/en/sft_trainer) +- [Papier de la méthode *Direct Preference Optimization* (DPO)](https://arxiv.org/abs/2305.18290) +- [La documentation de *TRL* sur le *finetuning* supervisé](https://huggingface.co/docs/trl/sft_trainer) +- [Comment finetuner le modèle Gemma de Google avec *ChatML* et *TRL*](https://github.com/huggingface/alignment-handbook) +- [*Finetuning* d'un LLM pour générer des catalogues de produits en persan au format JSON](https://huggingface.co/learn/cookbook/en/fine_tuning_llm_to_generate_persian_product_catalogs_in_json_format) diff --git a/chapters/fr/chapter11/2.mdx b/chapters/fr/chapter11/2.mdx new file mode 100644 index 000000000..971b19807 --- /dev/null +++ b/chapters/fr/chapter11/2.mdx @@ -0,0 +1,255 @@ + +# Gabarits de chat + +## Introduction + +Les gabarits de chat sont essentiels pour structurer les interactions entre les modèles de langage et les utilisateurs. Que vous construisiez un simple robot conversationnel ou un [agent complexe](https://huggingface.co/learn/agents-course/fr/unit0/introduction), il est essentiel de comprendre comment formater correctement vos conversations pour obtenir les meilleurs résultats en utilisant votre modèle. Dans ce guide, nous allons explorer ce que sont les gabarits de chat, pourquoi ils sont importants et comment les utiliser efficacement. + + +Les gabarits de chat sont essentiels pour :
+- Maintenir une structure de conversation cohérente
+- Assurer une identification correcte des rôles
+- Gérer le contexte à travers plusieurs tours
+- Prendre en charge des fonctions avancées telles que l'utilisation d'outils +
+ +## Types de modèles et gabarits + +### Modèles de base vs. modèles instruits +Un modèle de base est entraîné sur des données textuelles brutes pour prédire le prochain *token*, tandis qu'un modèle instruit est finetuné spécifiquement pour suivre des instructions et converser. Par exemple, [`SmolLM2-135M`](https://huggingface.co/HuggingFaceTB/SmolLM2-135M) est un modèle de base, tandis que [`SmolLM2-135M-Instruct`](https://huggingface.co/HuggingFaceTB/SmolLM2-135M-Instruct) est sa variante finetunée sur des instructions. + +Les modèles instruits sont entraînés à suivre une structure conversationnelle spécifique, ce qui les rend plus adaptés aux applications de chatbot. De plus, les modèles d'instruction peuvent gérer des interactions complexes (y compris l'utilisation d'outils), les entrées multimodales et l'appel de fonctions. + +Pour qu'un modèle de base se comporte comme un modèle instruit, nous devons formater nos instructions d'une manière cohérente que le modèle peut comprendre. C'est là qu'interviennent les gabarits de chat. ChatML (pour *Chat Markup Language*) est un de ces gabarits qui structure les conversations avec des indicateurs de rôle clairs (système, utilisateur, assistant). Vous pouvez trouver un guide sur ChatML [ici](https://huggingface.co/HuggingFaceTB/SmolLM2-135M-Instruct/blob/e2c3f7557efbdec707ae3a336371d169783f1da1/tokenizer_config.json#L146). + + +Lorsque vous utilisez un modèle instruit, vérifiez toujours que vous utilisez le bon format de gabarits de chat. L'utilisation d'un mauvais gabarit peut conduire à de mauvaises performances du modèle ou à un comportement inattendu. La façon la plus simple de s'en assurer est de vérifier la configuration du *tokenizer* du modèle sur le *Hub*. Par exemple, le modèle `SmolLM2-135M-Instruct` utilise cette configuration. + + +### Formats de gabarits courants + +Avant de se plonger dans des implémentations spécifiques, il est important de comprendre le formatage des conversations attendu par différents modèles. Explorons quelques gabarits courants à l'aide d'un simple exemple de conversation. + +Nous utiliserons la structure de conversation suivante pour tous les exemples : + +```python +messages = [ + {"role": "system", "content": "You are a helpful assistant."}, + {"role": "user", "content": "Hello!"}, + {"role": "assistant", "content": "Hi! How can I help you today?"}, + {"role": "user", "content": "What's the weather?"}, +] +``` + +Voici le gabarit ChatML utilisé dans des modèles tels que SmolLM2 et les Qwen 2 : + +```sh +<|im_start|>system +You are a helpful assistant.<|im_end|> +<|im_start|>user +Hello!<|im_end|> +<|im_start|>assistant +Hi! How can I help you today?<|im_end|> +<|im_start|>user +What's the weather?<|im_start|>assistant +``` + +Voici le format de gabarits utilisé par Mistral : +```sh +[INST] You are a helpful assistant. [/INST] +Hi! How can I help you today? +[INST] Hello! [/INST] +``` + +Les principales différences entre ces formats sont les suivantes : +1. **Gestion du message système** : + - Llama 2 insère les messages du système dans des balises `<>` + - Llama 3 utilise des balises `<|system|>` avec des fins `` + - Mistral inclut un message système dans la première instruction + - Qwen utilise le rôle `system` explicite avec les balises `<|im_start|>` + - ChatGPT utilise le préfixe `SYSTEM:` + +2. **Délimitation des messages**: + - Llama 2 utilise les balises `[INST]` et `[/INST]` + - Llama 3 utilise des balises spécifiques pour chaque rôle (`<|system|>`, `<|user|>`, `<|assistant|>`) avec `` comme fin + - Mistral utilise `[INST]` et `[/INST]` avec `` utilise `` + - Qwen utilise des *token* de début et de fin spécifiques pour chaque rôle + +3. **Tokens spéciaux**: + - Llama 2 utilise `` et `` pour les limites de la conversation + - Llama 3 utilise `` pour terminer chaque message + - Mistral utilise `` et `` pour les limites des tours + - Qwen utilise des *token* de début et de fin spécifiques pour chaque rôle + +Comprendre ces différences est essentiel pour travailler avec différents modèles. Voyons comment la bibliothèque 🤗 *Transformers* nous aide à gérer ces variations automatiquement : + +```python +from transformers import AutoTokenizer + +# Cela utilisera automatiquement des gabarits différents +mistral_tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-Instruct-v0.1") +qwen_tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen-7B-Chat") +smol_tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM2-135M-Instruct") + +messages = [ + {"role": "system", "content": "You are a helpful assistant."}, + {"role": "user", "content": "Hello!"}, +] + +# Chaque modèle sera formaté en fonction de son gabarit +mistral_chat = mistral_tokenizer.apply_chat_template(messages, tokenize=False) +qwen_chat = qwen_tokenizer.apply_chat_template(messages, tokenize=False) +smol_chat = smol_tokenizer.apply_chat_template(messages, tokenize=False) +``` + +
+Cliquer pour voir des exemples de gabarits + +Gabarits ChatML de Qwen 2 et SmolLM2 : + +```sh +<|im_start|>system +You are a helpful assistant.<|im_end|> +<|im_start|>user +Hello!<|im_end|> +<|im_start|>assistant +Hi! How can I help you today?<|im_end|> +<|im_start|>user +What's the weather?<|im_start|>assistant +``` + +Gabarit de Mistral : + +```sh +[INST] You are a helpful assistant. [/INST] +Hi! How can I help you today? +[INST] Hello! [/INST] +``` + +
+ + +### Fonctionnalités avancées +Les gabarits de chat peuvent gérer des scénarios plus complexes que les simples interactions conversationnelles, notamment : + +1. **Utilisation d'outils** : lorsque les modèles doivent interagir avec des outils externes ou des API. +2. **Entrées multimodales** : pour gérer les images, le son ou d'autres types de médias +3. **Appel de fonction** : pour l'exécution de fonctions structurées +4. **Contexte multi-tour** : pour conserver l'historique des conversations + + +Lors de l'implémentation de fonctions avancées : +- Testez minutieusement votre modèle. Les applications de vision et les outils utilisent des gabarits particulièrement variés.
+- Surveillez attentivement l'utilisation des tokens entre chaque fonctionnalité et chaque modèle.
+- Documenter le format attendu pour chaque fonctionnalité +
+ +Pour les conversations multimodales, les gabarits peuvent inclure des références d'images ou des images codées en base64 : +```python +messages = [ + { + "role": "system", + "content": "You are a helpful vision assistant that can analyze images.", + }, + { + "role": "user", + "content": [ + {"type": "text", "text": "What's in this image?"}, + {"type": "image", "image_url": "https://example.com/image.jpg"}, + ], + }, +] +``` + +Voici un exemple de gabarits de chat avec l'utilisation d'un outil : + +```python +messages = [ + { + "role": "system", + "content": "You are an AI assistant that can use tools. Available tools: calculator, weather_api", + }, + {"role": "user", "content": "What's 123 * 456 and is it raining in Paris?"}, + { + "role": "assistant", + "content": "Let me help you with that.", + "tool_calls": [ + { + "tool": "calculator", + "parameters": {"operation": "multiply", "x": 123, "y": 456}, + }, + {"tool": "weather_api", "parameters": {"city": "Paris", "country": "France"}}, + ], + }, + {"role": "tool", "tool_name": "calculator", "content": "56088"}, + { + "role": "tool", + "tool_name": "weather_api", + "content": "{'condition': 'rain', 'temperature': 15}", + }, +] +``` + +## Bonnes pratiques + +### Principes généraux +Lorsque vous travaillez avec des gabarits de chat, respectez les pratiques suivantes : + +1. **Formatage cohérent** : Utilisez toujours le même format de gabarits pour l'ensemble de votre application. +2. **Définition claire des rôles** : Spécifiez clairement les rôles (système, utilisateur, assistant, outil) pour chaque message. +3. **Gestion du contexte** : Tenir compte de la limite du nombre de *tokens* lors de la gestion de l'historique des conversations. +4. **Gestion des erreurs** : Inclure une gestion appropriée des erreurs pour les appels d'outils et les entrées multimodales. +5. **Validation** : Valider la structure du message avant de l'envoyer au modèle + + + +Les pièges à éviter : +- Mélanger différents gabarits dans la même application
+- Dépasser la limite du nombre de token avec de longs historiques de conversation
+- Ne pas escamoter correctement les caractères spéciaux dans les messages
+- Oublier de valider la structure des messages d'entrée
+- Ignorer les exigences de gabarits spécifiques à un modèle +
+ +## Exercice pratique + +Entraînons-nous à mettre en œuvre des gabarits de chat à l'aide d'un exemple concret. + + +Suivez les étapes suivantes pour convertir le jeu de données `HuggingFaceTB/smoltalk` au format ChatML : + +1. Chargez le jeu de données : +```python +from datasets import load_dataset + +dataset = load_dataset("HuggingFaceTB/smoltalk") +``` + +2. Créer une fonction de traitement : +```python +def convert_to_chatml(example): + return { + "messages": [ + {"role": "user", "content": example["input"]}, + {"role": "assistant", "content": example["output"]}, + ] + } +``` + +3. Appliquer le gabarit de chat en utilisant le *tokenizer* du modèle choisi. + +N'oubliez pas de vérifier que le format de sortie correspond aux exigences du modèle choisi ! + + +## Ressources complémentaires + +- [Guide sur les gabarits de chat dans la documentation d'Hugging Face](https://huggingface.co/docs/transformers/main/en/chat_templating) +- [Documentation de 🤗 *Transformers*](https://huggingface.co/docs/transformers) +- [Dépôt Github contenant des exemples de gabarits de chat](https://github.com/chujiezheng/chat_templates) \ No newline at end of file diff --git a/chapters/fr/chapter11/3.mdx b/chapters/fr/chapter11/3.mdx new file mode 100644 index 000000000..5a4616456 --- /dev/null +++ b/chapters/fr/chapter11/3.mdx @@ -0,0 +1,374 @@ + + +# *Finetuning* supervisé + +Le *finetuning* supervisé (SFT) est un processus principalement utilisé pour adapter des modèles de langage pré-entraînés afin qu'ils suivent des instructions, engagent un dialogue et utilisent des formats de sortie spécifiques. Alors que les modèles pré-entraînés ont des capacités générales impressionnantes, le SFT permet de les transformer en modèles de type assistant qui peuvent mieux comprendre et répondre aux instructions de l'utilisateur. Pour ce faire, il faut généralement entraîner sur des jeux de données de conversations et d'instructions écrites par des humains. + +Cette page fournit un guide étape par étape pour finetuner le modèle [`deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B`](https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B) en utilisant le [`SFTTrainer`](https://huggingface.co/docs/trl/en/sft_trainer). En suivant ces étapes, vous pouvez adapter le modèle pour effectuer des tâches spécifiques plus efficacement. + +## Quand utiliser le SFT ? + +Avant de se lancer dans son implémentation, il est important de comprendre quand le SFT est le bon choix pour votre projet. Dans un premier temps, vous devez vous demander si l'utilisation d'un modèle existant instruit avec des instructions bien conçues suffirait pour votre cas d'utilisation. Le SFT implique des ressources de calcul et des efforts d'ingénierie considérables, et ne doit donc être envisagé que lorsque les instructions des modèles existants s'avèrent insuffisantes. + + +N'envisagez le SFT que si vous : +- Vous avez besoin de performances supplémentaires par rapport à ce que les instructions peuvent réaliser.
+- Vus avez un cas d'utilisation spécifique pour lequel le coût d'utilisation d'un grand modèle polyvalent l'emporte sur le coût du *finetuning* d'un modèle plus petit
+- Vous avez besoin de formats de sortie spécialisés ou de connaissances spécifiques à un domaine que les modèles existantsne maîtrisent pas. +
+ +Si vous déterminez que le SFT est nécessaire, la décision de procéder dépend de deux facteurs principaux : + +### Contrôle des gabarits +Le SFT permet un contrôle précis de la structure de sortie du modèle. Ceci est particulièrement utile lorsque vous avez besoin que le modèle : +1. Génére des réponses dans un format de gabarits de chat spécifique. +2. Suivre des schémas de sortie stricts +3. Maintenir un style cohérent dans les réponses + +### Adaptation au domaine +Lorsque l'on travaille dans des domaines spécialisés, le SFT permet d'aligner le modèle sur les impératifs propres au domaine en : +1. Enseignant la terminologie et les concepts du domaine +2. Appliquant les normes professionnelles +3. Traitant les questions techniques de manière appropriée +4. Suivant les lignes directrices spécifiques à l'industrie + + +Avant de commencer à utiliser le SFT, évaluez si votre cas d'utilisation nécessite :
+- un formatage précis des résultats
+- des connaissances spécifiques à un domaine
+- des schémas de réponse cohérents
+- le respect de lignes directrices spécifiques. + +Cette évaluation vous aidera à déterminer si le SFT est la bonne approche pour vos besoins. +
+ +## Préparation du jeu de données + +Le processus de *finetuning* supervisé nécessite un jeu de données spécifique à la tâche, structuré avec des paires entrée-sortie. Chaque paire doit comprendre +1. Une instruction d'entrée +2. La réponse attendue du modèle +3. Tout contexte ou métadonnée supplémentaire + +La qualité de vos données d'entraînement est cruciale pour un *finetuning* réussi. Voyons comment préparer et valider votre jeu de données : + + + +## Configuration de l'entraînement + +La configuration de `SFTTrainer` nécessite la prise en compte de plusieurs paramètres qui contrôlent le processus d`entrainement. Examinons chaque paramètre et son utilité : + +1. **Paramètres concernant la durée de l'entraînement**: + - `num_train_epochs`: Contrôle la durée totale de l'entraînement + - `max_steps`: Alternative aux époques, définit le nombre maximum d'étapes d'entraînement. + - Un plus grand nombre d'époques permet un meilleur apprentissage, mais risque d'entraîner un surentraînement. + +2. **Paramètres concernant la taille des batchs**: + - `per_device_train_batch_size`: Détermine l'utilisation de la mémoire et la stabilité de l'entraînement + - `gradient_accumulation_steps`: Permet d'augmenter la taille des batchs + - Des lots batchs plus grands permettent d'obtenir des gradients plus stables mais nécessitent plus de mémoire + +3. **Paramètres concernant le taux d'apprentissage**: + - `learning_rate`: Contrôle les mises à jour de la taille des poids + - `warmup_ratio`: Partie de l'entraînement utilisée pour l'échauffement du taux d'apprentissage + - Un taux trop élevé peut provoquer une instabilité, un taux trop faible entraîne un apprentissage lent. + +4. **Paramètres de contrôle**: + - `logging_steps`: Fréquence de l'enregistrement des métriques + - `eval_steps`: Fréquence d'évaluation sur les données de validation + - `save_steps`: Fréquence des sauvegardes des points de contrôle du modèle + + +Commencez par des valeurs prudentes et ajustez-les en fonction du contrôle : +- Commencer avec 1-3 époques
+- Utiliser des batchs de plus petite taille dans un premier temps
+- Surveiller de près les métriques de validation
+- Ajuster le taux d'apprentissage si l'entraînement est instable
+
+ +## Implémentation avec TRL + +Maintenant que nous comprenons les composants clés, mettons en œuvre l'entraînement avec une validation et un suivi appropriés. Nous allons utiliser la classe `SFTTrainer` de la bibliothèque *Transformers Reinforcement Learning* (TRL), qui est construite au-dessus de la bibliothèque 🤗 *Transformers*. Voici un exemple complet utilisant la bibliothèque TRL : + +```python +from datasets import load_dataset +from trl import SFTConfig, SFTTrainer +import torch + +# Définir l'appareil +device = "cuda" if torch.cuda.is_available() else "cpu" + +# Charger le jeu de données +dataset = load_dataset("HuggingFaceTB/smoltalk", "all") + +# Configurer les arguments de la classe Trainer +training_args = SFTConfig( + output_dir="./sft_output", + max_steps=1000, + per_device_train_batch_size=4, + learning_rate=5e-5, + logging_steps=10, + save_steps=100, + eval_strategy="steps", + eval_steps=50, +) + +# Initialisation de la classe Trainer +trainer = SFTTrainer( + model=model, + args=training_args, + train_dataset=dataset["train"], + eval_dataset=dataset["test"], + processing_class=tokenizer, +) + +# Débuter l'entraînement +trainer.train() +``` + + +Lorsqu'on utilise un jeu de données avec un champ « messages » (comme l'exemple ci-dessus), SFTTrainer applique automatiquement le gabarit de chat du modèle depuis le Hub. Cela signifie que vous n'avez pas besoin de configuration supplémentaire pour gérer les conversations de type chat : la classe Trainer formatera les messages selon le format de gabarits attendu par le modèle. + + +## Empaquetage du jeu de données + +SFTTrainer supporte l'empaquetage des exemples afin d'optimiser l'efficacité de l'entraînement. Cette fonctionnalité permet de regrouper plusieurs exemples courts dans la même séquence d'entrée, maximisant ainsi l'utilisation du GPU pendant l'entraînement. Pour activer cette fonctionnalité, il suffit de mettre `packing=True` dans le constructeur SFTConfig. Lorsque vous utilisez des jeux de données avec `max_steps`, soyez conscient que vous pouvez entraîner pendant plus d'époques que prévu en fonction de votre configuration d'empaquetage. Vous pouvez personnaliser la façon dont les exemples sont combinés en utilisant une fonction de formatage. C'est particulièrement utile lorsque vous travaillez avec des jeux de données qui ont plusieurs champs comme les paires question-réponse. Pour les jeux de données d'évaluation, vous pouvez désactiver l'empaquetage en réglant `eval_packing=False` dans SFTConfig. Voici un exemple basique de personnalisation de la configuration d'empaquetage : + +```python +# Configuration +training_args = SFTConfig(packing=True) + +trainer = SFTTrainer(model=model, train_dataset=dataset, args=training_args) + +trainer.train() +``` + +Lorsque le jeu de données est rempli de plusieurs champs, vous pouvez définir une fonction de formatage personnalisée pour combiner les champs en une seule séquence d'entrée. Cette fonction doit prendre une liste d'exemples et renvoyer un dictionnaire contenant la séquence d'entrée condensée. Voici un exemple de fonction de formatage personnalisée : + +```python +def formatting_func(example): + text = f"### Question: {example['question']}\n ### Answer: {example['answer']}" + return text + + +training_args = SFTConfig(packing=True) +trainer = SFTTrainer( + "facebook/opt-350m", + train_dataset=dataset, + args=training_args, + formatting_func=formatting_func, +) +``` + +## Suivi des progrès de l'entraînement + +Un suivi efficace est essentiel pour un *finetuning* réussi. Voyons ce qu'il faut surveiller pendant l'entraînement : + +### Comprendre les schémas de la perte + +La fonction de perte de l'entraînement suit généralement trois phases distinctes : +1. Chute brutale initiale : Adaptation rapide à la nouvelle distribution des données +2. Stabilisation progressive : Le taux d'apprentissage ralentit au fur et à mesure du *finetuning* du modèle. +3. Convergence : Les valeurs de la perte se stabilisent, ce qui indique que l'entraînement est terminé. + +SFTTrainer Training + +### Métriques à surveiller + +Un suivi efficace implique le traquage de paramètres quantitatifs et l'évaluation de paramètres qualitatifs. Les mesures disponibles sont les suivantes : +- Perte d'entraînement +- Perte de validation +- Progression du taux d'apprentissage +- Normes du gradient + + +Soyez attentif à ces signes d'alerte pendant l'entraînement :
+1. La perte de validation augmente alors que la perte d'entraînement diminue (surentraînement)
+2. Pas d'amélioration significative des valeurs de la perte (sousentraînement)
+3. Valeurs de perte extrêmement faibles (mémorisation potentielle)
+4. Formatage incohérent des résultats (problèmes d'apprentissage des gabarits) +
+ +### Le chemin vers la convergence + +Au fur et à mesure que l'entraînement progresse, les courbes des pertes devraientt se stabiliser progressivement. L'indicateur clé d'un entraînement sain est un faible écart entre la perte d'entraînement et la perte de validation, ce qui suggère que le modèle apprend des schémas généralisables plutôt que de mémoriser des exemples spécifiques. Les valeurs de perte absolues varient en fonction de la tâche et de le jeu de données. + +### Suivi de la progression de l'entraînement + +Le graphique ci-dessus illustre une progression typique de l'entraînement. Remarquez que les pertes d'entraînement et de validation diminuent fortement au début, puis se stabilisent progressivement. Ce schéma indique que le modèle apprend efficacement tout en conservant sa capacité de généralisation. + +### Signes d'alerte à surveiller + +Plusieurs schémas dans les courbes de perte peuvent indiquer des problèmes potentiels. Nous illustrons ci-dessous les signes d'alerte courants et les solutions que nous pouvons envisager. + +SFTTrainer Training + +Si la perte de validation diminue à un rythme nettement plus lent que la perte d'entraînement, votre modèle est probablement surentraîné par rapport aux données d'entraînement. Envisagez de : +- Réduire le nombres d'étapes de l'entraînement +- Augmenter la taille du jeu de données +- Valider la qualité et la diversité du jeu de données + +SFTTrainer Training + +Si la perte ne montre pas d'amélioration significative, le modèle pourrait : +- Apprendre trop lentement (essayez d'augmenter le taux d'apprentissage) +- Avoir des difficultés avec la tâche (vérifiez la qualité des données et la complexité de la tâche) +- Se heurter aux limites de l'architecture (envisager un autre modèle) + +SFTTrainer Training + +Des valeurs de perte extrêmement faibles peuvent suggérer une mémorisation plutôt qu'un apprentissage. Ceci est particulièrement inquiétant si +- Le modèle donne des résultats médiocres sur de nouveaux exemples similaires. +- Les résultats manquent de diversité +- Les réponses sont trop similaires aux exemples d'entraînement. + + +Surveillez à la fois les valeurs de perte et les sorties réelles du modèle pendant l'entraînement. Parfois, la perte peut sembler bonne alors que le modèle développe des comportements indésirables. Une évaluation qualitative régulière des réponses du modèle permet de déceler des problèmes que les mesures seules pourraient ne pas déceler. + + +Il convient de noter que l'interprétation des valeurs de la perte que nous décrivons ici vise le cas le plus courant, et qu'en fait, elles peuvent se comporter de diverses manières en fonction du modèle, du jeu de données, des paramètres d'entraînement, etc. Si vous souhaitez en savoir plus sur les schémas décrits, nous vous invitons à consulter cet article de blog de l'équipe de [Fast AI](https://www.fast.ai/posts/2023-09-04-learning-jumps/). + +## Évaluation après SFT + +Dans la section [11.4](/fr/chapter11/4), nous apprendrons à évaluer le modèle à l'aide de jeux de données d'évaluation. Pour l'instant, nous nous concentrerons sur l'évaluation qualitative du modèle. + +Après avoir terminé le SFT, envisagez les actions de suivi suivantes : +1. Évaluer le modèle de manière approfondie sur des données de test conservées. +2. Valider le respect des gabarits pour les différentes données d'entrée. +3. Tester la rétention des connaissances spécifiques au domaine +4. Contrôler les mesures de performance dans le monde réel + + +Documentez votre processus d'entraînement, y compris : +- Les caractéristiques du jeu de données +- Les paramètres d'entraînement +- Les métriques de performance +- Les limites connues. +Cette documentation sera précieuse pour les itérations futures du modèle. + + +## Quiz + +### 1. Quels sont les paramètres qui déterminent la durée de l'entraînement dans le cadre du SFT ? + + + +### 2. Quelle schéma dans les courbes de perte indique un surentraînement potentiel ? + + + +### 3. À quoi sert la fonction gradient_accumulation_steps ? + + + +### 4. Que faut-il surveiller pendant l'entraînement SFT ? + + + +### 5. Qu'est-ce qui indique une convergence saine pendant l'entraînement ? + + + +## 💐 Beau travail ! + +Vous avez appris à finetuner des modèles à l'aide du SFT ! Pour poursuivre votre apprentissage : +1. Essayez le *notebook* avec différents paramètres +2. Expérimentez avec d'autres jeux de données +3. Contribuer à l'amélioration du matériel de cours + +## Additional Resources + +- [Documentation de *TRL*](https://huggingface.co/docs/trl) +- [Répertoire contenant des exemples de SFT](https://github.com/huggingface/trl/blob/main/trl/scripts/sft.py) +- [Les bonnes pratiques pour le *finetuning*](https://huggingface.co/docs/transformers/training) diff --git a/chapters/fr/chapter11/4.mdx b/chapters/fr/chapter11/4.mdx new file mode 100644 index 000000000..19fad9720 --- /dev/null +++ b/chapters/fr/chapter11/4.mdx @@ -0,0 +1,173 @@ + + +# LoRA (Low-Rank Adaptation) + +Le *finetuning* de LLM est un processus gourmand en ressources. LoRA est une technique qui nous permet de finetuner de tels modèles avec un petit nombre de paramètres. Elle fonctionne en ajoutant et en optimisant des matrices plus petites aux poids d'attention, ce qui réduit généralement les paramètres entraînables d'environ 90 %. + +## Comprendre la méthode LoRA + +LoRA (Low-Rank Adaptation) est une technique de *finetuning* efficace en termes de paramètres qui gèle les poids du modèle pré-entraîné et injecte des matrices de décomposition de rangs entraînables dans les couches du modèle. Au lieu d'entraîner tous les paramètres du modèle pendant le *finetuning*, LoRA décompose les mises à jour des poids en matrices plus petites par le biais d'une décomposition de rang inférieur, réduisaint ainsi considérablement le nombre de paramètres à entraîner tout en maintenant les performances du modèle. Par exemple, lorsqu'il est appliqué au GPT-3 175B, LoRA réduit de 10 000 fois le nombre de paramètres entraînables et de trois fois les besoins en mémoire du par rapport à un *finetuning* complet. Pour en savoir plus sur cette méthode, consultez ce [papier](https://arxiv.org/pdf/2106.09685). + +LoRA fonctionne en ajoutant, généralement sur les poids des couches dattention du *transformer*, des paires de matrices de décomposition des rangs. Pendant l'inférence, ces poids d'adaptateur peuvent être fusionnés avec le modèle de base, ce qui n'entraîne aucune latence supplémentaire. LoRA est particulièrement utile pour adapter de grands modèles de langage à des tâches ou domaines spécifiques tout en conservant des besoins en ressources gérables. + +## Principaux avantages du LoRA + +1. **Efficacité de la mémoire** : + - Seuls les paramètres de l`adaptateur sont stockés dans la mémoire du GPU + - Les poids du modèle de base restent gelés et peuvent être chargés avec une précision inférieure. + - Permet un *finetuning* des grands modèles sur des GPU grand public. + +2. **Caractéristiques d'entraînement** : + - Intégration native des PEFT/LoRA avec une configuration minimale + - Prise en charge de QLoRA (Quantized LoRA) pour une meilleure efficacité de la mémoire. + +3. **Gestion des adaptateurs** : + - Réduction du poids de l'adaptateur lors des *checkpoints* + - Fonctionnalités permettant de fusionner les adaptateurs dans le modèle de base + +## Chargement des adaptateurs LoRA avec PEFT + +[*PEFT*](https://github.com/huggingface/peft) est une bibliothèque qui fournit une interface unifiée pour charger et gérer les méthodes PEFT (*Parameter-Efficient Fine-Tuning*), y compris LoRA. Elle permet de charger et de passer facilement d'une méthode PEFT à l'autre, ce qui facilite l'expérimentation de différentes techniques de *finetuning*. + +Les adaptateurs peuvent être chargés sur un modèle pré-entraîné avec `load_adapter()`, ce qui est utile pour en essayer différents dont les poids ne sont pas fusionnés. Définissez les poids de l'adaptateur actif avec la fonction `set_adapter()`. Pour retourner le modèle de base, vous pouvez utiliser `unload()` pour décharger tous les modules LoRA. Cela facilite le basculement entre différents poids spécifiques à une tâche. + +```python +from peft import PeftModel, PeftConfig + +config = PeftConfig.from_pretrained("ybelkada/opt-350m-lora") +model = AutoModelForCausalLM.from_pretrained(config.base_model_name_or_path) +lora_model = PeftModel.from_pretrained(model, "ybelkada/opt-350m-lora") +``` + +![lora_load_adapter](https://github.com/huggingface/smol-course/raw/main/3_parameter_efficient_finetuning/images/lora_adapter.png) + +## Finetuner un LLM en utilisant `trl` et `SFTTrainer` avec LoRA + +[SFTTrainer](https://huggingface.co/docs/trl/sft_trainer) de `trl` fournit une intégration avec les adaptateurs LoRA à travers la bibliothèque [PEFT](https://huggingface.co/docs/peft/en/index). Cela signifie que nous pouvons finetuner un modèle de la même manière que nous l'avons fait avec le SFT, mais en utilisant LoRA pour réduire le nombre de paramètres que nous avons besoin d'entraîner. + +Nous utiliserons la classe `LoRAConfig` de PEFT dans notre exemple. L'installation ne nécessite que quelques étapes de configuration : + +1. Définir la configuration LoRA (rang, alpha, *dropout*). +2. Créer le SFTTrainer avec la configuration PEFT +3. Entraîner et sauvegarder les poids de l'adaptateur. + +## Configuration du LoRA + +Passons en revue la configuration et les paramètres clés du LoRA. +*** Traduit avec www.DeepL.com/Translator (version gratuite) *** + + +| Paramètres | Description | +|-----------|-------------| +| `r` (rank) | Dimension des matrices de rang inférieur utilisées pour la mise à jour des poids. Elle est généralement comprise entre 4 et 32. Des valeurs plus faibles permettent une plus grande compression mais potentiellement moins d'expressivité. | +| `lora_alpha` | Facteur d'échelle pour les couches LoRA, généralement fixé à deux fois la valeur du rang. Des valeurs plus élevées se traduisent par des effets d'adaptation plus forts. | +| `lora_dropout` | Probabilité de *dropout* pour les couches LoRA, généralement de 0,05 à 0,1. Des valeurs plus élevées permettent d'éviter un surentraînement pendant l'entraînement. | +| `bias` | Contrôle l'entraînement des termes de biais. Les options sont « none », « all » ou « lora_only ». L'option « none » est la plus courante pour des raisons d'efficacité de mémoire. | +| `target_modules` | Spécifie les modules du modèle auxquels appliquer la méthode LoRA. Il peut s'agir de « tous les modules linéaires » ou de modules spécifiques tels que « q_proj, v_proj ». Un plus grand nombre de modules permet une plus grande adaptabilité mais augmente l'utilisation de la mémoire. | + + +Lors de l'implémentation des méthodes PEFT, commencez par de petites valeurs de rang (4-8) pour LoRA et surveillez la perte d'entraînement. Utilisez des ensembles de validation pour éviter le surentraîneùent et comparez les résultats avec des baselines via finetuning complet lorsque cela est possible. L'efficacité des différentes méthodes peut varier en fonction de la tâche, c'est pourquoi l'expérimentation est essentielle. + + +## Utilisation de TRL avec PEFT + +Les méthodes PEFT peuvent être combinées avec TRL pour un *finetuning* permettant de réduire les besoins de mémoire. Nous pouvons passer `LoraConfig` au modèle lors de son chargement. + +```python +from peft import LoraConfig + +# TODO : Configurer les paramètres de LoRA +# r : dimension du rang des matrices LoRA (plus petite = plus de compression) +rank_dimension = 6 +# lora_alpha : facteur d'échelle pour les couches LoRA (plus élevé = adaptation plus forte) +lora_alpha = 8 +# lora_dropout : probabilité de dropout pour les couches LoRA (aide à prévenir le surentraînement) +lora_dropout = 0.05 + +peft_config = LoraConfig( + r=rank_dimension, # Dimension du rang, généralement entre 4 et 32 + lora_alpha=lora_alpha, # Facteur d'échelle LoRA, généralement 2x le rang + lora_dropout=lora_dropout, # Probabilité de dropout probability pour les couches de LoRA + bias="none", # Type de biais pour le LoRA. Les biais correspondants seront mis à jour pendant l'entraînement + target_modules="all-linear", # Modules auxquels appliquer le LoRA + task_type="CAUSAL_LM", # Type de tâche pour l'architecture du modèle +) +``` + +Ci-dessus, nous avons utilisé `device_map="auto"` pour assigner automatiquement le modèle au bon appareil. Vous pouvez également assigner manuellement le modèle à un appareil spécifique en utilisant `device_map={"": device_index}`. + +Nous aurons également besoin de définir le `SFTTrainer` avec la configuration du LoRA. + +```python +# Créer un SFTTrainer avec la configuration LoRA +trainer = SFTTrainer( + model=model, + args=args, + train_dataset=dataset["train"], + peft_config=peft_config, # Configuration LoRA + max_seq_length=max_seq_length, # Longueur maximale de la séquence + processing_class=tokenizer, +) +``` + + +✏️ Essayez ! Reprenez votre modèle de la section précédente, mais finetuné-le avec LoRA. Utilisez le jeu de données `HuggingFaceTB/smoltalk` pour finetuner un modèle `deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B`, en utilisant la configuration LoRA que nous avons définie ci-dessus. + + +## Fusion des adaptateurs LoRA + +Après l'entraînement avec LoRA, vous pouvez souhaiter fusionner les poids des adaptateurs dans le modèle de base pour faciliter le déploiement. Cela permet de créer un modèle unique avec les poids combinés, éliminant ainsi la nécessité de charger les adaptateurs séparément pendant l'inférence. + +Le processus de fusion nécessite une attention particulière de la gestion de la mémoire et de la précision. Comme vous devrez charger simultanément le modèle de base et les poids des adaptateurs, assurez-vous que la mémoire du GPU/CPU est suffisante. L'utilisation de `device_map="auto"` dans 🤗 *Transformers* trouvera le bon périphérique pour le modèle en fonction de votre matériel. + +Maintenez une précision cohérente tout au long du processus, en utilisant la précision utilisée pendant l'entraînement et en sauvegardant le modèle fusionné dans le même format pour le déploiement. + +## Mise en œuvre de la fusion + +Après l'entraînement d'un adaptateur LoRA, vous pouvez fusionner les poids de l'adaptateur dans le modèle de base. Voici comment procéder : + +```python +import torch +from transformers import AutoModelForCausalLM +from peft import PeftModel + +# 1. Charger le modèle de basel +base_model = AutoModelForCausalLM.from_pretrained( + "base_model_name", torch_dtype=torch.float16, device_map="auto" +) + +# 2. Charger le modèle PEFT avec l'adaptateur +peft_model = PeftModel.from_pretrained( + base_model, "path/to/adapter", torch_dtype=torch.float16 +) + +# 3. Fusionner les poids de l'adaptateur avec le modèle de base +merged_model = peft_model.merge_and_unload() +``` + +Si vous constatez des différences de taille dans le modèle sauvegardé, assurez-vous que vous sauvegardez également le *tokenizer* : + +```python +# Sauvegarde du modèle et du tokenizer +tokenizer = AutoTokenizer.from_pretrained("base_model_name") +merged_model.save_pretrained("path/to/save/merged_model") +tokenizer.save_pretrained("path/to/save/merged_model") +``` + + +✏️ Essayez ! Fusionner les poids de l'adaptateur dans le modèle de base. Utiliser le jeu de données `HuggingFaceTB/smoltalk` pour finetuner un modèle `deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B` grâce à l'approche LoRA que nous avons définie ci-dessus. + + + +# Ressources + +- [Papier de la méthode LoRA (*Low-Rank Adaptation of Large Language Models*)](https://arxiv.org/pdf/2106.09685) +- [Documentation de la bibliothèque *PEFT*](https://huggingface.co/docs/peft) +- [Article de blog d'Hugging Face sur *PEFT-](https://huggingface.co/blog/peft) diff --git a/chapters/fr/chapter11/5.mdx b/chapters/fr/chapter11/5.mdx new file mode 100644 index 000000000..2917fa0ec --- /dev/null +++ b/chapters/fr/chapter11/5.mdx @@ -0,0 +1,252 @@ +# Évaluation + +Avec un modèle finetuné par SFT ou LoRA, nous devrions l'évaluer sur des jeux d'évaluation standards. En tant qu'ingénieurs en apprentissage automatique, vous devez maintenir une série d'évaluations pertinentes pour votre domaine d'intérêt ciblé. Dans cette page, nous examinons certains des jeux d'évaluation les plus courants et la manière de les utiliser pour évaluer votre modèle. Nous verrons également comment créer des jeux d'évaluation personnalisés pour votre cas d'utilisation spécifique. + +## Jeux d'évaluation automatiques + +Les jeux d'évaluation (*benchmark* en anglais) automatiques servent d'outils standardisés pour l'évaluation des modèles dans différentes tâches et capacités. S'ils constituent un point de départ utile pour comprendre les performances des modèles, il est important de reconnaître qu'ils ne représentent qu'un élément d'une stratégie d'évaluation globale. + +## Comprendre les jeux d'évaluation automatiques + +Les jeux d'évaluation automatiques consistent généralement en des jeux de données nettoyés avec des tâches et des mesures d'évaluation prédéfinies. Ils visent à évaluer divers aspects de la capacité des modèles, de la compréhension du langage de base au raisonnement complexe. Leur avantage principal est leur standardisation, permettant une comparaison cohérente entre différents modèles et permettent d'obtenir des résultats reproductibles. + +Toutefois, il est essentiel de comprendre que les performances des jeux d'évaluation ne se traduisent pas toujours directement par une efficacité dans le monde réel. Un modèle qui excelle sur des jeux académiques peut encore éprouver des difficultés avec des applications de domaines spécifiques ou des cas d'utilisation pratiques. + +## Jeux d'évaluation de connaissances générales + +[MMLU](https://huggingface.co/datasets/cais/mmlu) (*Massive Multitask Language Understanding*) permet de tester les connaissances d'un modèle dans 57 matières, des sciences aux sciences humaines. Bien qu'il soit complet, il peut ne pas refléter la profondeur de l'expertise nécessaire pour des domaines spécifiques. TruthfulQA évalue la tendance d'un modèle à reproduire les idées fausses les plus courantes, bien qu'il ne puisse pas saisir toutes les formes de désinformation. + +## Jeux d'évaluation du raisonnement + +[BBH](https://huggingface.co/datasets/lukaemon/bbh) (*Big Bench Hard*) et [GSM8K](https://huggingface.co/datasets/openai/gsm8k) se concentrent sur des tâches de raisonnement complexes. BBH teste la pensée logique et la planification, tandis que le GSM8K cible spécifiquement la résolution de problèmes mathématiques. Ces jeux d'évaluation permettent d'évaluer les capacités d'analyse, mais peuvent ne pas rendre compte du raisonnement nuancé requis dans les scénarios du monde réel. + +## Compréhension du langage + +[HELM](https://github.com/stanford-crfm/helm) fournit un cadre d'évaluation holistique. Les jeux d'évaluation comme HELM donnent un aperçu des capacités de traitement du langage sur des aspects tels que le bon sens, la connaissance du monde et le raisonnement. Mais ils peuvent ne pas représenter pleinement la complexité d'une conversation naturelle ou d'une terminologie spécifique à un domaine. + +## Jeux d'évaluation spécifiques à un domaine + +Examinons quelques jeux d'évaluation axés sur des domaines spécifiques tels que les mathématiques, le codage et le chat. + +Le [MATH](https://huggingface.co/papers/2103.03874) est un autre outil d'évaluation important pour le raisonnement mathématique. Il se compose de 12 500 problèmes issus de concours de mathématiques, couvrant l'algèbre, la géométrie, la théorie des nombres, le comptage, les probabilités, etc. Ce qui rend MATH particulièrement difficile, c'est qu'il exige un raisonnement en plusieurs étapes, la compréhension de la notation mathématique formelle et la capacité à générer des solutions étape par étape. Contrairement aux tâches arithmétiques plus simples, les problèmes de MATH exigent souvent des stratégies de résolution de problèmes sophistiquées et l'application de concepts mathématiques. + +[HumanEval](https://github.com/openai/human-eval) est un jeu de données d'évaluation axé sur le codage et composé de 164 problèmes de programmation. Il teste la capacité d'un modèle à générer un code Python fonctionnellement correct qui résout les tâches de programmation données. Ce qui rend HumanEval particulièrement précieux, c'est qu'il évalue à la fois les capacités de génération de code et la correction fonctionnelle par le biais de l'exécution de cas de test réels, plutôt que par une simple similitude superficielle avec des solutions de référence. Les problèmes vont de la simple manipulation de chaînes de caractères à des algorithmes et des structures de données plus complexes. + +[Alpaca Eval](https://tatsu-lab.github.io/alpaca_eval/) est un cadre d'évaluation automatisé conçu pour évaluer la qualité des modèles de langage à suivre des instructions. Il utilise GPT-4 comme juge pour évaluer les résultats du modèle selon diverses dimensions, notamment l'utilité, l'honnêteté et l'innocuité. Le cadre comprend un jeu de données de 805 d'instructions soigneusement sélectionnées et peut évaluer les réponses par rapport à plusieurs modèles de référence tels que Claude, GPT-4 et d'autres. Ce qui rend Alpaca Eval particulièrement utile, c'est sa capacité à fournir des évaluations cohérentes et évolutives sans nécessiter d'annotateurs humains, tout en capturant des aspects nuancés de la performance du modèle que les mesures traditionnelles pourraient manquer. + +## Autres méthodes d'évaluation + +De nombreuses organisations ont développé des méthodes d'évaluation alternatives pour répondre aux limites des jeux d'évaluation standards : + +### *LLM-as-Judge* + +L'utilisation d'un modèle de langage pour évaluer les résultats d'un autre modèle est de plus en plus populaire. Cette approche peut fournir un retour d'information plus nuancé que les mesures traditionnelles, bien qu'elle s'accompagne de ses propres biais et limites. + +### Arènes d'évaluation + +Les arènes d'évaluation telles que [Chatbot Arena](https://lmarena.ai/) offrent une approche unique pour évaluer les LLM via des retours humains massifs. Sur ces plateformes, les utilisateurs s'engagent dans des « batailles » anonymes entre deux LLM, en posant des questions et en votant pour le modèle qui fournit les meilleures réponses. Cette approche permet de saisir les modes d'utilisation et les préférences du monde réel grâce à des questions variées et stimulantes, et les études montrent une forte concordance entre les votes de la foule et les évaluations d'experts. Bien que puissantes, ces plateformes présentent des limites, notamment un biais potentiel de la base d'utilisateurs, des distributions d'instructions biaisées et un accent mis sur l'utilité plutôt que sur les considérations de sécurité. + +### Jeux d'évaluation personnalisés + +Les organisations développent souvent des suites d'évaluations internes adaptées à leurs besoins spécifiques et à leurs cas d'utilisation. Il peut s'agir de tests de connaissances spécifiques à un domaine ou de scénarios d'évaluation qui reflètent les conditions réelles de déploiement. + +## Évaluation personnalisée + +Si les jeux d'évaluation standards constituent une base de référence utile, ils ne doivent pas être votre seule méthode d'évaluation. Voici comment développer une approche plus complète : + +1. Commencez par des jeux d'évaluation standards pertinents pour établir une base de référence et permettre la comparaison avec d'autres modèles. + +2. Identifiez les exigences et les défis spécifiques de votre cas d'utilisation. Quelles tâches votre modèle va-t-il réellement accomplir ? Quels types d'erreurs seraient les plus problématiques ? + +3. Développez des jeux de données d'évaluation personnalisés qui reflètent votre cas d'utilisation réel. Cela pourrait inclure : + - Des requêtes d'utilisateurs réels provenant de votre domaine + - Des cas de figure courants que vous avez rencontrés + - Des exemples de scénarios particulièrement difficiles. + +4. Envisagez de mettre en œuvre une stratégie d'évaluation à plusieurs niveaux : + - Mesures automatisées pour un retour d'information rapide + - Évaluation humaine pour une compréhension nuancée + - Examen par des experts du domaine pour les applications spécialisées + - Tests A/B dans des environnements contrôlés + +## Implémentation d'évaluations personnalisées + +Dans cette section, nous allons implémenter l'évaluation de notre modèle finetuné. Nous pouvons utiliser [`lighteval`](https://github.com/huggingface/lighteval) pour évaluer notre modèle sur des jeux d'évaluation standards, car contient une large gamme de tâches intégrées dans la bibliothèque. Il suffit de définir les tâches que nous voulons évaluer et les paramètres de l'évaluation. + +Les tâches de LightEval sont définies selon un format spécifique : + +``` +{suite}|{task}|{num_few_shot}|{auto_reduce} +``` + +| Paramètres | Description | +|-----------|-------------| +| `suite` | La suite de jeux d'évaluation (ex : 'mmlu', 'truthfulqa') | +| `task` | Tâche spécifique au sein de la suite (ex : 'abstract_algebra') | +| `num_few_shot` | Nombre d'exemples à inclure dans l'instruction | +| `auto_reduce` | Possibilité de réduire automatiquement les exemples si l'instruction est trop longue (0 ou 1) | + +Exemple : `"mmlu|abstract_algebra|0|0"` évalue le modèle sur la tâche d'algèbre abstraite de MMLU via une inférence avec zéro exemple. + +## Exemple de pipeline d'évaluation + +Mettons en place un pipeline d'évaluation pour notre modèle finetuné. Nous évaluerons le modèle sur un ensemble de sous-tâches liées au domaine de la médecine. + +Voici un exemple complet d'évaluation sur des jeux d'évaluation automatiques relatifs à un domaine spécifique en utilisant Lighteval avec le *backend* VLLM : + +```bash +lighteval accelerate \ + "pretrained=your-model-name" \ + "mmlu|anatomy|0|0" \ + "mmlu|high_school_biology|0|0" \ + "mmlu|high_school_chemistry|0|0" \ + "mmlu|professional_medicine|0|0" \ + --max_samples 40 \ + --batch_size 1 \ + --output_path "./results" \ + --save_generations true +``` + +Les résultats sont affichés sous forme de tableau : + +``` +| Task |Version|Metric|Value | |Stderr| +|----------------------------------------|------:|------|-----:|---|-----:| +|all | |acc |0.3333|± |0.1169| +|leaderboard:mmlu:_average:5 | |acc |0.3400|± |0.1121| +|leaderboard:mmlu:anatomy:5 | 0|acc |0.4500|± |0.1141| +|leaderboard:mmlu:high_school_biology:5 | 0|acc |0.1500|± |0.0819| +``` + +Lighteval inclut également une API python pour des tâches d'évaluation plus détaillées, ce qui est utile pour manipuler les résultats d'une manière plus flexible. Consultez la [documentation de Lighteval](https://huggingface.co/docs/lighteval/using-the-python-api) pour plus d'informations. + + +✏️ Essayez ! Évaluez votre modèle finetuné sur une tâche spécifique de lighteval. + + +# Quiz de fin de chapitre + + + +### 1. Quels sont les principaux avantages de l'utilisation de jeux d'évaluation automatiques pour l'évaluation des modèles ? + + + +### 2. Quel jeu d'évaluation teste les connaissances dans 57 matières différentes ?? + + + +### 3. Qu'est-ce qu'un LLM-as-Judge ? + + + +### 4. Quels sont les éléments à inclure dans une stratégie d'évaluation globale ? + + + +### 5. Qu'est-ce qu'une limitation des jeux d'évaluation automatiques ? + + + +### 6. Quel est l'objectif de la création de jeux de données d'évaluation personnalisés ? + + diff --git a/chapters/fr/chapter11/6.mdx b/chapters/fr/chapter11/6.mdx new file mode 100644 index 000000000..d3022a2a1 --- /dev/null +++ b/chapters/fr/chapter11/6.mdx @@ -0,0 +1,13 @@ +# Conclusion + +Dans ce chapitre, nous avons exploré les composantes essentielles du *finetuning* des modèles de langage : + +1. Les **Gabarits de chat** structurent les interactions du modèle, garantissant des réponses cohérentes et appropriées grâce à une mise en forme standardisée. + +2. Le ***Finetuning* Supervisé (SFT)** permet d'adapter les modèles pré-entraînés à des tâches spécifiques tout en conservant leurs connaissances fondamentales. + +3. **LoRA** offre une approche efficace du *finetuning* en réduisant les paramètres entraînables tout en préservant les performances du modèle. + +4. **L'évaluation** permet de mesurer et de valider l'efficacité du *finetuning* à l'aide de diverses mesures et références. + +Ces techniques, lorsqu'elles sont combinées, permettent la création de modèles spécialisés qui peuvent exceller dans des tâches spécifiques tout en restant efficaces en termes de calcul. Que vous construisiez un robot de service à la clientèle ou un assistant spécifique à un domaine, la compréhension de ces concepts est cruciale pour une adaptation réussie du modèle. \ No newline at end of file diff --git a/chapters/fr/chapter11/7.mdx b/chapters/fr/chapter11/7.mdx new file mode 100644 index 000000000..e5faf6998 --- /dev/null +++ b/chapters/fr/chapter11/7.mdx @@ -0,0 +1,30 @@ +# C'est l'heure de l'examen ! + +Il est temps de mettre vos connaissances à l'épreuve ! Nous avons préparé un petit questionnaire pour tester votre compréhension des concepts abordés dans ce chapitre. + +Pour répondre à ce questionnaire, vous devez suivre les étapes suivantes : + +1. Connectez-vous à votre compte Hugging Face. +2. Répondez aux questions du questionnaire. +3. Envoyez vos réponses. + +## Quiz à choix multiples + +Dans ce quiz, il vous sera demandé de sélectionner la bonne réponse à partir d'une liste d'options. Nous allons vous tester sur les principes fondamentaux du *finetuning* supervisé. + + + +## Quiz sur le code + +Dans ce quiz, il vous sera demandé d'écrire du code pour accomplir une tâche. Nous vous testerons sur le code que vous avez étudié dans le cours à partir de bibliothèques comme `datasets`, `transformers`, `peft`, et `TRL`. + \ No newline at end of file diff --git a/chapters/fr/chapter7/5.mdx b/chapters/fr/chapter7/5.mdx index 0a963e8cb..3b997d136 100644 --- a/chapters/fr/chapter7/5.mdx +++ b/chapters/fr/chapter7/5.mdx @@ -589,7 +589,7 @@ def compute_metrics(eval_pred): Ensuite, nous devons définir un assembleur de données pour notre tâche de séquence à séquence. Comme mT5 est un *transformer* encodeur-décodeur, une des subtilités de la préparation de nos batchs est que, pendant le décodage, nous devons décaler les étiquettes d'une unité vers la droite. Ceci est nécessaire pour garantir que le décodeur ne voit que les étiquettes de vérité terrain précédentes et non les étiquettes actuelles ou futures, qui seraient faciles à mémoriser pour le modèle. Cela ressemble à la façon dont l'auto-attention masquée est appliquée aux entrées dans une tâche comme [la modélisation causale du langage](/course/fr/chapter7/6). -Heureusement, 🤗 *Transformers* fournit un assembleur `DataCollatorForSeq2Seq` qui rembourrera dynamiquement les entrées et les étiquettes pour nous. Pour instancier ce assembleur, nous devons simplement fournir le *tokenizer* et le *modèle* : +Heureusement, 🤗 *Transformers* fournit un assembleur `DataCollatorForSeq2Seq` qui rembourrera dynamiquement les entrées et les étiquettes pour nous. Pour instancier cet assembleur, nous devons simplement fournir le *tokenizer* et le *modèle* : {#if fw === 'pt'} @@ -609,7 +609,7 @@ data_collator = DataCollatorForSeq2Seq(tokenizer, model=model, return_tensors="t {/if} -Voyons ce que produit ce assembleur lorsqu'on lui donne un petit batch d'exemples. Tout d'abord, nous devons supprimer les colonnes contenant des chaînes de caractères, car le assembleur ne saura pas comment remplir ces éléments : +Voyons ce que produit cet assembleur lorsqu'on lui donne un petit batch d'exemples. Tout d'abord, nous devons supprimer les colonnes contenant des chaînes de caractères, car l'assembleur ne saura pas comment remplir ces éléments : ```python tokenized_datasets = tokenized_datasets.remove_columns( @@ -617,7 +617,7 @@ tokenized_datasets = tokenized_datasets.remove_columns( ) ``` -Comme le assembleur attend une liste de `dict`, où chaque `dict` représente un seul exemple du jeu de données, nous devons également mettre les données dans le format attendu avant de les transmettre au assembleur de données : +Comme l'assembleur attend une liste de `dict`, où chaque `dict` représente un seul exemple du jeu de données, nous devons également mettre les données dans le format attendu avant de les transmettre à l'assembleur de données : ```python features = [tokenized_datasets["train"][i] for i in range(2)] @@ -700,7 +700,7 @@ Pour conclure cette section, voyons comment nous pouvons également *finetuner* {:else} -Nous sommes presque prêts à nous entraîner ! Nous devons juste convertir nos jeux de données en `tf.data.Dataset` en utilisant le assembleur de données que nous avons défini ci-dessus, puis utiliser `compile()` et `fit()`. D'abord, les jeux de données : +Nous sommes presque prêts à nous entraîner ! Nous devons juste convertir nos jeux de données en `tf.data.Dataset` en utilisant l'assembleur de données que nous avons défini ci-dessus, puis utiliser `compile()` et `fit()`. D'abord, les jeux de données : ```python tf_train_dataset = model.prepare_tf_dataset( @@ -835,7 +835,7 @@ Maintenant que nous avons des jeux de données constitués uniquement de tenseur model = AutoModelForSeq2SeqLM.from_pretrained(model_checkpoint) ``` -Nous pouvons ensuite instancier le assembleur de données et l'utiliser pour définir nos chargeurs de données : +Nous pouvons ensuite instancier l'assembleur de données et l'utiliser pour définir nos chargeurs de données : ```python from torch.utils.data import DataLoader diff --git a/chapters/fr/chapter7/6.mdx b/chapters/fr/chapter7/6.mdx index 91c90a96c..2529d3bc8 100644 --- a/chapters/fr/chapter7/6.mdx +++ b/chapters/fr/chapter7/6.mdx @@ -324,7 +324,7 @@ _________________________________________________________________ {/if} -Notre modèle comporte 124 millions de paramètres que nous devrons régler. Avant de commencer l'entraînement, nous devons configurer un assembleur de données qui se chargera de créer les batchs. Nous pouvons utiliser le assembleur `DataCollatorForLanguageModeling`, qui est conçu spécifiquement pour la modélisation du langage (comme son nom le suggère subtilement). En plus de l'empilage et du rembourrage des batchs, il s'occupe aussi de la création des étiquettes du modèle de langage. Dans la modélisation causale du langage, les entrées servent aussi d'étiquettes (juste décalées d'un élément) et que le assembleur de données crée à la volée pendant l'entraînement pour ne pas avoir à dupliquer les `input_ids`. +Notre modèle comporte 124 millions de paramètres que nous devrons régler. Avant de commencer l'entraînement, nous devons configurer un assembleur de données qui se chargera de créer les batchs. Nous pouvons utiliser l'assembleur `DataCollatorForLanguageModeling`, qui est conçu spécifiquement pour la modélisation du langage (comme son nom le suggère subtilement). En plus de l'empilage et du rembourrage des batchs, il s'occupe aussi de la création des étiquettes du modèle de langage. Dans la modélisation causale du langage, les entrées servent aussi d'étiquettes (juste décalées d'un élément) et que l'assembleur de données crée à la volée pendant l'entraînement pour ne pas avoir à dupliquer les `input_ids`. Notez que `DataCollatorForLanguageModeling` supporte à la fois la modélisation du langage masqué (MLM pour *masked language modeling*) et la modélisation du langage causal (CLM pour *causal language modeling*). Par défaut, il prépare les données pour la MLM mais nous pouvons passer à la CLM en définissant l'argument `mlm=False` : diff --git a/chapters/fr/chapter9/1.mdx b/chapters/fr/chapter9/1.mdx index 8dd18331c..7c89fdc75 100644 --- a/chapters/fr/chapter9/1.mdx +++ b/chapters/fr/chapter9/1.mdx @@ -1,37 +1,37 @@ -# Introduction à Gradio - - - -Dans ce chapitre, nous allons apprendre à construire des **démos interactives** pour vos modèles d'apprentissage automatique. - -Pourquoi construire une démo ou une interface graphique pour votre modèle d'apprentissage automatique ? Les démos permettent : - -- aux **développeurs en apprentissage automatique** de présenter facilement leur travail à un large public, y compris des équipes non techniques ou des clients. -- aux **chercheurs** de reproduire plus facilement les modèles d'apprentissage automatique et leur comportement. -- aux **testeurs qualité** ou **utilisateurs finaux** d'identifier et de déboguer plus facilement les points de défaillance des modèles. -- aux **utilisateurs divers** de découvrir les biais algorithmiques des modèles. - -Nous utiliserons la bibliothèque *Gradio* pour construire des démos pour nos modèles. *Gradio* vous permet de construire, de personnaliser et de partager des démos en ligne pour n'importe quel modèle d'apprentissage automatique. Et cela entièrement en Python. - -Voici quelques exemples de démos d'apprentissage automatique construites avec Gradio : - -* Un modèle de **reconnaissance de croquis** qui prend un croquis et produit des étiquettes de ce qu'il pense être dessiné : - - - -* Un modèle extractif de **réponse à une question** qui prend en entrée un paragraphe de contexte et une requête et produit une réponse et un score de probabilité (nous avons discuté de ce type de modèle [au chapitre 7](/course/fr/chapter7/7)) : - - - -* Un modèle de **suppression de l'arrière-plan** qui prend une image et la restitue avec l'arrière-plan supprimé : - - - -Ce chapitre est divisé en sections qui comprennent à la fois des _concepts_ et des _applications_. Après avoir appris le concept dans chaque section, vous l'appliquerez pour construire un type particulier de démo, allant de la classification d'images à la reconnaissance vocale. À la fin de ce chapitre, vous serez en mesure de créer ces démos (et bien d'autres !) en quelques lignes de code Python seulement. - - -👀 Consultez Hugging Face Spaces pour voir de nombreux exemples récents de démos d'apprentissage automatique construites par la communauté ! - +# Introduction à Gradio + + + +Dans ce chapitre, nous allons apprendre à construire des **démos interactives** pour vos modèles d'apprentissage automatique. + +Pourquoi construire une démo ou une interface graphique pour votre modèle d'apprentissage automatique ? Les démos permettent : + +- aux **développeurs en apprentissage automatique** de présenter facilement leur travail à un large public, y compris des équipes non techniques ou des clients. +- aux **chercheurs** de reproduire plus facilement les modèles d'apprentissage automatique et leur comportement. +- aux **testeurs qualité** ou **utilisateurs finaux** d'identifier et de déboguer plus facilement les points de défaillance des modèles. +- aux **utilisateurs divers** de découvrir les biais algorithmiques des modèles. + +Nous utiliserons la bibliothèque *Gradio* pour construire des démos pour nos modèles. *Gradio* vous permet de construire, de personnaliser et de partager des démos en ligne pour n'importe quel modèle d'apprentissage automatique. Et cela entièrement en Python. + +Voici quelques exemples de démos d'apprentissage automatique construites avec Gradio : + +* Un modèle de **reconnaissance de croquis** qui prend un croquis et produit des étiquettes de ce qu'il pense être dessiné : + + + +* Un modèle extractif de **réponse à une question** qui prend en entrée un paragraphe de contexte et une requête et produit une réponse et un score de probabilité (nous avons discuté de ce type de modèle [au chapitre 7](/course/fr/chapter7/7)) : + + + +* Un modèle de **suppression de l'arrière-plan** qui prend une image et la restitue avec l'arrière-plan supprimé : + + + +Ce chapitre est divisé en sections qui comprennent à la fois des _concepts_ et des _applications_. Après avoir appris le concept dans chaque section, vous l'appliquerez pour construire un type particulier de démo, allant de la classification d'images à la reconnaissance vocale. À la fin de ce chapitre, vous serez en mesure de créer ces démos (et bien d'autres !) en quelques lignes de code Python seulement. + + +👀 Consultez Hugging Face Spaces pour voir de nombreux exemples récents de démos d'apprentissage automatique construites par la communauté ! + diff --git a/chapters/fr/chapter9/2.mdx b/chapters/fr/chapter9/2.mdx index 8d2ba3e71..dca028ea1 100644 --- a/chapters/fr/chapter9/2.mdx +++ b/chapters/fr/chapter9/2.mdx @@ -1,119 +1,119 @@ -# Construire votre première démo - - - -Commençons par installer *Gradio* ! Comme il s'agit d'un *package* Python, il suffit de l'exécuter : - -`$ pip install gradio ` - -Vous pouvez exécuter *Gradio* n'importe où, que ce soit dans votre IDE Python préféré, dans des *notebooks* ou même dans Google Colab 🤯 ! -Alors installez *Gradio* partout où vous exécutez Python ! - -Commençons par un exemple simple de type « *Hello World* » pour nous familiariser avec la syntaxe de *Gradio* : - -```py -import gradio as gr - - -def greet(name): - return "Hello " + name - - -demo = gr.Interface(fn=greet, inputs="text", outputs="text") - -demo.launch() -``` - -Parcourons le code ci-dessus : - -- D'abord, nous définissons une fonction appelée `greet()`. Dans ce cas, c'est une simple fonction qui ajoute « *Hello* » devant votre nom, mais cela peut être *n'importe quelle* fonction Python en général. Par exemple, dans les applications d'apprentissage automatique, cette fonction pourrait *appeler un modèle pour faire une prédiction* sur une entrée et retourner la sortie. -- Ensuite, nous créons une `Interface` *Gradio* avec trois arguments, `fn`, `inputs`, et `outputs`. Ces arguments définissent la fonction de prédiction, ainsi que le _type_ de composants d'entrée et de sortie que nous souhaitons. Dans notre cas, les deux composants sont de simples boîtes de texte. -- Nous appelons ensuite la méthode `launch()` sur l'`Interface` que nous avons créée. - -Si vous exécutez ce code, l'interface ci-dessous apparaîtra automatiquement dans un *notebook* Jupyter/Colab ou dans un navigateur sur **[http://localhost:7860](http://localhost:7860/)** si vous l'exécutez à partir d'un script. - - - -Essayez d'utiliser cette interface maintenant avec votre propre nom ou une autre entrée ! - -Vous remarquerez que dedans, *Gradio* a automatiquement déduit le nom du paramètre d'entrée (`name`) et l'a appliqué comme étiquette au dessus de la zone de texte. Que faire si vous souhaitez changer cela ? -Ou si vous souhaitez personnaliser la zone de texte d'une autre manière ? Dans ce cas, vous pouvez instancier un objet de classe représentant le composant de saisie. - -Jetez un coup d'œil à l'exemple ci-dessous : - -```py -import gradio as gr - - -def greet(name): - return "Hello " + name - - -# Nous instancions la classe Textbox -textbox = gr.Textbox(label="Type your name here:", placeholder="John Doe", lines=2) - -gr.Interface(fn=greet, inputs=textbox, outputs="text").launch() -``` - - - -Ici, nous avons créé une zone de texte d'entrée avec une étiquette, un espace réservé et un nombre de lignes défini. -Vous pourriez faire la même chose pour la zone de texte de sortie, mais nous allons laisser cela pour le moment. - -Nous avons vu qu'avec seulement quelques lignes de code, *Gradio* vous permet de créer une interface simple autour de n'importe quelle fonction -avec n'importe quel type d'entrées ou de sorties. Dans cette section, nous avons commencé par une simple boîte de texte mais dans les sections suivantes, nous couvrirons d'autres types d'entrées et de sorties. Voyons maintenant comment inclure un peu de NLP dans une application *Gradio*. - - -## 🤖 Inclure les prédictions du modèle - -Construisons maintenant une interface simple qui permet de faire une démo d'un modèle de **génération de texte** comme le GPT-2. - -Nous allons charger notre modèle en utilisant la fonction `pipeline()` de 🤗 *Transformers*. -Si vous avez besoin d'un rafraîchissement rapide, vous pouvez revenir à [cette section du chapitre 1](/course/fr/chapter1/3#text-generation). - -Tout d'abord, nous définissons une fonction de prédiction qui prend une invite de texte et renvoie la complétion du texte : - -```py -from transformers import pipeline - -model = pipeline("text-generation") - - -def predict(prompt): - completion = model(prompt)[0]["generated_text"] - return completion -``` - -Cette fonction complète le texte que vous fournissez, et vous pouvez l'exécuter avec les votres pour voir comment elle fonctionne. Voici un exemple (vous obtiendrez peut-être un résultat différent) : - - -``` -predict("My favorite programming language is") # Mon langage de programmation préféré est -``` - -``` ->> My favorite programming language is Haskell. I really enjoyed the Haskell language, but it doesn't have all the features that can be applied to any other language. For example, all it does is compile to a byte array. -# Mon langage de programmation préféré est Haskell. J'ai vraiment apprécié le langage Haskell, mais il n'a pas toutes les caractéristiques que l'on peut appliquer à n'importe quel autre langage. Par exemple, il ne fait que compiler un tableau d'octets. -``` - -Maintenant que nous avons une fonction pour générer des prédictions, nous pouvons créer et lancer une `Interface` de la même manière que nous l'avons fait précédemment : - -```py -import gradio as gr - -gr.Interface(fn=predict, inputs="text", outputs="text").launch() -``` - - -C'est fait ! Vous pouvez maintenant utiliser cette interface pour générer du texte en utilisant le modèle GPT-2 comme indiqué ci-dessous 🤯. - - - -Continuez votre lecture du cours pour voir comment construire d'autres types de démos avec *Gradio* ! +# Construire votre première démo + + + +Commençons par installer *Gradio* ! Comme il s'agit d'un *package* Python, il suffit de l'exécuter : + +`$ pip install gradio ` + +Vous pouvez exécuter *Gradio* n'importe où, que ce soit dans votre IDE Python préféré, dans des *notebooks* ou même dans Google Colab 🤯 ! +Alors installez *Gradio* partout où vous exécutez Python ! + +Commençons par un exemple simple de type « *Hello World* » pour nous familiariser avec la syntaxe de *Gradio* : + +```py +import gradio as gr + + +def greet(name): + return "Hello " + name + + +demo = gr.Interface(fn=greet, inputs="text", outputs="text") + +demo.launch() +``` + +Parcourons le code ci-dessus : + +- D'abord, nous définissons une fonction appelée `greet()`. Dans ce cas, c'est une simple fonction qui ajoute « *Hello* » devant votre nom, mais cela peut être *n'importe quelle* fonction Python en général. Par exemple, dans les applications d'apprentissage automatique, cette fonction pourrait *appeler un modèle pour faire une prédiction* sur une entrée et retourner la sortie. +- Ensuite, nous créons une `Interface` *Gradio* avec trois arguments, `fn`, `inputs`, et `outputs`. Ces arguments définissent la fonction de prédiction, ainsi que le _type_ de composants d'entrée et de sortie que nous souhaitons. Dans notre cas, les deux composants sont de simples boîtes de texte. +- Nous appelons ensuite la méthode `launch()` sur l'`Interface` que nous avons créée. + +Si vous exécutez ce code, l'interface ci-dessous apparaîtra automatiquement dans un *notebook* Jupyter/Colab ou dans un navigateur sur **[http://localhost:7860](http://localhost:7860/)** si vous l'exécutez à partir d'un script. + + + +Essayez d'utiliser cette interface maintenant avec votre propre nom ou une autre entrée ! + +Vous remarquerez que dedans, *Gradio* a automatiquement déduit le nom du paramètre d'entrée (`name`) et l'a appliqué comme étiquette au dessus de la zone de texte. Que faire si vous souhaitez changer cela ? +Ou si vous souhaitez personnaliser la zone de texte d'une autre manière ? Dans ce cas, vous pouvez instancier un objet de classe représentant le composant de saisie. + +Jetez un coup d'œil à l'exemple ci-dessous : + +```py +import gradio as gr + + +def greet(name): + return "Hello " + name + + +# Nous instancions la classe Textbox +textbox = gr.Textbox(label="Type your name here:", placeholder="John Doe", lines=2) + +gr.Interface(fn=greet, inputs=textbox, outputs="text").launch() +``` + + + +Ici, nous avons créé une zone de texte d'entrée avec une étiquette, un espace réservé et un nombre de lignes défini. +Vous pourriez faire la même chose pour la zone de texte de sortie, mais nous allons laisser cela pour le moment. + +Nous avons vu qu'avec seulement quelques lignes de code, *Gradio* vous permet de créer une interface simple autour de n'importe quelle fonction +avec n'importe quel type d'entrées ou de sorties. Dans cette section, nous avons commencé par une simple boîte de texte mais dans les sections suivantes, nous couvrirons d'autres types d'entrées et de sorties. Voyons maintenant comment inclure un peu de NLP dans une application *Gradio*. + + +## 🤖 Inclure les prédictions du modèle + +Construisons maintenant une interface simple qui permet de faire une démo d'un modèle de **génération de texte** comme le GPT-2. + +Nous allons charger notre modèle en utilisant la fonction `pipeline()` de 🤗 *Transformers*. +Si vous avez besoin d'un rafraîchissement rapide, vous pouvez revenir à [cette section du chapitre 1](/course/fr/chapter1/3#text-generation). + +Tout d'abord, nous définissons une fonction de prédiction qui prend une invite de texte et renvoie la complétion du texte : + +```py +from transformers import pipeline + +model = pipeline("text-generation") + + +def predict(prompt): + completion = model(prompt)[0]["generated_text"] + return completion +``` + +Cette fonction complète le texte que vous fournissez, et vous pouvez l'exécuter avec les votres pour voir comment elle fonctionne. Voici un exemple (vous obtiendrez peut-être un résultat différent) : + + +``` +predict("My favorite programming language is") # Mon langage de programmation préféré est +``` + +``` +>> My favorite programming language is Haskell. I really enjoyed the Haskell language, but it doesn't have all the features that can be applied to any other language. For example, all it does is compile to a byte array. +# Mon langage de programmation préféré est Haskell. J'ai vraiment apprécié le langage Haskell, mais il n'a pas toutes les caractéristiques que l'on peut appliquer à n'importe quel autre langage. Par exemple, il ne fait que compiler un tableau d'octets. +``` + +Maintenant que nous avons une fonction pour générer des prédictions, nous pouvons créer et lancer une `Interface` de la même manière que nous l'avons fait précédemment : + +```py +import gradio as gr + +gr.Interface(fn=predict, inputs="text", outputs="text").launch() +``` + + +C'est fait ! Vous pouvez maintenant utiliser cette interface pour générer du texte en utilisant le modèle GPT-2 comme indiqué ci-dessous 🤯. + + + +Continuez votre lecture du cours pour voir comment construire d'autres types de démos avec *Gradio* ! diff --git a/chapters/fr/chapter9/3.mdx b/chapters/fr/chapter9/3.mdx index caabfd317..74388c76f 100644 --- a/chapters/fr/chapter9/3.mdx +++ b/chapters/fr/chapter9/3.mdx @@ -1,168 +1,168 @@ -# 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*](https://gradio.app/docs). 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](/course/fr/chapter9/2), 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"`. - - -```py -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()` : - -```py -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](/course/fr/chapter1/3). 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 : - -```py -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 ! +# 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*](https://gradio.app/docs). 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](/course/fr/chapter9/2), 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"`. + + +```py +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()` : + +```py +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](/course/fr/chapter1/3). 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 : + +```py +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 ! diff --git a/chapters/fr/chapter9/4.mdx b/chapters/fr/chapter9/4.mdx index 937ac66d0..15735ecff 100644 --- a/chapters/fr/chapter9/4.mdx +++ b/chapters/fr/chapter9/4.mdx @@ -1,148 +1,296 @@ -# Partager ses démos avec les autres - - - -Maintenant que vous avez construit une démo, vous voudrez probablement la partager à d'autres personnes. Les démos *Gradio* peuvent être partagées de deux façons : en utilisant un lien de partage temporaire (***temporary share link***) ou un hébergement permanent (***permanent hosting on Spaces***). - -Nous aborderons ces deux approches sous peu. Mais avant de partager votre démo, vous voudrez peut-être la peaufiner 💅. - -### Polir votre démo Gradio - -
-Overview of a gradio interface - -
- -Pour ajouter du contenu supplémentaire à votre démo, la classe `Interface` supporte quelques paramètres optionnels : - - `title` : vous pouvez donner un titre à votre démo, qui apparaît _au-dessus_ des composants d'entrée et de sortie. - - `description` : vous pouvez donner une description (en texte, Markdown, ou HTML) pour l'interface, qui apparaît au-dessus des composants d'entrée et de sortie et en dessous du titre. - - `article` : vous pouvez également écrire un article étendu (en texte, Markdown ou HTML) expliquant l'interface. S'il est fourni, il apparaît _sous_ les composants d'entrée et de sortie. - - `theme` : vous n'aimez pas les couleurs par défaut ? Définissez le thème pour utiliser une des couleurs suivantes : `default`, `huggingface`, `grass`, `peach`. Vous pouvez également ajouter le préfixe `dark-`, par exemple `dark-peach` pour un thème sombre (ou juste `dark` pour le thème sombre par défaut). - - `examples` : pour rendre votre démo *beaucoup plus facile à utiliser*, vous pouvez fournir quelques exemples d'entrées pour la fonction. Ceux-ci apparaissent sous les composants de l'interface utilisateur et peuvent être utilisés pour remplir l'interface. Ils doivent être fournis sous forme de liste imbriquée, dans laquelle la liste extérieure est constituée d'exemples et chaque liste intérieure est constituée d'une entrée correspondant à chaque composant d'entrée. - - `live` : si vous voulez que votre modèle soit relancé à chaque fois que l'entrée change, vous pouvez mettre `live=True`. Ceci est utile pour les modèles rapides (nous verrons un exemple à la fin de cette section). -En utilisant les options ci-dessus, nous obtenons une interface plus complète. Exécutez le code ci-dessous pour pouvoir discuter avec Rick et Morty : - -```py -title = "Ask Rick a Question" # "Posez une question à Rick" -description = """ -The bot was trained to answer questions based on Rick and Morty dialogues. Ask Rick anything! -# Le robot a été entraîné à répondre à des questions basées sur les dialogues de Rick et Morty. -# Demandez à Rick ce que vous voulez ! - -""" - -article = "Check out [the original Rick and Morty Bot](https://huggingface.co/spaces/kingabzpro/Rick_and_Morty_Bot) that this demo is based off of." -# Jetez un coup d'œil au [bot original Rick et Morty](https://huggingface.co/spaces/kingabzpro/Rick_and_Morty_Bot) sur lequel cette démo est basée. - -gr.Interface( - fn=predict, - inputs="textbox", - outputs="text", - title=title, - description=description, - article=article, - examples=[["What are you doing?"], ["Where should we time travel to?"]], - # ["Que faites-vous ?"], ["Où devrions-nous voyager dans le temps ?"] -).launch() -``` - -En utilisant les options ci-dessus, nous obtenons une interface plus complète. Essayez l'interface ci-dessous : - - - -### Partager votre démo avec des liens temporaires -Maintenant que nous avons une démo fonctionnelle de notre modèle d'apprentissage automatique, apprenons à partager facilement un lien vers notre interface. -Les interfaces peuvent être facilement partagées publiquement en mettant `share=True` dans la méthode `launch()` : - -```python -gr.Interface(classify_image, "image", "label").launch(share=True) -``` - -Cela génère un lien public et partageable que vous pouvez envoyer à n'importe qui ! Lorsque vous envoyez ce lien, l'utilisateur de l'autre côté peut essayer le modèle dans son navigateur pendant 72 heures au maximum. Le traitement s'effectuant sur votre appareil (tant qu'il reste allumé !), vous n'avez pas à vous soucier de la mise en place de dépendances. Si vous travaillez à partir d'un *notebook* Google Colab, un lien de partage est toujours créé automatiquement. Il ressemble généralement à quelque chose comme ceci : **XXXXX.gradio.app**. Bien que le lien soit servi par un lien *Gradio*, nous ne sommes qu'un proxy pour votre serveur local, et nous ne stockons pas les données envoyées par les interfaces. - -Gardez cependant à l'esprit que ces liens sont accessibles au public, ce qui signifie que n'importe qui peut utiliser votre modèle pour la prédiction ! Par conséquent, assurez-vous de ne pas exposer d'informations sensibles à travers les fonctions que vous écrivez, ou de permettre que des changements critiques se produisent sur votre appareil. Si vous définissez `share=False` (la valeur par défaut), seul un lien local est créé. - -### Hébergement de votre démo sur Hugging Face Spaces - -Un lien de partage que vous pouvez passer à vos collègues est cool, mais comment pouvez-vous héberger de façon permanente votre démo et la faire exister dans son propre « espace » sur internet ? - -*Hugging Face Spaces* fournit l'infrastructure pour héberger de façon permanente votre démo *Gradio* sur internet et **gratuitement** ! *Spaces* vous permet de créer et de pousser vers un dépôt (public ou privé) le code de votre interface *Gradio*. Il sera placé dans un fichier `app.py`. [Lisez ce tutoriel étape par étape](https://huggingface.co/blog/gradio-spaces) pour commencer ou regardez la vidéo ci-dessous. - - - -## ✏️ Appliquons ça ! - -En utilisant ce que nous avons appris dans les sections précédentes, créons la démo de reconnaissance de croquis que nous avons décrit dans la [section un de ce chapitre](/course/fr/chapter9/1). Ajoutons quelques personnalisations à notre interface et définissons `share=True` pour créer un lien public que nous pouvons faire circuler. - -Nous pouvons charger les étiquettes depuis [class_names.txt](https://huggingface.co/spaces/dawood/Sketch-Recognition/blob/main/class_names.txt) et charger le modèle Pytorch pré-entraîné depuis [pytorch_model.bin](https://huggingface.co/spaces/dawood/Sketch-Recognition/blob/main/pytorch_model.bin). Téléchargez ces fichiers en suivant le lien et en cliquant sur « *download* » dans le coin supérieur gauche de l'aperçu du fichier. Regardons le code ci-dessous pour voir comment nous utilisons ces fichiers pour charger notre modèle et créer une fonction `predict()` : - -```py -from pathlib import Path -import torch -import gradio as gr -from torch import nn - -LABELS = Path("class_names.txt").read_text().splitlines() - -model = nn.Sequential( - nn.Conv2d(1, 32, 3, padding="same"), - nn.ReLU(), - nn.MaxPool2d(2), - nn.Conv2d(32, 64, 3, padding="same"), - nn.ReLU(), - nn.MaxPool2d(2), - nn.Conv2d(64, 128, 3, padding="same"), - nn.ReLU(), - nn.MaxPool2d(2), - nn.Flatten(), - nn.Linear(1152, 256), - nn.ReLU(), - nn.Linear(256, len(LABELS)), -) -state_dict = torch.load("pytorch_model.bin", map_location="cpu") -model.load_state_dict(state_dict, strict=False) -model.eval() - - -def predict(im): - x = torch.tensor(im, dtype=torch.float32).unsqueeze(0).unsqueeze(0) / 255.0 - with torch.no_grad(): - out = model(x) - probabilities = torch.nn.functional.softmax(out[0], dim=0) - values, indices = torch.topk(probabilities, 5) - return {LABELS[i]: v.item() for i, v in zip(indices, values)} -``` - -Maintenant que nous avons une fonction `predict()`. La prochaine étape est de définir et de lancer notre interface *Gradio* : - -```py -interface = gr.Interface( - predict, - inputs="sketchpad", - outputs="label", - theme="huggingface", - title="Sketch Recognition", - description="Who wants to play Pictionary? Draw a common object like a shovel or a laptop, and the algorithm will guess in real time!", - # Qui veut jouer au Pictionary ? Dessinez un objet courant comme une pelle ou un ordinateur portable, et l'algorithme le devinera en temps réel ! - article="

Sketch Recognition | Demo Model

", - live=True, -) -interface.launch(share=True) -``` - - - - -Remarquez le paramètre `live=True` dans `Interface`, qui signifie que la démo de sketchs fait une prédiction chaque fois que quelqu'un dessine sur le bloc (pas de bouton de soumission !). - -De plus, nous avons également défini l'argument `share=True` dans la méthode `launch()`. -Cela créera un lien public que vous pourrez envoyer à n'importe qui ! Lorsque vous envoyez ce lien, l'utilisateur de l'autre côté peut essayer le modèle de reconnaissance de croquis. Pour réitérer, vous pouvez également héberger le modèle sur *Hugging Face Spaces*, ce qui nous permet d'intégrer la démo ci-dessus. - -La prochaine fois, nous couvrirons d'autres façons dont *Gradio* peut être utilisé avec l'écosystème d'*Hugging Face* ! +# Partager ses démos avec les autres + + + +Maintenant que vous avez construit une démo, vous voudrez probablement la partager à d'autres personnes. Les démos *Gradio* peuvent être partagées de deux façons : en utilisant un lien de partage temporaire (***temporary share link***) ou un hébergement permanent (***permanent hosting on Spaces***). + +Nous aborderons ces deux approches sous peu. Mais avant de partager votre démo, vous voudrez peut-être la peaufiner 💅. + +### Polir votre démo Gradio + +
+Overview of a gradio interface + +
+ +Pour ajouter du contenu supplémentaire à votre démo, la classe `Interface` supporte quelques paramètres optionnels : + - `title` : vous pouvez donner un titre à votre démo, qui apparaît _au-dessus_ des composants d'entrée et de sortie. + - `description` : vous pouvez donner une description (en texte, Markdown, ou HTML) pour l'interface, qui apparaît au-dessus des composants d'entrée et de sortie et en dessous du titre. + - `article` : vous pouvez également écrire un article étendu (en texte, Markdown ou HTML) expliquant l'interface. S'il est fourni, il apparaît _sous_ les composants d'entrée et de sortie. + - `theme` : vous n'aimez pas les couleurs par défaut ? Définissez le thème pour utiliser une des couleurs suivantes : `default`, `huggingface`, `grass`, `peach`. Vous pouvez également ajouter le préfixe `dark-`, par exemple `dark-peach` pour un thème sombre (ou juste `dark` pour le thème sombre par défaut). + - `examples` : pour rendre votre démo *beaucoup plus facile à utiliser*, vous pouvez fournir quelques exemples d'entrées pour la fonction. Ceux-ci apparaissent sous les composants de l'interface utilisateur et peuvent être utilisés pour remplir l'interface. Ils doivent être fournis sous forme de liste imbriquée, dans laquelle la liste extérieure est constituée d'exemples et chaque liste intérieure est constituée d'une entrée correspondant à chaque composant d'entrée. + - `live` : si vous voulez que votre modèle soit relancé à chaque fois que l'entrée change, vous pouvez mettre `live=True`. Ceci est utile pour les modèles rapides (nous verrons un exemple à la fin de cette section). +En utilisant les options ci-dessus, nous obtenons une interface plus complète. Exécutez le code ci-dessous pour pouvoir discuter avec Rick et Morty : + +```py +title = "Ask Rick a Question" # "Posez une question à Rick" +description = """ +The bot was trained to answer questions based on Rick and Morty dialogues. Ask Rick anything! +# Le robot a été entraîné à répondre à des questions basées sur les dialogues de Rick et Morty. +# Demandez à Rick ce que vous voulez ! + +""" + +article = "Check out [the original Rick and Morty Bot](https://huggingface.co/spaces/kingabzpro/Rick_and_Morty_Bot) that this demo is based off of." +# Jetez un coup d'œil au [bot original Rick et Morty](https://huggingface.co/spaces/kingabzpro/Rick_and_Morty_Bot) sur lequel cette démo est basée. + +gr.Interface( + fn=predict, + inputs="textbox", + outputs="text", + title=title, + description=description, + article=article, + examples=[["What are you doing?"], ["Where should we time travel to?"]], + # ["Que faites-vous ?"], ["Où devrions-nous voyager dans le temps ?"] +).launch() +``` + +En utilisant les options ci-dessus, nous obtenons une interface plus complète. Essayez l'interface ci-dessous : + + + +### Partager votre démo avec des liens temporaires +Maintenant que nous avons une démo fonctionnelle de notre modèle d'apprentissage automatique, apprenons à partager facilement un lien vers notre interface. +Les interfaces peuvent être facilement partagées publiquement en mettant `share=True` dans la méthode `launch()` : + +```python +gr.Interface(classify_image, "image", "label").launch(share=True) +``` + +Cela génère un lien public et partageable que vous pouvez envoyer à n'importe qui ! Lorsque vous envoyez ce lien, l'utilisateur de l'autre côté peut essayer le modèle dans son navigateur pendant 72 heures au maximum. Le traitement s'effectuant sur votre appareil (tant qu'il reste allumé !), vous n'avez pas à vous soucier de la mise en place de dépendances. Si vous travaillez à partir d'un *notebook* Google Colab, un lien de partage est toujours créé automatiquement. Il ressemble généralement à quelque chose comme ceci : **XXXXX.gradio.app**. Bien que le lien soit servi par un lien *Gradio*, nous ne sommes qu'un proxy pour votre serveur local, et nous ne stockons pas les données envoyées par les interfaces. + +Gardez cependant à l'esprit que ces liens sont accessibles au public, ce qui signifie que n'importe qui peut utiliser votre modèle pour la prédiction ! Par conséquent, assurez-vous de ne pas exposer d'informations sensibles à travers les fonctions que vous écrivez, ou de permettre que des changements critiques se produisent sur votre appareil. Si vous définissez `share=False` (la valeur par défaut), seul un lien local est créé. + +### Hébergement de votre démo sur Hugging Face Spaces + +Un lien de partage que vous pouvez passer à vos collègues est cool, mais comment pouvez-vous héberger de façon permanente votre démo et la faire exister dans son propre « espace » sur internet ? + +*Hugging Face Spaces* fournit l'infrastructure pour héberger de façon permanente votre démo *Gradio* sur internet et **gratuitement** ! *Spaces* vous permet de créer et de pousser vers un dépôt (public ou privé) le code de votre interface *Gradio*. Il sera placé dans un fichier `app.py`. [Lisez ce tutoriel étape par étape](https://huggingface.co/blog/gradio-spaces) pour commencer ou regardez la vidéo ci-dessous. + + + +## ✏️ Appliquons ça ! + +En utilisant ce que nous avons appris dans les sections précédentes, créons la démo de reconnaissance de croquis que nous avons décrit dans la [section un de ce chapitre](/course/fr/chapter9/1). Ajoutons quelques personnalisations à notre interface et définissons `share=True` pour créer un lien public que nous pouvons faire circuler. + +Nous pouvons charger les étiquettes depuis [class_names.txt](https://huggingface.co/spaces/dawood/Sketch-Recognition/blob/main/class_names.txt) et charger le modèle Pytorch pré-entraîné depuis [pytorch_model.bin](https://huggingface.co/spaces/dawood/Sketch-Recognition/blob/main/pytorch_model.bin). Téléchargez ces fichiers en suivant le lien et en cliquant sur « *download* » dans le coin supérieur gauche de l'aperçu du fichier. Regardons le code ci-dessous pour voir comment nous utilisons ces fichiers pour charger notre modèle et créer une fonction `predict()` : + +```py +from pathlib import Path +import torch +import gradio as gr +from torch import nn + +LABELS = Path("class_names.txt").read_text().splitlines() + +model = nn.Sequential( + nn.Conv2d(1, 32, 3, padding="same"), + nn.ReLU(), + nn.MaxPool2d(2), + nn.Conv2d(32, 64, 3, padding="same"), + nn.ReLU(), + nn.MaxPool2d(2), + nn.Conv2d(64, 128, 3, padding="same"), + nn.ReLU(), + nn.MaxPool2d(2), + nn.Flatten(), + nn.Linear(1152, 256), + nn.ReLU(), + nn.Linear(256, len(LABELS)), +) +state_dict = torch.load("pytorch_model.bin", map_location="cpu") +model.load_state_dict(state_dict, strict=False) +model.eval() + + +def predict(im): + x = torch.tensor(im, dtype=torch.float32).unsqueeze(0).unsqueeze(0) / 255.0 + with torch.no_grad(): + out = model(x) + probabilities = torch.nn.functional.softmax(out[0], dim=0) + values, indices = torch.topk(probabilities, 5) + return {LABELS[i]: v.item() for i, v in zip(indices, values)} +``` + +Maintenant que nous avons une fonction `predict()`. La prochaine étape est de définir et de lancer notre interface *Gradio* : + +```py +interface = gr.Interface( + predict, + inputs="sketchpad", + outputs="label", + theme="huggingface", + title="Sketch Recognition", + description="Who wants to play Pictionary? Draw a common object like a shovel or a laptop, and the algorithm will guess in real time!", + # Qui veut jouer au Pictionary ? Dessinez un objet courant comme une pelle ou un ordinateur portable, et l'algorithme le devinera en temps réel ! + article="

Sketch Recognition | Demo Model

", + live=True, +) +interface.launch(share=True) +``` + + + + +Remarquez le paramètre `live=True` dans `Interface`, qui signifie que la démo de sketchs fait une prédiction chaque fois que quelqu'un dessine sur le bloc (pas de bouton de soumission !). + +De plus, nous avons également défini l'argument `share=True` dans la méthode `launch()`. +Cela créera un lien public que vous pourrez envoyer à n'importe qui ! Lorsque vous envoyez ce lien, l'utilisateur de l'autre côté peut essayer le modèle de reconnaissance de croquis. Pour réitérer, vous pouvez également héberger le modèle sur *Hugging Face Spaces*, ce qui nous permet d'intégrer la démo ci-dessus. + +La prochaine fois, nous couvrirons d'autres façons dont *Gradio* peut être utilisé avec l'écosystème d'*Hugging Face* ! +# Partager ses démos avec les autres + + + +Maintenant que vous avez construit une démo, vous voudrez probablement la partager à d'autres personnes. Les démos *Gradio* peuvent être partagées de deux façons : en utilisant un lien de partage temporaire (***temporary share link***) ou un hébergement permanent (***permanent hosting on Spaces***). + +Nous aborderons ces deux approches sous peu. Mais avant de partager votre démo, vous voudrez peut-être la peaufiner 💅. + +### Polir votre démo Gradio + +
+Overview of a gradio interface + +
+ +Pour ajouter du contenu supplémentaire à votre démo, la classe `Interface` supporte quelques paramètres optionnels : + - `title` : vous pouvez donner un titre à votre démo, qui apparaît _au-dessus_ des composants d'entrée et de sortie. + - `description` : vous pouvez donner une description (en texte, Markdown, ou HTML) pour l'interface, qui apparaît au-dessus des composants d'entrée et de sortie et en dessous du titre. + - `article` : vous pouvez également écrire un article étendu (en texte, Markdown ou HTML) expliquant l'interface. S'il est fourni, il apparaît _sous_ les composants d'entrée et de sortie. + - `theme` : vous n'aimez pas les couleurs par défaut ? Définissez le thème pour utiliser une des couleurs suivantes : `default`, `huggingface`, `grass`, `peach`. Vous pouvez également ajouter le préfixe `dark-`, par exemple `dark-peach` pour un thème sombre (ou juste `dark` pour le thème sombre par défaut). + - `examples` : pour rendre votre démo *beaucoup plus facile à utiliser*, vous pouvez fournir quelques exemples d'entrées pour la fonction. Ceux-ci apparaissent sous les composants de l'interface utilisateur et peuvent être utilisés pour remplir l'interface. Ils doivent être fournis sous forme de liste imbriquée, dans laquelle la liste extérieure est constituée d'exemples et chaque liste intérieure est constituée d'une entrée correspondant à chaque composant d'entrée. + - `live` : si vous voulez que votre modèle soit relancé à chaque fois que l'entrée change, vous pouvez mettre `live=True`. Ceci est utile pour les modèles rapides (nous verrons un exemple à la fin de cette section). +En utilisant les options ci-dessus, nous obtenons une interface plus complète. Exécutez le code ci-dessous pour pouvoir discuter avec Rick et Morty : + +```py +title = "Ask Rick a Question" # "Posez une question à Rick" +description = """ +The bot was trained to answer questions based on Rick and Morty dialogues. Ask Rick anything! +# Le robot a été entraîné à répondre à des questions basées sur les dialogues de Rick et Morty. +# Demandez à Rick ce que vous voulez ! + +""" + +article = "Check out [the original Rick and Morty Bot](https://huggingface.co/spaces/kingabzpro/Rick_and_Morty_Bot) that this demo is based off of." +# Jetez un coup d'œil au [bot original Rick et Morty](https://huggingface.co/spaces/kingabzpro/Rick_and_Morty_Bot) sur lequel cette démo est basée. + +gr.Interface( + fn=predict, + inputs="textbox", + outputs="text", + title=title, + description=description, + article=article, + examples=[["What are you doing?"], ["Where should we time travel to?"]], + # ["Que faites-vous ?"], ["Où devrions-nous voyager dans le temps ?"] +).launch() +``` + +En utilisant les options ci-dessus, nous obtenons une interface plus complète. Essayez l'interface ci-dessous : + + + +### Partager votre démo avec des liens temporaires +Maintenant que nous avons une démo fonctionnelle de notre modèle d'apprentissage automatique, apprenons à partager facilement un lien vers notre interface. +Les interfaces peuvent être facilement partagées publiquement en mettant `share=True` dans la méthode `launch()` : + +```python +gr.Interface(classify_image, "image", "label").launch(share=True) +``` + +Cela génère un lien public et partageable que vous pouvez envoyer à n'importe qui ! Lorsque vous envoyez ce lien, l'utilisateur de l'autre côté peut essayer le modèle dans son navigateur pendant 72 heures au maximum. Le traitement s'effectuant sur votre appareil (tant qu'il reste allumé !), vous n'avez pas à vous soucier de la mise en place de dépendances. Si vous travaillez à partir d'un *notebook* Google Colab, un lien de partage est toujours créé automatiquement. Il ressemble généralement à quelque chose comme ceci : **XXXXX.gradio.app**. Bien que le lien soit servi par un lien *Gradio*, nous ne sommes qu'un proxy pour votre serveur local, et nous ne stockons pas les données envoyées par les interfaces. + +Gardez cependant à l'esprit que ces liens sont accessibles au public, ce qui signifie que n'importe qui peut utiliser votre modèle pour la prédiction ! Par conséquent, assurez-vous de ne pas exposer d'informations sensibles à travers les fonctions que vous écrivez, ou de permettre que des changements critiques se produisent sur votre appareil. Si vous définissez `share=False` (la valeur par défaut), seul un lien local est créé. + +### Hébergement de votre démo sur Hugging Face Spaces + +Un lien de partage que vous pouvez passer à vos collègues est cool, mais comment pouvez-vous héberger de façon permanente votre démo et la faire exister dans son propre « espace » sur internet ? + +*Hugging Face Spaces* fournit l'infrastructure pour héberger de façon permanente votre démo *Gradio* sur internet et **gratuitement** ! *Spaces* vous permet de créer et de pousser vers un dépôt (public ou privé) le code de votre interface *Gradio*. Il sera placé dans un fichier `app.py`. [Lisez ce tutoriel étape par étape](https://huggingface.co/blog/gradio-spaces) pour commencer ou regardez la vidéo ci-dessous. + + + +## ✏️ Appliquons ça ! + +En utilisant ce que nous avons appris dans les sections précédentes, créons la démo de reconnaissance de croquis que nous avons décrit dans la [section un de ce chapitre](/course/fr/chapter9/1). Ajoutons quelques personnalisations à notre interface et définissons `share=True` pour créer un lien public que nous pouvons faire circuler. + +Nous pouvons charger les étiquettes depuis [class_names.txt](https://huggingface.co/spaces/dawood/Sketch-Recognition/blob/main/class_names.txt) et charger le modèle Pytorch pré-entraîné depuis [pytorch_model.bin](https://huggingface.co/spaces/dawood/Sketch-Recognition/blob/main/pytorch_model.bin). Téléchargez ces fichiers en suivant le lien et en cliquant sur « *download* » dans le coin supérieur gauche de l'aperçu du fichier. Regardons le code ci-dessous pour voir comment nous utilisons ces fichiers pour charger notre modèle et créer une fonction `predict()` : + +```py +from pathlib import Path +import torch +import gradio as gr +from torch import nn + +LABELS = Path("class_names.txt").read_text().splitlines() + +model = nn.Sequential( + nn.Conv2d(1, 32, 3, padding="same"), + nn.ReLU(), + nn.MaxPool2d(2), + nn.Conv2d(32, 64, 3, padding="same"), + nn.ReLU(), + nn.MaxPool2d(2), + nn.Conv2d(64, 128, 3, padding="same"), + nn.ReLU(), + nn.MaxPool2d(2), + nn.Flatten(), + nn.Linear(1152, 256), + nn.ReLU(), + nn.Linear(256, len(LABELS)), +) +state_dict = torch.load("pytorch_model.bin", map_location="cpu") +model.load_state_dict(state_dict, strict=False) +model.eval() + + +def predict(im): + x = torch.tensor(im, dtype=torch.float32).unsqueeze(0).unsqueeze(0) / 255.0 + with torch.no_grad(): + out = model(x) + probabilities = torch.nn.functional.softmax(out[0], dim=0) + values, indices = torch.topk(probabilities, 5) + return {LABELS[i]: v.item() for i, v in zip(indices, values)} +``` + +Maintenant que nous avons une fonction `predict()`. La prochaine étape est de définir et de lancer notre interface *Gradio* : + +```py +interface = gr.Interface( + predict, + inputs="sketchpad", + outputs="label", + theme="huggingface", + title="Sketch Recognition", + description="Who wants to play Pictionary? Draw a common object like a shovel or a laptop, and the algorithm will guess in real time!", + # Qui veut jouer au Pictionary ? Dessinez un objet courant comme une pelle ou un ordinateur portable, et l'algorithme le devinera en temps réel ! + article="

Sketch Recognition | Demo Model

", + live=True, +) +interface.launch(share=True) +``` + + + + +Remarquez le paramètre `live=True` dans `Interface`, qui signifie que la démo de sketchs fait une prédiction chaque fois que quelqu'un dessine sur le bloc (pas de bouton de soumission !). + +De plus, nous avons également défini l'argument `share=True` dans la méthode `launch()`. +Cela créera un lien public que vous pourrez envoyer à n'importe qui ! Lorsque vous envoyez ce lien, l'utilisateur de l'autre côté peut essayer le modèle de reconnaissance de croquis. Pour réitérer, vous pouvez également héberger le modèle sur *Hugging Face Spaces*, ce qui nous permet d'intégrer la démo ci-dessus. + +La prochaine fois, nous couvrirons d'autres façons dont *Gradio* peut être utilisé avec l'écosystème d'*Hugging Face* ! diff --git a/chapters/fr/chapter9/5.mdx b/chapters/fr/chapter9/5.mdx index 81a91e9d5..e84267a77 100644 --- a/chapters/fr/chapter9/5.mdx +++ b/chapters/fr/chapter9/5.mdx @@ -1,77 +1,77 @@ -# Intégrations avec le Hub d'Hugging Face - - - -Pour vous rendre la vie encore plus facile, *Gradio* s'intègre directement avec *Hub* et *Spaces*. -Vous pouvez charger des démos depuis le *Hub* et les *Spaces* avec seulement *une ligne de code*. - -### Chargement de modèles depuis le Hub d'Hugging Face - -Pour commencer, choisissez un des milliers de modèles qu'*Hugging Face* offre à travers le *Hub*, comme décrit dans le [chapitre 4](/course/fr/chapter4/2). - -En utilisant la méthode spéciale `Interface.load()`, vous passez `"model/"` (ou, de manière équivalente, `"huggingface/"`) suivi du nom du modèle. -Par exemple, voici le code pour construire une démo pour le [GPT-J](https://huggingface.co/EleutherAI/gpt-j-6B), un grand modèle de langue, ajouter quelques exemples d'entrées : - -```py -import gradio as gr - -title = "GPT-J-6B" -description = "Gradio Demo for GPT-J 6B, a transformer model trained using Ben Wang's Mesh Transformer JAX. 'GPT-J' refers to the class of model, while '6B' represents the number of trainable parameters. To use it, simply add your text, or click one of the examples to load them. Read more at the links below." -# Démo Gradio pour GPT-J 6B, un modèle de transformer entraîné avec le Mesh Transformer JAX de Ben Wang. GPT-J fait référence à la classe du modèle, tandis que '6B' représente le nombre de paramètres entraînables. Pour l'utiliser, il suffit d'ajouter votre texte, ou de cliquer sur l'un des exemples pour le charger. Pour en savoir plus, consultez les liens ci-dessous. -article = "

GPT-J-6B: A 6 Billion Parameter Autoregressive Language Model

" -# GPT-J-6B : Un modèle linguistique autorégressif à 6 milliards de paramètres -examples = [ - ["The tower is 324 metres (1,063 ft) tall,"], - # La tour mesure 324 mètres (1 063 pieds) de haut, - ["The Moon's orbit around Earth has"], - # L'orbite de la Lune autour de la Terre a - ["The smooth Borealis basin in the Northern Hemisphere covers 40%"], - # Le bassin de Borealis dans l'hémisphère nord couvre 40 %. -] -gr.Interface.load( - "huggingface/EleutherAI/gpt-j-6B", - inputs=gr.Textbox(lines=5, label="Input Text"), - title=title, - description=description, - article=article, - examples=examples, - enable_queue=True, -).launch() -``` - -Le code ci-dessus produira l'interface ci-dessous : - - - -Le chargement d'un modèle de cette manière utilise l'[API d'Inference](https://huggingface.co/inference-api) de *Hugging Face* au lieu de charger le modèle en mémoire. C'est idéal pour les modèles énormes comme GPT-J ou T0pp qui nécessitent beaucoup de RAM. - -### Chargement depuis Hugging Face Spaces - -Pour charger n'importe quel *Space* depuis le *Hub* et le recréer localement, vous pouvez passer `spaces/` à l'`Interface`, suivi du nom du *Space*. - -Vous vous souvenez de la démo de la section 1 qui supprime le fond d'une image ? Chargeons-la à partir de *Hugging Face Spaces* : - -```py -gr.Interface.load("spaces/abidlabs/remove-bg").launch() -``` - - - -L'un des avantages du chargement de démos à partir du *Hub* ou de *Spaces* est que vous pouvez les personnaliser en remplaçant n'importe lequel des paramètres. Ici, nous ajoutons un titre et faisons en sorte qu'elle fonctionne avec une webcam à la place : - -```py -gr.Interface.load( - "spaces/abidlabs/remove-bg", inputs="webcam", title="Remove your webcam background!" -).launch() -``` - - - -Maintenant que nous avons exploré quelques façons d'intégrer *Gradio* avec le *Hub*, jetons un coup d'oeil à certaines fonctionnalités avancées de la classe `Interface`. C'est le sujet de la prochaine section ! +# Intégrations avec le Hub d'Hugging Face + + + +Pour vous rendre la vie encore plus facile, *Gradio* s'intègre directement avec *Hub* et *Spaces*. +Vous pouvez charger des démos depuis le *Hub* et les *Spaces* avec seulement *une ligne de code*. + +### Chargement de modèles depuis le Hub d'Hugging Face + +Pour commencer, choisissez un des milliers de modèles qu'*Hugging Face* offre à travers le *Hub*, comme décrit dans le [chapitre 4](/course/fr/chapter4/2). + +En utilisant la méthode spéciale `Interface.load()`, vous passez `"model/"` (ou, de manière équivalente, `"huggingface/"`) suivi du nom du modèle. +Par exemple, voici le code pour construire une démo pour le [GPT-J](https://huggingface.co/EleutherAI/gpt-j-6B), un grand modèle de langue, ajouter quelques exemples d'entrées : + +```py +import gradio as gr + +title = "GPT-J-6B" +description = "Gradio Demo for GPT-J 6B, a transformer model trained using Ben Wang's Mesh Transformer JAX. 'GPT-J' refers to the class of model, while '6B' represents the number of trainable parameters. To use it, simply add your text, or click one of the examples to load them. Read more at the links below." +# Démo Gradio pour GPT-J 6B, un modèle de transformer entraîné avec le Mesh Transformer JAX de Ben Wang. GPT-J fait référence à la classe du modèle, tandis que '6B' représente le nombre de paramètres entraînables. Pour l'utiliser, il suffit d'ajouter votre texte, ou de cliquer sur l'un des exemples pour le charger. Pour en savoir plus, consultez les liens ci-dessous. +article = "

GPT-J-6B: A 6 Billion Parameter Autoregressive Language Model

" +# GPT-J-6B : Un modèle linguistique autorégressif à 6 milliards de paramètres +examples = [ + ["The tower is 324 metres (1,063 ft) tall,"], + # La tour mesure 324 mètres (1 063 pieds) de haut, + ["The Moon's orbit around Earth has"], + # L'orbite de la Lune autour de la Terre a + ["The smooth Borealis basin in the Northern Hemisphere covers 40%"], + # Le bassin de Borealis dans l'hémisphère nord couvre 40 %. +] +gr.Interface.load( + "huggingface/EleutherAI/gpt-j-6B", + inputs=gr.Textbox(lines=5, label="Input Text"), + title=title, + description=description, + article=article, + examples=examples, + enable_queue=True, +).launch() +``` + +Le code ci-dessus produira l'interface ci-dessous : + + + +Le chargement d'un modèle de cette manière utilise l'[API d'Inference](https://huggingface.co/inference-api) de *Hugging Face* au lieu de charger le modèle en mémoire. C'est idéal pour les modèles énormes comme GPT-J ou T0pp qui nécessitent beaucoup de RAM. + +### Chargement depuis Hugging Face Spaces + +Pour charger n'importe quel *Space* depuis le *Hub* et le recréer localement, vous pouvez passer `spaces/` à l'`Interface`, suivi du nom du *Space*. + +Vous vous souvenez de la démo de la section 1 qui supprime le fond d'une image ? Chargeons-la à partir de *Hugging Face Spaces* : + +```py +gr.Interface.load("spaces/abidlabs/remove-bg").launch() +``` + + + +L'un des avantages du chargement de démos à partir du *Hub* ou de *Spaces* est que vous pouvez les personnaliser en remplaçant n'importe lequel des paramètres. Ici, nous ajoutons un titre et faisons en sorte qu'elle fonctionne avec une webcam à la place : + +```py +gr.Interface.load( + "spaces/abidlabs/remove-bg", inputs="webcam", title="Remove your webcam background!" +).launch() +``` + + + +Maintenant que nous avons exploré quelques façons d'intégrer *Gradio* avec le *Hub*, jetons un coup d'oeil à certaines fonctionnalités avancées de la classe `Interface`. C'est le sujet de la prochaine section ! diff --git a/chapters/fr/chapter9/6.mdx b/chapters/fr/chapter9/6.mdx index 49b7c78f1..edb35e23f 100644 --- a/chapters/fr/chapter9/6.mdx +++ b/chapters/fr/chapter9/6.mdx @@ -1,140 +1,140 @@ -# Fonctionnalités avancées de l'interface - - - -Maintenant que nous pouvons construire et partager une interface de base, explorons quelques fonctionnalités plus avancées comme l'état, l'interprétation et l'authentification. - -### Utilisation de l'état pour faire persister les données - -*Gradio* supporte *l'état de session* où les données persistent à travers plusieurs soumissions dans un chargement de page. L'état de session est utile pour construire des démos où vous souhaitez faire persister les données au fur et à mesure que l'utilisateur interagit avec le modèle (par exemple des chatbots). Notez que l'état de session ne partage pas les données entre les différents utilisateurs de votre modèle. - -Pour stocker des données dans un état de session, vous devez faire trois choses : - -- Passez un *paramètre supplémentaire* dans votre fonction, qui représente l'état de l'interface. -- A la fin de la fonction, renvoyer la valeur mise à jour de l'état comme une *valeur de retour supplémentaire*. -- Ajoutez les composants "state" input et "state" output lors de la création de votre `Interface`. - -Voir l'exemple de chatbot ci-dessous : - -```py -import random - -import gradio as gr - - -def chat(message, history): - history = history or [] - if message.startswith("How many"): - response = random.randint(1, 10) - elif message.startswith("How"): - response = random.choice(["Great", "Good", "Okay", "Bad"]) - elif message.startswith("Where"): - response = random.choice(["Here", "There", "Somewhere"]) - else: - response = "I don't know" - history.append((message, response)) - return history, history - - -iface = gr.Interface( - chat, - ["text", "state"], - ["chatbot", "state"], - allow_screenshot=False, - allow_flagging="never", -) -iface.launch() -``` - - -Remarquez comment l'état du composant de sortie persiste entre les soumissions. -Remarque : vous pouvez transmettre une valeur par défaut au paramètre state, qui est utilisée comme valeur initiale de l'état. - -### Utilisation de l'interprétation pour comprendre les prédictions - -La plupart des modèles d'apprentissage automatique sont des boîtes noires et la logique interne de la fonction est cachée à l'utilisateur final. Pour encourager la transparence, nous avons fait en sorte qu'il soit très facile d'ajouter l'interprétation à votre modèle en définissant simplement le mot-clé interprétation dans la classe Interface par défaut. Cela permet à vos utilisateurs de comprendre quelles parties de l'entrée sont responsables de la sortie. Jetez un coup d'œil à l'interface simple ci-dessous qui montre un classifieur d'images incluant l'interprétation : - -```py -import requests -import tensorflow as tf - -import gradio as gr - -inception_net = tf.keras.applications.MobileNetV2() # charger le modèle - -# Télécharger des étiquettes lisibles par l'homme pour ImageNet -response = requests.get("https://git.io/JJkYN") -labels = response.text.split("\n") - - -def classify_image(inp): - inp = inp.reshape((-1, 224, 224, 3)) - inp = tf.keras.applications.mobilenet_v2.preprocess_input(inp) - prediction = inception_net.predict(inp).flatten() - return {labels[i]: float(prediction[i]) for i in range(1000)} - - -image = gr.Image(shape=(224, 224)) -label = gr.Label(num_top_classes=3) - -title = "Gradio Image Classifiction + Interpretation Example" -gr.Interface( - fn=classify_image, inputs=image, outputs=label, interpretation="default", title=title -).launch() -``` - -Testez la fonction d'interprétation en soumettant une entrée puis en cliquant sur « Interpréter » sous le composant de sortie. - - - -En plus de la méthode d'interprétation par défaut fournie par *Gradio*, vous pouvez également spécifier `shap` pour le paramètre `interpretation` et définir le paramètre `num_shap`. Ceci utilise l'interprétation basée sur Shapley, dont vous pouvez lire plus sur [ici](https://christophm.github.io/interpretable-ml-book/shap.html). -Enfin, vous pouvez aussi passer votre propre fonction d'interprétation dans le paramètre `interpretation`. Vous trouverez un exemple dans la page de démarrage de *Gradio* [ici](https://gradio.app/getting_started/). - - -### Ajouter l'authentification - -Vous pouvez vouloir ajouter une authentification à votre interface *Gradio* afin de contrôler qui peut accéder et utiliser votre démo. - -L'authentification peut être ajoutée en fournissant une liste de tuples de nom d'utilisateur/mot de passe au paramètre `auth` de la méthode `launch()`. Pour une gestion plus complexe de l'authentification, vous pouvez passer une fonction qui prend un nom d'utilisateur et un mot de passe comme arguments, et retourne `True` pour permettre l'authentification, `False` sinon. - -Prenons la démo de classification d'images ci-dessus et ajoutons l'authentification : - -```py -import requests -import tensorflow as tf - -import gradio as gr - -inception_net = tf.keras.applications.MobileNetV2() # charger le modèle - -# Télécharger des étiquettes lisibles par l'homme pour ImageNet -response = requests.get("https://git.io/JJkYN") -labels = response.text.split("\n") - - -def classify_image(inp): - inp = inp.reshape((-1, 224, 224, 3)) - inp = tf.keras.applications.mobilenet_v2.preprocess_input(inp) - prediction = inception_net.predict(inp).flatten() - return {labels[i]: float(prediction[i]) for i in range(1000)} - - -image = gr.Image(shape=(224, 224)) -label = gr.Label(num_top_classes=3) - -title = "Gradio Image Classifiction + Interpretation Example" -gr.Interface( - fn=classify_image, inputs=image, outputs=label, interpretation="default", title=title -).launch(auth=("admin", "pass1234")) -``` - - - -Ceci conclut notre plongée dans la classe `Interface` de *Gradio*. Comme nous l'avons vu, cette classe permet de créer facilement des démos d'apprentissage automatique en quelques lignes de code Python. Cependant, vous voudrez parfois personnaliser votre démo en changeant la mise en page ou en enchaînant plusieurs fonctions de prédiction. Ne serait-il pas agréable de pouvoir diviser l'interface en blocs personnalisables ? Heureusement, c'est possible ! C'est le sujet de la dernière section. +# Fonctionnalités avancées de l'interface + + + +Maintenant que nous pouvons construire et partager une interface de base, explorons quelques fonctionnalités plus avancées comme l'état, l'interprétation et l'authentification. + +### Utilisation de l'état pour faire persister les données + +*Gradio* supporte *l'état de session* où les données persistent à travers plusieurs soumissions dans un chargement de page. L'état de session est utile pour construire des démos où vous souhaitez faire persister les données au fur et à mesure que l'utilisateur interagit avec le modèle (par exemple des chatbots). Notez que l'état de session ne partage pas les données entre les différents utilisateurs de votre modèle. + +Pour stocker des données dans un état de session, vous devez faire trois choses : + +- Passez un *paramètre supplémentaire* dans votre fonction, qui représente l'état de l'interface. +- A la fin de la fonction, renvoyer la valeur mise à jour de l'état comme une *valeur de retour supplémentaire*. +- Ajoutez les composants "state" input et "state" output lors de la création de votre `Interface`. + +Voir l'exemple de chatbot ci-dessous : + +```py +import random + +import gradio as gr + + +def chat(message, history): + history = history or [] + if message.startswith("How many"): + response = random.randint(1, 10) + elif message.startswith("How"): + response = random.choice(["Great", "Good", "Okay", "Bad"]) + elif message.startswith("Where"): + response = random.choice(["Here", "There", "Somewhere"]) + else: + response = "I don't know" + history.append((message, response)) + return history, history + + +iface = gr.Interface( + chat, + ["text", "state"], + ["chatbot", "state"], + allow_screenshot=False, + allow_flagging="never", +) +iface.launch() +``` + + +Remarquez comment l'état du composant de sortie persiste entre les soumissions. +Remarque : vous pouvez transmettre une valeur par défaut au paramètre state, qui est utilisée comme valeur initiale de l'état. + +### Utilisation de l'interprétation pour comprendre les prédictions + +La plupart des modèles d'apprentissage automatique sont des boîtes noires et la logique interne de la fonction est cachée à l'utilisateur final. Pour encourager la transparence, nous avons fait en sorte qu'il soit très facile d'ajouter l'interprétation à votre modèle en définissant simplement le mot-clé interprétation dans la classe Interface par défaut. Cela permet à vos utilisateurs de comprendre quelles parties de l'entrée sont responsables de la sortie. Jetez un coup d'œil à l'interface simple ci-dessous qui montre un classifieur d'images incluant l'interprétation : + +```py +import requests +import tensorflow as tf + +import gradio as gr + +inception_net = tf.keras.applications.MobileNetV2() # charger le modèle + +# Télécharger des étiquettes lisibles par l'homme pour ImageNet +response = requests.get("https://git.io/JJkYN") +labels = response.text.split("\n") + + +def classify_image(inp): + inp = inp.reshape((-1, 224, 224, 3)) + inp = tf.keras.applications.mobilenet_v2.preprocess_input(inp) + prediction = inception_net.predict(inp).flatten() + return {labels[i]: float(prediction[i]) for i in range(1000)} + + +image = gr.Image(shape=(224, 224)) +label = gr.Label(num_top_classes=3) + +title = "Gradio Image Classifiction + Interpretation Example" +gr.Interface( + fn=classify_image, inputs=image, outputs=label, interpretation="default", title=title +).launch() +``` + +Testez la fonction d'interprétation en soumettant une entrée puis en cliquant sur « Interpréter » sous le composant de sortie. + + + +En plus de la méthode d'interprétation par défaut fournie par *Gradio*, vous pouvez également spécifier `shap` pour le paramètre `interpretation` et définir le paramètre `num_shap`. Ceci utilise l'interprétation basée sur Shapley, dont vous pouvez lire plus sur [ici](https://christophm.github.io/interpretable-ml-book/shap.html). +Enfin, vous pouvez aussi passer votre propre fonction d'interprétation dans le paramètre `interpretation`. Vous trouverez un exemple dans la page de démarrage de *Gradio* [ici](https://gradio.app/getting_started/). + + +### Ajouter l'authentification + +Vous pouvez vouloir ajouter une authentification à votre interface *Gradio* afin de contrôler qui peut accéder et utiliser votre démo. + +L'authentification peut être ajoutée en fournissant une liste de tuples de nom d'utilisateur/mot de passe au paramètre `auth` de la méthode `launch()`. Pour une gestion plus complexe de l'authentification, vous pouvez passer une fonction qui prend un nom d'utilisateur et un mot de passe comme arguments, et retourne `True` pour permettre l'authentification, `False` sinon. + +Prenons la démo de classification d'images ci-dessus et ajoutons l'authentification : + +```py +import requests +import tensorflow as tf + +import gradio as gr + +inception_net = tf.keras.applications.MobileNetV2() # charger le modèle + +# Télécharger des étiquettes lisibles par l'homme pour ImageNet +response = requests.get("https://git.io/JJkYN") +labels = response.text.split("\n") + + +def classify_image(inp): + inp = inp.reshape((-1, 224, 224, 3)) + inp = tf.keras.applications.mobilenet_v2.preprocess_input(inp) + prediction = inception_net.predict(inp).flatten() + return {labels[i]: float(prediction[i]) for i in range(1000)} + + +image = gr.Image(shape=(224, 224)) +label = gr.Label(num_top_classes=3) + +title = "Gradio Image Classifiction + Interpretation Example" +gr.Interface( + fn=classify_image, inputs=image, outputs=label, interpretation="default", title=title +).launch(auth=("admin", "pass1234")) +``` + + + +Ceci conclut notre plongée dans la classe `Interface` de *Gradio*. Comme nous l'avons vu, cette classe permet de créer facilement des démos d'apprentissage automatique en quelques lignes de code Python. Cependant, vous voudrez parfois personnaliser votre démo en changeant la mise en page ou en enchaînant plusieurs fonctions de prédiction. Ne serait-il pas agréable de pouvoir diviser l'interface en blocs personnalisables ? Heureusement, c'est possible ! C'est le sujet de la dernière section. diff --git a/chapters/fr/chapter9/7.mdx b/chapters/fr/chapter9/7.mdx index 34395d9e7..9331d4eb9 100644 --- a/chapters/fr/chapter9/7.mdx +++ b/chapters/fr/chapter9/7.mdx @@ -1,242 +1,242 @@ -# Introduction à la classe Blocks - - - -Dans les sections précédentes, nous avons exploré et créé des démos en utilisant la classe `Interface`. Dans cette section, nous allons présenter une **nouvelle** API de bas niveau appelée `gradio.Blocks`. - -Quelle est la différence entre `Interface` et `Blocks` ? - -- ⚡ `Interface` : une API de haut niveau qui vous permet de créer une démo complète d'apprentissage automatique simplement en fournissant une liste d'entrées et de sorties. - -- 🧱 `Blocks` : une API de bas niveau qui vous permet d'avoir un contrôle total sur les flux de données et la disposition de votre application. Vous pouvez construire des applications très complexes, en plusieurs étapes, en utilisant `Blocks`. - - -### Pourquoi Blocks 🧱 ? - -Comme nous l'avons vu dans les sections précédentes, la classe `Interface` vous permet de créer facilement des démos d'apprentissage automatique à part entière avec seulement quelques lignes de code. L'API `Interface` est extrêmement facile à utiliser, mais elle n'a pas la flexibilité qu'offre l'API `Blocks`. Par exemple, vous pourriez vouloir : - -- regrouper des démos connexes sous forme d'onglets multiples dans une application web, -- modifier la mise en page de votre démo, par exemple pour spécifier l'emplacement des entrées et des sorties, -- disposer d'interfaces multi-étapes dans lesquelles la sortie d'un modèle devient l'entrée du modèle suivant ou avoir des flux de données plus flexibles en général, -- modifier les propriétés d'un composant (par exemple, les choix dans une liste déroulante) ou sa visibilité en fonction des entrées de l'utilisateur. - -Nous allons explorer tous ces concepts ci-dessous. - -### Création d'une démo simple en utilisant Blocks - -Après avoir installé *Gradio*, exécutez le code ci-dessous sous forme de script Python, de *notebook* Jupyter ou de *notebook* Colab. - -```py -import gradio as gr - - -def flip_text(x): - return x[::-1] - - -demo = gr.Blocks() - -with demo: - gr.Markdown( - """ - # Flip Text! - Start typing below to see the output. - """ - ) - input = gr.Textbox(placeholder="Flip this text") - output = gr.Textbox() - - input.change(fn=flip_text, inputs=input, outputs=output) - -demo.launch() -``` - - - -Ce simple exemple ci-dessus introduit 4 concepts qui sous-tendent les *Blocks* : - -1. Les *Blocks* vous permettent de construire des applications web qui combinent Markdown, HTML, boutons et composants interactifs simplement en instanciant des objets en Python dans un contexte `with gradio.Blocks`. - - -🙋Si vous n'êtes pas familier avec l'instruction `with` en Python, nous vous recommandons de consulter l'excellent tutoriel de Real Python. Revenez ici après l'avoir lu 🤗 - - -L'ordre dans lequel vous instanciez les composants est important car chaque élément est restitué dans l'application Web dans l'ordre où il a été créé. (Les mises en page plus complexes sont abordées ci-dessous) - -2. Vous pouvez définir des fonctions Python ordinaires n'importe où dans votre code et les exécuter avec des entrées utilisateur en utilisant les `Blocks`. Dans notre exemple, nous avons une fonction simple qui inverse le texte entré mais vous pouvez écrire n'importe quelle fonction Python, du simple calcul au traitement des prédictions d'un modèle d'apprentissage automatique. - -3. Vous pouvez assigner des événements à n'importe quel composant `Blocks`. Ainsi, votre fonction sera exécutée lorsque le composant sera cliqué, modifié, etc. Lorsque vous assignez un événement, vous passez trois paramètres : -- `fn` : la fonction qui doit être appelée, -- `inputs` : la (liste) des composants d'entrée -- `outputs` : la (liste) des composants de sortie qui doivent être appelés. - Dans l'exemple ci-dessus, nous exécutons la fonction `flip_text()` lorsque la valeur de la `Textbox` nommée input `input` change. L'événement lit la valeur dans `input`, la passe comme paramètre de nom à `flip_text()`, qui renvoie alors une valeur qui est assignée à notre seconde `Textbox` nommée `output`. - Pour voir la liste des événements que chaque composant supporte, consultez la [documentation](https://www.gradio.app/docs/) de *Gradio*. - -4. *Blocks* détermine automatiquement si un composant doit être interactif (accepter les entrées de l'utilisateur) ou non, en fonction des déclencheurs d'événements que vous définissez. Dans notre exemple, la première zone de texte est interactive, puisque sa valeur est utilisée par la fonction `flip_text()`. La deuxième zone de texte n'est pas interactive, puisque sa valeur n'est jamais utilisée comme entrée. Dans certains cas, vous voudrez peut-être passer outre, ce que vous pouvez faire en passant un booléen au paramètre `interactive` du composant (par exemple, `gr.Textbox(placeholder="Flip this text", interactive=True)`). - - -### Personnaliser la mise en page de votre démo - -Comment pouvons-nous utiliser `Blocks` pour personnaliser la mise en page de notre démo ? Par défaut, `Blocks` affiche verticalement dans une colonne les composants que vous créez. Vous pouvez changer cela en créant des colonnes supplémentaires `avec gradio.Column():` ou des lignes `avec gradio.Row():` et en créant des composants dans ces contextes. - -Voici ce que vous devez garder à l'esprit : tout composant créé sous une `Column` (c'est aussi le défaut) sera disposé verticalement. Tout composant créé sous une `Row` sera disposé horizontalement, comme le [modèle flexbox dans le développement web](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox). - -Enfin, vous pouvez également créer des onglets pour votre démo en utilisant le gestionnaire de contexte `with gradio.Tabs()`. Dans ce contexte, vous pouvez créer plusieurs onglets en spécifiant des enfants `with gradio.TabItem(name_of_tab):`. Tout composant créé dans un contexte `with gradio.TabItem(name_of_tab):` apparaît dans cet onglet. - -Maintenant, ajoutons une fonction `flip_image()` à notre démo et ajoutons un nouvel onglet qui retourne les images. Vous trouverez ci-dessous un exemple avec 2 onglets et utilisant également une `Row` : - -```py -import numpy as np -import gradio as gr - -demo = gr.Blocks() - - -def flip_text(x): - return x[::-1] - - -def flip_image(x): - return np.fliplr(x) - - -with demo: - gr.Markdown("Flip text or image files using this demo.") - with gr.Tabs(): - with gr.TabItem("Flip Text"): - with gr.Row(): - text_input = gr.Textbox() - text_output = gr.Textbox() - text_button = gr.Button("Flip") - with gr.TabItem("Flip Image"): - with gr.Row(): - image_input = gr.Image() - image_output = gr.Image() - image_button = gr.Button("Flip") - - text_button.click(flip_text, inputs=text_input, outputs=text_output) - image_button.click(flip_image, inputs=image_input, outputs=image_output) - -demo.launch() -``` - - - - -Vous remarquerez que dans cet exemple, nous avons également créé un composant `Button` dans chaque onglet et avons assigné un événement de clic à chaque bouton qui est l'élément qui exécute réellement la fonction. - -### Exploration des événements et de l'état - -De la même manière que vous pouvez contrôler la mise en page, `Blocks` vous donne un contrôle fin sur les événements qui déclenchent les appels de fonction. Chaque composant et de nombreux layouts ont des événements spécifiques qu'ils supportent. - -Par exemple, le composant `Textbox` a 2 événements : `change()` (lorsque la valeur contenue dans la zone de texte change), et `submit()` (lorsqu'un utilisateur appuie sur la touche Entrée alors qu'il est concentré sur la zone de texte). Les composants plus complexes peuvent avoir encore plus d'événements : par exemple, le composant `Audio` a aussi des événements séparés pour quand le fichier audio est joué, effacé, mis en pause, etc. Consultez la documentation pour connaître les événements pris en charge par chaque composant. - -Vous pouvez attacher un déclencheur d'événement à aucun, un ou plusieurs de ces événements. Vous créez un déclencheur d'événement en appelant le nom de l'événement sur l'instance du composant comme une fonction. Par exemple, `textbox.change(...)` ou `btn.click(...)`. La fonction prend trois paramètres, comme indiqué ci-dessus : - -- `fn` : la fonction à exécuter -- `inputs` : une (liste de) composante(s) dont les valeurs doivent être fournies comme paramètres d'entrée à la fonction. La valeur de chaque composant est mise en correspondance avec le paramètre de fonction correspondant, dans l'ordre. Ce paramètre peut être `None` si la fonction ne prend aucun paramètre. -- `outputs` : un (liste de) composant(s) dont les valeurs doivent être mises à jour en fonction des valeurs retournées par la fonction. Chaque valeur de retour met à jour la valeur du composant correspondant, dans l'ordre. Ce paramètre peut être None si la fonction ne retourne rien. - -Vous pouvez même faire en sorte que le composant d'entrée et de sortie soit le même composant, comme nous le faisons dans cet exemple qui utilise un modèle GPT pour compléter du texte : - -```py -import gradio as gr - -api = gr.Interface.load("huggingface/EleutherAI/gpt-j-6B") - - -def complete_with_gpt(text): - # Utilise les 50 derniers caractères du texte comme contexte. - return text[:-50] + api(text[-50:]) - - -with gr.Blocks() as demo: - textbox = gr.Textbox(placeholder="Type here and press enter...", lines=4) - btn = gr.Button("Generate") - - btn.click(complete_with_gpt, textbox, textbox) - -demo.launch() -``` - - - -### Création de démos multi-étapes - -Dans certains cas, vous pouvez vouloir une _démo multi-étapes_, dans laquelle vous réutilisez la sortie d'une fonction comme entrée de la suivante. C'est très facile à faire avec les `Blocks`, car vous pouvez utiliser un composant pour l'entrée d'un déclencheur d'événement mais la sortie d'un autre. Regardez le composant texte dans l'exemple ci-dessous, sa valeur est le résultat d'un modèle de conversion de la parole en texte, mais il est également transmis à un modèle d'analyse des sentiments : - -```py -from transformers import pipeline - -import gradio as gr - -asr = pipeline("automatic-speech-recognition", "facebook/wav2vec2-base-960h") -classifier = pipeline("text-classification") - - -def speech_to_text(speech): - text = asr(speech)["text"] - return text - - -def text_to_sentiment(text): - return classifier(text)[0]["label"] - - -demo = gr.Blocks() - -with demo: - audio_file = gr.Audio(type="filepath") - text = gr.Textbox() - label = gr.Label() - - b1 = gr.Button("Recognize Speech") - b2 = gr.Button("Classify Sentiment") - - b1.click(speech_to_text, inputs=audio_file, outputs=text) - b2.click(text_to_sentiment, inputs=text, outputs=label) - -demo.launch() -``` - - - -### Mise à jour des propriétés des composants - -Jusqu'à présent, nous avons vu comment créer des événements pour mettre à jour la valeur d'un autre composant. Mais que se passe-t-il si vous voulez modifier d'autres propriétés d'un composant, comme la visibilité d'une zone de texte ou les choix dans un groupe de boutons radio ? Vous pouvez le faire en renvoyant la méthode `update()` d'une classe de composant au lieu d'une valeur de retour normale de votre fonction. - -L'exemple le plus facile à illustrer est le suivant : - -```py -import gradio as gr - - -def change_textbox(choice): - if choice == "short": - return gr.Textbox.update(lines=2, visible=True) - elif choice == "long": - return gr.Textbox.update(lines=8, visible=True) - else: - return gr.Textbox.update(visible=False) - - -with gr.Blocks() as block: - radio = gr.Radio( - ["short", "long", "none"], label="What kind of essay would you like to write?" - ) - text = gr.Textbox(lines=2, interactive=True) - - radio.change(fn=change_textbox, inputs=radio, outputs=text) - block.launch() -``` - - - -Nous venons d'explorer tous les concepts de base des `Blocks` ! Tout comme avec `Interface`, vous pouvez créer des démos sympas qui peuvent être partagées en utilisant `share=True` dans la méthode `launch()` ou déployées sur [*Spaces*](https://huggingface.co/spaces). +# Introduction à la classe Blocks + + + +Dans les sections précédentes, nous avons exploré et créé des démos en utilisant la classe `Interface`. Dans cette section, nous allons présenter une **nouvelle** API de bas niveau appelée `gradio.Blocks`. + +Quelle est la différence entre `Interface` et `Blocks` ? + +- ⚡ `Interface` : une API de haut niveau qui vous permet de créer une démo complète d'apprentissage automatique simplement en fournissant une liste d'entrées et de sorties. + +- 🧱 `Blocks` : une API de bas niveau qui vous permet d'avoir un contrôle total sur les flux de données et la disposition de votre application. Vous pouvez construire des applications très complexes, en plusieurs étapes, en utilisant `Blocks`. + + +### Pourquoi Blocks 🧱 ? + +Comme nous l'avons vu dans les sections précédentes, la classe `Interface` vous permet de créer facilement des démos d'apprentissage automatique à part entière avec seulement quelques lignes de code. L'API `Interface` est extrêmement facile à utiliser, mais elle n'a pas la flexibilité qu'offre l'API `Blocks`. Par exemple, vous pourriez vouloir : + +- regrouper des démos connexes sous forme d'onglets multiples dans une application web, +- modifier la mise en page de votre démo, par exemple pour spécifier l'emplacement des entrées et des sorties, +- disposer d'interfaces multi-étapes dans lesquelles la sortie d'un modèle devient l'entrée du modèle suivant ou avoir des flux de données plus flexibles en général, +- modifier les propriétés d'un composant (par exemple, les choix dans une liste déroulante) ou sa visibilité en fonction des entrées de l'utilisateur. + +Nous allons explorer tous ces concepts ci-dessous. + +### Création d'une démo simple en utilisant Blocks + +Après avoir installé *Gradio*, exécutez le code ci-dessous sous forme de script Python, de *notebook* Jupyter ou de *notebook* Colab. + +```py +import gradio as gr + + +def flip_text(x): + return x[::-1] + + +demo = gr.Blocks() + +with demo: + gr.Markdown( + """ + # Flip Text! + Start typing below to see the output. + """ + ) + input = gr.Textbox(placeholder="Flip this text") + output = gr.Textbox() + + input.change(fn=flip_text, inputs=input, outputs=output) + +demo.launch() +``` + + + +Ce simple exemple ci-dessus introduit 4 concepts qui sous-tendent les *Blocks* : + +1. Les *Blocks* vous permettent de construire des applications web qui combinent Markdown, HTML, boutons et composants interactifs simplement en instanciant des objets en Python dans un contexte `with gradio.Blocks`. + + +🙋Si vous n'êtes pas familier avec l'instruction `with` en Python, nous vous recommandons de consulter l'excellent tutoriel de Real Python. Revenez ici après l'avoir lu 🤗 + + +L'ordre dans lequel vous instanciez les composants est important car chaque élément est restitué dans l'application Web dans l'ordre où il a été créé. (Les mises en page plus complexes sont abordées ci-dessous) + +2. Vous pouvez définir des fonctions Python ordinaires n'importe où dans votre code et les exécuter avec des entrées utilisateur en utilisant les `Blocks`. Dans notre exemple, nous avons une fonction simple qui inverse le texte entré mais vous pouvez écrire n'importe quelle fonction Python, du simple calcul au traitement des prédictions d'un modèle d'apprentissage automatique. + +3. Vous pouvez assigner des événements à n'importe quel composant `Blocks`. Ainsi, votre fonction sera exécutée lorsque le composant sera cliqué, modifié, etc. Lorsque vous assignez un événement, vous passez trois paramètres : +- `fn` : la fonction qui doit être appelée, +- `inputs` : la (liste) des composants d'entrée +- `outputs` : la (liste) des composants de sortie qui doivent être appelés. + Dans l'exemple ci-dessus, nous exécutons la fonction `flip_text()` lorsque la valeur de la `Textbox` nommée input `input` change. L'événement lit la valeur dans `input`, la passe comme paramètre de nom à `flip_text()`, qui renvoie alors une valeur qui est assignée à notre seconde `Textbox` nommée `output`. + Pour voir la liste des événements que chaque composant supporte, consultez la [documentation](https://www.gradio.app/docs/) de *Gradio*. + +4. *Blocks* détermine automatiquement si un composant doit être interactif (accepter les entrées de l'utilisateur) ou non, en fonction des déclencheurs d'événements que vous définissez. Dans notre exemple, la première zone de texte est interactive, puisque sa valeur est utilisée par la fonction `flip_text()`. La deuxième zone de texte n'est pas interactive, puisque sa valeur n'est jamais utilisée comme entrée. Dans certains cas, vous voudrez peut-être passer outre, ce que vous pouvez faire en passant un booléen au paramètre `interactive` du composant (par exemple, `gr.Textbox(placeholder="Flip this text", interactive=True)`). + + +### Personnaliser la mise en page de votre démo + +Comment pouvons-nous utiliser `Blocks` pour personnaliser la mise en page de notre démo ? Par défaut, `Blocks` affiche verticalement dans une colonne les composants que vous créez. Vous pouvez changer cela en créant des colonnes supplémentaires `avec gradio.Column():` ou des lignes `avec gradio.Row():` et en créant des composants dans ces contextes. + +Voici ce que vous devez garder à l'esprit : tout composant créé sous une `Column` (c'est aussi le défaut) sera disposé verticalement. Tout composant créé sous une `Row` sera disposé horizontalement, comme le [modèle flexbox dans le développement web](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox). + +Enfin, vous pouvez également créer des onglets pour votre démo en utilisant le gestionnaire de contexte `with gradio.Tabs()`. Dans ce contexte, vous pouvez créer plusieurs onglets en spécifiant des enfants `with gradio.TabItem(name_of_tab):`. Tout composant créé dans un contexte `with gradio.TabItem(name_of_tab):` apparaît dans cet onglet. + +Maintenant, ajoutons une fonction `flip_image()` à notre démo et ajoutons un nouvel onglet qui retourne les images. Vous trouverez ci-dessous un exemple avec 2 onglets et utilisant également une `Row` : + +```py +import numpy as np +import gradio as gr + +demo = gr.Blocks() + + +def flip_text(x): + return x[::-1] + + +def flip_image(x): + return np.fliplr(x) + + +with demo: + gr.Markdown("Flip text or image files using this demo.") + with gr.Tabs(): + with gr.TabItem("Flip Text"): + with gr.Row(): + text_input = gr.Textbox() + text_output = gr.Textbox() + text_button = gr.Button("Flip") + with gr.TabItem("Flip Image"): + with gr.Row(): + image_input = gr.Image() + image_output = gr.Image() + image_button = gr.Button("Flip") + + text_button.click(flip_text, inputs=text_input, outputs=text_output) + image_button.click(flip_image, inputs=image_input, outputs=image_output) + +demo.launch() +``` + + + + +Vous remarquerez que dans cet exemple, nous avons également créé un composant `Button` dans chaque onglet et avons assigné un événement de clic à chaque bouton qui est l'élément qui exécute réellement la fonction. + +### Exploration des événements et de l'état + +De la même manière que vous pouvez contrôler la mise en page, `Blocks` vous donne un contrôle fin sur les événements qui déclenchent les appels de fonction. Chaque composant et de nombreux layouts ont des événements spécifiques qu'ils supportent. + +Par exemple, le composant `Textbox` a 2 événements : `change()` (lorsque la valeur contenue dans la zone de texte change), et `submit()` (lorsqu'un utilisateur appuie sur la touche Entrée alors qu'il est concentré sur la zone de texte). Les composants plus complexes peuvent avoir encore plus d'événements : par exemple, le composant `Audio` a aussi des événements séparés pour quand le fichier audio est joué, effacé, mis en pause, etc. Consultez la documentation pour connaître les événements pris en charge par chaque composant. + +Vous pouvez attacher un déclencheur d'événement à aucun, un ou plusieurs de ces événements. Vous créez un déclencheur d'événement en appelant le nom de l'événement sur l'instance du composant comme une fonction. Par exemple, `textbox.change(...)` ou `btn.click(...)`. La fonction prend trois paramètres, comme indiqué ci-dessus : + +- `fn` : la fonction à exécuter +- `inputs` : une (liste de) composante(s) dont les valeurs doivent être fournies comme paramètres d'entrée à la fonction. La valeur de chaque composant est mise en correspondance avec le paramètre de fonction correspondant, dans l'ordre. Ce paramètre peut être `None` si la fonction ne prend aucun paramètre. +- `outputs` : un (liste de) composant(s) dont les valeurs doivent être mises à jour en fonction des valeurs retournées par la fonction. Chaque valeur de retour met à jour la valeur du composant correspondant, dans l'ordre. Ce paramètre peut être None si la fonction ne retourne rien. + +Vous pouvez même faire en sorte que le composant d'entrée et de sortie soit le même composant, comme nous le faisons dans cet exemple qui utilise un modèle GPT pour compléter du texte : + +```py +import gradio as gr + +api = gr.Interface.load("huggingface/EleutherAI/gpt-j-6B") + + +def complete_with_gpt(text): + # Utilise les 50 derniers caractères du texte comme contexte. + return text[:-50] + api(text[-50:]) + + +with gr.Blocks() as demo: + textbox = gr.Textbox(placeholder="Type here and press enter...", lines=4) + btn = gr.Button("Generate") + + btn.click(complete_with_gpt, textbox, textbox) + +demo.launch() +``` + + + +### Création de démos multi-étapes + +Dans certains cas, vous pouvez vouloir une _démo multi-étapes_, dans laquelle vous réutilisez la sortie d'une fonction comme entrée de la suivante. C'est très facile à faire avec les `Blocks`, car vous pouvez utiliser un composant pour l'entrée d'un déclencheur d'événement mais la sortie d'un autre. Regardez le composant texte dans l'exemple ci-dessous, sa valeur est le résultat d'un modèle de conversion de la parole en texte, mais il est également transmis à un modèle d'analyse des sentiments : + +```py +from transformers import pipeline + +import gradio as gr + +asr = pipeline("automatic-speech-recognition", "facebook/wav2vec2-base-960h") +classifier = pipeline("text-classification") + + +def speech_to_text(speech): + text = asr(speech)["text"] + return text + + +def text_to_sentiment(text): + return classifier(text)[0]["label"] + + +demo = gr.Blocks() + +with demo: + audio_file = gr.Audio(type="filepath") + text = gr.Textbox() + label = gr.Label() + + b1 = gr.Button("Recognize Speech") + b2 = gr.Button("Classify Sentiment") + + b1.click(speech_to_text, inputs=audio_file, outputs=text) + b2.click(text_to_sentiment, inputs=text, outputs=label) + +demo.launch() +``` + + + +### Mise à jour des propriétés des composants + +Jusqu'à présent, nous avons vu comment créer des événements pour mettre à jour la valeur d'un autre composant. Mais que se passe-t-il si vous voulez modifier d'autres propriétés d'un composant, comme la visibilité d'une zone de texte ou les choix dans un groupe de boutons radio ? Vous pouvez le faire en renvoyant la méthode `update()` d'une classe de composant au lieu d'une valeur de retour normale de votre fonction. + +L'exemple le plus facile à illustrer est le suivant : + +```py +import gradio as gr + + +def change_textbox(choice): + if choice == "short": + return gr.Textbox.update(lines=2, visible=True) + elif choice == "long": + return gr.Textbox.update(lines=8, visible=True) + else: + return gr.Textbox.update(visible=False) + + +with gr.Blocks() as block: + radio = gr.Radio( + ["short", "long", "none"], label="What kind of essay would you like to write?" + ) + text = gr.Textbox(lines=2, interactive=True) + + radio.change(fn=change_textbox, inputs=radio, outputs=text) + block.launch() +``` + + + +Nous venons d'explorer tous les concepts de base des `Blocks` ! Tout comme avec `Interface`, vous pouvez créer des démos sympas qui peuvent être partagées en utilisant `share=True` dans la méthode `launch()` ou déployées sur [*Spaces*](https://huggingface.co/spaces). diff --git a/chapters/fr/chapter9/8.mdx b/chapters/fr/chapter9/8.mdx index 307e0c813..990587139 100644 --- a/chapters/fr/chapter9/8.mdx +++ b/chapters/fr/chapter9/8.mdx @@ -1,23 +1,23 @@ -# Gradio, coché ! - - - -Ceci conclut le chapitre sur la construction de démos d'apprentissage automatique avec *Gradio*. Nous espérons que vous l'avez apprécié ! Pour récapituler, dans ce chapitre nous avons appris : - -- à créer des démos *Gradio* avec l'API `Interface` de haut niveau et comment configurer les différentes modalités d'entrée et de sortie, -- les différentes manières de partager les démos *Gradio*, à travers des liens temporaires et l'hébergement sur [*Hugging Face Spaces*](https://huggingface.co/spaces), -- comment intégrer les démos *Gradio* avec le *Hub* et *Spaces*, -- des fonctionnalités avancées comme le stockage de l'état dans une démo ou l'authentification, -- comment avoir un contrôle total sur le flux de données et la mise en page de votre démo avec les *Blocks*. - -Si vous souhaitez tester votre compréhension des concepts abordés dans ce chapitre, consultez le quiz dans la section suivante ! - -## Où aller ensuite ? - -Si vous voulez en savoir plus à propos de Gradio, vous pouvez : -- Jeter un coup d'œil à la page [Demos](https://github.com/gradio-app/gradio/tree/main/demo) dans le dépôt GitHub pour consulter beaucoup d'exemples. -- Voir la page [Guides](https://gradio.app/guides/) où vous trouverez des guides sur les fonctionnalités avancées. +# Gradio, coché ! + + + +Ceci conclut le chapitre sur la construction de démos d'apprentissage automatique avec *Gradio*. Nous espérons que vous l'avez apprécié ! Pour récapituler, dans ce chapitre nous avons appris : + +- à créer des démos *Gradio* avec l'API `Interface` de haut niveau et comment configurer les différentes modalités d'entrée et de sortie, +- les différentes manières de partager les démos *Gradio*, à travers des liens temporaires et l'hébergement sur [*Hugging Face Spaces*](https://huggingface.co/spaces), +- comment intégrer les démos *Gradio* avec le *Hub* et *Spaces*, +- des fonctionnalités avancées comme le stockage de l'état dans une démo ou l'authentification, +- comment avoir un contrôle total sur le flux de données et la mise en page de votre démo avec les *Blocks*. + +Si vous souhaitez tester votre compréhension des concepts abordés dans ce chapitre, consultez le quiz dans la section suivante ! + +## Où aller ensuite ? + +Si vous voulez en savoir plus à propos de Gradio, vous pouvez : +- Jeter un coup d'œil à la page [Demos](https://github.com/gradio-app/gradio/tree/main/demo) dans le dépôt GitHub pour consulter beaucoup d'exemples. +- Voir la page [Guides](https://gradio.app/guides/) où vous trouverez des guides sur les fonctionnalités avancées. - Consulter la page [Docs](https://gradio.app/docs/) pour connaître les détails. \ No newline at end of file diff --git a/chapters/fr/chapter9/9.mdx b/chapters/fr/chapter9/9.mdx index 0f4169307..8eee4ec7c 100644 --- a/chapters/fr/chapter9/9.mdx +++ b/chapters/fr/chapter9/9.mdx @@ -1,238 +1,238 @@ - - -# Quiz de fin de chapitre - - - -Testons ce que vous avez appris dans ce chapitre ! - -### 1. Que pouvez-vous faire avec Gradio ? - -share=True dans la méthode de lancement, vous pouvez générer un lien de partage à envoyer à tout le monde.", - correct: true - }, - { - text: "Déboguez votre modèle.", - explain: "L'un des avantages d'une démo Gradio est de pouvoir tester votre modèle avec des données réelles que vous pouvez modifier et observer les prédictions du modèle changer en temps réel, ce qui vous aide à déboguer votre modèle.", - correct: true - }, - { - text: "Entraîner votre modèle.", - explain: "Gradio est conçu pour être utilisé pour l'inférence, APRÈS que votre modèle a été entraîné.", - } - ]} -/> - -### 2. Gradio fonctionne UNIQUEMENT avec les modèles en PyTorch - -Gradio fonctionne avec les modèles Pytorch mais aussi pour tout type de modèle d'apprentissage automatique !" - }, - { - text: "Faux", - explain: "Gradio est indifférent au modèle ce qui signifie que vous pouvez créer une démo pour tout type de modèle d'apprentissage automatique.", - correct: true - } - ]} -/> - -### 3. D'où pouvez-vous lancer une démo Gradio ? - -Gradio fonctionne parfaitement avec votre IDE préféré.", - correct: true - }, - { - text: "De notebooks Google Colab", - explain: "Vous pouvez créer et lancer une démo dans votre notebook Google Colab.", - correct: true - }, - { - text: "De notebooks Jupyter", - explain: "Vous pouvez créer et lancer une démo dans votre notebook Jupyter.", - correct: true - } - ]} -/> - -### 4. Gradio est conçu principalement pour les modèles de NLP - -Gradio fonctionne avec pratiquement tous les types de données, pas seulement avec le NLP." - }, - { - text: "Faux", - explain: "Gradio fournit aux développeurs une bibliothèque de composants préconstruits pour pratiquement tous les types de données.", - correct: true - } - ]} -/> - -### 5. Parmi les fonctionnalités suivantes, lesquelles sont prises en charge par Gradio ? - -Gradio. Tout ce que vous devez faire est de passer une liste d'entrées et de sorties à leurs paramètres correspondants.", - correct: true - }, - { - text: "État pour la persistance des données.", - explain: "Gradio est capable d'ajouter un état à votre interface.", - correct: true - }, - { - text: "Authentification par nom d'utilisateur et mot de passe.", - explain: "Passez une liste de tuples de nom d'utilisateur/mot de passe à la méthode de lancement pour ajouter l'authentification.", - correct: true - }, - { - text: "Analyse automatique de l'utilisation de votre démo Gradio.", - explain: "Gradio ne fournit pas aux développeurs des analyses sur les personnes qui utilisent leurs démos." - }, - { - text: "Chargement d'un modèle à partir du Hub ou de Space.", - explain: "Charger n'importe quel modèle de Hugging Face en utilisant la méthode gr.Interface.load().", - correct: true - } - ]} -/> - -### 6. Lesquelles des méthodes suivantes sont valides pour charger un modèle à partir du Hub ou de Space ? - -gr.Interface.load('huggingface/{user}/{model_name}')", - explain: "Il s'agit d'une méthode valide de chargement d'un modèle à partir du Hub.", - correct: true - }, - { - text: "gr.Interface.load('model/{user}/{model_name}')", - explain: "Il s'agit d'une méthode valide de chargement d'un modèle à partir du Hub.", - correct: true - }, - { - text: "gr.Interface.load('demos/{user}/{model_name}')", - explain: "Vous ne pouvez pas charger un modèle en utilisant le préfixe demos." - }, - { - text: "gr.Interface.load('spaces/{user}/{model_name}')", - explain: "Il s'agit d'une méthode valide de chargement d'un modèle à partir de Space.", - correct: true - } - ]} -/> - -### 7. Sélectionnez toutes les étapes nécessaires pour ajouter un état à votre interface Gradio - -Gradio fournit un composant d'entrée et de sortie d'état pour persister les données.", - correct: true - } - ]} -/> - -### 8. Lesquels des éléments suivants sont des composants inclus dans la bibliothèque Gradio ? - -Textbox.", - explain: "Oui, vous pouvez créer des zones de texte avec le composant Textbox.", - correct: true - }, - { - text: "Graph.", - explain: "Il n'y a actuellement aucun composant Graph.", - }, - { - text: "Image.", - explain: "Oui, vous pouvez créer un widget de téléchargement d'images avec le composant Image.", - correct: true - }, - { - text: "Audio.", - explain: "Oui, vous pouvez créer un widget de téléchargement audio avec le composant Audio.", - correct: true - }, - ]} -/> - -### 9. Qu'est-ce que les `Blocks` vous permet de faire ? - -with gradio.Tabs(): pour ajouter des onglets pour plusieurs démos.", - correct: true - }, - { - text: "Attribuer des déclencheurs d'événements tels que clicked/changed/etc aux composants Blocks.", - explain: "Lorsque vous assignez un événement, vous passez trois paramètres : fn qui est la fonction qui doit être appelée, inputs qui est la (liste) des composants d'entrée, et outputs qui est la (liste) des composants de sortie qui doivent être appelés.", - correct: true - }, - { - text: "Déterminer automatiquement quel composant Blocks doit être interactif ou statique.", - explain: "En fonction des déclencheurs d'événements que vous définissez, Blocks détermine automatiquement si un composant doit accepter ou non les entrées de l'utilisateur..", - correct: true - }, - { - text: "Créer des démos en plusieurs étapes, c'est-à-dire vous permettre de réutiliser la sortie d'un composant comme entrée pour le suivant.", - explain: "Vous pouvez utiliser un composant pour l'entrée d'un déclencheur d'événement mais la sortie d'un autre.", - correct: true - }, - ]} -/> - -### 10. Vous pouvez partager un lien public vers une démo Blocks et accueillir une démo Blocks sur Space - -Interface, toutes les capacités de partage et d'hébergement sont les mêmes pour les démos basées sur Blocks !", - correct: true - }, - { - text: "Faux", - explain: "Tout comme Interface, toutes les capacités de partage et d'hébergement sont les mêmes pour les démos basées sur Blocks !", - } - ]} + + +# Quiz de fin de chapitre + + + +Testons ce que vous avez appris dans ce chapitre ! + +### 1. Que pouvez-vous faire avec Gradio ? + +share=True dans la méthode de lancement, vous pouvez générer un lien de partage à envoyer à tout le monde.", + correct: true + }, + { + text: "Déboguez votre modèle.", + explain: "L'un des avantages d'une démo Gradio est de pouvoir tester votre modèle avec des données réelles que vous pouvez modifier et observer les prédictions du modèle changer en temps réel, ce qui vous aide à déboguer votre modèle.", + correct: true + }, + { + text: "Entraîner votre modèle.", + explain: "Gradio est conçu pour être utilisé pour l'inférence, APRÈS que votre modèle a été entraîné.", + } + ]} +/> + +### 2. Gradio fonctionne UNIQUEMENT avec les modèles en PyTorch + +Gradio fonctionne avec les modèles Pytorch mais aussi pour tout type de modèle d'apprentissage automatique !" + }, + { + text: "Faux", + explain: "Gradio est indifférent au modèle ce qui signifie que vous pouvez créer une démo pour tout type de modèle d'apprentissage automatique.", + correct: true + } + ]} +/> + +### 3. D'où pouvez-vous lancer une démo Gradio ? + +Gradio fonctionne parfaitement avec votre IDE préféré.", + correct: true + }, + { + text: "De notebooks Google Colab", + explain: "Vous pouvez créer et lancer une démo dans votre notebook Google Colab.", + correct: true + }, + { + text: "De notebooks Jupyter", + explain: "Vous pouvez créer et lancer une démo dans votre notebook Jupyter.", + correct: true + } + ]} +/> + +### 4. Gradio est conçu principalement pour les modèles de NLP + +Gradio fonctionne avec pratiquement tous les types de données, pas seulement avec le NLP." + }, + { + text: "Faux", + explain: "Gradio fournit aux développeurs une bibliothèque de composants préconstruits pour pratiquement tous les types de données.", + correct: true + } + ]} +/> + +### 5. Parmi les fonctionnalités suivantes, lesquelles sont prises en charge par Gradio ? + +Gradio. Tout ce que vous devez faire est de passer une liste d'entrées et de sorties à leurs paramètres correspondants.", + correct: true + }, + { + text: "État pour la persistance des données.", + explain: "Gradio est capable d'ajouter un état à votre interface.", + correct: true + }, + { + text: "Authentification par nom d'utilisateur et mot de passe.", + explain: "Passez une liste de tuples de nom d'utilisateur/mot de passe à la méthode de lancement pour ajouter l'authentification.", + correct: true + }, + { + text: "Analyse automatique de l'utilisation de votre démo Gradio.", + explain: "Gradio ne fournit pas aux développeurs des analyses sur les personnes qui utilisent leurs démos." + }, + { + text: "Chargement d'un modèle à partir du Hub ou de Space.", + explain: "Charger n'importe quel modèle de Hugging Face en utilisant la méthode gr.Interface.load().", + correct: true + } + ]} +/> + +### 6. Lesquelles des méthodes suivantes sont valides pour charger un modèle à partir du Hub ou de Space ? + +gr.Interface.load('huggingface/{user}/{model_name}')", + explain: "Il s'agit d'une méthode valide de chargement d'un modèle à partir du Hub.", + correct: true + }, + { + text: "gr.Interface.load('model/{user}/{model_name}')", + explain: "Il s'agit d'une méthode valide de chargement d'un modèle à partir du Hub.", + correct: true + }, + { + text: "gr.Interface.load('demos/{user}/{model_name}')", + explain: "Vous ne pouvez pas charger un modèle en utilisant le préfixe demos." + }, + { + text: "gr.Interface.load('spaces/{user}/{model_name}')", + explain: "Il s'agit d'une méthode valide de chargement d'un modèle à partir de Space.", + correct: true + } + ]} +/> + +### 7. Sélectionnez toutes les étapes nécessaires pour ajouter un état à votre interface Gradio + +Gradio fournit un composant d'entrée et de sortie d'état pour persister les données.", + correct: true + } + ]} +/> + +### 8. Lesquels des éléments suivants sont des composants inclus dans la bibliothèque Gradio ? + +Textbox.", + explain: "Oui, vous pouvez créer des zones de texte avec le composant Textbox.", + correct: true + }, + { + text: "Graph.", + explain: "Il n'y a actuellement aucun composant Graph.", + }, + { + text: "Image.", + explain: "Oui, vous pouvez créer un widget de téléchargement d'images avec le composant Image.", + correct: true + }, + { + text: "Audio.", + explain: "Oui, vous pouvez créer un widget de téléchargement audio avec le composant Audio.", + correct: true + }, + ]} +/> + +### 9. Qu'est-ce que les `Blocks` vous permet de faire ? + +with gradio.Tabs(): pour ajouter des onglets pour plusieurs démos.", + correct: true + }, + { + text: "Attribuer des déclencheurs d'événements tels que clicked/changed/etc aux composants Blocks.", + explain: "Lorsque vous assignez un événement, vous passez trois paramètres : fn qui est la fonction qui doit être appelée, inputs qui est la (liste) des composants d'entrée, et outputs qui est la (liste) des composants de sortie qui doivent être appelés.", + correct: true + }, + { + text: "Déterminer automatiquement quel composant Blocks doit être interactif ou statique.", + explain: "En fonction des déclencheurs d'événements que vous définissez, Blocks détermine automatiquement si un composant doit accepter ou non les entrées de l'utilisateur..", + correct: true + }, + { + text: "Créer des démos en plusieurs étapes, c'est-à-dire vous permettre de réutiliser la sortie d'un composant comme entrée pour le suivant.", + explain: "Vous pouvez utiliser un composant pour l'entrée d'un déclencheur d'événement mais la sortie d'un autre.", + correct: true + }, + ]} +/> + +### 10. Vous pouvez partager un lien public vers une démo Blocks et accueillir une démo Blocks sur Space + +Interface, toutes les capacités de partage et d'hébergement sont les mêmes pour les démos basées sur Blocks !", + correct: true + }, + { + text: "Faux", + explain: "Tout comme Interface, toutes les capacités de partage et d'hébergement sont les mêmes pour les démos basées sur Blocks !", + } + ]} /> \ No newline at end of file