Text Generation
PyTorch
Portuguese
Boakpe commited on
Commit
883ce05
·
verified ·
1 Parent(s): 514c612

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ imgs/architecture.png filter=lfs diff=lfs merge=lfs -text
37
+ imgs/historinhas-logo.png filter=lfs diff=lfs merge=lfs -text
breno-trabalho-final.ipynb ADDED
@@ -0,0 +1,524 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "id": "e176393b",
6
+ "metadata": {},
7
+ "source": [
8
+ "<img src=\"IMGS/historinhas-logo.png\" alt=\"drawing\" width=\"400\"/>"
9
+ ]
10
+ },
11
+ {
12
+ "cell_type": "markdown",
13
+ "id": "c1fbc91d",
14
+ "metadata": {},
15
+ "source": [
16
+ "# Historinhas-102M\n",
17
+ "\n",
18
+ "## Visão Geral\n",
19
+ "\n",
20
+ "Inspirado no artigo [TinyStories: How Small Can Language Models Be and Still Speak Coherent English?](https://arxiv.org/abs/2305.07759), este projeto tem como objetivo a criação de um conjunto de dados e o treinamento de um modelo de linguagem do zero capaz de gerar texto coerente em português brasileiro. O foco principal está na geração de histórias infantis simples e coerentes, demonstrando que mesmo modelos extremamente pequenos para os padrões atuais podem produzir conteúdo textual de qualidade."
21
+ ]
22
+ },
23
+ {
24
+ "cell_type": "markdown",
25
+ "id": "a12941c0",
26
+ "metadata": {},
27
+ "source": [
28
+ "#### Imports"
29
+ ]
30
+ },
31
+ {
32
+ "cell_type": "code",
33
+ "execution_count": 1,
34
+ "id": "6ecd2350",
35
+ "metadata": {},
36
+ "outputs": [],
37
+ "source": [
38
+ "import torch\n",
39
+ "import torch.nn as nn\n",
40
+ "import torch.nn.functional as F\n",
41
+ "\n",
42
+ "from tokenizers import Tokenizer\n",
43
+ "\n",
44
+ "from dataclasses import dataclass"
45
+ ]
46
+ },
47
+ {
48
+ "cell_type": "code",
49
+ "execution_count": 2,
50
+ "id": "f4c90336",
51
+ "metadata": {},
52
+ "outputs": [],
53
+ "source": [
54
+ "# Seleciona a GPU se disponível, caso contrário, usa a CPU\n",
55
+ "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n",
56
+ "\n",
57
+ "# Configurações do modelo (102 milhões de parâmetros)\n",
58
+ "@dataclass\n",
59
+ "class ModelConfig:\n",
60
+ " d_emb: int = 512\n",
61
+ " vocab_size: int = 20000\n",
62
+ " num_layers: int = 8\n",
63
+ " num_heads: int = 8\n",
64
+ " num_hidden: int = 4 * d_emb"
65
+ ]
66
+ },
67
+ {
68
+ "cell_type": "markdown",
69
+ "id": "71f512c4",
70
+ "metadata": {},
71
+ "source": [
72
+ "## Arquitetura do modelo"
73
+ ]
74
+ },
75
+ {
76
+ "cell_type": "markdown",
77
+ "id": "4b996dfc",
78
+ "metadata": {},
79
+ "source": [
80
+ "## Arquitetura Inspirada no LLaMA\n",
81
+ "\n",
82
+ "Esta arquitetura segue os princípios da família de modelos **LLaMA**, com algumas modificações para melhorar o desempenho.\n",
83
+ "\n",
84
+ "### Principais Modificações\n",
85
+ "\n",
86
+ "* Substituição do **Grouped Query Attention** por **Multi-Head Attention**\n",
87
+ "\n",
88
+ " > Prioriza desempenho, mesmo com maior custo computacional.\n",
89
+ "\n",
90
+ "* **KV-cache** não implementado\n",
91
+ "\n",
92
+ " > Foco em simplicidade e clareza no fluxo de atenção.\n",
93
+ "\n",
94
+ "\n",
95
+ "### Comparação com a Arquitetura Original do Transformer\n",
96
+ "\n",
97
+ "| Característica | Arquitetura Atual | Transformer Original |\n",
98
+ "| ------------------------------ | ---------------------------- | --------------------------- |\n",
99
+ "| Estrutura | **Decoder-only** | Encoder-Decoder |\n",
100
+ "| Normalização | **RMS Norm** | Layer Norm |\n",
101
+ "| Ordem da Normalização | **Antes da adição residual** | Depois da adição residual |\n",
102
+ "| Função de Ativação | **SwiGLU** | ReLU |\n",
103
+ "| Positional Embedding | **Rotary Embedding** | Absolute Positional Embedding |\n",
104
+ "| Weight Tying | ✅ Sim | ❌ Ausente (em muitos casos) |\n",
105
+ "\n",
106
+ "\n",
107
+ "### Diagrama da Arquitetura do Modelo\n",
108
+ "<img src=\"imgs/architecture.png\" alt=\"drawing\" width=\"200\"/>\n"
109
+ ]
110
+ },
111
+ {
112
+ "cell_type": "code",
113
+ "execution_count": 3,
114
+ "id": "c65bba83",
115
+ "metadata": {},
116
+ "outputs": [],
117
+ "source": [
118
+ "class SwiGlu(nn.Module):\n",
119
+ " def __init__(self, d_emb):\n",
120
+ " super().__init__()\n",
121
+ " self.ll = nn.Linear(d_emb, 2 * d_emb)\n",
122
+ " self.silu = nn.SiLU()\n",
123
+ "\n",
124
+ " def forward(self, x):\n",
125
+ " x = self.ll(x)\n",
126
+ " a, b = x.chunk(2, dim=-1)\n",
127
+ " return self.silu(a) * b\n",
128
+ "\n",
129
+ "\n",
130
+ "class FeedForward(nn.Module):\n",
131
+ " def __init__(self, d_emb, num_hidden):\n",
132
+ " super().__init__()\n",
133
+ " self.fc1 = nn.Linear(d_emb, num_hidden)\n",
134
+ " self.swiglu = SwiGlu(num_hidden)\n",
135
+ " self.fc2 = nn.Linear(num_hidden, d_emb)\n",
136
+ "\n",
137
+ " def forward(self, x):\n",
138
+ " return self.fc2(self.swiglu(self.fc1(x)))\n",
139
+ "\n",
140
+ "\n",
141
+ "class RoPe(nn.Module):\n",
142
+ " def __init__(self, head_d_emb, base=10000.0):\n",
143
+ " super().__init__()\n",
144
+ " inv_freq = 1 / (base ** (torch.arange(0, head_d_emb, 2).float() / head_d_emb))\n",
145
+ " self.register_buffer(\"inv_freq\", inv_freq)\n",
146
+ "\n",
147
+ " def _build_cos_sin(self, seq_length):\n",
148
+ " t = torch.arange(0, seq_length, device=device).type_as(self.inv_freq)\n",
149
+ " freq = torch.einsum(\"i,j->ij\", t, self.inv_freq)\n",
150
+ " freq = torch.repeat_interleave(freq, 2, dim=-1)\n",
151
+ " cos, sin = freq.cos(), freq.sin()\n",
152
+ " return cos, sin\n",
153
+ "\n",
154
+ " def forward(self, q, k):\n",
155
+ " seq_length = q.shape[-2]\n",
156
+ " cos, sin = self._build_cos_sin(seq_length)\n",
157
+ " cos = cos[None, None, :, :].to(q.dtype)\n",
158
+ " sin = sin[None, None, :, :].to(q.dtype)\n",
159
+ "\n",
160
+ " def rotate(x):\n",
161
+ " x_even, x_odd = x[..., ::2], x[..., 1::2]\n",
162
+ " new_x = torch.stack((-x_odd, x_even), dim=-1).flatten(-2)\n",
163
+ " return new_x\n",
164
+ "\n",
165
+ " q_rot = q * cos + rotate(q) * sin\n",
166
+ " k_rot = k * cos + rotate(k) * sin\n",
167
+ "\n",
168
+ " return q_rot, k_rot\n",
169
+ "\n",
170
+ "\n",
171
+ "class MultiheadAttention(nn.Module):\n",
172
+ " def __init__(self, num_heads, d_emb):\n",
173
+ " super().__init__()\n",
174
+ " self.num_heads = num_heads\n",
175
+ " self.head_dim = d_emb // num_heads\n",
176
+ " self.qkv_layer = nn.Linear(d_emb, 3 * d_emb)\n",
177
+ " self.rope = RoPe(self.head_dim)\n",
178
+ " self.ll = nn.Linear(d_emb, d_emb)\n",
179
+ "\n",
180
+ " def forward(self, x):\n",
181
+ " batch_size, seq_length, d_emb = x.shape\n",
182
+ " qkv = self.qkv_layer(x)\n",
183
+ " qkv = qkv.view(batch_size, seq_length, self.num_heads, 3 * self.head_dim)\n",
184
+ " qkv = qkv.permute(0, 2, 1, 3)\n",
185
+ " q, k, v = qkv.chunk(3, dim=-1)\n",
186
+ "\n",
187
+ " q, k = self.rope(q, k)\n",
188
+ "\n",
189
+ " values = F.scaled_dot_product_attention(q, k, v, is_causal=True)\n",
190
+ " values = values.permute(0, 2, 1, 3)\n",
191
+ " values = values.contiguous()\n",
192
+ " values = values.view(batch_size, seq_length, self.num_heads * self.head_dim)\n",
193
+ " out = self.ll(values)\n",
194
+ " return out\n",
195
+ "\n",
196
+ "\n",
197
+ "class TransformerDecoderBlock(nn.Module):\n",
198
+ " def __init__(self, num_heads, d_emb, num_hidden):\n",
199
+ " super().__init__()\n",
200
+ " self.rmsn1 = nn.RMSNorm(d_emb)\n",
201
+ " self.multihead_attention = MultiheadAttention(num_heads, d_emb)\n",
202
+ " self.rmsn2 = nn.RMSNorm(d_emb)\n",
203
+ " self.ff = FeedForward(d_emb, num_hidden)\n",
204
+ "\n",
205
+ " def forward(self, x):\n",
206
+ " x = x + self.multihead_attention(self.rmsn1(x))\n",
207
+ " x = x + self.ff(self.rmsn2(x))\n",
208
+ " return x\n",
209
+ "\n",
210
+ "\n",
211
+ "class HistorinhasLM(nn.Module):\n",
212
+ " def __init__(self, config: ModelConfig, tokenizer: Tokenizer):\n",
213
+ " super().__init__()\n",
214
+ " self.vocab_size = config.vocab_size\n",
215
+ " self.we = nn.Embedding(config.vocab_size, config.d_emb)\n",
216
+ " self.sequential = nn.Sequential(\n",
217
+ " *[\n",
218
+ " TransformerDecoderBlock(\n",
219
+ " config.num_heads, config.d_emb, config.num_hidden\n",
220
+ " )\n",
221
+ " for _ in range(config.num_layers)\n",
222
+ " ]\n",
223
+ " )\n",
224
+ " self.rmsn = nn.RMSNorm(config.d_emb)\n",
225
+ " self.fc = nn.Linear(config.d_emb, config.vocab_size, bias=False)\n",
226
+ "\n",
227
+ " self.we.weight = self.fc.weight\n",
228
+ "\n",
229
+ " self.criterion = nn.CrossEntropyLoss()\n",
230
+ " \n",
231
+ " self.tokenizer = tokenizer\n",
232
+ " self.tokenizer.enable_truncation(max_length=512)\n",
233
+ "\n",
234
+ " def forward(self, x, y=None):\n",
235
+ " x = self.we(x)\n",
236
+ " x = self.sequential(x)\n",
237
+ " x = self.rmsn(x)\n",
238
+ " logits = self.fc(x)\n",
239
+ " if y != None:\n",
240
+ " loss = self.criterion(logits.view(-1, self.vocab_size), y.view(-1))\n",
241
+ " return logits, loss\n",
242
+ "\n",
243
+ " return logits\n",
244
+ " \n",
245
+ " # Função para gerar texto a partir de um modelo treinado\n",
246
+ " @torch.no_grad()\n",
247
+ " def generate(self, input, temperature=0.3, max_length=500, k=10):\n",
248
+ " self.eval()\n",
249
+ " input = torch.tensor([self.tokenizer.encode(input).ids], dtype=torch.long).to(device)\n",
250
+ " print(self.tokenizer.decode(input[0].tolist(), skip_special_tokens=False), end=\"\")\n",
251
+ "\n",
252
+ " for i in range(max_length):\n",
253
+ " logits = self(input)\n",
254
+ " logits = logits[:, -1, :]\n",
255
+ "\n",
256
+ " if temperature == 0:\n",
257
+ " idx_next = torch.argmax(logits, dim=-1, keepdim=True) \n",
258
+ " else:\n",
259
+ " logits = logits / temperature \n",
260
+ " top_k_logits, top_k_indices = torch.topk(logits, k, dim=-1) \n",
261
+ " top_k_probs = F.softmax(top_k_logits, dim=-1)\n",
262
+ " sampled_relative_index = torch.multinomial(top_k_probs, num_samples=1)\n",
263
+ " idx_next = torch.gather(top_k_indices, dim=-1, index=sampled_relative_index) \n",
264
+ "\n",
265
+ " input = torch.cat((input, idx_next), dim=-1)\n",
266
+ "\n",
267
+ " generated_token_id = idx_next[0, 0].item()\n",
268
+ " print(self.tokenizer.decode([generated_token_id], skip_special_tokens=False),end=\"\")\n",
269
+ "\n",
270
+ " if generated_token_id == self.tokenizer.encode(\"<|end|>\").ids[0]:\n",
271
+ " break\n",
272
+ "\n",
273
+ " print() \n",
274
+ " self.train()\n",
275
+ " return input\n",
276
+ " \n",
277
+ " def get_num_parameters(self):\n",
278
+ " return sum([x.view(-1).shape[0] for x in self.parameters()])"
279
+ ]
280
+ },
281
+ {
282
+ "cell_type": "markdown",
283
+ "id": "919c3d61",
284
+ "metadata": {},
285
+ "source": [
286
+ "## 📚 Conjunto de Dados e Treinamento do Modelo\n",
287
+ "\n",
288
+ "O projeto **Historinhas-102M** utiliza um conjunto de dados com **1.255.240 histórias infantis**, totalizando **mais de 300 milhões de tokens**.\n",
289
+ "\n",
290
+ "---\n",
291
+ "\n",
292
+ "### 🧠 Geração dos Dados\n",
293
+ "\n",
294
+ "As histórias foram geradas com auxílio dos seguintes modelos de linguagem:\n",
295
+ "\n",
296
+ "- **Gemini 2.0 Flash**\n",
297
+ "- **Gemini 2.0 Flash-exp**\n",
298
+ "- **Gemini 2.0 Flash-Lite**\n",
299
+ "- **Gemini 2.0 Flash Thinking**\n",
300
+ "- **Gemma 3 27B**\n",
301
+ "\n",
302
+ "> 🕒 *Todo o processo de geração foi realizado de forma gratuita e levou aproximadamente **3 semanas** para ser concluído.*\n",
303
+ "\n",
304
+ "---\n",
305
+ "\n",
306
+ "### 🏋️ Treinamento do Modelo\n",
307
+ "\n",
308
+ "- **Número de épocas:** ~5 \n",
309
+ "- **Duração total:** ~25 horas \n",
310
+ "- **Hardware utilizado:** NVIDIA T4 GPU\n",
311
+ "\n",
312
+ "> O modelo possui **102 milhões de parâmetros** (equivalente ao tamanho do BERT base) e foi treinado para gerar histórias infantis coerentes em português.\n",
313
+ "\n",
314
+ "---\n",
315
+ "\n",
316
+ "### 💻 Código de Treinamento\n",
317
+ "\n",
318
+ "Devido ao tamanho do conjunto de dados, ao tempo necessário e à complexidade do código de treinamento, o notebook **não está incluído aqui**. \n",
319
+ "Você pode acessá-lo diretamente no repositório do Github:\n",
320
+ "\n",
321
+ "🔗 [Código de Treinamento – Github](https://github.com/Boakpe/Historinhas-102M)\n",
322
+ "\n",
323
+ "---\n",
324
+ "\n",
325
+ "### 📥 Download do Dataset\n",
326
+ "\n",
327
+ "O conjunto de dados completo, junto com mais informações, está disponível aqui:\n",
328
+ "\n",
329
+ "🔗 [Dataset \"Historinhas\" – Hugging Face](https://huggingface.co/datasets/Boakpe/historinhas)\n"
330
+ ]
331
+ },
332
+ {
333
+ "cell_type": "markdown",
334
+ "id": "1991c82a",
335
+ "metadata": {},
336
+ "source": [
337
+ "## ✂️ Tokenizer\n",
338
+ "\n",
339
+ "O **tokenizer** utilizado neste projeto foi treinado com a biblioteca [🤗 Hugging Face Tokenizers](https://huggingface.co/docs/tokenizers/index), utilizando o algoritmo **BPE (Byte Pair Encoding)**.\n",
340
+ "\n",
341
+ "---\n",
342
+ "\n",
343
+ "### 📦 Detalhes do Tokenizer\n",
344
+ "\n",
345
+ "- **Algoritmo:** BPE (Byte Pair Encoding) \n",
346
+ "- **Vocabulário:** 20.000 tokens \n",
347
+ "- **Dataset utilizado:** [Historinhas Dataset](https://huggingface.co/datasets/Boakpe/historinhas)\n",
348
+ "\n",
349
+ "> ⚠️ Devido ao tamanho do conjunto de dados, o treinamento do tokenizer leva aproximadamente **20 minutos**. \n",
350
+ "> Para facilitar, o tokenizer já foi previamente treinado e está disponível no arquivo: \n",
351
+ "> **`tokenizer.json`**\n",
352
+ "\n",
353
+ "---\n",
354
+ "\n",
355
+ "### 🧩 Carregando o Tokenizer\n",
356
+ "\n",
357
+ "O código abaixo apenas realiza o carregamento do tokenizer já treinado:\n"
358
+ ]
359
+ },
360
+ {
361
+ "cell_type": "code",
362
+ "execution_count": 4,
363
+ "id": "b9be5960",
364
+ "metadata": {},
365
+ "outputs": [],
366
+ "source": [
367
+ "tokenizer = Tokenizer.from_file(\"historinhas-102M/tokenizer.json\")\n",
368
+ "tokenizer.enable_padding(direction=\"right\", pad_id=0, pad_token=\"<|pad|>\")"
369
+ ]
370
+ },
371
+ {
372
+ "cell_type": "markdown",
373
+ "id": "313e835f",
374
+ "metadata": {},
375
+ "source": [
376
+ "## Carrega o modelo e realiza a inferência"
377
+ ]
378
+ },
379
+ {
380
+ "cell_type": "code",
381
+ "execution_count": 5,
382
+ "id": "e3e5c0eb",
383
+ "metadata": {},
384
+ "outputs": [
385
+ {
386
+ "name": "stdout",
387
+ "output_type": "stream",
388
+ "text": [
389
+ "102.59 milhões de parâmetros\n"
390
+ ]
391
+ },
392
+ {
393
+ "data": {
394
+ "text/plain": [
395
+ "<All keys matched successfully>"
396
+ ]
397
+ },
398
+ "execution_count": 5,
399
+ "metadata": {},
400
+ "output_type": "execute_result"
401
+ }
402
+ ],
403
+ "source": [
404
+ "# Carrega o modelo e move para o dispositivo correto\n",
405
+ "model = HistorinhasLM(ModelConfig(), tokenizer)\n",
406
+ "model.to(device)\n",
407
+ "\n",
408
+ "# Imprime o número total de parâmetros do modelo\n",
409
+ "print(round((model.get_num_parameters() / 1_000_000), 2), 'milhões de parâmetros')\n",
410
+ "\n",
411
+ "# Carrega os pesos do modelo com os pesos pré-treinados\n",
412
+ "model.load_state_dict(torch.load('historinhas-102M/historinhas-102M.pth'))"
413
+ ]
414
+ },
415
+ {
416
+ "cell_type": "code",
417
+ "execution_count": 11,
418
+ "id": "9a4cb122",
419
+ "metadata": {},
420
+ "outputs": [
421
+ {
422
+ "name": "stdout",
423
+ "output_type": "stream",
424
+ "text": [
425
+ "<|end|> Denilson era um cientista muito inteligente, mas um pouco distraído. Ele adorava inventar coisas em seu laboratório, mas às vezes, suas invenções não saíam como planejado.\n",
426
+ "\n",
427
+ "Um dia, Denilson estava trabalhando em uma fórmula para fazer as plantas crescerem mais rápido. Ele misturou vários ingredientes, mas a fórmula explodiu, sujando todo o laboratório e transformando-o em um monte de lama.\n",
428
+ "\n",
429
+ "Denilson ficou muito triste. Ele havia falhado em sua pesquisa e agora tudo estava arruinado. Ele se sentou no chão, desanimado.\n",
430
+ "\n",
431
+ "De repente, ele ouviu uma voz. \"Não desista, Denilson! Você é um cientista incrível! Use sua criatividade para resolver os problemas!\"\n",
432
+ "\n",
433
+ "Era a voz de sua amiga, a cientista Sofia. Ela tinha vindo de outro laboratório para ajudar Denilson a criar uma nova fórmula.\n",
434
+ "\n",
435
+ "Denilson pensou um pouco e decidiu seguir o conselho de Sofia. Ele começou a usar os materiais que encontrou no laboratório para criar uma nova fórmula, mais simples e eficaz.\n",
436
+ "\n",
437
+ "Ele misturou os ingredientes com cuidado, seguindo a receita antiga de Sofia. Ele misturou os ingredientes com carinho e atenção.\n",
438
+ "\n",
439
+ "Depois de algumas horas, a nova fórmula estava pronta. Era uma mistura de vinagre, vinagre e um pouco de glitter.\n",
440
+ "\n",
441
+ "Denilson ficou muito feliz com sua invenção. Ele percebeu que, mesmo com os erros, ele podia aprender com eles e criar coisas incríveis.\n",
442
+ "\n",
443
+ "Ele agradeceu a Sofia por acreditar nele e por ensiná-lo a importância da persistência. Ele aprendeu que a gratidão é uma forma de reconhecer o valor das pessoas e de valorizar o trabalho em equipe.\n",
444
+ "\n",
445
+ "Denilson continuou a inventar coisas incríveis, sempre com gratidão no coração. Ele sabia que, com a ajuda de seus amigos e a persistência, ele poderia superar qualquer desafio.<|end|>\n"
446
+ ]
447
+ }
448
+ ],
449
+ "source": [
450
+ "# Exemplo de uso da função de geração\n",
451
+ "# Sempre use o token <|end|> para iniciar a geração\n",
452
+ "# Outros exemplos:\n",
453
+ "# <|end|>Denilson era um professor\n",
454
+ "# <|end|>\n",
455
+ "# <|end|>Era uma vez\n",
456
+ "# <|end|>Em uma terra\n",
457
+ "texto = \"<|end|>Denilson era um cientista\"\n",
458
+ "generated_id = model.generate(texto)"
459
+ ]
460
+ },
461
+ {
462
+ "cell_type": "markdown",
463
+ "id": "aee7e533",
464
+ "metadata": {},
465
+ "source": [
466
+ "## Considerações Finais\n",
467
+ "\n",
468
+ "### Desempenho e Generalização\n",
469
+ "\n",
470
+ "O modelo apresentou um desempenho muito bom, sendo capaz de gerar histórias coerentes na grande maioria dos casos testados. Um aspecto particularmente impressionante foi sua capacidade de generalização - mesmo quando apresentado a nomes de personagens que nunca apareceram no conjunto de treinamento (como \"Denilson\"), o modelo consegue gerar narrativas perfeitamente estruturadas. Além disso, todas as histórias criadas são inéditas, sem cópias de histórias existentes no conjunto de dados.\n",
471
+ "\n",
472
+ "### Tamanho do Modelo vs. Conjunto de Dados\n",
473
+ "\n",
474
+ "Apesar do modelo ser relativamente grande em comparação ao tamanho do conjunto de dados (102M de parâmetros para 300 milhões de tokens) - aproximadamente 3 parâmetros por token, bem abaixo dos 20 recomendados pela Chinchilla scaling laws - ele não apresentou sinais de overfitting. \n",
475
+ "\n",
476
+ "Além disso, a qualidade das saídas geradas foi significativamente superior quando comparada a modelos menores que seguem mais estritamente as recomendações de escala. Durante o desenvolvimento, foram treinados dois modelos adicionais com 32 milhões e 69 milhões de parâmetros, respectivamente, mas esta versão de 102M parâmetros foi a que demonstrou melhor criatividade e qualidade nas histórias geradas.\n"
477
+ ]
478
+ },
479
+ {
480
+ "cell_type": "markdown",
481
+ "id": "d7e6c310",
482
+ "metadata": {},
483
+ "source": [
484
+ "## Bibliografia\n",
485
+ "\n",
486
+ "- **TinyStories: How Small Can Language Models Be and Still Speak Coherent English?** \n",
487
+ " [arXiv:2305.07759](https://arxiv.org/abs/2305.07759)\n",
488
+ "\n",
489
+ "- **GLU Variants Improve Transformer** \n",
490
+ " [arXiv:2002.05202](https://arxiv.org/abs/2002.05202)\n",
491
+ "\n",
492
+ "- **RoFormer: Enhanced Transformer with Rotary Position Embedding** \n",
493
+ " [arXiv:2104.09864](https://arxiv.org/abs/2104.09864)\n",
494
+ "\n",
495
+ "- **Language Models are Unsupervised Multitask Learners** \n",
496
+ " [OpenAI Technical Report](https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf)\n",
497
+ "\n",
498
+ "- **Language Models are Few-Shot Learners** \n",
499
+ " [arXiv:2005.14165](https://arxiv.org/abs/2005.14165)"
500
+ ]
501
+ }
502
+ ],
503
+ "metadata": {
504
+ "kernelspec": {
505
+ "display_name": ".venv",
506
+ "language": "python",
507
+ "name": "python3"
508
+ },
509
+ "language_info": {
510
+ "codemirror_mode": {
511
+ "name": "ipython",
512
+ "version": 3
513
+ },
514
+ "file_extension": ".py",
515
+ "mimetype": "text/x-python",
516
+ "name": "python",
517
+ "nbconvert_exporter": "python",
518
+ "pygments_lexer": "ipython3",
519
+ "version": "3.12.9"
520
+ }
521
+ },
522
+ "nbformat": 4,
523
+ "nbformat_minor": 5
524
+ }
historinhas-102M/historinhas-102M.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d3434b74068a50a7be276ffff8cddad3343b578586c690fa07b5d57a7fd609e7
3
+ size 410412348
historinhas-102M/tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
imgs/architecture.png ADDED

Git LFS Details

  • SHA256: dee44494446d841093c80ddedd21a054dc1448983cbb99ae6b5d0749db01abfe
  • Pointer size: 131 Bytes
  • Size of remote file: 200 kB
imgs/historinhas-logo.png ADDED

Git LFS Details

  • SHA256: c51193a6d20b3233831b6c960a5b95277e7d0a7e2883d92610f5d5ac97f5bf66
  • Pointer size: 131 Bytes
  • Size of remote file: 587 kB
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ torch
2
+ tokenizers
3
+ numpy