subtitles/fr/73_debugging-the-training-pipeline-(pytorch).srt (129 lines of code) (raw):
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 !