1
00:00:06,080 --> 00:00:10,960
Dans cette vidéo, nous verrons comment déboguer une erreur que vous rencontrez lors de l'exécution de `trainer.train()`.

2
00:00:12,240 --> 00:00:17,280
À titre d'exemple, nous utiliserons ce script qui finetune un modèle BERT sur le jeu de données GLUE MNLI.

3
00:00:17,840 --> 00:00:20,880
Consultez les vidéos liées ci-dessous pour voir comment nous sommes arrivés à un tel script,

4
00:00:21,680 --> 00:00:26,960
ici, nous voulons apprendre à déboguer les problèmes qu'il contient. L'exécution du script génère une erreur assez

5
00:00:26,960 --> 00:00:31,920
rapidement. Cela se produit à la ligne où nous donnons les entrées au modèle, selon le « Traceback ».

6
00:00:32,640 --> 00:00:36,720
Cela nous indique qu'il y a un problème, mais le problème peut provenir de nombreuses causes différentes.

7
00:00:37,520 --> 00:00:41,600
Pour déboguer une erreur dans une entraînement, vous devez vous assurer que chaque étape du pipeline d'entraînement

8
00:00:41,600 --> 00:00:46,160
fonctionne comme prévu. Cela signifie vérifier que les entrées de votre jeu de données sont correctes,

9
00:00:46,800 --> 00:00:50,560
vous pouvez les regrouper, les donner au modèle pour obtenir une perte,

10
00:00:50,560 --> 00:00:54,080
puis calculer les gradients de cette perte avant d'effectuer une étape d'optimisation.

11
00:00:55,280 --> 00:01:00,480
Commençons donc par examiner le jeu de données d'entraînement utilisé par ce `trainer`. Il y a certainement un

12
00:01:00,480 --> 00:01:07,040
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

13
00:01:07,040 --> 00:01:13,120
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

14
00:01:13,120 --> 00:01:18,800
fait une erreur et transmis les mauvais jeux de données au Trainer. Alors réparons cela et exécutons à nouveau.

15
00:01:20,240 --> 00:01:25,680
Nous avons maintenant une nouvelle erreur. L'inspection du « Traceback » nous indique que cela se produit lorsque nous essayons de créer un batch,

16
00:01:25,680 --> 00:01:31,920
spécifiquement pour regrouper les caractéristiques dans un tenseur. Nous pouvons le confirmer en demandant au Trainer de

17
00:01:31,920 --> 00:01:37,600
nous fournir un batch du chargeur de données d'entraînement, qui reproduit la même erreur. Soit en inspectant

18
00:01:37,600 --> 00:01:43,600
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

19
00:01:43,600 --> 00:01:48,240
pas passé d'assembleur de données pour effectuer le rembourrage dans le Trainer et nous n'avons pas non plus rembourré

20
00:01:48,240 --> 00:01:53,440
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

21
00:01:53,440 --> 00:01:58,800
votre tokenizer au Trainer, et nous avons oublié de le faire. Alors résolvons le problème et recommençons.

22
00:02:00,320 --> 00:02:06,400
Cette fois, nous obtenons une méchante erreur CUDA. Elles sont très difficiles à déboguer car d'une part,

23
00:02:07,120 --> 00:02:11,280
elles mettent votre noyau dans un état irrécupérable (vous devez donc redémarrer votre

24
00:02:11,280 --> 00:02:15,840
notebook depuis le début) et d'autre part, le « Traceback » est complètement inutile pour celles-là.

25
00:02:16,800 --> 00:02:22,240
Ici, le « Traceback » nous indique que l'erreur se produit lorsque nous effectuons le calcul du gradient avec `loss.backward`,

26
00:02:22,240 --> 00:02:27,840
mais comme nous le verrons plus tard, ce n'est pas le cas. En effet, tout ce qui se passe

27
00:02:27,840 --> 00:02:33,520
sur le GPU est effectué de manière asynchrone : lorsque vous exécutez l'appel de modèle, ce que fait le programme

28
00:02:33,520 --> 00:02:39,280
est simplement d'empiler cela dans la file d'attente du GPU, puis (si le GPU n'avait aucune tâche en cours à faire),

29
00:02:39,280 --> 00:02:43,920
le travail commencera sur le GPU en même temps que le CPU passera à l'instruction suivante.

30
00:02:44,800 --> 00:02:50,000
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

31
00:02:50,000 --> 00:02:54,960
à l'instruction `loss.backward`. Mais le GPU n'a toujours pas terminé la passe avant du

32
00:02:54,960 --> 00:03:01,760
modèle puisque tout cela n'a pris aucun temps. Le CPU arrête d'avancer, car `loss.backward` en tant

33
00:03:01,760 --> 00:03:09,360
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,

34
00:03:09,360 --> 00:03:15,040
il renvoie un message au CPU, qui génère l'erreur au mauvais endroit.

35
00:03:16,080 --> 00:03:20,320
Donc, pour déboguer cela, nous devrons exécuter les prochaines étapes du pipeline d'entraînement sur le CPU.

36
00:03:20,960 --> 00:03:26,320
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,

37
00:03:26,320 --> 00:03:32,720
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.

38
00:03:33,360 --> 00:03:38,800
Avec un peu de débogage, nous voyons que nous avons des étiquettes allant de 0 à 2, donc trois valeurs différentes,

39
00:03:38,800 --> 00:03:44,240
mais nos sorties ont une forme de taille de batch par 2. Il semble que notre modèle ait le mauvais nombre

40
00:03:44,240 --> 00:03:50,320
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

41
00:03:50,320 --> 00:03:58,720
`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

42
00:03:58,720 --> 00:04:02,640
encore besoin, mais voici comment déboguer l'étape suivante du pipeline, le calcul du gradient,

43
00:04:03,360 --> 00:04:13,840
ainsi que l'étape d'optimisation. Avec tout cela, bonne chance pour déboguer vos propres entraînements !