【大模型】tokenizer 中编码过程

【大模型】tokenizer 中编码过程

参考文章:Qwen(千问) 系列大模型的 tokenizer 为什么是乱码?

大模型采用了这样一个映射表:

def bytes_to_unicode():
    """
    生成字节到Unicode字符的正向映射表
    返回字典:{byte_value: unicode_char}
    """
    # 原始保留的字节范围
    bs = (
        list(range(ord("!"), ord("~") + 1)) +          # ASCII可打印字符(33-126)
        list(range(ord("¡"), ord("¬") + 1)) +          # 西班牙语特殊字符(161-172)
        list(range(ord("®"), ord("ÿ") + 1))            # 其他扩展字符(174-255)
    )
    
    cs = bs.copy()  # 初始字符列表
    n = 0
    
    # 遍历所有可能的字节(0-255)
    for b in range(2**8):
        if b not in bs:
            bs.append(b)
            cs.append(2**8 + n)  # 超出原始范围的字节映射到更高Unicode码位
            n += 1
    
    # 将码位转换为Unicode字符
    cs = [chr(code) for code in cs]
    
    return dict(zip(bs, cs))
十进制
DEC
八进制
OCT
十六进制
HEX
二进制
BIN
映射字符
0 000 00 00000000 Ā
1 001 01 00000001 ā
2 002 02 00000010 Ă
3 003 03 00000011 ă
4 004 04 00000100 Ą
5 005 05 00000101 ą
6 006 06 00000110 Ć
7 007 07 00000111 ć
8 010 08 00001000 Ĉ
9 011 09 00001001 ĉ
10 012 0A 00001010 Ċ
11 013 0B 00001011 ċ
12 014 0C 00001100 Č
13 015 0D 00001101 č
14 016 0E 00001110 Ď
15 017 0F 00001111 ď
16 020 10 00010000 Đ
17 021 11 00010001 đ
18 022 12 00010010 Ē
19 023 13 00010011 ē
20 024 14 00010100 Ĕ
21 025 15 00010101 ĕ
22 026 16 00010110 Ė
23 027 17 00010111 Ė
24 030 18 00011000 ė
25 031 19 00011001 Ę
26 032 1A 00011010 ę
27 033 1B 00011011 ě
28 034 1C 00011100 Ĝ
29 035 1D 00011101 ĝ
30 036 1E 00011110 Ğ
31 037 1F 00011111 ğ
32 040 20 00100000 Ġ
33 041 21 00100001 !
34 042 22 00100010 \
35 043 23 00100011 #
36 044 24 00100100 $
37 045 25 00100101 %
38 046 26 00100110 &
39 047 27 00100111
40 050 28 00101000 (
41 051 29 00101001 )
42 052 2A 00101010 *
43 053 2B 00101011 +
44 054 2C 00101100 ,
45 055 2D 00101101 -
46 056 2E 00101110 .
47 057 2F 00101111 /
48 060 30 00110000 0
49 061 31 00110001 1
50 062 32 00110010 2
51 063 33 00110011 3
52 064 34 00110100 4
53 065 35 00110101 5
54 066 36 00110110 6
55 067 37 00110111 7
56 070 38 00111000 8
57 071 39 00111001 9
58 072 3A 00111010 :
59 073 3B 00111011 ;
60 074 3C 00111100 <
61 075 3D 00111101 =
62 076 3E 00111110 >
63 077 3F 00111111 ?
64 100 40 01000000 @
65 101 41 01000001 A
66 102 42 01000010 B
67 103 43 01000011 C
68 104 44 01000100 D
69 105 45 01000101 E
70 106 46 01000110 F
71 107 47 01000111 G
72 110 48 01001000 H
73 111 49 01001001 I
74 112 4A 01001010 J
75 113 4B 01001011 K
76 114 4C 01001100 L
77 115 4D 01001101 M
78 116 4E 01001110 N
79 117 4F 01001111 O
80 120 50 01010000 P
81 121 51 01010001 Q
82 122 52 01010010 R
83 123 53 01010011 S
84 124 54 01010100 T
85 125 55 01010101 U
86 126 56 01010110 V
87 127 57 01010111 W
88 130 58 01011000 X
89 131 59 01011001 Y
90 132 5A 01011010 Z
91 133 5B 01011011 [
92 134 5C 01011100 \ \(双斜线)
93 135 5D 01011101 ]
94 136 5E 01011110 ^
95 137 5F 01011111 _
96 140 60 01100000 `
97 141 61 01100001 a
98 142 62 01100010 b
99 143 63 01100011 c
100 144 64 01100100 d
101 145 65 01100101 e
102 146 66 01100110 f
103 147 67 01100111 g
104 150 68 01101000 h
105 151 69 01101001 i
106 152 6A 01101010 j
107 153 6B 01101011 k
108 154 6C 01101100 l
109 155 6D 01101101 m
110 156 6E 01101110 n
111 157 6F 01101111 o
112 160 70 01110000 p
113 161 71 01110001 q
114 162 72 01110010 r
115 163 73 01110011 s
116 164 74 01110100 t
117 165 75 01110101 u
118 166 76 01110110 v
119 167 77 01110111 w
120 170 78 01111000 x
121 171 79 01111001 y
122 172 7A 01111010 z
123 173 7B 01111011 {
124 174 7C 01111100 |
125 175 7D 01111101 }
126 176 7E 01111110 ~
127 177 7F 01111111 ġ
128 200 80 10000000 Ģ
129 201 81 10000001 ģ
130 202 82 10000010 Ĥ
131 203 83 10000011 ĥ
132 204 84 10000100 Ħ
133 205 85 10000101 ħ
134 206 86 10000110 Ĩ
135 207 87 10000111 ĩ
136 210 88 10001000 Ī
137 211 89 10001001 ī
138 212 8A 10001010 Ĭ
139 213 8B 10001011 ĭ
140 214 8C 10001100 Į
141 215 8D 10001101 į
142 216 8E 10001110 İ
143 217 8F 10001111 ı
144 220 90 10010000 IJ
145 221 91 10010001 ij
146 222 92 10010010 Ĵ
147 223 93 10010011 ĵ
148 224 94 10010100 Ķ
149 225 95 10010101 ķ
150 226 96 10010110 ĸ
151 227 97 10010111 Ĺ
152 230 98 10011000 ĺ
153 231 99 10011001 Ļ
154 232 9A 10011010 ļ
155 233 9B 10011011 Ľ
156 234 9C 10011100 ľ
157 235 9D 10011101 Ŀ
158 236 9E 10011110 ŀ
159 237 9F 10011111 Ł
160 240 A0 10100000 ł
161 241 A1 10100001 ¡
162 242 A2 10100010 ¢
163 243 A3 10100011 £
164 244 A4 10100100 ¤
165 245 A5 10100101 ¥
166 246 A6 10100110 ¦
167 247 A7 10100111 §
168 250 A8 10101000 ¨
169 251 A9 10101001 ©
170 252 AA 10101010 ª
171 253 AB 10101011 «
172 254 AC 10101100 ¬
173 255 AD 10101101 Ń
174 256 AE 10101110 ®
175 257 AF 10101111 ¯
176 260 B0 10110000 °
177 261 B1 10110001 ±
178 262 B2 10110010 ²
179 263 B3 10110011 ³
180 264 B4 10110100 ´
181 265 B5 10110101 µ
182 266 B6 10110110
183 267 B7 10110111 ·
184 270 B8 10111000 ¸
185 271 B9 10111001 ¹
186 272 BA 10111010 º
187 273 BB 10111011 »
188 274 BC 10111100 ¼
189 275 BD 10111101 ½
190 276 BE 10111110 ¾
191 277 BF 10111111 ¿
192 300 C0 11000000 À
193 301 C1 11000001 Á
194 302 C2 11000010 Â
195 303 C3 11000011 Ã
196 304 C4 11000100 Ä
197 305 C5 11000101 Å
198 306 C6 11000110 Æ
199 307 C7 11000111 Ç
200 310 C8 11001000 È
201 311 C9 11001001 É
202 312 CA 11001010 Ê
203 313 CB 11001011 Ë
204 314 CC 11001100 Ì
205 315 CD 11001101 Í
206 316 CE 11001110 Î
207 317 CF 11001111 Ï
208 320 D0 11010000 Ð
209 321 D1 11010001 Ñ
210 322 D2 11010010 Ò
211 323 D3 11010011 Ó
212 324 D4 11010100 Ô
213 325 D5 11010101 Õ
214 326 D6 11010110 Ö
215 327 D7 11010111 ×
216 330 D8 11011000 Ø
217 331 D9 11011001 Ù
218 332 DA 11011010 Ú
219 333 DB 11011011 Û
220 334 DC 11011100 Ü
221 335 DD 11011101 Ý
222 336 DE 11011110 Þ
223 337 DF 11011111 ß
224 340 E0 11100000 à
225 341 E1 11100001 á
226 342 E2 11100010 â
227 343 E3 11100011 ã
228 344 E4 11100100 ä
229 345 E5 11100101 å
230 346 E6 11100110 æ
231 347 E7 11100111 ç
232 350 E8 11101000 è
233 351 E9 11101001 é
234 352 EA 11101010 ê
235 353 EB 11101011 ë
236 354 EC 11101100 ì
237 355 ED 11101101 í
238 356 EE 11101110 î
239 357 EF 11101111 ï
240 360 F0 11110000 ð
241 361 F1 11110001 ñ
242 362 F2 11110010 ò
243 363 F3 11110011 ó
244 364 F4 11110100 ô
245 365 F5 11110101 õ
246 366 F6 11110110 ö
247 367 F7 11110111 ÷
248 370 F8 11111000 ø
249 371 F9 11111001 ù
250 372 FA 11111010 ú
251 373 FB 11111011 û
252 374 FC 11111100 ü
253 375 FD 11111101 ý
254 376 FE 11111110 þ
255 377 FF 11111111 ÿ
此对照表应该没错,如果有什么问题可以按照上述代码生成一个映射表查看一下。
输入的任意字符串 -> UTF-8编码的 Unicode码
# 原始文本 -> UTF-8 编码字节
text = "你好世界"
bytes_data = text.encode('utf-8')
print(bytes_data)

此时输出对应的UTF-8 字节为b'\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c'
\xe4->ä\xbd->½\xa0->ł\xe5->å\xa5-> ¥\xbd->½\xe4->ä\xb8->¸\x96->ĸ\xe7->ç\x95->ķ\x8c->Į;组合即可得到:ä½łå¥½ä¸ĸçķĮ

我们可以用代码验证这个逻辑:

def bytes_to_unicode_str(byte_sequence):
    # 将字节二进制 转为 unicode编码
    return ''.join([forward_map[b] for b in byte_sequence])

# 正向映射表 字节 映射到 unicode 字符串
# 反向映射表  unicode 字符串 映射到 字节
forward_map = bytes_to_unicode()
reversed_map = get_reverse_map(forward_map)


# 步骤1:原始文本 -> UTF-8字节
text = "你好世界"
bytes_data = text.encode('utf-8')
print(bytes_data)

# 步骤2:字节 -> Unicode字符串
unicode_str = bytes_to_unicode_str(bytes_data)
print(unicode_str)

同样会输出ä½łå¥½ä¸ĸçķĮ

Qwen/Qwen2.5-7B-Instruct为例:

# 加载 Qwen tokenizer 
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")

tokenizer.tokenize("你好世界")

输出为['ä½łå¥½', 'ä¸ĸçķĮ'];Qwen在 token化的过程中,将你好世界转为['ä½łå¥½', 'ä¸ĸçķĮ'];然后在vocab.json中寻找'ä½łå¥½''ä¸ĸçķĮ'对应的映射数字。