Cion-lab commited on
Commit
55f23ef
·
verified ·
1 Parent(s): 6cf6f8d

publish_model.py: ship tokenizer_config.json + special_tokens_map.json (Gate 5 could not load a bare tokenizer.json)

Browse files
Files changed (1) hide show
  1. build/publish_model.py +32 -0
build/publish_model.py CHANGED
@@ -266,6 +266,38 @@ def main():
266
  # Gate 5 could never run (found by running it, 2026-09-21T13:40Z).
267
  shutil.copy(os.path.join(a.src, "tokenizer.json"), src) # ship the tokenizer that cut the mix
268
  have.add("tokenizer.json")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  cfg = json.load(open(os.path.join(src, "config.json")))
270
  run = {}
271
  if os.path.exists(os.path.join(src, "run_summary.json")):
 
266
  # Gate 5 could never run (found by running it, 2026-09-21T13:40Z).
267
  shutil.copy(os.path.join(a.src, "tokenizer.json"), src) # ship the tokenizer that cut the mix
268
  have.add("tokenizer.json")
269
+ # CARD_FILES already promised tokenizer_config.json and special_tokens_map.json, but nothing ever put
270
+ # them in the export, so the repo shipped a bare tokenizer.json. Without them AutoTokenizer falls back
271
+ # to a literal unknown-token name that this BPE vocab does not contain, so decoding raised
272
+ # "Unk token not found in the vocabulary" and Gate 5 could not load the tokenizer (2026-09-21T13:48Z).
273
+ # They are fetched from the tokenizer's own hub repo, so the published tokenizer is byte-complete.
274
+ TOK_SOURCE = "HuggingFaceTB/SmolLM2-135M"
275
+ tk = man.get("tokenizer") # manifest may hold a string or a mapping
276
+ if isinstance(tk, dict):
277
+ TOK_SOURCE = tk.get("hub") or tk.get("repo") or TOK_SOURCE
278
+ elif isinstance(tk, str) and "/" in tk:
279
+ TOK_SOURCE = tk
280
+ print("tokenizer source for config files:", TOK_SOURCE, flush=True)
281
+ for extra in ("tokenizer_config.json", "special_tokens_map.json"):
282
+ if extra in have:
283
+ continue
284
+ blob = urllib.request.urlopen(f"https://huggingface.co/{TOK_SOURCE}/resolve/main/{extra}",
285
+ timeout=120).read()
286
+ dec = json.loads(blob.decode("utf-8"))
287
+ u = dec.get("unk_token")
288
+ u = (u.get("content") if isinstance(u, dict) else u)
289
+ if u and u not in json.load(open(os.path.join(src, "tokenizer.json"), encoding="utf-8")
290
+ )["model"]["vocab"]:
291
+ dec["unk_token"] = None # never declare a token the vocab lacks
292
+ blob = json.dumps(dec, indent=2, ensure_ascii=False).encode("utf-8")
293
+ with open(os.path.join(src, extra), "wb") as fh:
294
+ fh.write(blob)
295
+ have.add(extra)
296
+ print("tokenizer config", extra, len(blob), "bytes sha256",
297
+ sha(os.path.join(src, extra))[:16], flush=True)
298
+ for required in ("tokenizer.json", "tokenizer_config.json", "special_tokens_map.json"):
299
+ if required not in have:
300
+ raise SystemExit(f"tokenizer is incomplete: {required} is missing from the export")
301
  cfg = json.load(open(os.path.join(src, "config.json")))
302
  run = {}
303
  if os.path.exists(os.path.join(src, "run_summary.json")):