Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于 tokenizer.json 词汇表中没有中文的问题 #111

Open
NightStar4Zou opened this issue Jan 9, 2025 · 2 comments
Open

关于 tokenizer.json 词汇表中没有中文的问题 #111

NightStar4Zou opened this issue Jan 9, 2025 · 2 comments

Comments

@NightStar4Zou
Copy link

您好,非常感谢作者做了这样精彩的模型,让我学习和理解大模型有了更好的切入点。我在玩这个模型的时候遇到不太理解的地方。train_tokenizer.py 训练出来的 vocab.json中的词汇我没有找到汉语的,但是 tokenizer_train.jsonl 这个里面其实是汉语,不知道为什么训练完了之后会这样

@jingyaogong
Copy link
Owner

jingyaogong commented Jan 9, 2025

ok感谢认可哈

vocab.json 一般都是不可读的,因为词表都用的是 Unicode 编码,分词单元类似 è¿Ļæĺ¯ä¸Ģ个 这样看起来乱码的形式。
(其他大模型分词都是这样的)例如可以看一下Qwen2.5-7B的vocab:https://huggingface.co/Qwen/Qwen2.5-7B-Instruct/blob/main/vocab.json

你可以测试以下脚本:

from transformers import AutoTokenizer

# 加载分词器
tokenizer = AutoTokenizer.from_pretrained("./model/minimind_tokenizer")

# 测试文本
text = "这是一个测试,看看分词器是否能正确处理中文。"

# 编码:将文本转换为 token IDs
encoded_ids = tokenizer.encode(text)
print("编码结果 (Token IDs):", encoded_ids)

# 解码:将 token IDs 转换回文本
decoded_text = tokenizer.decode(encoded_ids)
print("解码结果 (文本):", decoded_text)

decoded_text = tokenizer.decode([434])
print("解码结果 (文本):", decoded_text)

decoded_text = tokenizer.decode([1589])
print("解码结果 (文本):", decoded_text)

# 如果需要查看具体的 tokens(子词单元)
tokens = tokenizer.tokenize(text)
print("分词结果 (Tokens):", tokens)

结果是:

编码结果 (Token IDs): [434, 1589, 3560, 270, 1380, 1380, 554, 1582, 1179, 2010, 424, 2826, 1958, 413, 677, 286]
解码结果 (文本): 这是一个测试,看看分词器是否能正确处理中文。
解码结果 (文本): 这
解码结果 (文本): 是一个
分词结果 (Tokens): ['è¿Ļ', 'æĺ¯ä¸Ģ个', 'æµĭè¯ķ', 'ï¼Į', 'çľĭ', 'çľĭ', 'åĪĨ', 'è¯į', 'åĻ¨', 'æĺ¯åIJ¦', 'èĥ½', 'æŃ£ç¡®', 'å¤ĦçIJĨ', 'ä¸Ń', 'æĸĩ', 'ãĢĤ']

意味着

'è¿Ļ' -> '这'
'æĺ¯ä¸Ģ个' -> '是一个'

它们实际上都是有意义的中文token


进一步的用以下脚本,可以测试vocab-token数量占比:

from transformers import AutoTokenizer
import re

tokenizer = AutoTokenizer.from_pretrained("./model/minimind_tokenizer")

vocab = tokenizer.get_vocab()

total_tokens = len(vocab)
chinese_tokens = 0
english_tokens = 0
non_chinese_or_english_tokens = 0

def is_chinese(text):
    return all('\u4e00' <= char <= '\u9fff' for char in text)

def is_english(text):
    return all(re.match(r"[a-zA-Z]", char) for char in text)

for token_id in range(total_tokens):
    token = tokenizer.decode([token_id])
    if is_chinese(token):
        chinese_tokens += 1
    elif is_english(token):
        english_tokens += 1
    else:
        non_chinese_or_english_tokens += 1

chinese_ratio = chinese_tokens / total_tokens * 100
english_ratio = english_tokens / total_tokens * 100
other_ratio = non_chinese_or_english_tokens / total_tokens * 100
print(f"词表总大小: {total_tokens}")
print(f"中文 token 数量: {chinese_tokens} 占比: {chinese_ratio:.2f}%")
print(f"英文 token 数量: {english_tokens} 占比: {english_ratio:.2f}%")
print(f"其他 token 数量: {non_chinese_or_english_tokens} 占比: {other_ratio:.2f}%")

结果是:

词表总大小: 6400
中文 token 数量: 2448 占比: 38.25%
英文 token 数量: 1152 占比: 18.00%
其他 token 数量: 2800 占比: 43.75%

作为比较,Qwen2.5的结果是:

词表总大小: 151665
中文 token 数量: 24875 占比: 16.40%
英文 token 数量: 27376 占比: 18.05%
其他 token 数量: 99414 占比: 65.55%

@NightStar4Zou
Copy link
Author

谢谢作者的解惑~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants