English
samairtimer commited on
Commit
99033e7
·
verified ·
1 Parent(s): affabc6

Update MiniLLM.py

Browse files
Files changed (1) hide show
  1. MiniLLM.py +0 -182
MiniLLM.py CHANGED
@@ -6,63 +6,6 @@ import optax
6
  import tiktoken
7
  from pathlib import Path
8
 
9
- tokenizer = tiktoken.get_encoding("gpt2")
10
-
11
- vocab_size = tokenizer.n_vocab
12
- num_transformer_blocks = 6
13
- maxlen = 128
14
- embed_dim = 192
15
- num_heads = 6
16
- feed_forward_dim = int(2/3 * 4 * embed_dim)
17
- batch_size = 24
18
- num_epochs = 3
19
-
20
- def load_stories_from_file(
21
- file_path,
22
- max_stories = None
23
- ):
24
- """
25
- Efficiently load stories from a text file.
26
- Each story ends with <|endoftext|>.
27
- """
28
- file_path = Path(file_path)
29
- if not file_path.exists():
30
- raise FileNotFoundError(f"Data file not found: {file_path}")
31
-
32
- print(f"Loading stories from {file_path}...")
33
- stories = []
34
- current_story = []
35
-
36
- with open(file_path, 'r', encoding='utf-8', errors='replace') as f:
37
- for line in f:
38
- if '<|endoftext|>' in line:
39
- parts = line.split('<|endoftext|>')
40
- for part in parts[:-1]:
41
- current_story.append(part)
42
- story_text = ''.join(current_story).strip()
43
- if story_text:
44
- stories.append(story_text + '<|endoftext|>')
45
- if max_stories and len(stories) >= max_stories:
46
- break
47
- current_story = []
48
- if parts[-1].strip():
49
- current_story = [parts[-1]]
50
- else:
51
- current_story = []
52
- if max_stories and len(stories) >= max_stories:
53
- break
54
- else:
55
- current_story.append(line)
56
- if current_story and (not max_stories or len(stories) < max_stories):
57
- story_text = ''.join(current_story).strip()
58
- if story_text:
59
- stories.append(story_text + '<|endoftext|>')
60
-
61
- print(f"Loaded {len(stories):,} stories")
62
- return stories
63
-
64
-
65
-
66
  class TransformerBlock(nnx.Module):
67
 
68
  def __init__(self, embed_dim, num_heads, ff_dim, *, rngs):
@@ -152,128 +95,3 @@ class MiniGPT(nnx.Module):
152
 
153
  # 2. Decode the final list of token IDs back into a string
154
  return tokenizer.decode(tokens)
155
-
156
-
157
-
158
- def generate_story(model, story_prompt, temperature, max_new_tokens):
159
- start_tokens = tokenizer.encode(story_prompt)[:maxlen]
160
- generated = generate_text(model, start_tokens, max_new_tokens=max_new_tokens, temperature=temperature)
161
- return generated
162
-
163
-
164
- class StoryDataset:
165
- def __init__(self, stories, maxlen, tokenizer):
166
- self.stories = stories
167
- self.maxlen = maxlen
168
- self.tokenizer = tokenizer
169
- self.end_token = tokenizer.encode('<|endoftext|>', allowed_special={'<|endoftext|>'})[0]
170
-
171
- def __len__(self):
172
- return len(self.stories)
173
-
174
- def __getitem__(self, idx):
175
- story = self.stories[idx]
176
- tokens = self.tokenizer.encode(story, allowed_special={'<|endoftext|>'})
177
-
178
- if len(tokens) > self.maxlen:
179
- tokens = tokens[:self.maxlen]
180
-
181
- tokens.extend([0] * (self.maxlen - len(tokens)))
182
- return tokens
183
-
184
-
185
-
186
- def load_and_preprocess_data(
187
- file_path,
188
- batch_size,
189
- maxlen,
190
- max_stories = 100_000,
191
- num_epochs = 1,
192
- shuffle = False,
193
- seed = 42
194
- ):
195
- """
196
- Load and preprocess TinyStories data with memory-efficient chunk reading.
197
-
198
- Args:
199
- file_path: Path to the text file
200
- batch_size: Batch size for training
201
- maxlen: Maximum sequence length
202
- max_stories: Maximum number of stories to load (for memory efficiency)
203
- num_epochs: Number of training epochs
204
- shuffle: Whether to shuffle the data
205
- seed: Random seed for reproducibility
206
-
207
- Returns:
208
- Tuple of (Grain DataLoader, estimated_batches_per_epoch)
209
- """
210
-
211
- # Load and validate file
212
- file_path = file_path
213
-
214
- print(f"Loading data from {file_path} (max {max_stories:,} stories)")
215
-
216
- # Read file in chunks to avoid loading entire file into memory
217
- stories = []
218
- current_story = []
219
-
220
- with open(file_path, 'r', encoding='utf-8', errors='replace') as f:
221
- for line in f:
222
- if '<|endoftext|>' in line:
223
- # Split on end token and process parts
224
- parts = line.split('<|endoftext|>')
225
- for i, part in enumerate(parts[:-1]): # All but last part have end tokens
226
- current_story.append(part)
227
- story_text = ''.join(current_story).strip()
228
- if story_text:
229
- stories.append(story_text + '<|endoftext|>')
230
- if len(stories) >= max_stories:
231
- break
232
- current_story = []
233
-
234
- # Last part becomes start of next story
235
- if parts[-1].strip():
236
- current_story = [parts[-1]]
237
-
238
- if len(stories) >= max_stories:
239
- break
240
- else:
241
- current_story.append(line)
242
-
243
- # Don't forget the last story if file doesn't end with end token
244
- if current_story and len(stories) < max_stories:
245
- story_text = ''.join(current_story).strip()
246
- if story_text:
247
- stories.append(story_text + '<|endoftext|>')
248
-
249
- print(f"Loaded {len(stories):,} stories")
250
- if len(stories) == 0:
251
- raise ValueError("No valid stories found in the dataset")
252
-
253
- # Calculate estimated batches per epoch
254
- estimated_batches_per_epoch = len(stories) // batch_size
255
- print(f"Estimated batches per epoch: {estimated_batches_per_epoch:,}")
256
-
257
- # Create efficient dataset
258
- dataset = StoryDataset(stories, maxlen, tokenizer)
259
-
260
- # Configure sampler with sharding support
261
- sampler = pygrain.IndexSampler(
262
- num_records=len(dataset),
263
- shuffle=shuffle,
264
- seed=seed,
265
- shard_options=pygrain.NoSharding(),
266
- num_epochs=num_epochs,
267
- )
268
-
269
- # Create DataLoader with efficient batching
270
- dataloader = pygrain.DataLoader(
271
- data_source=dataset,
272
- sampler=sampler,
273
- operations=[
274
- pygrain.Batch(batch_size=batch_size, drop_remainder=True)
275
- ]
276
- )
277
-
278
- print(f"Created DataLoader with batch_size={batch_size}, maxlen={maxlen}")
279
- return dataloader, estimated_batches_per_epoch
 
6
  import tiktoken
7
  from pathlib import Path
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  class TransformerBlock(nnx.Module):
10
 
11
  def __init__(self, embed_dim, num_heads, ff_dim, *, rngs):
 
95
 
96
  # 2. Decode the final list of token IDs back into a string
97
  return tokenizer.decode(tokens)