camilaaeromoca commited on
Commit
9b1d856
·
verified ·
1 Parent(s): 6e1ea3b

Delete Mini-Projeto3-Modelagem.ipynb

Browse files
Files changed (1) hide show
  1. Mini-Projeto3-Modelagem.ipynb +0 -988
Mini-Projeto3-Modelagem.ipynb DELETED
@@ -1,988 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "markdown",
5
- "metadata": {},
6
- "source": [
7
- "# <font color='blue'>Data Science Academy</font>\n",
8
- "# <font color='blue'>Deep Learning Para Aplicações de IA com PyTorch e Lightning</font>\n",
9
- "\n",
10
- "## <font color='blue'>Mini-Projeto 3 - Modelagem</font>\n",
11
- "## <font color='blue'>Fine-Tuning de Modelo LLM Para Tarefa Específica e Deploy de Web App com Gradio</font>"
12
- ]
13
- },
14
- {
15
- "cell_type": "markdown",
16
- "metadata": {},
17
- "source": [
18
- "![DSA](imagens/MP3.png)"
19
- ]
20
- },
21
- {
22
- "cell_type": "markdown",
23
- "metadata": {},
24
- "source": [
25
- "## Instalando e Carregando os Pacotes"
26
- ]
27
- },
28
- {
29
- "cell_type": "code",
30
- "execution_count": 1,
31
- "metadata": {},
32
- "outputs": [
33
- {
34
- "name": "stdout",
35
- "output_type": "stream",
36
- "text": [
37
- "Versão da Linguagem Python Usada Neste Jupyter Notebook: 3.10.9\n"
38
- ]
39
- }
40
- ],
41
- "source": [
42
- "# Versão da Linguagem Python\n",
43
- "from platform import python_version\n",
44
- "print('Versão da Linguagem Python Usada Neste Jupyter Notebook:', python_version())"
45
- ]
46
- },
47
- {
48
- "cell_type": "code",
49
- "execution_count": 2,
50
- "metadata": {},
51
- "outputs": [],
52
- "source": [
53
- "# Para atualizar um pacote, execute o comando abaixo no terminal ou prompt de comando:\n",
54
- "# pip install -U nome_pacote\n",
55
- "\n",
56
- "# Para instalar a versão exata de um pacote, execute o comando abaixo no terminal ou prompt de comando:\n",
57
- "# !pip install nome_pacote==versão_desejada\n",
58
- "\n",
59
- "# Depois de instalar ou atualizar o pacote, reinicie o jupyter notebook.\n",
60
- "\n",
61
- "# Instala o pacote watermark. \n",
62
- "# Esse pacote é usado para gravar as versões de outros pacotes usados neste jupyter notebook.\n",
63
- "!pip install -q -U watermark"
64
- ]
65
- },
66
- {
67
- "cell_type": "code",
68
- "execution_count": 3,
69
- "metadata": {},
70
- "outputs": [
71
- {
72
- "name": "stdout",
73
- "output_type": "stream",
74
- "text": [
75
- "env: TF_CPP_MIN_LOG_LEVEL=3\n"
76
- ]
77
- }
78
- ],
79
- "source": [
80
- "%env TF_CPP_MIN_LOG_LEVEL=3"
81
- ]
82
- },
83
- {
84
- "cell_type": "code",
85
- "execution_count": 4,
86
- "metadata": {},
87
- "outputs": [],
88
- "source": [
89
- "!pip install -q torch==2.0.1"
90
- ]
91
- },
92
- {
93
- "cell_type": "code",
94
- "execution_count": 5,
95
- "metadata": {},
96
- "outputs": [],
97
- "source": [
98
- "!pip install -q transformers==4.31.0"
99
- ]
100
- },
101
- {
102
- "cell_type": "code",
103
- "execution_count": 6,
104
- "metadata": {},
105
- "outputs": [],
106
- "source": [
107
- "!pip install -q accelerate"
108
- ]
109
- },
110
- {
111
- "cell_type": "code",
112
- "execution_count": 7,
113
- "metadata": {},
114
- "outputs": [],
115
- "source": [
116
- "# Imports\n",
117
- "import torch\n",
118
- "import transformers\n",
119
- "import numpy as np\n",
120
- "import torch.nn.functional as F\n",
121
- "from accelerate import Accelerator\n",
122
- "from torch.utils.data import Dataset\n",
123
- "from transformers import AutoConfig, AutoModelForCausalLM, GPT2Tokenizer\n",
124
- "from transformers import GPT2Tokenizer"
125
- ]
126
- },
127
- {
128
- "cell_type": "code",
129
- "execution_count": 8,
130
- "metadata": {},
131
- "outputs": [
132
- {
133
- "name": "stdout",
134
- "output_type": "stream",
135
- "text": [
136
- "Author: Data Science Academy\n",
137
- "\n",
138
- "numpy : 1.23.5\n",
139
- "torch : 2.0.1\n",
140
- "transformers: 4.31.0\n",
141
- "\n"
142
- ]
143
- }
144
- ],
145
- "source": [
146
- "# Versões dos pacotes usados neste jupyter notebook\n",
147
- "%reload_ext watermark\n",
148
- "%watermark -a \"Data Science Academy\" --iversions"
149
- ]
150
- },
151
- {
152
- "cell_type": "markdown",
153
- "metadata": {},
154
- "source": [
155
- "## Carregando o LLM\n",
156
- "\n",
157
- "https://huggingface.co/gpt2\n",
158
- "\n",
159
- "O modelo terá a mesma arquitetura do GPT-2, mas com algumas modificações para torná-lo menor. As principais mudanças são o tamanho do vocabulário que é 13 porque só vai lidar com números mais o padding token, o \"+\" e o \"=\". A janela de contexto suportará apenas 6 tokens, pois estamos interessados apenas em realizar a adição de dois dígitos únicos."
160
- ]
161
- },
162
- {
163
- "cell_type": "code",
164
- "execution_count": 9,
165
- "metadata": {},
166
- "outputs": [],
167
- "source": [
168
- "# Tamanho do vocabulário\n",
169
- "vocab_size = 13"
170
- ]
171
- },
172
- {
173
- "cell_type": "code",
174
- "execution_count": 10,
175
- "metadata": {},
176
- "outputs": [],
177
- "source": [
178
- "# Comprimento da sequência\n",
179
- "sequence_length = 4"
180
- ]
181
- },
182
- {
183
- "cell_type": "code",
184
- "execution_count": 11,
185
- "metadata": {},
186
- "outputs": [],
187
- "source": [
188
- "# Comprimento do resultado\n",
189
- "result_length = 2"
190
- ]
191
- },
192
- {
193
- "cell_type": "code",
194
- "execution_count": 12,
195
- "metadata": {},
196
- "outputs": [],
197
- "source": [
198
- "# Comprimento do contexto\n",
199
- "context_length = sequence_length + result_length"
200
- ]
201
- },
202
- {
203
- "cell_type": "code",
204
- "execution_count": 13,
205
- "metadata": {},
206
- "outputs": [],
207
- "source": [
208
- "# Parâmetros de configuração do modelo GPT-2\n",
209
- "config = AutoConfig.from_pretrained(\"gpt2\", \n",
210
- " vocab_size = vocab_size, \n",
211
- " n_ctx = context_length, \n",
212
- " n_head = 4, \n",
213
- " n_layer = 2) "
214
- ]
215
- },
216
- {
217
- "cell_type": "code",
218
- "execution_count": 14,
219
- "metadata": {},
220
- "outputs": [],
221
- "source": [
222
- "# Carrega o modelo\n",
223
- "modelo = AutoModelForCausalLM.from_config(config)"
224
- ]
225
- },
226
- {
227
- "cell_type": "code",
228
- "execution_count": 15,
229
- "metadata": {},
230
- "outputs": [],
231
- "source": [
232
- "# Função para calcular o tamanho do modelo\n",
233
- "def model_size(model):\n",
234
- " return sum(t.numel() for t in modelo.parameters())"
235
- ]
236
- },
237
- {
238
- "cell_type": "code",
239
- "execution_count": 16,
240
- "metadata": {},
241
- "outputs": [
242
- {
243
- "name": "stdout",
244
- "output_type": "stream",
245
- "text": [
246
- "Tamanho do Modelo: 15.0M parâmetros\n"
247
- ]
248
- }
249
- ],
250
- "source": [
251
- "print(f'Tamanho do Modelo: {model_size(modelo)/1000**2:.1f}M parâmetros')"
252
- ]
253
- },
254
- {
255
- "cell_type": "markdown",
256
- "metadata": {},
257
- "source": [
258
- "Este modelo tem 15 milhões de parâmetros em vez dos 111 milhões de parâmetros da configuração padrão \"gpt2\"."
259
- ]
260
- },
261
- {
262
- "cell_type": "code",
263
- "execution_count": 17,
264
- "metadata": {},
265
- "outputs": [
266
- {
267
- "data": {
268
- "text/plain": [
269
- "transformers.models.gpt2.modeling_gpt2.GPT2LMHeadModel"
270
- ]
271
- },
272
- "execution_count": 17,
273
- "metadata": {},
274
- "output_type": "execute_result"
275
- }
276
- ],
277
- "source": [
278
- "type(modelo)"
279
- ]
280
- },
281
- {
282
- "cell_type": "code",
283
- "execution_count": 18,
284
- "metadata": {},
285
- "outputs": [],
286
- "source": [
287
- "# Salva o modelo em disco\n",
288
- "modelo.save_pretrained(\"modelos/modelo_inicial\")"
289
- ]
290
- },
291
- {
292
- "cell_type": "markdown",
293
- "metadata": {},
294
- "source": [
295
- "## Tokenizador Personalizado"
296
- ]
297
- },
298
- {
299
- "cell_type": "code",
300
- "execution_count": 19,
301
- "metadata": {},
302
- "outputs": [],
303
- "source": [
304
- "# Definindo uma classe chamada NumberTokenizer, que é usada para tokenizar os números\n",
305
- "class DSATokenizer:\n",
306
- " \n",
307
- " # Método construtor da classe, que é executado quando um objeto dessa classe é criado\n",
308
- " def __init__(self, numbers_qty = 10):\n",
309
- " \n",
310
- " # Lista de tokens possíveis que o tokenizador pode encontrar\n",
311
- " vocab = ['+', '=', '-1', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']\n",
312
- " \n",
313
- " # Definindo a quantidade de números que o tokenizador pode lidar\n",
314
- " self.numbers_qty = numbers_qty\n",
315
- " \n",
316
- " # Definindo o token de preenchimento (padding)\n",
317
- " self.pad_token = '-1'\n",
318
- " \n",
319
- " # Criando um dicionário que mapeia cada token para um índice único\n",
320
- " self.encoder = {str(v):i for i,v in enumerate(vocab)}\n",
321
- " \n",
322
- " # Criando um dicionário que mapeia cada índice único de volta ao token correspondente\n",
323
- " self.decoder = {i:str(v) for i,v in enumerate(vocab)}\n",
324
- " \n",
325
- " # Obtendo o índice do token de preenchimento no encoder\n",
326
- " self.pad_token_id = self.encoder[self.pad_token]\n",
327
- "\n",
328
- " # Método para decodificar uma lista de IDs de token de volta para uma string\n",
329
- " def decode(self, token_ids):\n",
330
- " return ' '.join(self.decoder[t] for t in token_ids)\n",
331
- "\n",
332
- " # Método que é chamado quando o objeto da classe é invocado como uma função\n",
333
- " def __call__(self, text):\n",
334
- " # Dividindo o texto em tokens individuais e retornando uma lista dos IDs correspondentes\n",
335
- " return [self.encoder[t] for t in text.split()]"
336
- ]
337
- },
338
- {
339
- "cell_type": "markdown",
340
- "metadata": {},
341
- "source": [
342
- "> Vamos testar o tokenizador!"
343
- ]
344
- },
345
- {
346
- "cell_type": "code",
347
- "execution_count": 20,
348
- "metadata": {},
349
- "outputs": [],
350
- "source": [
351
- "# Cria o objeto do tokenizador\n",
352
- "tokenizer = DSATokenizer(vocab_size)"
353
- ]
354
- },
355
- {
356
- "cell_type": "code",
357
- "execution_count": 21,
358
- "metadata": {},
359
- "outputs": [
360
- {
361
- "data": {
362
- "text/plain": [
363
- "{0: '+',\n",
364
- " 1: '=',\n",
365
- " 2: '-1',\n",
366
- " 3: '0',\n",
367
- " 4: '1',\n",
368
- " 5: '2',\n",
369
- " 6: '3',\n",
370
- " 7: '4',\n",
371
- " 8: '5',\n",
372
- " 9: '6',\n",
373
- " 10: '7',\n",
374
- " 11: '8',\n",
375
- " 12: '9'}"
376
- ]
377
- },
378
- "execution_count": 21,
379
- "metadata": {},
380
- "output_type": "execute_result"
381
- }
382
- ],
383
- "source": [
384
- "# Decoder do tokenizador\n",
385
- "tokenizer.decoder"
386
- ]
387
- },
388
- {
389
- "cell_type": "code",
390
- "execution_count": 22,
391
- "metadata": {},
392
- "outputs": [
393
- {
394
- "data": {
395
- "text/plain": [
396
- "[4, 0, 4, 1, 5]"
397
- ]
398
- },
399
- "execution_count": 22,
400
- "metadata": {},
401
- "output_type": "execute_result"
402
- }
403
- ],
404
- "source": [
405
- "# Testando o tokenizador\n",
406
- "tokenizer(\"1 + 1 = 2\")"
407
- ]
408
- },
409
- {
410
- "cell_type": "markdown",
411
- "metadata": {},
412
- "source": [
413
- "## Criando o Dataset\n",
414
- "\n",
415
- "O conjunto de dados deve ser criado neste formato:\n",
416
- "\n",
417
- "- Entrada: \"2 + 3 = 0\" onde os 4 primeiros caracteres representam a sequência de entrada e o quinto caractere representa o primeiro caracter da saída.\n",
418
- "\n",
419
- "- Saída: \"+ 3 = 0 5\" onde os 2 últimos dígitos representam o resultado da adição e os 3 primeiros dígitos são ignorados durante o treinamento e preenchidos com o pad.\n",
420
- "\n",
421
- "O resultado é um conjunto de dados de sequências tokenizadas de números."
422
- ]
423
- },
424
- {
425
- "cell_type": "code",
426
- "execution_count": 23,
427
- "metadata": {},
428
- "outputs": [],
429
- "source": [
430
- "# Definindo uma classe chamada CriaDataset, que herda da classe Dataset do PyTorch\n",
431
- "class CriaDataset(Dataset):\n",
432
- "\n",
433
- " # Método construtor da classe, que é executado quando um objeto dessa classe é criado\n",
434
- " def __init__(self, split, length = 6):\n",
435
- " \n",
436
- " # Verificando se a divisão do dataset (split) é 'treino' ou 'teste'\n",
437
- " assert split in {'treino', 'teste'}\n",
438
- " self.split = split\n",
439
- " self.length = length\n",
440
- " \n",
441
- " # Definindo o método len que retorna o tamanho do dataset. \n",
442
- " # Nesse caso, o tamanho é fixo e igual a 1 milhão.\n",
443
- " def __len__(self):\n",
444
- " return 1000000 \n",
445
- "\n",
446
- " # Definindo o método getitem que é usado para obter um item específico do dataset\n",
447
- " def __getitem__(self, idx):\n",
448
- "\n",
449
- " # Criando uma lista com todos os números disponíveis que não são tokens de padding e são numéricos\n",
450
- " available_numbers = [int(n) for n in tokenizer.decoder.values() if n != tokenizer.pad_token and str(n).isnumeric()]\n",
451
- " \n",
452
- " # Selecionando aleatoriamente números da lista de números disponíveis para criar uma entrada (input)\n",
453
- " inp = torch.tensor(np.random.choice(available_numbers, size = result_length))\n",
454
- " \n",
455
- " # Calculando a soma dos números selecionados e criando um tensor\n",
456
- " sol = torch.tensor([int(i) for i in str(inp.sum().item())])\n",
457
- " \n",
458
- " # Preenchendo o tensor com zeros para que tenha o tamanho desejado\n",
459
- " sol = torch.nn.functional.pad(sol, (1 if sol.size()[0] == 1 else 0,0), 'constant', 0)\n",
460
- "\n",
461
- " # Concatenando a entrada e a solução em um tensor\n",
462
- " cat = torch.cat((inp, sol), dim = 0)\n",
463
- "\n",
464
- " # Criando os tensores de entrada e alvo para o treinamento do modelo\n",
465
- " x = cat[:-1].clone()\n",
466
- " y = cat[1:].clone()\n",
467
- "\n",
468
- " # Definindo o primeiro elemento do tensor alvo como o token de padding\n",
469
- " y[:1] = int(tokenizer.pad_token)\n",
470
- "\n",
471
- " # Transformando os tensores x e y em strings\n",
472
- " x = str(x[0].item()) + ' + ' + str(x[1].item()) + ' = ' + str(x[2].item())\n",
473
- " y = '-1 ' + str(y[0].item()) + ' -1 ' + str(y[1].item()) + ' ' + str(y[2].item())\n",
474
- " \n",
475
- " # Tokenizando as strings de entrada e alvo\n",
476
- " tokenized_input = tokenizer(x)\n",
477
- " tokenized_output = tokenizer(y)\n",
478
- " \n",
479
- " # Retornando os tensores de entrada e alvo como itens do dataset\n",
480
- " return torch.tensor(tokenized_input), torch.tensor(tokenized_output)"
481
- ]
482
- },
483
- {
484
- "cell_type": "markdown",
485
- "metadata": {},
486
- "source": [
487
- "## Datasets de Treino e Teste"
488
- ]
489
- },
490
- {
491
- "cell_type": "code",
492
- "execution_count": 24,
493
- "metadata": {},
494
- "outputs": [],
495
- "source": [
496
- "dataset_treino = CriaDataset('treino', length = sequence_length)"
497
- ]
498
- },
499
- {
500
- "cell_type": "code",
501
- "execution_count": 25,
502
- "metadata": {},
503
- "outputs": [],
504
- "source": [
505
- "dataset_teste = CriaDataset('teste', length = sequence_length)"
506
- ]
507
- },
508
- {
509
- "cell_type": "code",
510
- "execution_count": 26,
511
- "metadata": {},
512
- "outputs": [],
513
- "source": [
514
- "x, y = dataset_treino[0]"
515
- ]
516
- },
517
- {
518
- "cell_type": "code",
519
- "execution_count": 27,
520
- "metadata": {},
521
- "outputs": [
522
- {
523
- "data": {
524
- "text/plain": [
525
- "tensor([10, 0, 4, 1, 3])"
526
- ]
527
- },
528
- "execution_count": 27,
529
- "metadata": {},
530
- "output_type": "execute_result"
531
- }
532
- ],
533
- "source": [
534
- "x"
535
- ]
536
- },
537
- {
538
- "cell_type": "code",
539
- "execution_count": 28,
540
- "metadata": {},
541
- "outputs": [
542
- {
543
- "data": {
544
- "text/plain": [
545
- "tensor([ 2, 2, 2, 3, 11])"
546
- ]
547
- },
548
- "execution_count": 28,
549
- "metadata": {},
550
- "output_type": "execute_result"
551
- }
552
- ],
553
- "source": [
554
- "y"
555
- ]
556
- },
557
- {
558
- "cell_type": "code",
559
- "execution_count": 29,
560
- "metadata": {},
561
- "outputs": [
562
- {
563
- "name": "stdout",
564
- "output_type": "stream",
565
- "text": [
566
- "7 + 1 = 0\n"
567
- ]
568
- }
569
- ],
570
- "source": [
571
- "print(tokenizer.decode(x.numpy()))"
572
- ]
573
- },
574
- {
575
- "cell_type": "code",
576
- "execution_count": 30,
577
- "metadata": {},
578
- "outputs": [
579
- {
580
- "name": "stdout",
581
- "output_type": "stream",
582
- "text": [
583
- "-1 -1 -1 0 8\n"
584
- ]
585
- }
586
- ],
587
- "source": [
588
- "print(tokenizer.decode(y.numpy()))"
589
- ]
590
- },
591
- {
592
- "cell_type": "markdown",
593
- "metadata": {},
594
- "source": [
595
- "## Loop de Treinamento"
596
- ]
597
- },
598
- {
599
- "cell_type": "code",
600
- "execution_count": 31,
601
- "metadata": {},
602
- "outputs": [],
603
- "source": [
604
- "num_epochs = 2"
605
- ]
606
- },
607
- {
608
- "cell_type": "code",
609
- "execution_count": 32,
610
- "metadata": {},
611
- "outputs": [],
612
- "source": [
613
- "batch_size = 100"
614
- ]
615
- },
616
- {
617
- "cell_type": "code",
618
- "execution_count": 33,
619
- "metadata": {},
620
- "outputs": [],
621
- "source": [
622
- "optimizer = torch.optim.Adam(modelo.parameters())"
623
- ]
624
- },
625
- {
626
- "cell_type": "code",
627
- "execution_count": 34,
628
- "metadata": {},
629
- "outputs": [],
630
- "source": [
631
- "dados = torch.utils.data.DataLoader(dataset_treino, shuffle = True, batch_size = batch_size)"
632
- ]
633
- },
634
- {
635
- "cell_type": "markdown",
636
- "metadata": {},
637
- "source": [
638
- "https://pypi.org/project/accelerate/"
639
- ]
640
- },
641
- {
642
- "cell_type": "code",
643
- "execution_count": 35,
644
- "metadata": {},
645
- "outputs": [],
646
- "source": [
647
- "import accelerate\n",
648
- "from accelerate import Accelerator"
649
- ]
650
- },
651
- {
652
- "cell_type": "code",
653
- "execution_count": 36,
654
- "metadata": {},
655
- "outputs": [],
656
- "source": [
657
- "accelerator = Accelerator()"
658
- ]
659
- },
660
- {
661
- "cell_type": "code",
662
- "execution_count": 37,
663
- "metadata": {},
664
- "outputs": [
665
- {
666
- "name": "stdout",
667
- "output_type": "stream",
668
- "text": [
669
- "Author: Data Science Academy\n",
670
- "\n",
671
- "numpy : 1.23.5\n",
672
- "accelerate : 0.21.0\n",
673
- "torch : 2.0.1\n",
674
- "transformers: 4.31.0\n",
675
- "\n"
676
- ]
677
- }
678
- ],
679
- "source": [
680
- "# Versões dos pacotes usados neste jupyter notebook\n",
681
- "%reload_ext watermark\n",
682
- "%watermark -a \"Data Science Academy\" --iversions"
683
- ]
684
- },
685
- {
686
- "cell_type": "code",
687
- "execution_count": 38,
688
- "metadata": {},
689
- "outputs": [],
690
- "source": [
691
- "modelo, optimizer, dados = accelerator.prepare(modelo, optimizer, dados)"
692
- ]
693
- },
694
- {
695
- "cell_type": "code",
696
- "execution_count": 39,
697
- "metadata": {},
698
- "outputs": [
699
- {
700
- "data": {
701
- "text/plain": [
702
- "GPT2LMHeadModel(\n",
703
- " (transformer): GPT2Model(\n",
704
- " (wte): Embedding(13, 768)\n",
705
- " (wpe): Embedding(1024, 768)\n",
706
- " (drop): Dropout(p=0.1, inplace=False)\n",
707
- " (h): ModuleList(\n",
708
- " (0-1): 2 x GPT2Block(\n",
709
- " (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True)\n",
710
- " (attn): GPT2Attention(\n",
711
- " (c_attn): Conv1D()\n",
712
- " (c_proj): Conv1D()\n",
713
- " (attn_dropout): Dropout(p=0.1, inplace=False)\n",
714
- " (resid_dropout): Dropout(p=0.1, inplace=False)\n",
715
- " )\n",
716
- " (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True)\n",
717
- " (mlp): GPT2MLP(\n",
718
- " (c_fc): Conv1D()\n",
719
- " (c_proj): Conv1D()\n",
720
- " (act): NewGELUActivation()\n",
721
- " (dropout): Dropout(p=0.1, inplace=False)\n",
722
- " )\n",
723
- " )\n",
724
- " )\n",
725
- " (ln_f): LayerNorm((768,), eps=1e-05, elementwise_affine=True)\n",
726
- " )\n",
727
- " (lm_head): Linear(in_features=768, out_features=13, bias=False)\n",
728
- ")"
729
- ]
730
- },
731
- "execution_count": 39,
732
- "metadata": {},
733
- "output_type": "execute_result"
734
- }
735
- ],
736
- "source": [
737
- "modelo.train()"
738
- ]
739
- },
740
- {
741
- "cell_type": "code",
742
- "execution_count": 40,
743
- "metadata": {},
744
- "outputs": [
745
- {
746
- "name": "stdout",
747
- "output_type": "stream",
748
- "text": [
749
- "Epoch: 1/2 --- Erro: 0.10058706998825073\n",
750
- "Epoch: 2/2 --- Erro: 0.05222655460238457\n",
751
- "CPU times: user 6min 51s, sys: 899 ms, total: 6min 52s\n",
752
- "Wall time: 6min 55s\n"
753
- ]
754
- }
755
- ],
756
- "source": [
757
- "%%time\n",
758
- "\n",
759
- "# Iniciando o loop para as épocas de treinamento\n",
760
- "for epoch in range(num_epochs):\n",
761
- "\n",
762
- " # Iterando por cada batch (conjunto) de dados de entrada e alvos no dataset de treinamento\n",
763
- " for source, targets in dados:\n",
764
- "\n",
765
- " # Resetando os gradientes acumulados no otimizador\n",
766
- " optimizer.zero_grad()\n",
767
- "\n",
768
- " # Calculando a perda (loss) através da entropia cruzada entre as previsões do modelo e os alvos verdadeiros. \n",
769
- " # Os tensores são \"achatados\" para que possam ser passados para a função de entropia cruzada. \n",
770
- " # O índice do token de preenchimento (pad_token) é ignorado no cálculo da perda.\n",
771
- " loss = F.cross_entropy(modelo(source).logits.flatten(end_dim = 1), \n",
772
- " targets.flatten(end_dim = 1), \n",
773
- " ignore_index = tokenizer.pad_token_id)\n",
774
- "\n",
775
- " # Calculando os gradientes da perda em relação aos parâmetros do modelo\n",
776
- " accelerator.backward(loss)\n",
777
- "\n",
778
- " # Atualizando os parâmetros do modelo utilizando os gradientes calculados\n",
779
- " optimizer.step()\n",
780
- "\n",
781
- " # Recalculando a perda após a etapa de otimização. \n",
782
- " loss = F.cross_entropy(modelo(source).logits.flatten(end_dim = 1), \n",
783
- " targets.flatten(end_dim = 1), \n",
784
- " ignore_index = tokenizer.pad_token_id)\n",
785
- "\n",
786
- " # Imprimindo a época atual e a perda após cada época de treinamento\n",
787
- " print(f'Epoch: {epoch+1}/{num_epochs} --- Erro: {loss.item()}')"
788
- ]
789
- },
790
- {
791
- "cell_type": "markdown",
792
- "metadata": {},
793
- "source": [
794
- "## Avaliação do Modelo"
795
- ]
796
- },
797
- {
798
- "cell_type": "code",
799
- "execution_count": 41,
800
- "metadata": {},
801
- "outputs": [],
802
- "source": [
803
- "# Definindo a função gera_solution com três parâmetros: input, solution_length e model\n",
804
- "def faz_previsao(entrada, solution_length = 6, model = modelo):\n",
805
- "\n",
806
- " # Colocando o modelo em modo de avaliação. \n",
807
- " model.eval()\n",
808
- "\n",
809
- " # Convertendo a entrada (string) em tensor utilizando o tokenizer. \n",
810
- " # O tensor é uma estrutura de dados que o modelo de aprendizado de máquina pode processar.\n",
811
- " entrada = torch.tensor(tokenizer(entrada))\n",
812
- "\n",
813
- " # Enviando o tensor de entrada para o dispositivo de cálculo disponível (CPU ou GPU)\n",
814
- " entrada = entrada.to(accelerator.device)\n",
815
- "\n",
816
- " # Iniciando uma lista vazia para armazenar a solução\n",
817
- " solution = []\n",
818
- "\n",
819
- " # Loop que gera a solução de comprimento solution_length\n",
820
- " for i in range(solution_length):\n",
821
- "\n",
822
- " # Alimentando a entrada atual ao modelo e obtendo a saída\n",
823
- " saida = model(entrada)\n",
824
- "\n",
825
- " # Pegando o índice do maior valor no último conjunto de logits (log-odds) da saída, \n",
826
- " # que é a previsão do modelo para o próximo token\n",
827
- " predicted = saida.logits[-1].argmax()\n",
828
- "\n",
829
- " # Concatenando a previsão atual com a entrada atual. \n",
830
- " # Isso servirá como a nova entrada para a próxima iteração.\n",
831
- " entrada = torch.cat((entrada, predicted.unsqueeze(0)), dim = 0)\n",
832
- "\n",
833
- " # Adicionando a previsão atual à lista de soluções e convertendo o tensor em um número Python padrão\n",
834
- " solution.append(predicted.cpu().item())\n",
835
- "\n",
836
- " # Decodificando a lista de soluções para obter a string de saída e retornando-a\n",
837
- " return tokenizer.decode(solution)"
838
- ]
839
- },
840
- {
841
- "cell_type": "code",
842
- "execution_count": 42,
843
- "metadata": {},
844
- "outputs": [],
845
- "source": [
846
- "# Definindo a função avalia_modelo com dois parâmetros: num_samples e log\n",
847
- "def avalia_modelo(num_samples = 1000, log = False):\n",
848
- "\n",
849
- " # Iniciando um contador para as previsões corretas\n",
850
- " correct = 0\n",
851
- "\n",
852
- " # Loop que itera num_samples vezes\n",
853
- " for i in range(num_samples):\n",
854
- "\n",
855
- " # Obtendo a entrada e o alvo (resposta correta) do i-ésimo exemplo do conjunto de teste\n",
856
- " entrada, target = dataset_teste[i]\n",
857
- "\n",
858
- " # Convertendo os tensores de entrada e alvo em arrays numpy para processamento posterior\n",
859
- " entrada = entrada.cpu().numpy()\n",
860
- " target = target.cpu().numpy()\n",
861
- "\n",
862
- " # Decodificando a entrada e o alvo utilizando o tokenizer\n",
863
- " entrada = tokenizer.decode(entrada[:sequence_length])\n",
864
- " target = tokenizer.decode(target[sequence_length-1:])\n",
865
- "\n",
866
- " # Gerando a previsão utilizando a função faz_previsao\n",
867
- " predicted = faz_previsao(entrada, solution_length = result_length, model = modelo)\n",
868
- " \n",
869
- " # Se a previsão for igual ao alvo, incrementa o contador de previsões corretas\n",
870
- " if target == predicted:\n",
871
- " correct += 1\n",
872
- " # Se log for True, imprime detalhes do exemplo e a previsão correta\n",
873
- " if log:\n",
874
- " print(f'Acerto do Modelo: Input: {entrada} Target: {target} Previsão: {predicted}')\n",
875
- " else:\n",
876
- " # Se log for True, imprime detalhes do exemplo e a previsão errada\n",
877
- " if log:\n",
878
- " print(f'Erro do Modelo: Input: {entrada} Target: {target} Previsão: {predicted}')\n",
879
- "\n",
880
- " # Ao final do loop, calcula a acurácia (número de previsões corretas dividido pelo número total de exemplos) \n",
881
- " print(f'Acurácia: {correct/num_samples}')"
882
- ]
883
- },
884
- {
885
- "cell_type": "code",
886
- "execution_count": 43,
887
- "metadata": {},
888
- "outputs": [
889
- {
890
- "name": "stdout",
891
- "output_type": "stream",
892
- "text": [
893
- "Acerto do Modelo: Input: 0 + 1 = Target: 0 1 Previsão: 0 1\n",
894
- "Acerto do Modelo: Input: 0 + 3 = Target: 0 3 Previsão: 0 3\n",
895
- "Acerto do Modelo: Input: 1 + 8 = Target: 0 9 Previsão: 0 9\n",
896
- "Acerto do Modelo: Input: 2 + 4 = Target: 0 6 Previsão: 0 6\n",
897
- "Acerto do Modelo: Input: 2 + 4 = Target: 0 6 Previsão: 0 6\n",
898
- "Acerto do Modelo: Input: 5 + 8 = Target: 1 3 Previsão: 1 3\n",
899
- "Acerto do Modelo: Input: 1 + 4 = Target: 0 5 Previsão: 0 5\n",
900
- "Acerto do Modelo: Input: 8 + 9 = Target: 1 7 Previsão: 1 7\n",
901
- "Acerto do Modelo: Input: 5 + 9 = Target: 1 4 Previsão: 1 4\n",
902
- "Acerto do Modelo: Input: 2 + 4 = Target: 0 6 Previsão: 0 6\n",
903
- "Acurácia: 1.0\n"
904
- ]
905
- }
906
- ],
907
- "source": [
908
- "# Executa a função\n",
909
- "avalia_modelo(num_samples = 10, log = True)"
910
- ]
911
- },
912
- {
913
- "cell_type": "code",
914
- "execution_count": 44,
915
- "metadata": {},
916
- "outputs": [
917
- {
918
- "name": "stdout",
919
- "output_type": "stream",
920
- "text": [
921
- "Acurácia: 1.0\n"
922
- ]
923
- }
924
- ],
925
- "source": [
926
- "# Executa a função\n",
927
- "avalia_modelo(num_samples = 1000, log = False)"
928
- ]
929
- },
930
- {
931
- "cell_type": "code",
932
- "execution_count": 45,
933
- "metadata": {},
934
- "outputs": [
935
- {
936
- "data": {
937
- "text/plain": [
938
- "transformers.models.gpt2.modeling_gpt2.GPT2LMHeadModel"
939
- ]
940
- },
941
- "execution_count": 45,
942
- "metadata": {},
943
- "output_type": "execute_result"
944
- }
945
- ],
946
- "source": [
947
- "type(modelo)"
948
- ]
949
- },
950
- {
951
- "cell_type": "code",
952
- "execution_count": 46,
953
- "metadata": {},
954
- "outputs": [],
955
- "source": [
956
- "modelo.save_pretrained(\"modelos/modelo_final\")"
957
- ]
958
- },
959
- {
960
- "cell_type": "markdown",
961
- "metadata": {},
962
- "source": [
963
- "# Fim"
964
- ]
965
- }
966
- ],
967
- "metadata": {
968
- "kernelspec": {
969
- "display_name": "Python 3 (ipykernel)",
970
- "language": "python",
971
- "name": "python3"
972
- },
973
- "language_info": {
974
- "codemirror_mode": {
975
- "name": "ipython",
976
- "version": 3
977
- },
978
- "file_extension": ".py",
979
- "mimetype": "text/x-python",
980
- "name": "python",
981
- "nbconvert_exporter": "python",
982
- "pygments_lexer": "ipython3",
983
- "version": "3.10.9"
984
- }
985
- },
986
- "nbformat": 4,
987
- "nbformat_minor": 2
988
- }