camilaaeromoca commited on
Commit
526f029
·
verified ·
1 Parent(s): 6b7264a

Upload Mini-Projeto3-Deploy.ipynb

Browse files
Files changed (1) hide show
  1. Mini-Projeto3-Deploy.ipynb +375 -0
Mini-Projeto3-Deploy.ipynb ADDED
@@ -0,0 +1,375 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 - Deploy</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
+ "# https://pypi.org/project/gradio/\n",
90
+ "!pip install -q gradio"
91
+ ]
92
+ },
93
+ {
94
+ "cell_type": "code",
95
+ "execution_count": 5,
96
+ "metadata": {},
97
+ "outputs": [],
98
+ "source": [
99
+ "# Imports\n",
100
+ "import torch\n",
101
+ "import gradio as gr\n",
102
+ "from transformers import AutoModelForCausalLM"
103
+ ]
104
+ },
105
+ {
106
+ "cell_type": "code",
107
+ "execution_count": 6,
108
+ "metadata": {},
109
+ "outputs": [
110
+ {
111
+ "name": "stdout",
112
+ "output_type": "stream",
113
+ "text": [
114
+ "Author: Data Science Academy\n",
115
+ "\n",
116
+ "torch : 2.0.1\n",
117
+ "gradio: 3.39.0\n",
118
+ "\n"
119
+ ]
120
+ }
121
+ ],
122
+ "source": [
123
+ "# Versões dos pacotes usados neste jupyter notebook\n",
124
+ "%reload_ext watermark\n",
125
+ "%watermark -a \"Data Science Academy\" --iversions"
126
+ ]
127
+ },
128
+ {
129
+ "cell_type": "code",
130
+ "execution_count": 7,
131
+ "metadata": {},
132
+ "outputs": [],
133
+ "source": [
134
+ "# Carrega o modelo\n",
135
+ "modelo_llm = AutoModelForCausalLM.from_pretrained(\"modelos/modelo_final\")"
136
+ ]
137
+ },
138
+ {
139
+ "cell_type": "code",
140
+ "execution_count": 8,
141
+ "metadata": {},
142
+ "outputs": [],
143
+ "source": [
144
+ "# Definindo uma classe chamada NumberTokenizer, que é usada para tokenizar os números\n",
145
+ "class DSATokenizer:\n",
146
+ " \n",
147
+ " # Método construtor da classe, que é executado quando um objeto dessa classe é criado\n",
148
+ " def __init__(self, numbers_qty = 10):\n",
149
+ " \n",
150
+ " # Lista de tokens possíveis que o tokenizador pode encontrar\n",
151
+ " vocab = ['+', '=', '-1', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']\n",
152
+ " \n",
153
+ " # Definindo a quantidade de números que o tokenizador pode lidar\n",
154
+ " self.numbers_qty = numbers_qty\n",
155
+ " \n",
156
+ " # Definindo o token de preenchimento (padding)\n",
157
+ " self.pad_token = '-1'\n",
158
+ " \n",
159
+ " # Criando um dicionário que mapeia cada token para um índice único\n",
160
+ " self.encoder = {str(v):i for i,v in enumerate(vocab)}\n",
161
+ " \n",
162
+ " # Criando um dicionário que mapeia cada índice único de volta ao token correspondente\n",
163
+ " self.decoder = {i:str(v) for i,v in enumerate(vocab)}\n",
164
+ " \n",
165
+ " # Obtendo o índice do token de preenchimento no encoder\n",
166
+ " self.pad_token_id = self.encoder[self.pad_token]\n",
167
+ "\n",
168
+ " # Método para decodificar uma lista de IDs de token de volta para uma string\n",
169
+ " def decode(self, token_ids):\n",
170
+ " return ' '.join(self.decoder[t] for t in token_ids)\n",
171
+ "\n",
172
+ " # Método que é chamado quando o objeto da classe é invocado como uma função\n",
173
+ " def __call__(self, text):\n",
174
+ " # Dividindo o texto em tokens individuais e retornando uma lista dos IDs correspondentes\n",
175
+ " return [self.encoder[t] for t in text.split()]"
176
+ ]
177
+ },
178
+ {
179
+ "cell_type": "code",
180
+ "execution_count": 9,
181
+ "metadata": {},
182
+ "outputs": [],
183
+ "source": [
184
+ "# Cria o objeto\n",
185
+ "tokenizer = DSATokenizer(13)"
186
+ ]
187
+ },
188
+ {
189
+ "cell_type": "code",
190
+ "execution_count": 10,
191
+ "metadata": {},
192
+ "outputs": [],
193
+ "source": [
194
+ "# Definindo a função gera_solution com três parâmetros: input, solution_length e model\n",
195
+ "def faz_previsao(entrada, solution_length = 6, model = modelo_llm):\n",
196
+ "\n",
197
+ " # Colocando o modelo em modo de avaliação. \n",
198
+ " model.eval()\n",
199
+ "\n",
200
+ " # Convertendo a entrada (string) em tensor utilizando o tokenizer. \n",
201
+ " # O tensor é uma estrutura de dados que o modelo de aprendizado de máquina pode processar.\n",
202
+ " entrada = torch.tensor(tokenizer(entrada))\n",
203
+ "\n",
204
+ " # Iniciando uma lista vazia para armazenar a solução\n",
205
+ " solution = []\n",
206
+ "\n",
207
+ " # Loop que gera a solução de comprimento solution_length\n",
208
+ " for i in range(solution_length):\n",
209
+ "\n",
210
+ " # Alimentando a entrada atual ao modelo e obtendo a saída\n",
211
+ " saida = model(entrada)\n",
212
+ "\n",
213
+ " # Pegando o índice do maior valor no último conjunto de logits (log-odds) da saída, \n",
214
+ " # que é a previsão do modelo para o próximo token\n",
215
+ " predicted = saida.logits[-1].argmax()\n",
216
+ "\n",
217
+ " # Concatenando a previsão atual com a entrada atual. \n",
218
+ " # Isso servirá como a nova entrada para a próxima iteração.\n",
219
+ " entrada = torch.cat((entrada, predicted.unsqueeze(0)), dim = 0)\n",
220
+ "\n",
221
+ " # Adicionando a previsão atual à lista de soluções e convertendo o tensor em um número Python padrão\n",
222
+ " solution.append(predicted.cpu().item())\n",
223
+ "\n",
224
+ " # Decodificando a lista de soluções para obter a string de saída e retornando-a\n",
225
+ " return tokenizer.decode(solution)"
226
+ ]
227
+ },
228
+ {
229
+ "cell_type": "code",
230
+ "execution_count": 11,
231
+ "metadata": {},
232
+ "outputs": [
233
+ {
234
+ "data": {
235
+ "text/plain": [
236
+ "'0 8'"
237
+ ]
238
+ },
239
+ "execution_count": 11,
240
+ "metadata": {},
241
+ "output_type": "execute_result"
242
+ }
243
+ ],
244
+ "source": [
245
+ "# Testa a função\n",
246
+ "faz_previsao('3 + 5 =', solution_length = 2)"
247
+ ]
248
+ },
249
+ {
250
+ "cell_type": "code",
251
+ "execution_count": 12,
252
+ "metadata": {},
253
+ "outputs": [],
254
+ "source": [
255
+ "# Função para retornar a função que faz a previsão\n",
256
+ "def funcsolve(entrada):\n",
257
+ " return faz_previsao(entrada, solution_length = 2)"
258
+ ]
259
+ },
260
+ {
261
+ "cell_type": "code",
262
+ "execution_count": 13,
263
+ "metadata": {},
264
+ "outputs": [],
265
+ "source": [
266
+ "# Cria a web app\n",
267
+ "webapp = gr.Interface(fn = funcsolve, \n",
268
+ " inputs = [gr.Textbox(label = \"Dados de Entrada\", \n",
269
+ " lines = 1, \n",
270
+ " info = \"Os dados devem estar na forma: '1 + 2 =' com um único espaço entre cada caractere e apenas números de um dígito são permitidos.\")],\n",
271
+ " outputs = [gr.Textbox(label = \"Resultado (Previsão do Modelo)\", lines = 1)],\n",
272
+ " title = \"Deploy de LLM Após o Fine-Tuning\",\n",
273
+ " description = \"Digite os dados de entrada e clique no botão Submit para o modelo fazer a previsão.\",\n",
274
+ " examples = [\"5 + 3 =\", \"2 + 9 =\"]) "
275
+ ]
276
+ },
277
+ {
278
+ "cell_type": "code",
279
+ "execution_count": 14,
280
+ "metadata": {},
281
+ "outputs": [
282
+ {
283
+ "name": "stdout",
284
+ "output_type": "stream",
285
+ "text": [
286
+ "Running on local URL: http://127.0.0.1:7860\n",
287
+ "\n",
288
+ "To create a public link, set `share=True` in `launch()`.\n"
289
+ ]
290
+ },
291
+ {
292
+ "data": {
293
+ "text/html": [
294
+ "<div><iframe src=\"http://127.0.0.1:7860/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
295
+ ],
296
+ "text/plain": [
297
+ "<IPython.core.display.HTML object>"
298
+ ]
299
+ },
300
+ "metadata": {},
301
+ "output_type": "display_data"
302
+ },
303
+ {
304
+ "data": {
305
+ "text/plain": []
306
+ },
307
+ "execution_count": 14,
308
+ "metadata": {},
309
+ "output_type": "execute_result"
310
+ },
311
+ {
312
+ "name": "stderr",
313
+ "output_type": "stream",
314
+ "text": [
315
+ "Traceback (most recent call last):\n",
316
+ " File \"/Users/dmpm/anaconda3/lib/python3.10/site-packages/gradio/routes.py\", line 442, in run_predict\n",
317
+ " output = await app.get_blocks().process_api(\n",
318
+ " File \"/Users/dmpm/anaconda3/lib/python3.10/site-packages/gradio/blocks.py\", line 1392, in process_api\n",
319
+ " result = await self.call_function(\n",
320
+ " File \"/Users/dmpm/anaconda3/lib/python3.10/site-packages/gradio/blocks.py\", line 1097, in call_function\n",
321
+ " prediction = await anyio.to_thread.run_sync(\n",
322
+ " File \"/Users/dmpm/anaconda3/lib/python3.10/site-packages/anyio/to_thread.py\", line 28, in run_sync\n",
323
+ " return await get_asynclib().run_sync_in_worker_thread(func, *args, cancellable=cancellable,\n",
324
+ " File \"/Users/dmpm/anaconda3/lib/python3.10/site-packages/anyio/_backends/_asyncio.py\", line 818, in run_sync_in_worker_thread\n",
325
+ " return await future\n",
326
+ " File \"/Users/dmpm/anaconda3/lib/python3.10/site-packages/anyio/_backends/_asyncio.py\", line 754, in run\n",
327
+ " result = context.run(func, *args)\n",
328
+ " File \"/Users/dmpm/anaconda3/lib/python3.10/site-packages/gradio/utils.py\", line 703, in wrapper\n",
329
+ " response = f(*args, **kwargs)\n",
330
+ " File \"/var/folders/dc/lqrc3k5j4438r150cbrdr_000000gn/T/ipykernel_5062/1694334565.py\", line 3, in funcsolve\n",
331
+ " return faz_previsao(entrada, solution_length = 2)\n",
332
+ " File \"/var/folders/dc/lqrc3k5j4438r150cbrdr_000000gn/T/ipykernel_5062/2965097493.py\", line 9, in faz_previsao\n",
333
+ " entrada = torch.tensor(tokenizer(entrada))\n",
334
+ " File \"/var/folders/dc/lqrc3k5j4438r150cbrdr_000000gn/T/ipykernel_5062/3426772234.py\", line 32, in __call__\n",
335
+ " return [self.encoder[t] for t in text.split()]\n",
336
+ " File \"/var/folders/dc/lqrc3k5j4438r150cbrdr_000000gn/T/ipykernel_5062/3426772234.py\", line 32, in <listcomp>\n",
337
+ " return [self.encoder[t] for t in text.split()]\n",
338
+ "KeyError: '122220'\n"
339
+ ]
340
+ }
341
+ ],
342
+ "source": [
343
+ "webapp.launch()"
344
+ ]
345
+ },
346
+ {
347
+ "cell_type": "markdown",
348
+ "metadata": {},
349
+ "source": [
350
+ "# Fim"
351
+ ]
352
+ }
353
+ ],
354
+ "metadata": {
355
+ "kernelspec": {
356
+ "display_name": "Python 3 (ipykernel)",
357
+ "language": "python",
358
+ "name": "python3"
359
+ },
360
+ "language_info": {
361
+ "codemirror_mode": {
362
+ "name": "ipython",
363
+ "version": 3
364
+ },
365
+ "file_extension": ".py",
366
+ "mimetype": "text/x-python",
367
+ "name": "python",
368
+ "nbconvert_exporter": "python",
369
+ "pygments_lexer": "ipython3",
370
+ "version": "3.10.9"
371
+ }
372
+ },
373
+ "nbformat": 4,
374
+ "nbformat_minor": 2
375
+ }