OpenSoftware-World commited on
Commit
1eaec28
·
verified ·
1 Parent(s): b65dc0a

We have switched from the Regex tokenizer to the SentencePiece tokenizer. (The updated code was written by OpenSoftware-World and corrected by ChatGPT.)

Browse files

SentencePiece is much more effective than the Regex tokenizer and is also used in large language models. At OpenSoftware-World, we have switched to the SentencePiece tokenizer for our OpenSoftware-World-OSW1 AI model so that it can produce high-quality and accurate results, just like other large language models.

Files changed (1) hide show
  1. model_init.py +51 -30
model_init.py CHANGED
@@ -7,6 +7,7 @@ import math
7
  import torch
8
  import torch.nn as nn
9
  import torch.nn.functional as F
 
10
 
11
  NUM_THREADS = os.cpu_count() or 4
12
  torch.set_num_threads(NUM_THREADS)
@@ -17,40 +18,62 @@ except RuntimeError:
17
 
18
  DEVICE = torch.device("cpu")
19
  print(f"🧵 Number of CPU threads : {NUM_THREADS}")
20
- TOKEN_RE = re.compile(r"\w+|[^\w\s]", re.UNICODE)
21
-
22
- def tokenize(text: str):
23
- return TOKEN_RE.findall(text.lower())
24
 
25
  class Vocab:
26
- PAD, UNK, BOS, EOS = "<pad>", "<unk>", "<bos>", "<eos>"
 
 
 
 
 
 
 
27
 
28
- def __init__(self):
29
- self.stoi = {}
30
- self.itos = []
 
31
 
32
  def encode(self, text, add_bos=False, add_eos=False):
33
- ids = [self.stoi.get(t, self.stoi[Vocab.UNK]) for t in tokenize(text)]
 
34
  if add_bos:
35
- ids = [self.stoi[Vocab.BOS]] + ids
 
36
  if add_eos:
37
- ids = ids + [self.stoi[Vocab.EOS]]
 
38
  return ids
39
 
40
  def decode(self, ids):
41
- toks = [self.itos[i] for i in ids if 0 <= i < len(self.itos)]
42
- toks = [t for t in toks if t != Vocab.PAD and t != Vocab.BOS]
43
- out = []
44
- for t in toks:
45
- if t == Vocab.EOS:
46
- break
47
- out.append(t)
48
- text = " ".join(out)
49
- text = re.sub(r"\s+([.,!?;:])", r"\1", text)
50
- return text
51
 
52
  def __len__(self):
53
- return len(self.itos)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
  class CausalSelfAttention(nn.Module):
56
  def __init__(self, d_model, n_head, dropout):
@@ -155,10 +178,8 @@ def load_checkpoint(path: str):
155
  ckpt = torch.load(path, map_location="cpu")
156
 
157
  cfg = ckpt["config"]
158
- vocab = Vocab()
159
- vocab.stoi = ckpt["vocab_stoi"]
160
- vocab.itos = ckpt["vocab_itos"]
161
- pad_id = ckpt["pad_id"]
162
 
163
  model = OSW1Model(len(vocab), cfg, pad_id=pad_id).to(DEVICE)
164
  model.load_state_dict(ckpt["model_state_dict"])
@@ -187,7 +208,7 @@ def load_checkpoint(path: str):
187
 
188
  def chat_loop(model: OSW1Model, vocab: Vocab):
189
  print("=" * 64)
190
- print("💬 OSW1 ready! You can start chatting. Type 'exit' to quit.")
191
  print("=" * 64)
192
 
193
  eos_id = vocab.stoi[Vocab.EOS]
@@ -211,7 +232,7 @@ def chat_loop(model: OSW1Model, vocab: Vocab):
211
  out = model.generate(x, max_new_tokens=60, temperature=0.85, top_k=40, eos_id=eos_id)
212
  answer_ids = out[0, len(ids):].tolist()
213
  answer = vocab.decode(answer_ids)
214
- print(f"OSW1: {answer if answer else '(...silence...)'}")
215
 
216
  def main():
217
  if len(sys.argv) > 1:
@@ -224,8 +245,8 @@ def main():
224
  if ckpt_path is None:
225
  print(
226
  "❌ No checkpoint files found in the directory.\n"
227
- " Please train a model using 'python train_osw1.py' or\n"
228
- " specify a checkpoint file using 'python model_init.py <file_path>'."
229
  )
230
  sys.exit(1)
231
 
 
7
  import torch
8
  import torch.nn as nn
9
  import torch.nn.functional as F
10
+ import sentencepiece as spm
11
 
12
  NUM_THREADS = os.cpu_count() or 4
13
  torch.set_num_threads(NUM_THREADS)
 
18
 
19
  DEVICE = torch.device("cpu")
20
  print(f"🧵 Number of CPU threads : {NUM_THREADS}")
 
 
 
 
21
 
22
  class Vocab:
23
+ PAD = "<pad>"
24
+ UNK = "<unk>"
25
+ BOS = "<bos>"
26
+ EOS = "<eos>"
27
+
28
+ def __init__(self, model_path="opensoftware_world_osw1_tokenizer.model"):
29
+ self.sp = spm.SentencePieceProcessor()
30
+ self.sp.load(model_path)
31
 
32
+ self.pad_id = self.sp.pad_id()
33
+ self.unk_id = self.sp.unk_id()
34
+ self.bos_id = self.sp.bos_id()
35
+ self.eos_id = self.sp.eos_id()
36
 
37
  def encode(self, text, add_bos=False, add_eos=False):
38
+ ids = self.sp.encode(text, out_type=int)
39
+
40
  if add_bos:
41
+ ids = [self.bos_id] + ids
42
+
43
  if add_eos:
44
+ ids = ids + [self.eos_id]
45
+
46
  return ids
47
 
48
  def decode(self, ids):
49
+ ids = [
50
+ i for i in ids
51
+ if i not in (self.pad_id, self.bos_id)
52
+ ]
53
+
54
+ if self.eos_id in ids:
55
+ ids = ids[:ids.index(self.eos_id)]
56
+
57
+ return self.sp.decode(ids)
 
58
 
59
  def __len__(self):
60
+ return self.sp.get_piece_size()
61
+
62
+ @property
63
+ def stoi(self):
64
+ return {
65
+ self.PAD: self.pad_id,
66
+ self.UNK: self.unk_id,
67
+ self.BOS: self.bos_id,
68
+ self.EOS: self.eos_id,
69
+ }
70
+
71
+ @property
72
+ def itos(self):
73
+ return [
74
+ self.sp.id_to_piece(i)
75
+ for i in range(self.sp.get_piece_size())
76
+ ]
77
 
78
  class CausalSelfAttention(nn.Module):
79
  def __init__(self, d_model, n_head, dropout):
 
178
  ckpt = torch.load(path, map_location="cpu")
179
 
180
  cfg = ckpt["config"]
181
+ vocab = Vocab("opensoftware_world_osw1_tokenizer.model")
182
+ pad_id = vocab.sp.pad_id()
 
 
183
 
184
  model = OSW1Model(len(vocab), cfg, pad_id=pad_id).to(DEVICE)
185
  model.load_state_dict(ckpt["model_state_dict"])
 
208
 
209
  def chat_loop(model: OSW1Model, vocab: Vocab):
210
  print("=" * 64)
211
+ print("💬 OpenSoftware-World-OSW1 ready! You can start chatting. Type 'exit' to quit.")
212
  print("=" * 64)
213
 
214
  eos_id = vocab.stoi[Vocab.EOS]
 
232
  out = model.generate(x, max_new_tokens=60, temperature=0.85, top_k=40, eos_id=eos_id)
233
  answer_ids = out[0, len(ids):].tolist()
234
  answer = vocab.decode(answer_ids)
235
+ print(f"OpenSoftware-World-OSW1: {answer if answer else '(...silence...)'}")
236
 
237
  def main():
238
  if len(sys.argv) > 1:
 
245
  if ckpt_path is None:
246
  print(
247
  "❌ No checkpoint files found in the directory.\n"
248
+ " Please train a model using 'python3 model_training.py' or\n"
249
+ " specify a checkpoint file using 'python3 model_init.py <file_path>'."
250
  )
251
  sys.exit(1)
252