:文字怎么变成数字)
上篇七从3秒记忆到过目不忘——语言模型的三代进化把语言模型这三代进化捋了一遍结尾停在 Transformer 用 Self-Attention 把记不住这个问题给解决了。不过有个更基础的问题我还一直没碰。计算机里全是 0 和 1这没啥可说的可汉字、英文这些符号到底怎么送进 Transformer 让它算这篇就来理一理。先说一个绕不开的矛盾。语言的本质是符号。你看猫、cat、猫咪三个写法指的都是同一种东西一条四只脚、会喵喵叫的小动物。它们本身没有任何数值纯粹是咱们人类商量好了、拿来当记号用的一套东西。可 Transformer 是个纯数值的系统。它只会做加减乘除喂它一个猫字它根本接不住。要让一个只懂数字的机器去理解一堆充满符号的语言这是第一步就得解决的事。第一次尝试给每个词发个编号最直白的想法是给每个词发个编号。假设词表特别小就五个词猫、狗、喜欢、吃、鱼。那就给每个词配一个五维向量它自己那个位置填 1别的位置全填 0。猫 [1, 0, 0, 0, 0] 狗 [0, 1, 0, 0, 0] 喜欢 [0, 0, 1, 0, 0] 吃 [0, 0, 0, 1, 0] 鱼 [0, 0, 0, 0, 1]这样每个词都成了数字能交给计算机了。这种编法有个专门的名叫 One-Hot 编码。它的定义一句话就说完一个词用一个向量表示整个向量里只有一位是 1其余全是 0。至于哪个位置是 1取决于这个词在词表里排第几个。听着挺像回事但真要用起来毛病一下就冒出来了还不止一个。第一个毛病维度太高上面才五个词就得用五维。那换成 ChatGPT 呢GPT-3 的词表大概有五万个 token每个 token 就得用一个五万维的向量来表示里面四万九千九百九十九个位都是 0就一个 1。只为了表达一个词就得存下五万个数字里面还几乎全是废的。又高维又稀疏算起来存起来开销直接爆炸。第二个毛病语义没了这个更要命。先说一下相似度是啥它就是量两个词挨得近不近的一个数越大越像。算法也不复杂两个向量挨着位置相乘把结果全加起来这一步叫点积再除以它俩各自长度得到的值在 -1 到 1 之间。拿 One-Hot 里猫和狗算一遍猫 [1, 0, 0, 0, 0] 狗 [0, 1, 0, 0, 0] 挨着位置乘起来再相加 1×0 0×1 0×0 0×0 0×0 0 它俩长度都是 1所以 相似度 0 ÷ 1 0结果是零一丁点相似性都没有。可现实里猫和狗都是动物都爱当宠物老在各种养猫养狗的讨论里一起冒头明明亲得很。再算猫跟鱼还是 0——猫爱吃鱼这话谁都听过俩词关系近得很可在这套编码里照样是零。再换猫跟吃也还是 0。这套编码里谁跟谁都一样远。这就跟图书馆按入库顺序给书编号一个道理。每本书都有个独一无二的号你拿着号确实能精准取到书可光看号码你完全不知道这本是小说还是菜谱、跟另一本是不是同一个作者写的。号码能定位但给不了你任何关于书本身的信息。说白了One-Hot 把词变成了数字可把词的意义给弄丢了。而语言模型偏偏是最缺不得意义的。它得知道猫和鱼沾边才能猜对猫喜欢吃后面大概率该接鱼而不是电脑。换个思路Embedding那怎么办2013 年Google 有个研究员叫 Mikolov搞出一个叫 Word2Vec 的东西后来慢慢演化成咱们现在说的 Embedding。Embedding字面是嵌入你就想成把一个号码牌塞进一大块密密麻麻写满字的软木板上塞进去的位置还是精心挑的。它跟 One-Hot 比起来就换了三件事位数不用那么多了五万维砍到一万两千多维数字不再是清一色的 1 和 0而是一堆有正有负的小数每个位都塞了点信息词跟词之间有了远近关系不再是各占一个坑、谁也不挨着谁一句话别再把词当成一个个孤零零的编号改成把它放在一张能比出远近的地图上。什么叫带着语义GPT-3 没用那五万维的 One-Hot而是给每个词一个 12288 维的向量。这一万多个数可不是只有一个 1 别处全 0它每个位置都有讲究猫 [0.2, -0.5, 0.7, 0.1, -0.3, ..., 0.4] ← 12288这一万两千多个数合起来在描述猫这个形象它是动物生物属性、有四条腿长啥样、老跟鱼一起出现共现关系、会喜欢会抓会睡觉平常干啥。就这一串数把猫的意义整个裹进去了。这不就跟拿一张体检表描述人一个道理吗光看编号认不出人可换成一堆具体指标就不同了指标 身高 体重 饭量 力气 跑得快 唱歌 ──────────────────────────────────────────── 阿明 175 70 3 8 7 2 阿伟 173 68 3 7 8 3 ← 跟阿明很像 阿强 165 60 1 3 2 9 ← 完全另一路人阿明跟阿伟个头差不多体重差不多体力也接近这串数字自然就挨得近。阿强完全是另一路数字就离得老远。所以 One-Hot 只能把人分开Embedding 既能叫人分开又能比个亲疏还能算出到底多像。这才是它真正值钱的地方。这串数字是哪儿来的总不会是哪个专家手工填的吧。当然不是全是模型自己练出来的。整个过程分四步走一遍就清楚了。第一步先随便给个数训练刚开始的时候每个词的向量就是一堆随机数毫无意义猫 [0.01, -0.03, 0.05, ...] ← 随机数字啥也不代表 鱼 [0.02, 0.01, -0.04, ...] ← 一样是随机数字就好比一群人刚上场先随便站谁也不挨着谁。这时候的向量是纯噪声别说语义了连猫和鱼该不该靠近都还不知道。第二步慢慢调模型开始读海量文本几百万篇里猫吃鱼猫抓老鼠狗喜欢跑这种话它看了无数遍。每读到一个句子它就顺手调一下相关那几个词的向量读到猫喜欢吃鱼 → 把猫和鱼拉近一点 读到猫抓老鼠 → 把猫和老鼠拉近一点 读到狗喜欢跑 → 把狗和跑拉近一点第三步调到稳下来这样调上几千万次向量就不怎么动了稳定下来词 训练后的向量 语义关系 ──────────────────────────────────────────────── 猫 [0.2, -0.5, 0.7, ...] 编码了猫自己的味道 鱼 [0.15, -0.48, 0.65, ...] 和猫靠得近常同框 狗 [0.18, -0.52, 0.68, ...] 和猫也近都是动物 电脑 [-0.3, 0.6, -0.1, ...] 离猫十万八千里第四步验收这时候再让模型看猫喜欢吃它就比一下P(鱼 | 猫喜欢吃) 0.35 ← 高因为猫和鱼贴得近 P(电脑 | 猫喜欢吃) 0.001 ← 低因为猫和电脑八竿子打不着所以 Embedding 根本就不是人设计出来的是模型为了把预测下一个词这活干好被逼着悟出来的。它得摸清哪些词老一起出现、哪些词用法像、哪些词语义挨得近然后把这一堆发现全塞进那一万两千多个数字里。这也是为啥这些向量充满语义不充满不行任务完不成。这个思路跟上篇学的归纳法是一回事不给规则给海量数据规律自己就冒出来了。一句话是怎么跑完六步的接下来说说 ChatGPT 处理一句话实际是咋一步步跑的大概六步。先看一张图有个整体印象下面再一步步说。第一步分词。输入先切成一个个 token。比如今天天气真好切成 [今天, 天气, 真, 好]。第二步映射成整数。每个 token 在词表里有个固定的号今天 → 12456 天气 → 8901 真 → 3345 好 → 7823为啥要有号因为计算机不认字只认数字每个 token 都得对应一个。第三步查 Embedding 表。ChatGPT 里头其实有一张特别大的查找表拿编号一查就能取出对应的那一万两千多维向量12456 → [0.23, -0.45, 0.67, ..., 0.12] ← 今天 8901 → [0.34, -0.12, 0.45, ..., 0.23] ← 天气 3345 → [-0.12, 0.56, -0.34, ..., 0.45] ← 真 7823 → [0.45, 0.23, -0.67, ..., -0.12] ← 好第四步把这组向量喂给 Transformer。它里头主要转两道手一道叫 Self-Attention上篇学过的那个圆桌会议让每个词都看看周围别的词决定该关照谁另一道叫前馈网络把拿到的信息再加工一遍。这两个东西具体怎么算后面分开学现在只要知道有这两道手就行。第五步Transformer 输出那五万个 token 各自的概率挑概率最高的当下一个词。第六步把新生成的这个词接回原来那串然后重复上面这一套一个词一个词地顺下去。看到这里就明白了Embedding 就是那座把符号世界文字跟数值世界计算连起来的桥缺了它后面这些都无从谈起。顺带提个小细节。这张 Embedding 表的参数是算进模型总参数里的。拿 GPT-3 算算词表大小乘维度五万乘一万两千二百八十八约等于六点一四四亿个参数。这六亿个数只是那传说中一千七百五十亿参数里的一个小角大概占了百分之零点三五。剩下的绝大部分都藏在 Transformer 里面那些层——注意力层、前馈网络、归一化层这些名字先不用记后面会一个个学。分工上Embedding 那层管词都啥意思别的层管这些词怎么排布它俩是一起训的不是分开弄。到这里文字怎么变成数字这件事就顺下来了。One-Hot 能把符号变成数字可惜维度太高、又把语义弄丢了Embedding 换成一万两千多维的稠密向量每个位都有说法既能分开词又能比个亲疏。这些数不是人填的是模型为了预测下一个词自己学出来的。