alainbrown commited on
Commit
f167ee5
·
verified ·
1 Parent(s): b3873f1

Publish trained storyteller checkpoint

Browse files
config.json CHANGED
@@ -6,20 +6,20 @@
6
  "AutoConfig": "configuration_tiny_gpt.TinyGPTConfig",
7
  "AutoModelForCausalLM": "modeling_tiny_gpt.TinyGPTForCausalLM"
8
  },
9
- "context_size": 512,
10
- "d_model": 256,
11
- "dropout": 0.1,
12
  "dtype": "float32",
13
  "eos_token_id": 0,
14
- "hidden_size": 256,
15
- "max_position_embeddings": 512,
16
  "model_type": "tiny_gpt",
17
- "n_heads": 8,
18
- "n_layers": 6,
19
- "num_attention_heads": 8,
20
- "num_hidden_layers": 6,
21
  "pad_token_id": 0,
22
  "tie_word_embeddings": true,
23
  "transformers_version": "5.12.1",
24
- "vocab_size": 10000
25
  }
 
6
  "AutoConfig": "configuration_tiny_gpt.TinyGPTConfig",
7
  "AutoModelForCausalLM": "modeling_tiny_gpt.TinyGPTForCausalLM"
8
  },
9
+ "context_size": 1024,
10
+ "d_model": 384,
11
+ "dropout": 0.0,
12
  "dtype": "float32",
13
  "eos_token_id": 0,
14
+ "hidden_size": 384,
15
+ "max_position_embeddings": 1024,
16
  "model_type": "tiny_gpt",
17
+ "n_heads": 6,
18
+ "n_layers": 10,
19
+ "num_attention_heads": 6,
20
+ "num_hidden_layers": 10,
21
  "pad_token_id": 0,
22
  "tie_word_embeddings": true,
23
  "transformers_version": "5.12.1",
24
+ "vocab_size": 16000
25
  }
generation_config.json CHANGED
@@ -1,4 +1,6 @@
1
  {
2
  "_from_model_config": true,
 
 
3
  "transformers_version": "5.12.1"
4
  }
 
1
  {
2
  "_from_model_config": true,
3
+ "output_attentions": false,
4
+ "output_hidden_states": false,
5
  "transformers_version": "5.12.1"
6
  }
model.py CHANGED
@@ -1,24 +1,18 @@
1
- import math
2
  import torch
 
3
  from torch import nn
4
 
5
- """
6
- token embeddings
7
- learned positional embeddings
8
- causal self-attention
9
- feed-forward network
10
- custom LayerNorm
11
- residual connections
12
- stacked transformer blocks
13
- GELU
14
- dropout
15
- Pre-LayerNorm
16
- tied token embedding/output projection weights
17
- multi-head attention
18
-
19
- """
20
- class Model(nn.Module):
21
- def __init__(self, context_size, vocab_size, d_model, n_layers, n_heads, dropout=0.1):
22
  super().__init__()
23
 
24
  self.context_size = context_size
@@ -31,136 +25,166 @@ class Model(nn.Module):
31
  self.token_embedding = nn.Embedding(vocab_size, d_model)
32
  self.position_embedding = nn.Embedding(context_size, d_model)
33
  self.transformer_blocks = nn.ModuleList(
34
- [TransformerBlock(d_model, n_heads, dropout) for _ in range(n_layers)]
 
 
 
35
  )
36
  self.linear = nn.Linear(d_model, vocab_size, bias=False)
37
  self.dropout = nn.Dropout(dropout)
38
- self.final_layer_norm = LayerNorm(d_model)
39
 
40
  def forward(self, x):
41
- B, T = x.shape
42
-
43
- assert T <= self.context_size, "Input sequence is longer than context_size"
44
 
45
- positions = torch.arange(T, device=x.device)
 
 
46
 
 
47
  position = self.position_embedding(positions)
48
  token = self.token_embedding(x)
49
 
50
- x = token + position
51
- x = self.dropout(x)
52
-
53
  for block in self.transformer_blocks:
54
  x = block(x)
55
 
56
  x = self.final_layer_norm(x)
57
- logits = self.linear(x)
58
 
59
- return logits
60
 
61
  class FeedForward(nn.Module):
62
  def __init__(self, d_model):
63
  super().__init__()
64
  self.ff1 = nn.Linear(d_model, 4 * d_model)
65
- self.ff2 = nn.Linear(d_model * 4, d_model)
66
 
67
  def forward(self, x):
68
- x = self.ff1(x)
69
- x = nn.functional.gelu(x)
70
- x = self.ff2(x)
71
- return x
72
 
73
- class LayerNorm(nn.Module):
74
- def __init__(self, d_model):
 
75
  super().__init__()
76
- self.gamma = nn.Parameter(torch.ones(d_model))
77
- self.beta = nn.Parameter(torch.zeros(d_model))
 
 
 
 
 
 
 
 
78
 
79
  def forward(self, x):
80
- mean = x.mean(dim=-1, keepdim=True)
81
- diff = (x - mean)
82
- variance = (diff * diff).mean(dim=-1, keepdim=True)
83
- normalized = diff / torch.sqrt(variance + 1e-6)
84
- return self.gamma * normalized + self.beta
 
85
 
86
  class MultiHeadAttention(nn.Module):
87
  def __init__(self, d_model, n_heads, dropout=0.1):
88
  super().__init__()
89
 
90
- assert d_model % n_heads == 0, "d_model must be divisible by n_heads"
 
 
91
 
92
  self.n_heads = n_heads
93
  self.head_dim = d_model // n_heads
94
- self.scale = math.sqrt(self.head_dim)
95
-
96
- self.query = nn.Linear(d_model, d_model)
97
- self.key = nn.Linear(d_model, d_model)
98
- self.value = nn.Linear(d_model, d_model)
99
 
 
100
  self.head_proj = nn.Linear(d_model, d_model)
101
 
102
  def forward(self, x):
103
- query = self.split_heads(self.query(x))
104
- key = self.split_heads(self.key(x))
105
- value = self.split_heads(self.value(x))
106
-
107
- scores = torch.matmul(query, key.transpose(-2, -1))
108
- scores = scores / self.scale
109
-
110
- context_size = query.shape[2]
111
-
112
- mask = torch.tril(
113
- torch.ones(context_size, context_size, device=query.device)
114
  )
115
- mask = mask.view(1, 1, context_size, context_size)
116
-
117
- scores = scores.masked_fill(mask == 0, float("-inf"))
118
-
119
- weights = torch.nn.functional.softmax(scores, dim=-1)
120
-
121
- attended = torch.matmul(weights, value)
122
-
123
- attended = self.combine_heads(attended)
124
-
125
- attended = self.head_proj(attended)
126
-
127
- return attended
128
 
129
  def split_heads(self, x):
130
- batch_size, seq_len, d_model = x.shape
131
-
132
- x = x.reshape(batch_size, seq_len, self.n_heads, self.head_dim)
133
- x = x.transpose(1, 2)
134
-
135
- return x
 
 
136
 
137
  def combine_heads(self, x):
138
- batch_size, n_heads, seq_len, head_dim = x.shape
139
-
140
  x = x.transpose(1, 2)
141
- x = x.contiguous().view(batch_size, seq_len, n_heads * head_dim)
142
-
143
- return x
144
-
145
- class TransformerBlock(nn.Module):
146
- def __init__(self, d_model, n_heads, dropout=0.1):
147
- super().__init__()
148
-
149
- self.feed_forward = FeedForward(d_model)
150
- self.layer_norm1 = LayerNorm(d_model)
151
- self.layer_norm2 = LayerNorm(d_model)
152
- self.dropout = nn.Dropout(dropout)
153
- self.multi_head_attention = MultiHeadAttention(d_model, n_heads, dropout)
154
-
155
- def forward(self, x):
156
- attention = self.multi_head_attention(self.layer_norm1(x))
157
- attention = self.dropout(attention)
158
 
159
- x = x + attention
160
 
161
- feed_forward = self.feed_forward(self.layer_norm2(x))
162
- feed_forward = self.dropout(feed_forward)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
 
164
- x = x + feed_forward
165
 
166
- return x
 
 
 
 
 
 
 
 
 
1
  import torch
2
+ import torch.nn.functional as F
3
  from torch import nn
4
 
5
+
6
+ class GPTModel(nn.Module):
7
+ def __init__(
8
+ self,
9
+ context_size,
10
+ vocab_size,
11
+ d_model,
12
+ n_layers,
13
+ n_heads,
14
+ dropout=0.1,
15
+ ):
 
 
 
 
 
 
16
  super().__init__()
17
 
18
  self.context_size = context_size
 
25
  self.token_embedding = nn.Embedding(vocab_size, d_model)
26
  self.position_embedding = nn.Embedding(context_size, d_model)
27
  self.transformer_blocks = nn.ModuleList(
28
+ [
29
+ TransformerBlock(d_model, n_heads, dropout)
30
+ for _ in range(n_layers)
31
+ ]
32
  )
33
  self.linear = nn.Linear(d_model, vocab_size, bias=False)
34
  self.dropout = nn.Dropout(dropout)
35
+ self.final_layer_norm = nn.LayerNorm(d_model, eps=1e-6)
36
 
37
  def forward(self, x):
38
+ _, sequence_length = x.shape
 
 
39
 
40
+ assert sequence_length <= self.context_size, (
41
+ "Input sequence is longer than context_size"
42
+ )
43
 
44
+ positions = torch.arange(sequence_length, device=x.device)
45
  position = self.position_embedding(positions)
46
  token = self.token_embedding(x)
47
 
48
+ x = self.dropout(token + position)
 
 
49
  for block in self.transformer_blocks:
50
  x = block(x)
51
 
52
  x = self.final_layer_norm(x)
53
+ return self.linear(x)
54
 
 
55
 
56
  class FeedForward(nn.Module):
57
  def __init__(self, d_model):
58
  super().__init__()
59
  self.ff1 = nn.Linear(d_model, 4 * d_model)
60
+ self.ff2 = nn.Linear(4 * d_model, d_model)
61
 
62
  def forward(self, x):
63
+ return self.ff2(F.gelu(self.ff1(x)))
 
 
 
64
 
65
+
66
+ class TransformerBlock(nn.Module):
67
+ def __init__(self, d_model, n_heads, dropout=0.1):
68
  super().__init__()
69
+
70
+ self.feed_forward = FeedForward(d_model)
71
+ self.layer_norm1 = nn.LayerNorm(d_model, eps=1e-6)
72
+ self.layer_norm2 = nn.LayerNorm(d_model, eps=1e-6)
73
+ self.dropout = nn.Dropout(dropout)
74
+ self.multi_head_attention = MultiHeadAttention(
75
+ d_model=d_model,
76
+ n_heads=n_heads,
77
+ dropout=dropout,
78
+ )
79
 
80
  def forward(self, x):
81
+ attention = self.multi_head_attention(self.layer_norm1(x))
82
+ x = x + self.dropout(attention)
83
+
84
+ feed_forward = self.feed_forward(self.layer_norm2(x))
85
+ return x + self.dropout(feed_forward)
86
+
87
 
88
  class MultiHeadAttention(nn.Module):
89
  def __init__(self, d_model, n_heads, dropout=0.1):
90
  super().__init__()
91
 
92
+ assert d_model % n_heads == 0, (
93
+ "d_model must be divisible by n_heads"
94
+ )
95
 
96
  self.n_heads = n_heads
97
  self.head_dim = d_model // n_heads
98
+ self.dropout_p = dropout
 
 
 
 
99
 
100
+ self.qkv = nn.Linear(d_model, 3 * d_model)
101
  self.head_proj = nn.Linear(d_model, d_model)
102
 
103
  def forward(self, x):
104
+ query, key, value = self.qkv(x).chunk(3, dim=-1)
105
+ query = self.split_heads(query)
106
+ key = self.split_heads(key)
107
+ value = self.split_heads(value)
108
+
109
+ attended = F.scaled_dot_product_attention(
110
+ query,
111
+ key,
112
+ value,
113
+ dropout_p=self.dropout_p if self.training else 0.0,
114
+ is_causal=True,
115
  )
116
+ return self.head_proj(self.combine_heads(attended))
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
  def split_heads(self, x):
119
+ batch_size, sequence_length, _ = x.shape
120
+ x = x.reshape(
121
+ batch_size,
122
+ sequence_length,
123
+ self.n_heads,
124
+ self.head_dim,
125
+ )
126
+ return x.transpose(1, 2)
127
 
128
  def combine_heads(self, x):
129
+ batch_size, n_heads, sequence_length, head_dim = x.shape
 
130
  x = x.transpose(1, 2)
131
+ return x.contiguous().view(
132
+ batch_size,
133
+ sequence_length,
134
+ n_heads * head_dim,
135
+ )
 
 
 
 
 
 
 
 
 
 
 
 
136
 
 
137
 
138
+ Model = GPTModel
139
+
140
+
141
+ def convert_reference_state_dict(state_dict):
142
+ """Convert reference Q/K/V and LayerNorm keys to the optimized layout."""
143
+ converted = dict(state_dict)
144
+
145
+ for key in list(converted):
146
+ if key.endswith(".gamma"):
147
+ converted[key.removesuffix(".gamma") + ".weight"] = converted.pop(
148
+ key
149
+ )
150
+ elif key.endswith(".beta"):
151
+ converted[key.removesuffix(".beta") + ".bias"] = converted.pop(
152
+ key
153
+ )
154
+
155
+ attention_suffix = ".multi_head_attention.query.weight"
156
+ query_weight_keys = [
157
+ key for key in converted if key.endswith(attention_suffix)
158
+ ]
159
+ for query_weight_key in query_weight_keys:
160
+ prefix = query_weight_key.removesuffix("query.weight")
161
+ qkv_weight_key = prefix + "qkv.weight"
162
+ qkv_bias_key = prefix + "qkv.bias"
163
+
164
+ converted[qkv_weight_key] = torch.cat(
165
+ [
166
+ converted.pop(prefix + "query.weight"),
167
+ converted.pop(prefix + "key.weight"),
168
+ converted.pop(prefix + "value.weight"),
169
+ ],
170
+ dim=0,
171
+ )
172
+ converted[qkv_bias_key] = torch.cat(
173
+ [
174
+ converted.pop(prefix + "query.bias"),
175
+ converted.pop(prefix + "key.bias"),
176
+ converted.pop(prefix + "value.bias"),
177
+ ],
178
+ dim=0,
179
+ )
180
 
181
+ return converted
182
 
183
+ __all__ = [
184
+ "convert_reference_state_dict",
185
+ "FeedForward",
186
+ "GPTModel",
187
+ "Model",
188
+ "MultiHeadAttention",
189
+ "TransformerBlock",
190
+ ]
model.safetensors CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:9e9f8e95c7fa765cda29765de8ccd1c89d0f08545d42c72943b9c546665db657
3
- size 39973360
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fcd36c7f8d81cbb66a20f2b28a8b1afe03c99d3f57e110845755ee510aa35a07
3
+ size 97146024
modeling_tiny_gpt.py CHANGED
@@ -4,16 +4,17 @@ from transformers.generation import GenerationMixin
4
  from transformers.modeling_outputs import CausalLMOutput
5
 
6
  from .configuration_tiny_gpt import TinyGPTConfig
7
- from .model import Model
8
 
9
 
10
  class TinyGPTForCausalLM(PreTrainedModel, GenerationMixin):
11
  config_class = TinyGPTConfig
12
  main_input_name = "input_ids"
 
13
 
14
  def __init__(self, config):
15
  super().__init__(config)
16
- self.core_model = Model(
17
  context_size=config.context_size,
18
  vocab_size=config.vocab_size,
19
  d_model=config.d_model,
 
4
  from transformers.modeling_outputs import CausalLMOutput
5
 
6
  from .configuration_tiny_gpt import TinyGPTConfig
7
+ from .model import GPTModel
8
 
9
 
10
  class TinyGPTForCausalLM(PreTrainedModel, GenerationMixin):
11
  config_class = TinyGPTConfig
12
  main_input_name = "input_ids"
13
+ _tied_weights_keys = {"core_model.linear.weight": "core_model.token_embedding.weight"}
14
 
15
  def __init__(self, config):
16
  super().__init__(config)
17
+ self.core_model = GPTModel(
18
  context_size=config.context_size,
19
  vocab_size=config.vocab_size,
20
  d_model=config.d_model,
tokenizer.json CHANGED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "backend": "tokenizers",
3
  "eos_token": "<EOS>",
4
- "model_max_length": 512,
5
  "pad_token": "<EOS>",
6
  "tokenizer_class": "TokenizersBackend"
7
  }
 
1
  {
2
  "backend": "tokenizers",
3
  "eos_token": "<EOS>",
4
+ "model_max_length": 1024,
5
  "pad_token": "<EOS>",
6
  "tokenizer_class": "TokenizersBackend"
7
  }