Murali Chandran commited on
Commit
4356e85
·
1 Parent(s): 64c820b

Harden vocab loader: accept tuple/dict/list and rebuild missing sides; EOS-tolerant decode

Browse files
Files changed (1) hide show
  1. bot_inference.py +65 -47
bot_inference.py CHANGED
@@ -162,72 +162,90 @@ def _load_ckpt():
162
 
163
  _checkpoint = _load_ckpt()
164
 
165
- # ---- Build tokenizer (ultra-robust) ----
166
  def _build_vocab(checkpoint):
167
  v = checkpoint.get("vocab", None)
168
  stoi = None
169
  itos = None
170
 
171
- # 1) tuple or list of length 2: (stoi, itos)
172
- if isinstance(v, (tuple, list)) and len(v) == 2:
173
- s_raw, i_raw = v
174
- # normalize stoi
175
- if isinstance(s_raw, dict) and s_raw:
176
- stoi = s_raw
177
- elif s_raw is None and isinstance(i_raw, (dict, list)) and i_raw:
178
- pass # we'll build stoi from itos below
179
- # normalize itos
180
- if isinstance(i_raw, dict) and i_raw:
181
- itos = i_raw
182
- elif isinstance(i_raw, list) and i_raw:
183
- itos = {i: ch for i, ch in enumerate(i_raw)}
184
- elif i_raw is None and isinstance(s_raw, dict) and s_raw:
185
- pass # we'll build itos from stoi below
186
-
187
- # 2) dict form inside 'vocab'
188
- elif isinstance(v, dict) and v:
189
- if "stoi" in v: stoi = v["stoi"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  if "itos" in v:
191
- itos_raw = v["itos"]
192
- if isinstance(itos_raw, dict) and itos_raw:
193
- itos = itos_raw
194
- elif isinstance(itos_raw, list) and itos_raw:
195
- itos = {i: ch for i, ch in enumerate(itos_raw)}
196
- # pure itos or pure stoi in v
197
  if itos is None and all(isinstance(k, int) for k in v.keys()):
198
- itos = v # id->char dict
 
199
  if stoi is None and all(isinstance(k, str) for k in v.keys()):
200
- stoi = v # char->id dict
201
-
202
- # 3) legacy separate keys at top-level
 
 
 
 
 
203
  else:
204
- if "stoi" in checkpoint: stoi = checkpoint["stoi"]
 
205
  if "itos" in checkpoint:
206
- i_raw = checkpoint["itos"]
207
- if isinstance(i_raw, dict) and i_raw:
208
- itos = i_raw
209
- elif isinstance(i_raw, list) and i_raw:
210
- itos = {i: ch for i, ch in enumerate(i_raw)}
211
-
212
- # 4) Rebuild the missing side if possible
213
- if itos is None and isinstance(stoi, dict) and stoi:
214
- itos = {i: ch for ch, i in stoi.items()}
215
- if stoi is None and isinstance(itos, dict) and itos:
216
  stoi = {ch: i for i, ch in itos.items()}
217
 
218
- # 5) Final sanity
219
- if not isinstance(stoi, dict) or not stoi or not isinstance(itos, dict) or not itos:
220
  raise KeyError(
221
- "Checkpoint vocab not usable. Expected 'vocab'=(stoi, itos), "
222
- "'vocab'={'stoi','itos'}, pure stoi/itos, or legacy keys. "
223
- f"Found keys: {list(checkpoint.keys())}; type(vocab)={type(v)}"
224
  )
225
  return stoi, itos
226
 
227
  stoi, itos = _build_vocab(_checkpoint)
228
 
229
  EOS = "<EOS>"
230
- EOS_ID = stoi.get(EOS, None) # ok if None
231
 
232
 
233
  block_size = _checkpoint.get("block_size", None)
 
162
 
163
  _checkpoint = _load_ckpt()
164
 
165
+ # ---- Build tokenizer (ultra-robust, reconstruct missing sides) ----
166
  def _build_vocab(checkpoint):
167
  v = checkpoint.get("vocab", None)
168
  stoi = None
169
  itos = None
170
 
171
+ def dictify_itos(x):
172
+ # accept dict[int->str] or list[str]
173
+ if isinstance(x, dict) and x and all(isinstance(k, int) for k in x.keys()):
174
+ return x
175
+ if isinstance(x, list) and x:
176
+ return {i: ch for i, ch in enumerate(x)}
177
+ return None
178
+
179
+ def dictify_stoi(x):
180
+ # accept dict[str->int]
181
+ if isinstance(x, dict) and x and all(isinstance(k, str) for k in x.keys()):
182
+ return x
183
+ return None
184
+
185
+ # Case A: vocab is a tuple/list (any length >= 2)
186
+ if isinstance(v, (tuple, list)) and len(v) >= 2:
187
+ s_raw, i_raw = v[0], v[1]
188
+ s_norm = dictify_stoi(s_raw)
189
+ i_norm = dictify_itos(i_raw)
190
+
191
+ # If itos is None but stoi exists, build itos from stoi
192
+ if i_norm is None and isinstance(s_raw, dict) and s_raw:
193
+ itos = {i: ch for ch, i in s_raw.items()}
194
+ else:
195
+ itos = i_norm
196
+
197
+ # If stoi is None but itos exists, build stoi from itos
198
+ if s_norm is None and isinstance(itos, dict) and itos:
199
+ stoi = {ch: i for i, ch in itos.items()}
200
+ else:
201
+ stoi = s_norm
202
+
203
+ # Case B: vocab is a dict (may contain keys 'stoi' and/or 'itos', or be pure stoi/itos)
204
+ elif isinstance(v, dict) and v is not None:
205
+ if "stoi" in v:
206
+ stoi = dictify_stoi(v["stoi"])
207
  if "itos" in v:
208
+ itos = dictify_itos(v["itos"])
209
+ # pure itos (id->char dict)
 
 
 
 
210
  if itos is None and all(isinstance(k, int) for k in v.keys()):
211
+ itos = v
212
+ # pure stoi (char->id dict)
213
  if stoi is None and all(isinstance(k, str) for k in v.keys()):
214
+ stoi = v
215
+ # reconstruct missing side
216
+ if itos is None and isinstance(stoi, dict) and stoi:
217
+ itos = {i: ch for ch, i in stoi.items()}
218
+ if stoi is None and isinstance(itos, dict) and itos:
219
+ stoi = {ch: i for i, ch in itos.items()}
220
+
221
+ # Case C: legacy top-level keys
222
  else:
223
+ if "stoi" in checkpoint:
224
+ stoi = dictify_stoi(checkpoint["stoi"])
225
  if "itos" in checkpoint:
226
+ itos = dictify_itos(checkpoint["itos"])
227
+ if itos is None and isinstance(stoi, dict) and stoi:
228
+ itos = {i: ch for ch, i in stoi.items()}
229
+ if stoi is None and isinstance(itos, dict) and itos:
230
+ stoi = {ch: i for i, ch in itos.items()}
231
+
232
+ # Final fallback: if vocab is a flat list/tuple of characters
233
+ if (not stoi or not itos) and isinstance(v, (list, tuple)) and v and all(isinstance(x, str) for x in v):
234
+ itos = {i: ch for i, ch in enumerate(v)}
 
235
  stoi = {ch: i for i, ch in itos.items()}
236
 
237
+ if not (isinstance(stoi, dict) and stoi and isinstance(itos, dict) and itos):
 
238
  raise KeyError(
239
+ "Checkpoint vocab not usable. Expected 'vocab'=(stoi, itos) or dict with 'stoi'/'itos', "
240
+ "or pure stoi/itos; can reconstruct if one side present. "
241
+ f"Found keys: {list(checkpoint.keys())}; type(vocab)={type(v)}; value sample={repr(v)[:200]}"
242
  )
243
  return stoi, itos
244
 
245
  stoi, itos = _build_vocab(_checkpoint)
246
 
247
  EOS = "<EOS>"
248
+ EOS_ID = stoi.get(EOS, None) # if missing, we'll just decode to max_new_tokens
249
 
250
 
251
  block_size = _checkpoint.get("block_size", None)