Dans cette vidéo, nous verrons comment déboguer une erreur que vous rencontrez lors de l'exécution de `trainer.train()`.
À titre d'exemple, nous utiliserons ce script qui finetune un modèle BERT sur le jeu de données GLUE MNLI.
Consultez les vidéos liées ci-dessous pour voir comment nous sommes arrivés à un tel script,
ici, nous voulons apprendre à déboguer les problèmes qu'il contient. L'exécution du script génère une erreur assez
rapidement. Cela se produit à la ligne où nous donnons les entrées au modèle, selon le « Traceback ».
Cela nous indique qu'il y a un problème, mais le problème peut provenir de nombreuses causes différentes.
Pour déboguer une erreur dans une entraînement, vous devez vous assurer que chaque étape du pipeline d'entraînement
fonctionne comme prévu. Cela signifie vérifier que les entrées de votre jeu de données sont correctes,
vous pouvez les regrouper, les donner au modèle pour obtenir une perte,
puis calculer les gradients de cette perte avant d'effectuer une étape d'optimisation.
Commençons donc par examiner le jeu de données d'entraînement utilisé par ce `trainer`. Il y a certainement un
problème car nous voyons des textes et non des chiffres. Le message d'erreur nous indiquait que le modèle n'avait pas reçu
d'`input_ids` et que nous n'en avons pas dans le jeu de données. En examinant notre code, nous pouvons constater que nous avons
fait une erreur et transmis les mauvais jeux de données au Trainer. Alors réparons cela et exécutons à nouveau.
Nous avons maintenant une nouvelle erreur. L'inspection du « Traceback » nous indique que cela se produit lorsque nous essayons de créer un batch,
spécifiquement pour regrouper les caractéristiques dans un tenseur. Nous pouvons le confirmer en demandant au Trainer de
nous fournir un batch du chargeur de données d'entraînement, qui reproduit la même erreur. Soit en inspectant
les entrées, soit en déboguant, nous pouvons alors voir qu'elles ne sont pas toutes de la même taille. En effet, nous n'avons
pas passé d'assembleur de données pour effectuer le rembourrage dans le Trainer et nous n'avons pas non plus rembourré
le prétraitement des données. Le rembourrage à l'intérieur du Trainer est normalement la valeur par défaut, mais uniquement si vous fournissez
votre tokenizer au Trainer, et nous avons oublié de le faire. Alors résolvons le problème et recommençons.
Cette fois, nous obtenons une méchante erreur CUDA. Elles sont très difficiles à déboguer car d'une part,
elles mettent votre noyau dans un état irrécupérable (vous devez donc redémarrer votre
notebook depuis le début) et d'autre part, le « Traceback » est complètement inutile pour celles-là.
Ici, le « Traceback » nous indique que l'erreur se produit lorsque nous effectuons le calcul du gradient avec `loss.backward`,
mais comme nous le verrons plus tard, ce n'est pas le cas. En effet, tout ce qui se passe
sur le GPU est effectué de manière asynchrone : lorsque vous exécutez l'appel de modèle, ce que fait le programme
est simplement d'empiler cela dans la file d'attente du GPU, puis (si le GPU n'avait aucune tâche en cours à faire),
le travail commencera sur le GPU en même temps que le CPU passera à l'instruction suivante.
En continuant avec l'extraction de la perte, celle-ci est empilée dans la file d'attente du GPU pendant que le CPU passe
à l'instruction `loss.backward`. Mais le GPU n'a toujours pas terminé la passe avant du
modèle puisque tout cela n'a pris aucun temps. Le CPU arrête d'avancer, car `loss.backward` en tant
qu'instruction lui indiquant d'attendre que les GPU soient finis pour être sûr que les gradients sont corrects. Et lorsque le GPU rencontre une erreur,
il renvoie un message au CPU, qui génère l'erreur au mauvais endroit.
Donc, pour déboguer cela, nous devrons exécuter les prochaines étapes du pipeline d'entraînement sur le CPU.
C'est très facile à faire, et nous obtenons un « Traceback » auquel nous pouvons faire confiance cette fois. Comme nous l'avons déjà dit,
l'erreur se produit lors de la passe avant du modèle et nons dans la passe arrière. C'est une erreur d'index.
Avec un peu de débogage, nous voyons que nous avons des étiquettes allant de 0 à 2, donc trois valeurs différentes,
mais nos sorties ont une forme de taille de batch par 2. Il semble que notre modèle ait le mauvais nombre
d'étiquettes ! Nous pouvons en effet le confirmer, et maintenant que nous savons qu'il est facile de le corriger dans le code en ajoutant
`num_labels=3` lorsque nous créons le modèle. Le script d'entraînement va maintenant s'exécuter jusqu'à la fin ! Nous n'en avions pas
encore besoin, mais voici comment déboguer l'étape suivante du pipeline, le calcul du gradient,
ainsi que l'étape d'optimisation. Avec tout cela, bonne chance pour déboguer vos propres entraînements !