RuVI-AI
/

ArushCodes commited on
Commit
b8731f0
·
verified ·
1 Parent(s): bc89891

Upload tokenization_pragya.py

Browse files
Files changed (1) hide show
  1. tokenization_pragya.py +170 -0
tokenization_pragya.py ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+
4
+ import tiktoken
5
+ from transformers import PreTrainedTokenizer
6
+
7
+
8
+ def bytes_to_unicode():
9
+ """Reversible byte -> printable-char map (GPT-2 style). Every byte maps to
10
+ a unique character, so token strings never lose bytes."""
11
+ bs = (list(range(ord("!"), ord("~") + 1))
12
+ + list(range(ord("¡"), ord("¬") + 1))
13
+ + list(range(ord("®"), ord("ÿ") + 1)))
14
+ cs = bs[:]
15
+ n = 0
16
+ for b in range(256):
17
+ if b not in bs:
18
+ bs.append(b)
19
+ cs.append(256 + n)
20
+ n += 1
21
+ return {b: chr(c) for b, c in zip(bs, cs)}
22
+
23
+
24
+ _BYTE_ENCODER = bytes_to_unicode()
25
+ _BYTE_DECODER = {v: k for k, v in _BYTE_ENCODER.items()}
26
+
27
+
28
+ class PragyaTokenizer(PreTrainedTokenizer):
29
+ vocab_files_names = {"tokenizer_file": "pragya.tokenizer.json"}
30
+
31
+ def __init__(self, tokenizer_file=None, bos_token="<|bos|>",
32
+ eos_token="<|bos|>", pad_token="<|bos|>",
33
+ unk_token="<|bos|>", **kwargs):
34
+ if tokenizer_file is None:
35
+ raise ValueError(
36
+ "PragyaTokenizer needs tokenizer_file=<path to pragya.tokenizer.json>, "
37
+ "or load it with from_pretrained()."
38
+ )
39
+ with open(tokenizer_file, "r", encoding="utf-8") as f:
40
+ self._raw = json.load(f)
41
+
42
+ mergeable_ranks = {bytes.fromhex(k): int(v)
43
+ for k, v in self._raw["mergeable_ranks"].items()}
44
+ special_tokens = {k: int(v) for k, v in self._raw["special_tokens"].items()}
45
+ self._enc = tiktoken.Encoding(
46
+ name=self._raw["name"],
47
+ pat_str=self._raw["pat_str"],
48
+ mergeable_ranks=mergeable_ranks,
49
+ special_tokens=special_tokens,
50
+ )
51
+
52
+ # id <-> token string. Ordinary tokens use the reversible byte map;
53
+ # special tokens keep their literal string.
54
+ self._special_set = set(special_tokens)
55
+ self._id_to_tok = {}
56
+ for i in range(self._enc.n_vocab):
57
+ if i in set(special_tokens.values()):
58
+ continue
59
+ raw = self._enc.decode_single_token_bytes(i)
60
+ self._id_to_tok[i] = "".join(_BYTE_ENCODER[b] for b in raw)
61
+ for name, i in special_tokens.items():
62
+ self._id_to_tok[i] = name
63
+ self._tok_to_id = {t: i for i, t in self._id_to_tok.items()}
64
+
65
+ kwargs.setdefault("clean_up_tokenization_spaces", False)
66
+ kwargs.setdefault("padding_side", "left") # generation needs left padding
67
+ kwargs.setdefault("model_max_length", 1024) # CONTEXT in config__1_.py
68
+ super().__init__(bos_token=bos_token, eos_token=eos_token,
69
+ pad_token=pad_token, unk_token=unk_token, **kwargs)
70
+
71
+ @classmethod
72
+ def _from_pretrained(cls, resolved_vocab_files, pretrained_model_name_or_path,
73
+ *args, **kwargs):
74
+ # Transformers 5 can resolve our file to a default name (tokenizer.json)
75
+ # that we never ship. Work from any resolved file's cache directory,
76
+ # which also works when pretrained_model_name_or_path is a Hub repo id.
77
+ if resolved_vocab_files.get("tokenizer_file") is None:
78
+ for path in resolved_vocab_files.values():
79
+ if path:
80
+ candidate = os.path.join(os.path.dirname(path), "pragya.tokenizer.json")
81
+ if os.path.isfile(candidate):
82
+ resolved_vocab_files["tokenizer_file"] = candidate
83
+ break
84
+ else:
85
+ raise FileNotFoundError(
86
+ f"pragya.tokenizer.json not found for {pretrained_model_name_or_path}. "
87
+ "The repository must ship it alongside the other tokenizer files."
88
+ )
89
+ return super()._from_pretrained(resolved_vocab_files,
90
+ pretrained_model_name_or_path,
91
+ *args, **kwargs)
92
+
93
+ def _add_tokens(self, new_tokens, special_tokens=False):
94
+ # Transformers assigns ids past the end of the vocab to unknown tokens,
95
+ # which the model embedding cannot look up. Refuse them instead.
96
+ unknown = [t for t in new_tokens
97
+ if str(t) not in self._tok_to_id and str(t) not in self.added_tokens_encoder]
98
+ if unknown:
99
+ raise ValueError(
100
+ f"Cannot add tokens {unknown!r}: this tokenizer has a fixed vocab "
101
+ f"of {self._enc.n_vocab} tokens and the model embedding cannot grow "
102
+ f"without retraining."
103
+ )
104
+ return super()._add_tokens(new_tokens, special_tokens=special_tokens)
105
+
106
+ def tokenize(self, text, **kwargs):
107
+ # Bypass HF's special-token splitting: the training pipeline encoded
108
+ # "<|bos|>" in text as ordinary characters, so match that exactly.
109
+ return self._tokenize(text, **kwargs)
110
+
111
+ @property
112
+ def vocab_size(self):
113
+ return self._enc.n_vocab
114
+
115
+ def get_vocab(self):
116
+ return {**self._tok_to_id, **self.added_tokens_encoder}
117
+
118
+ def _tokenize(self, text, **kwargs):
119
+ return [self._id_to_tok[i] for i in self._enc.encode_ordinary(text)]
120
+
121
+ def _convert_token_to_id(self, token):
122
+ if token in self._tok_to_id:
123
+ return self._tok_to_id[token]
124
+ if token in self.added_tokens_encoder:
125
+ return self.added_tokens_encoder[token]
126
+ raise ValueError(
127
+ f"Unknown token {token!r}. This tokenizer ships with a fixed vocab "
128
+ f"of {self._enc.n_vocab} tokens; new special tokens cannot be added "
129
+ f"without retraining the model embedding."
130
+ )
131
+
132
+ def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None):
133
+ # Training wrapper prepends <|bos|> by default (add_bos=True).
134
+ ids = [self.bos_token_id] + list(token_ids_0)
135
+ if token_ids_1 is not None:
136
+ ids += list(token_ids_1)
137
+ return ids
138
+
139
+ def _convert_id_to_token(self, index):
140
+ index = int(index)
141
+ if index not in self._id_to_tok:
142
+ raise ValueError(
143
+ f"Token id {index} is outside the vocab of {self.vocab_size} tokens."
144
+ )
145
+ return self._id_to_tok[index]
146
+
147
+ def _decode(self, token_ids, skip_special_tokens=False, **kwargs):
148
+ valid = [int(i) for i in token_ids if 0 <= int(i) < self.vocab_size]
149
+ return super()._decode(valid, skip_special_tokens=skip_special_tokens, **kwargs)
150
+
151
+ def convert_tokens_to_string(self, tokens):
152
+ special = self._special_set | set(self.added_tokens_encoder)
153
+ out = bytearray()
154
+ parts = []
155
+ for t in tokens:
156
+ if t in special:
157
+ parts.append(out.decode("utf-8", errors="replace"))
158
+ out = bytearray()
159
+ parts.append(t)
160
+ else:
161
+ out.extend(_BYTE_DECODER[c] for c in t)
162
+ parts.append(out.decode("utf-8", errors="replace"))
163
+ return "".join(parts)
164
+
165
+ def save_vocabulary(self, save_directory, filename_prefix=None):
166
+ name = (filename_prefix + "-" if filename_prefix else "") + "pragya.tokenizer.json"
167
+ path = os.path.join(save_directory, name)
168
+ with open(path, "w", encoding="utf-8") as f:
169
+ json.dump(self._raw, f, indent=2, ensure_ascii=False)
170
+ return (path,)