cs336-01-bpe编码

cs336-01-bpe编码
gogongxtunicode编码
在python可以使用ord函数查询某个字符的unicode编码,可以chr函数反查
特殊的,chr(0) 就是空字符(NUL)
- print打印这个字符是看不到的
- repr可以更精细,看到的是’’
1
2
3
4
5
6
ord('牛') #29275
chr(29275) #'牛'
chr(0) #'\x00'
print(chr(0)) #
"this is a test" + chr(0) + "string" #'this is a test\x00string'
print("this is a test" + chr(0) + "string")#this is a teststringQ:为什么用UTF-8编码进行tokenizer而不是UTF-16/UTF-32
UTF-32:每个Unicode字符固定4 字节,不管是 a、中、🙂,全部 4
字节,例如 'a' -> 00 00 00 61
'中' -> 00 00 4E 2D
UTF-16:常见字符2 字节,少数(emoji / 古文字)4 字节,相比UTF-32好一些,但是还是有点大
UTF-8:字符ASCII 1字节;中文 3 字节;Emoji 4 字节;并且完全向后兼容
ASCII,例如 'a' -> 61 '中' -> E4 B8 AD
'🙂' -> F0 9F 99 82
Q:下面的代码有什么问题,怎么修正
1
2
3
4
5
6
7
def decode_utf8_bytes_to_str_wrong(bytestring: bytes):
return "".join(
[bytes([b]).decode("utf-8") for b in bytestring]
)
>>> print(decode_utf8_bytes_to_str_wrong("hello".encode("utf-8")))
'hello'问题在于UTF-8 是变长编码,而上面的代码在按字节强行拆开解码
比如print(decode_utf8_bytes_to_str_wrong("中文".encode("utf-8")))就会有问题'utf-8' codec can't decode byte 0xe4 in position 0: unexpected end of data
Q:有没有两字节的序列,不是合法的unicode编码
以UTF-8来说,byte 序列空间 ≫ Unicode
字符空间,有效的两字节序列只有一类:110xxxxx 10xxxxxx,对应到
- 第 1 字节:
0xC2 – 0xDF - 第 2 字节:
0x80 – 0xBF
留下大量非法序列可以快速进行错误检测
bpe(byte-pair encoding, Gage, 1994)
简单来讲就是每一次迭代合并两个词,选择频率最高的那组进行组合,下一次依旧是选择频率最高的那组组合
如果合并过程中碰到两个合并频率相同,比如”ab”和”fe”,我们按照lexicographically greater pair优先(选择字符串排序大的那个),选择”fe”
举一个简单的例子:
1
2
3
low low low low low
lower lower widest widest widest
newest newest newest newest newest newest首先按照空格分词:
- low 5
- lower 2
- widest 3
- newest 6
第一轮:依次组合两个字符组合,按照频率,最高的是(e,s)和(s,t),都是9次,按照排序选择(s,t)
第二轮:依次组合两个字符组合,按照频率,最高的是(e,st)是9次
以此类推,假设再跑四轮,组合依次是:(o,w) (l,ow) (w,est) (n,e)
经过六轮过后,我们有了(st) (est) (ow) (low) (west) (ne)
把他们应用到原来的词上,得到:
- low: low
- lower: low e r
- widest: w i d est
- newest: ne west




