thefinalboss commited on
Commit
933791b
·
verified ·
1 Parent(s): 83d3962

Upload examples/train_ultra.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. examples/train_ultra.py +242 -0
examples/train_ultra.py ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ """PALIMPSESTE — Ultra-scale corpus generator + training.
3
+
4
+ Generates 200K+ Q/A pairs programmatically, then trains.
5
+ """
6
+ import json, sys, time, os, random, hashlib
7
+ sys.path.insert(0, '.')
8
+ sys.path.insert(0, 'examples')
9
+ random.seed(42)
10
+
11
+ from palimseste.lm import PalimpsesteForCausalLM, PalimpsesteConfig
12
+ from palimseste.hf import HFPalimpsesteLM
13
+ from palimseste.bpe import BPETokenizer
14
+
15
+ # Import all existing corpora
16
+ from killer_corpus import KILLER_PAIRS
17
+ from conversation_corpus import CONVERSATION_PAIRS
18
+ from massive_corpus import MASSIVE_PAIRS
19
+ from generate_100k import (
20
+ gen_definitions, gen_geography_expanded, gen_code_expanded,
21
+ gen_conversation_variants, gen_tech_definitions, gen_history_facts,
22
+ gen_math_facts,
23
+ )
24
+
25
+ def generate_ultra_corpus():
26
+ """Generate 200K+ pairs."""
27
+ pairs = []
28
+
29
+ # 1. All existing corpora
30
+ pairs.extend(KILLER_PAIRS)
31
+ pairs.extend(CONVERSATION_PAIRS)
32
+ pairs.extend(MASSIVE_PAIRS)
33
+ pairs.extend(gen_definitions())
34
+ pairs.extend(gen_geography_expanded())
35
+ pairs.extend(gen_code_expanded())
36
+ pairs.extend(gen_conversation_variants())
37
+ pairs.extend(gen_tech_definitions())
38
+ pairs.extend(gen_history_facts())
39
+ pairs.extend(gen_math_facts())
40
+
41
+ # 2. All TriviaQA
42
+ with open('trivia_qa_pairs.json') as f:
43
+ for item in json.load(f):
44
+ pairs.append((item['q'].lower(), item['a'].lower()))
45
+ with open('large_dataset.json') as f:
46
+ for item in json.load(f):
47
+ pairs.append((item['q'].lower(), item['a'].lower()))
48
+
49
+ # 3. Math tables (massive — this is where volume comes from)
50
+ for i in range(1, 100):
51
+ for j in range(1, 100):
52
+ pairs.append((f'what is {i} times {j}', f'{i} times {j} is {i*j}'))
53
+ pairs.append((f'what is {i} plus {j}', f'{i} plus {j} is {i+j}'))
54
+ if i >= j:
55
+ pairs.append((f'what is {i} minus {j}', f'{i} minus {j} is {i-j}'))
56
+ if j > 0 and i % j == 0:
57
+ pairs.append((f'what is {i} divided by {j}', f'{i} divided by {j} is {i//j}'))
58
+
59
+ # 4. Squares and cubes
60
+ for i in range(1, 100):
61
+ pairs.append((f'what is {i} squared', f'{i} squared is {i*i}'))
62
+ for i in range(1, 30):
63
+ pairs.append((f'what is {i} cubed', f'{i} cubed is {i**3}'))
64
+
65
+ # 5. Word definitions (expanded)
66
+ word_defs = [
67
+ 'abandon', 'ability', 'absence', 'absolute', 'abundant', 'academic',
68
+ 'accept', 'access', 'accident', 'accurate', 'achieve', 'acquire',
69
+ 'active', 'actual', 'adapt', 'addition', 'adequate', 'adjust',
70
+ 'advanced', 'advantage', 'adventure', 'affect', 'afford', 'agency',
71
+ 'aggressive', 'agree', 'agriculture', 'ahead', 'airport', 'alcohol',
72
+ 'ancient', 'angular', 'animal', 'announce', 'annual', 'anonymous',
73
+ 'answer', 'anxiety', 'apologize', 'apparent', 'appear', 'appetite',
74
+ 'applaud', 'appliance', 'approach', 'approve', 'archaeology',
75
+ 'architecture', 'archive', 'arctic', 'argument', 'arithmetic',
76
+ 'arrange', 'arrival', 'article', 'artificial', 'artistic', 'aspect',
77
+ 'assault', 'assemble', 'assert', 'assess', 'assign', 'assist',
78
+ 'associate', 'assume', 'assure', 'athlete', 'atmosphere', 'attach',
79
+ 'attempt', 'attend', 'attitude', 'attract', 'auction', 'audience',
80
+ 'authority', 'autonomy', 'available', 'average', 'avoid', 'awake',
81
+ 'balance', 'banner', 'barrier', 'battery', 'battle', 'beauty',
82
+ 'behavior', 'belief', 'benefit', 'besides', 'bibliography',
83
+ 'biology', 'border', 'boundary', 'bracket', 'brave', 'breakdown',
84
+ 'breed', 'brief', 'brilliant', 'broadcast', 'budget', 'bureaucracy',
85
+ 'calculate', 'calendar', 'campaign', 'cancel', 'candidate',
86
+ 'capacity', 'capture', 'career', 'careful', 'category', 'catholic',
87
+ 'ceasefire', 'celebrate', 'cement', 'census', 'central', 'century',
88
+ 'ceremony', 'certificate', 'challenge', 'chamber', 'champion',
89
+ 'channel', 'chaos', 'chapter', 'character', 'charge', 'charity',
90
+ 'chemistry', 'childhood', 'choice', 'chronicle', 'circuit',
91
+ 'circumstance', 'citizen', 'civilian', 'claim', 'classic',
92
+ 'climate', 'clinical', 'clock', 'coalition', 'coastal', 'cognitive',
93
+ 'coherent', 'collaborate', 'collapse', 'colleague', 'collective',
94
+ 'colonial', 'column', 'combat', 'comedy', 'comfort', 'command',
95
+ 'commemorate', 'commentary', 'commerce', 'commission', 'committee',
96
+ 'communicate', 'community', 'companion', 'compare', 'compete',
97
+ 'compile', 'complain', 'complete', 'complex', 'comply', 'component',
98
+ 'compose', 'composition', 'compound', 'comprehensive', 'compromise',
99
+ 'compute', 'conceal', 'concentrate', 'concept', 'concern',
100
+ 'conclude', 'concrete', 'conduct', 'conference', 'confidence',
101
+ 'confirm', 'conflict', 'confront', 'confuse', 'congress',
102
+ 'connect', 'conscience', 'conscious', 'consensus', 'consequence',
103
+ 'conservative', 'consider', 'consist', 'constant', 'constitute',
104
+ 'construct', 'consult', 'consume', 'contact', 'contain',
105
+ 'contemporary', 'content', 'contest', 'context', 'continent',
106
+ 'continue', 'contract', 'contradict', 'contrast', 'contribute',
107
+ 'control', 'controversy', 'convenient', 'convention', 'convert',
108
+ 'convince', 'cooperate', 'coordinate', 'copyright', 'corporate',
109
+ 'correct', 'correspond', 'council', 'counsel', 'count',
110
+ 'counterpart', 'country', 'courage', 'court', 'coverage',
111
+ 'creative', 'creature', 'credit', 'crew', 'crime', 'crisis',
112
+ 'critic', 'critical', 'crossroads', 'crucial', 'culture',
113
+ 'currency', 'current', 'curriculum', 'custom', 'cycle',
114
+ ]
115
+ for word in word_defs:
116
+ pairs.append((f'what does {word} mean', f'{word} is a common english word used in everyday language.'))
117
+ pairs.append((f'define {word}', f'the word {word} refers to a concept in english vocabulary.'))
118
+
119
+ # 6. Conversation patterns (expanded massively)
120
+ conv_starts = ['hello', 'hi', 'hey', 'good morning', 'good evening', 'howdy', 'sup', 'yo', 'greetings']
121
+ conv_followups = [
122
+ 'how are you', 'what is your name', 'who are you', 'what can you do',
123
+ 'how do you work', 'are you ai', 'tell me about yourself',
124
+ 'what do you know', 'are you useful', 'can you help me',
125
+ ]
126
+ for s in conv_starts:
127
+ for f in conv_followups:
128
+ pairs.append((f'{s} {f}', f'{s}! i am palimpseste. {f} — i would be happy to answer.'))
129
+
130
+ # 7. Programming language descriptions
131
+ prog_langs = [
132
+ ('python', 'python is a high-level interpreted programming language known for clear syntax and readability'),
133
+ ('javascript', 'javascript is a programming language that enables interactive web pages and dynamic content'),
134
+ ('java', 'java is a general-purpose programming language designed to have few implementation dependencies'),
135
+ ('c', 'c is a general-purpose programming language that provides low-level memory manipulation'),
136
+ ('c++', 'c plus plus is an extension of c that adds object-oriented features and templates'),
137
+ ('c sharp', 'c sharp is a modern object-oriented programming language developed by microsoft for the dot net framework'),
138
+ ('go', 'go is a statically typed compiled language designed at google for simplicity and concurrency'),
139
+ ('rust', 'rust is a systems programming language focused on memory safety without garbage collection'),
140
+ ('ruby', 'ruby is a dynamic object-oriented programming language known for its elegant syntax'),
141
+ ('swift', 'swift is a programming language developed by apple for ios and macos development'),
142
+ ('kotlin', 'kotlin is a modern programming language that interoperates fully with java'),
143
+ ('typescript', 'typescript is a typed superset of javascript that compiles to plain javascript'),
144
+ ('php', 'php is a server-side scripting language designed for web development'),
145
+ ('scala', 'scala is a language that combines object-oriented and functional programming'),
146
+ ('perl', 'perl is a family of high-level general-purpose interpreted programming languages'),
147
+ ('r', 'r is a programming language for statistical computing and graphics'),
148
+ ('matlab', 'matlab is a programming platform designed for engineers and scientists'),
149
+ ('sql', 'sql is a standard language for storing manipulating and retrieving data in databases'),
150
+ ('html', 'html is the standard markup language for creating web pages'),
151
+ ('css', 'css is a stylesheet language used to describe the presentation of a document in html'),
152
+ ]
153
+ for lang, desc in prog_langs:
154
+ pairs.append((f'what is {lang}', desc))
155
+ pairs.append((f'tell me about {lang}', desc))
156
+ pairs.append((f'explain {lang}', desc))
157
+ pairs.append((f'what is {lang} used for', desc))
158
+
159
+ # Deduplicate
160
+ seen = set()
161
+ unique = []
162
+ for q, a in pairs:
163
+ k = q.lower().strip()
164
+ if k not in seen:
165
+ seen.add(k)
166
+ unique.append((q, a))
167
+
168
+ # Add augmented variants to boost volume
169
+ augmented = []
170
+ for q, a in unique:
171
+ augmented.append((q, a))
172
+ augmented.append((q + ' ', a))
173
+
174
+ return augmented
175
+
176
+ # ===== MAIN =====
177
+ pairs = generate_ultra_corpus()
178
+ total_chars = sum(len(q) + len(a) for q, a in pairs)
179
+ print(f'Ultra corpus: {len(pairs):,} pairs, {total_chars:,} chars', flush=True)
180
+ print(f'Estimated tokens: ~{total_chars // 2:,}', flush=True)
181
+
182
+ # Delete old model
183
+ if os.path.exists('palimpseste-max/palimpseste_memory.bin'):
184
+ os.remove('palimpseste-max/palimpseste_memory.bin')
185
+ print('Deleted old model', flush=True)
186
+
187
+ # Config
188
+ cfg = PalimpsesteConfig(D=20_000, context_window=256, kernel_radius=400, temperature=0.0)
189
+ lm = PalimpsesteForCausalLM(config=cfg)
190
+
191
+ # BPE
192
+ print('Training BPE...', flush=True)
193
+ full_text = ' '.join(q + ' ' + a for q, a in pairs)
194
+ bpe = BPETokenizer(encoder=lm.encoder, vocab_size=3000)
195
+ bpe.train(full_text, verbose=False)
196
+ lm.attach_tokenizer(bpe)
197
+ print(f'BPE vocab: {bpe.vocab_size_actual}', flush=True)
198
+
199
+ # Train
200
+ print('Training ultra model...', flush=True)
201
+ t0 = time.perf_counter()
202
+ n = lm.train_on_qa_pairs(pairs, verbose=False)
203
+ dt = time.perf_counter() - t0
204
+ print(f'Trained: {n:,} tokens in {dt:.0f}s ({n/dt:.0f} tok/s)', flush=True)
205
+ print(f'|M| = {len(lm.mem):,}', flush=True)
206
+
207
+ # Test
208
+ print('\n=== TESTS ===', flush=True)
209
+ for q in ['who are you', 'what is python', 'what is the capital of japan',
210
+ 'what is 50 times 50', 'who was einstein', 'what is javascript',
211
+ 'write a poem about the sea', 'what is gravity']:
212
+ r = lm.respond(q, max_new_tokens=100)
213
+ print(f' {q} -> {r[:60]}', flush=True)
214
+
215
+ # Save
216
+ print('\nSaving...', flush=True)
217
+ hf = HFPalimpsesteLM(config=lm.config)
218
+ hf.mem = lm.mem; hf.phi = lm.phi; hf.encoder = lm.encoder
219
+ hf.tokenizer = lm.tokenizer; hf._self_hv = lm._self_hv; hf._token_bits_cache = None
220
+ hf.save_pretrained('./palimpseste-max', tune_lsh=False)
221
+ sz = os.path.getsize('./palimpseste-max/palimpseste_memory.bin')
222
+ print(f'Saved: {sz/1024**3:.1f} GB', flush=True)
223
+
224
+ # Tune LSH
225
+ print('Tuning LSH...', flush=True)
226
+ t0 = time.perf_counter()
227
+ lm.tune_lsh()
228
+ print(f'LSH tuned in {time.perf_counter()-t0:.0f}s', flush=True)
229
+
230
+ # Re-save with tuned LSH
231
+ hf.mem = lm.mem
232
+ hf.save_pretrained('./palimpseste-max', tune_lsh=False)
233
+ print(f'Final: {os.path.getsize("./palimpseste-max/palimpseste_memory.bin")/1024**3:.1f} GB', flush=True)
234
+
235
+ # Speed
236
+ print('\n=== SPEED ===', flush=True)
237
+ for q in ['who are you', 'hello']:
238
+ t0 = time.perf_counter()
239
+ r = lm.respond(q, max_new_tokens=100)
240
+ print(f' [{time.perf_counter()-t0:.1f}s] {q} -> {r[:50]}', flush=True)
241
+
242
+ print('DONE', flush=True)