【大模型开发】将vocab解码

【大模型开发】将vocab解码

在这篇博客中【大模型】tokenizer 中编码过程,说明了tokenizer分词编码过程。

在这里,我在简单叙述一下,vocab.json文件中存储的是一个字典,key是token分词标记,value是这个token对应的代码点。

举个例子:词汇你好;在Qwen 的词汇表中使用一个token表示的,按理来说,我们可以直接在vocab.json文件中直接表示为"你好": 108386;但似乎目前的大模型都不是这样设计的。而是按照以下的方法对应的:

你好使用utf-8编码,得到b'\xe4\xbd\xa0\xe5\xa5\xbd;然后根据【大模型】tokenizer 中编码过程中提到的映射集合,进行映射:\xe4->ä\xbd->½\xa0->ł\xe5->å\xa5-> ¥\xbd->½ ;然后组合得到ä½łå¥½;因此,你好这一词汇,在vocab.json中是这样表示的:ä½łå¥½:108386

(目前,我还没确切地搞懂为什么要这样进行表示和编码...,我觉得可能是因为解析时间和压缩的优势?)

因此,要解析vocab.json文件中的内容,进行逆向解码即可。

先获得Qwen2.5的词汇表vocab;这是一个字典,key是token,所以我们对每一个key进行解码;使用一个关系映射表进行解码即可。

python 复制代码
import json  
from transformers import AutoTokenizer  
    
def bytes_to_unicode():  
    """  
    Returns list of utf-8 byte and a mapping to unicode strings. We specifically avoids mapping to whitespace/control    characters the bpe code barfs on.  
    The reversible bpe codes work on unicode strings. This means you need a large # of unicode characters in your vocab    if you want to avoid UNKs. When you're at something like a 10B token dataset you end up needing around 5K for    decent coverage. This is a significant percentage of your normal, say, 32K bpe vocab. To avoid that, we want lookup    tables between utf-8 bytes and unicode strings.    """    bs = (  
        list(range(ord("!"), ord("~") + 1)) + list(range(ord("¡"), ord("¬") + 1)) + list(range(ord("®"), ord("ÿ") + 1))  
    )  
    cs = bs[:]  
    n = 0  
    for b in range(2**8):  
        if b not in bs:  
            bs.append(b)  
            cs.append(2**8 + n)  
            n += 1  
    cs = [chr(n) for n in cs]  
    return dict(zip(bs, cs))  
  
def get_reverse_map(forward_map):  
    """  
    根据正向映射生成反向映射  
    返回字典:{unicode_char: byte_value}  
    """    return {v: k for k, v in forward_map.items()}  
  
def bytes_to_unicode_str(byte_sequence):  
    return ''.join([forward_map[b] for b in byte_sequence])  
  
def unicode_str_to_bytes(unicode_str):  
    return bytes([reverse_map[c] for c in unicode_str])  
  
  
# 生成映射表  
forward_map = bytes_to_unicode()  
reverse_map = get_reverse_map(forward_map)  
  
if __name__ == '__main__':  
	# 加载 Qwen tokenizer    
	tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")  
    # 加载词汇  
    vocab = tokenizer.vocab  
    decoded_data = dict()  
    # 进行逆向映射
    for k, v in vocab.items():  
        recovered_k = unicode_str_to_bytes(k)  
        try:  
            recovered_text = recovered_k.decode('utf-8')  
            decoded_data[str(recovered_text)] = v  
        except  UnicodeDecodeError:  
            decoded_data[str(recovered_k)] = v  
    with open(r"./Qwen/vocab_decoded.json", "w", encoding='utf-8') as f:  
        f.write(json.dumps(decoded_data, ensure_ascii=False))

以下是解码后的一些输出,Qwen2.5中的词汇表是一个多语言的词汇表;有一些词汇感觉有一点不能理解,例如)))\n\n\n;不排除我可能对某些token没有进行很好的解码。

python 复制代码
"führer": 142884, "皤": 121912, " freaking": 73240, " mono": 39674, " whom": 8711, "',...\n": 56268, " Wildcats": 96850, "你好": 108386, "_ot": 65614, "のではない": 127841, " disclosure": 27857, "῟": 149627, " pesquisa": 94630, "-wh": 55332, "===": 8707, "cade": 32796, "UIS": 28521, "引领": 104353, "_Tr": 21038, "_stub": 62781, ")))\n\n\n": 83809, " bytecode": 75129, "จำ": 124355, "NEWS": 68578, "_ent": 27425, ".exports": 7435, "狗狗": 109032, "鬣": 122119, " Alumni": 75426, "'>{": 63220, "ё": 44022, "朦胧": 116728, "GridColumn": 64144, "b'\\xb7\\xb8'": 32926, "逆转": 112229, " Abd": 29638, " Ünivers": 133696, " 너무": 133267, " Injection": 53811, "Nat": 65214, "manda": 35545,
相关推荐
漠北尘-Gavin15 分钟前
【Python3.12.9安装llama-cpp-python遇到编译报错问题解决】
python·llama
测试老哥44 分钟前
什么是集成测试?集成的方法有哪些?
自动化测试·软件测试·python·测试工具·职场和发展·单元测试·集成测试
豆芽8191 小时前
Conda配置Python环境
python·conda·pip
CANI_PLUS1 小时前
python 列表-元组-集合-字典
开发语言·python
东方佑1 小时前
使用 Python 自动处理 Excel 数据缺失值的完整指南
开发语言·python·excel
weixin_478689761 小时前
pytorch与其他ai工具
人工智能·pytorch·python
枫林血舞1 小时前
python笔记之函数
笔记·python
计算机徐师兄2 小时前
Python Django基于人脸识别的票务管理系统(附源码,文档说明)
python·django·人脸识别·票务系统·票务管理系统·票务管理·人脸识别票务系统
mosquito_lover12 小时前
Python调用手机摄像头检测火焰烟雾的三种方法
python·视觉检测