neuroflow-cpp / scripts /vocab_adapter.py
cwenzi's picture
Upload folder using huggingface_hub
26d5b81 verified
Raw
History Blame Contribute Delete
4.93 kB
import json
import os
import argparse
import logging
logger = logging.getLogger(__name__)
SPECIAL_TOKENS = {"<pad>": 0, "<s>": 1, "</s>": 2, "<unk>": 3}
def build_chinese_chars(start_id=4, count=3755):
vocab = {}
idx = start_id
for code in range(0x4E00, 0x4E00 + count):
if idx >= start_id + count:
break
char = chr(code)
vocab[char] = idx
idx += 1
return vocab
def build_english_subwords(start_id, count=500):
vocab = {}
idx = start_id
prefixes = ["un", "re", "pre", "dis", "mis", "over", "under", "out", "sub", "inter", "anti", "non", "semi", "multi", "bi", "co", "ex", "in", "im", "il", "ir"]
suffixes = ["ing", "ed", "er", "est", "ly", "tion", "sion", "ment", "ness", "ity", "ous", "ive", "able", "ible", "ful", "less", "al", "ial", "ic", "ical"]
roots = ["the", "be", "to", "of", "and", "a", "in", "that", "have", "it", "for", "not", "on", "with", "he", "as", "you", "do", "at", "this", "but", "his", "by", "from", "they", "we", "say", "her", "she", "or", "an", "will", "my", "one", "all", "would", "there", "their", "what", "so", "up", "out", "if", "about", "who", "get", "which", "go", "me", "when", "make", "can", "like", "time", "no", "just", "him", "know", "take", "people", "into", "year", "your", "good", "some", "could", "them", "see", "other", "than", "then", "now", "look", "only", "come", "its", "over", "think", "also", "back", "after", "use", "two", "how", "our", "work", "first", "well", "way", "even", "new", "want", "because", "any", "these", "give", "day", "most", "us"]
for r in roots:
if idx >= start_id + count:
break
vocab[r] = idx
idx += 1
for p in prefixes:
for r in roots[:50]:
if idx >= start_id + count:
break
token = p + r
if token not in vocab:
vocab[token] = idx
idx += 1
for s in suffixes:
for r in roots[:50]:
if idx >= start_id + count:
break
token = r + s
if token not in vocab:
vocab[token] = idx
idx += 1
return vocab
def build_punctuation(start_id):
vocab = {}
idx = start_id
puncts = list("。,、;:!?…—""''()【】《》·~、.,!?;:\"'()[]{}<>-_/\\|@#$%^&*+=~`")
for p in puncts:
vocab[p] = idx
idx += 1
return vocab
def build_digits(start_id):
vocab = {}
idx = start_id
for d in "0123456789":
vocab[d] = idx
idx += 1
for combo in ["10", "00", "01", "20", "30", "50", "100", "200", "500", "1000"]:
vocab[combo] = idx
idx += 1
return vocab
def build_merges(vocab, max_merges=2000):
merges = []
tokens = sorted(vocab.keys(), key=lambda t: len(t), reverse=True)
for i, t1 in enumerate(tokens):
if len(merges) >= max_merges:
break
for t2 in tokens[i:i+10]:
if len(merges) >= max_merges:
break
combined = t1 + t2
if combined in vocab:
merges.append(f"{t1} {t2}")
return merges
def generate_tokenizer_json(vocab_size=5000):
vocab = dict(SPECIAL_TOKENS)
next_id = len(vocab)
cn = build_chinese_chars(next_id, 3755)
vocab.update(cn)
next_id = max(vocab.values()) + 1
en = build_english_subwords(next_id, 500)
vocab.update(en)
next_id = max(vocab.values()) + 1
punct = build_punctuation(next_id)
vocab.update(punct)
next_id = max(vocab.values()) + 1
digits = build_digits(next_id)
vocab.update(digits)
while len(vocab) > vocab_size:
max_id = max(vocab.values())
for k, v in list(vocab.items()):
if v == max_id:
del vocab[k]
break
merges = build_merges(vocab)
return {
"model_type": "bpe",
"vocab_size": vocab_size,
"special_tokens": SPECIAL_TOKENS,
"vocab": vocab,
"merges": merges,
}
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description="NeuroFlow BPE词表适配器")
parser.add_argument("--vocab-size", type=int, default=5000, help="词表大小")
parser.add_argument("--output", type=str, default="configs/tokenizer_cn_013.json", help="输出路径")
args = parser.parse_args()
tokenizer = generate_tokenizer_json(args.vocab_size)
os.makedirs(os.path.dirname(args.output) or ".", exist_ok=True)
with open(args.output, "w", encoding="utf-8") as f:
json.dump(tokenizer, f, indent=2, ensure_ascii=False)
logger.info(f"词表已保存到 {args.output}, vocab_size={len(tokenizer['vocab'])}, merges={len(tokenizer['merges'])}")