Guide_Evaluation_LLM / pages /8_II.4._Conseils et astuces.py
bourdoiscatie's picture
Upload 44 files
1162aae verified
import streamlit as st
st.set_page_config(layout="wide")
from streamlit_extras.switch_page_button import switch_page
st.markdown(
"""
## Conseils et astuces
### Gestion de la contamination
En général, vous devez partir du principe qu'un jeu de données accessible au public sur l'internet est ou sera contaminé.
Les solutions pour y remédier sont les suivantes :<br>
- fournir une « ***canary string*** » dans l'échantillon d'évaluation (comme dans [BigBench](https://github.com/google/BIG-bench)) : il s'agit d'une combinaison de caractères spécifique que les créateurs de modèles peuvent rechercher dans leurs échantillons d'entraînement, ce qui indiquerait qu'ils contiennent une fuite.<br>
- fournir des échantillons d'évaluation sous forme **[cryptée](https://arxiv.org/abs/2309.16575) ou [fermée](https://huggingface.co/datasets/Idavidrein/gpqa)** afin qu'ils ne puissent pas être analysés facilement par les bots d'indexation et ne se retrouvent donc pas accidentellement dans les données d'entraînement.<br>
- l'exécution de [jeux d'évaluation dynamiques](https://arxiv.org/abs/2104.14337) : les jeux d'évaluation sont régulièrement mis à jour au fil du temps afin que les modèles ne puissent pas « apprendre les réponses par cœur » (cela augmente néanmoins le coût de la conception des jeux de données).<br>
- si vous exécutez un jeu d'évaluation, essayez de [détecter la contamination](https://arxiv.org/abs/2311.06233) post-hoc (par exemple, en examinant la perplexité de la génération ou en concevant des versions contradictoires des *prompts* ; cependant, aucune méthode n'est infaillible pour détecter la contamination).
Toutefois, ce n'est pas parce qu'un jeu de données est contaminé qu'il ne sera pas intéressant et qu'il n'aura pas de signal pendant l'entraînement.
""", unsafe_allow_html=True)
st.markdown(""" """)
st.markdown(""" """)
st.markdown(
"""
### Problématiques pratiques que vous pourriez rencontrer
##### Modèles finetunés, instruction système et gabarits de chat
Un certain nombre de modèles finetunés sur des instructions vont donner de très mauvais résultats si vous ne veillez pas à :<br>
- ajouter leur instruction système au tout début de l'inférence<br>
- utiliser une instruction suivant un gabarit de chat (en général en ajoutant les préfixes `Assistant` et `User` aux différents tours du dialogue). Pour en savoir plus, consultez [ce guide](https://huggingface.co/docs/transformers/main/en/chat_templating).<br>
Il est également très important de ne pas supposer que les différents *tokenizers* se comporteront de la même manière, en particulier en ce qui concerne les gabarits de chat, comme vous pouvez le voir dans cette image tirée de [ce tweet](https://x.com/danielhanchen/status/1796952220619157694).
""", unsafe_allow_html=True)
st.markdown(""" """)
st.image("https://pbs.twimg.com/media/GPANfpiasAA9b6F?format=png&name=medium", caption='Espacement, tokenisation et gabarit', use_container_width=True)
st.markdown(""" """)
st.markdown(
"""
##### Tokénisation
1. **Tokéniser le contexte et les choix ensemble ou séparément**
Lorsque l'on regarde une évaluation MCQA, en général, on veut tokéniser le contexte en même temps que les choix possibles, car cela crée une succession de *tokens* qui est probable/naturelle pour le modèle.
Cependant, certains *tokenizers* (comme celui du [Llama 1](https://github.com/EleutherAI/lm-evaluation-harness/pull/531#issuecomment-1595586257)) ne satisfont pas `enc(contexte + choix) = enc(contexte) + enc(choix)` (et ajoutent ou enlèvent l'espacement). Cela signifie que la comparaison des log-probabilités des choix n'est pas aisée car les *tokens* de contexte peuvent « déborder » dans ces log-probabilités, ce qui perturbe la comparaison.
Donc, si c'est le cas pour votre modèle, vous pourriez vouloir calculer les *tokens* de contexte et de choix séparément, puis les concaténer après avoir supprimé les *tokens* spéciaux de début et de fin de phrase qui auraient pu être ajoutés.
2. **Attention aux *tokens* de début et de fin de phrase**
Certains modèles, comme les [Gemma](https://huggingface.co/collections/google/googles-gemma-models-family-675bfd70e574a62dd0e406bd), sont extrêmement sensibles à l'[inclusion des *tokens* de début de phrase](https://github.com/EleutherAI/lm-evaluation-harness/pull/1465) lors de l'inférence. Vous pourriez avoir besoin de faire quelques expériences pour voir si cela se produit pour vous, et ajouter ces *tokens* manuellement lors de l'évaluation.
Vous pouvez également rencontrer des problèmes où votre modèle ne s'arrêtera pas sur un *token* de fin de phrase comme vous l'attendez (par exemple, sur `\\n`). En effet, votre modèle peut ne pas prédire ce *token* seul mais faisant parti d'un *token* de niveau supérieur (par exemple, `\\n\\n`, qui peut être un unique *token*, en particulier pour les modèles de code). Dans ce cas, vous pourriez avoir besoin d'ajouter une vérification spécifique pour « revenir en arrière » sur le texte généré afin de vous assurer que vous coupez votre phrase générée au bon endroit avant de calculer les métriques.
3. **Multilinguisme et tokénisation**
Dans le cadre d'évaluations multilingues, vous devrez également déterminer la façon de tokéniser votre texte, en fonction de votre tâche d'évaluation et de vos métriques. Comme certaines langues n'utilisent pas toujours l'espacement comme séparateur de mots (coréen, thaïlandais, japonais, chinois, pour n'en citer que quelques-unes), elles nécessiteront des *tokenizers* spécifiques à la langue pour être scindées correctement, sinon cela affectera leurs scores sur des métriques telles que [BLEU](https://github.com/EleutherAI/lm-evaluation-harness/issues/212).
4. **Évaluation du code et *tokens* de fin de phrase**
Les modèles de code ont généralement été entraînés avec `\\n\\t` comme *token* unique. Cela signifie que lorsqu'ils génèrent du texte, ils génèrent souvent `\\n\\t` en une seule étape. Une tâche qui définit `\\n` comme *token* de fin de phrase (= pour arrêter la génération) laissera le modèle continuer à générer après un `\\n\\t` puisque c'est un *token* différent de `\\n` alors que vous souhaitez que le modèle s'arrête. Dans ce cas, vous devez soit mettre à jour vos *tokens* de fin de phrase, soit définir un mécanisme permettant de revenir sur la représentation des caractères des derniers *tokens* générés pour arrêter (et couper) la génération a posteriori.
""", unsafe_allow_html=True)
st.markdown(""" """)
st.markdown("""
##### Accélérer facilement les évaluations des QCM
Vous pouvez accélérer considérablement vos prédictions de cette tâche si vous vous assurez que votre modèle n'a besoin de prédire qu'un seul *token* pour la tâche.
De cette façon, au lieu d'exécuter vos prédictions sur le nombre de choix (`contexte + choix 1`, `contexte + choix 2`, etc.), vous pouvez simplement exécuter l'inférence sur le `contexte` et calculer la distribution de probabilité sur le vocabulaire complet pour obtenir vos log-probabilités d'intérêt, et faire cette étape en une seule passe.<br>
C'est ainsi que nous procédons dans [lighteval](https://github.com/huggingface/lighteval).
""", unsafe_allow_html=True)
st.markdown(""" """)
st.markdown(""" """)
st.markdown(""" """)
st.markdown("""
### Mauvais résultats lors d'une évaluation générative
La première chose à faire est de toujours inspecter en détail les générations de votre modèle. Les éléments les plus fréquents à rechercher lors du diagnostic d'erreurs sont les suivants : <br>
- une analyse trop stricte de la sortie du modèle (avant le calcul de la métrique) qui entraîne la perte de la réponse.<br>
- Résolution : adaptez votre analyse.<br>
- incapacité des modèles à suivre le format de sortie donné dans les exemples (fréquent dans les modèles récents entraînés avec des données d'instructions, comme Llama 3.2 ou Qwen 2.5)<br>
- Résolution : soit vous adaptez le format de votre instruction, soit vous supposez que les modèles devraient être capables de le suivre.<br>
- modèle excessivement verbeux qui n'arrive jamais à la bonne réponse (plus fréquent dans les modèles à long contexte, que nous avons observé avec les modèles Qwen et CommandR)<br>
- Résolution : soit augmenter la longueur autorisée du contexte, soit ajouter des détails dans l'instruction afin d'être concis, soit simplement supposer que les modèles devraient être capables de répondre succinctement.
""", unsafe_allow_html=True)
st.markdown(""" """)
st.markdown(""" """)
st.markdown(""" """)
col1, col2, col3= st.columns(3)
with col1:
if st.button('Section précédente', use_container_width=True):
switch_page("II.3._Quelques_jeux_de_données_d'évaluation")
with col2:
if st.button("Accueil", use_container_width=True):
switch_page("Home")
with col3:
if st.button("Chapitre suivant", use_container_width=True):
switch_page("III._Évaluation_humaine")