1.1 说模型眼里的世界是一串 token 编号。但编号只是个 ID,没法拿来算。这一段补上中间缺的一环:编号怎么变成一串数字,那串数字为什么带着「意思」,以及大家常听到的「权重」「参数」到底是什么东西。答案全在线性代数里——而且只用到加减、点积、矩阵乘法三样。
所有演示都能用键盘操作。整页可直接打印,打印时按钮会自动隐藏。
1.1 那张循环图里,「全部文本」进去、「一张概率表」出来,中间只写了四个字:一次前向计算。这一段就是把那四个字拆开。拆开之后应该能回答三个问题:「1750 亿参数」数的是什么;为什么它能做类比、能跨语言;为什么它「知道」的东西没法指着某一条说「存在这里」。
1.1 的 Demo 1 里,「头痛」被切成一个 token,编号比如 15071。这个编号和 USUBJID 一样,只是个 key,它的大小没有任何含义——15071 不比 15070 更「头痛」。而模型内部只会做一件事:算数。所以进模型的第一步,永远是把每个编号换成一串数字。
那串数字叫向量,串的长度叫维度。整段补充只讨论三个问题:这串数字从哪来(第 1 节)、它为什么带着意思(第 2、3 节)、模型拿它做什么(第 4、5 节)。
一个向量就是一条 observation,有 d 个数值变量:dim1 到 dim12288。「12288 维」不比「一个数据集有 12288 列」更神秘。线性代数是对这种整表做运算的语言——整列相加、整行做加权求和——你在 PROC IML 或者 PROC REG 的 Xβ 里已经见过它。
这一节只做一件事:让「嵌入」(embedding)这个词落地。它不是什么算法,它是一张表——词表里每个 token 占一行,每行是一串数字。把编号换成向量,就是拿编号去这张表里取出那一行。
这是模型里第一批「参数」——而且是最容易看懂的一批
模型开机时,手里有一张固定的表:行数 = 词表大小(几万到二十几万),列数 = 维度(几千到一万多)。表里每一个数字都是训练时调出来的,出厂之后就不变了。一句话进来,切成 token,每个 token 拿编号去表里查出自己那一行,句子就从「5 个编号」变成了「5 行 × d 列的数字表」。这张数字表才是模型真正读到的输入。
点上面任意一个 token,看它去表里取哪一行;点「整句」看五个一起取出来。这里只画 8 列,真实模型是几千到一万多列;表里的数字是为演示编的。
四个数字来自 GPT-3 的论文(2020 年,结构全部公开,所以数字凑得整)。当前的商用模型(Claude、GPT-4 之后的 GPT 系列)不公开这些数字;开源模型(Llama、Qwen 等)公开,量级类似:词表十几万,维度几千到一万多。
PROC FORMAT 也是查表——区别只是这里取回的不是一个值,是一整行。一行 12288 个数字,等价于12288 维空间里的一个点。人画不出 12288 维,但二维、三维里的直觉都能搬过去。这一节的结论只有一句:训练做的事,就是把每个词的点挪到「意思相近的词挨在一起」的位置。
没有人告诉它「这几个是症状、那几个是药」——堆是自己长出来的
模型出厂前,嵌入表里填的是随机数:每个词是平面上一个随机位置的点,谁和谁都不挨着。然后开始训练——反复做「猜下一个 token」,猜错了就把相关的点各挪一点点。几万亿 token 做下来,在相似上下文里出现的词,会被一次次推到一起。「头痛」和「恶心」总出现在「患者服药后出现 ___」后面,所以它们最后靠得很近。
先点任意一个词,看它「最像」的邻居是谁——训练前的邻居是随机的。然后点「训练」,等点停下来再点同一个词。二维只是投影:真实模型里这些点在几千维空间里分堆,画不出来,但「挨得近 = 像」这条直觉不变。
「猜错程度」是这个演示里真算的:每个点到它训练完成位置的平均距离。真实训练里这个数叫损失(loss),衡量的是「下一个 token 猜错的程度」,含义一致,算法不同。
余弦相似度和 PROC CORR 算的 Pearson 相关系数是近亲:把两列先各自减去均值,再算夹角余弦,就是 Pearson 相关。你已经会读 0.9 和 0.1 的区别了,这里一样。
位置代表意思,那两个位置之差代表什么?代表「从这个词到那个词的关系」。关键性质是:同一种关系,在空间里是同一根箭头——「男人→国王」和「女人→王后」几乎平行等长。所以向量可以加减,加减出来的是「意思的加减」。这一节就演示这件事,以及它失灵的时候长什么样。
最著名的一个例子,2013 年 word2vec 论文里就有;换成 SDTM 和 ADaM 也一样成立
把「国王」的坐标减去「男人」的坐标,得到一根箭头,含义大致是「王权」。把这根箭头原封不动平移到「女人」上,箭头尖落在哪?落在「王后」旁边。这不是模型「懂」什么是王权——是训练把「男人/国王」和「女人/王后」摆成了平行四边形,而平行四边形是加减法能描述的东西。
选一组类比,一步一步点,看右边的坐标算式怎么和左边的箭头对应。最后试「自己搭」一组毫无道理的组合——注意它照样会给你一个「最近的词」。
ADAE − AE + LB ≈ ADLB 这组不是我编来讨好大家的:在真实的代码语料上训练过的模型,确实会把 SDTM 域和对应的 ADaM 数据集摆成平行关系,因为它们在几十万份 spec 和程序里成对出现。第三讲讲 Coding Agent 时,它能「顺手」把你写给 AE 的逻辑改成 LB 版本,几何上靠的就是这根箭头。
前三节讲的是输入长什么样。这一节讲模型拿它做什么:一层网络 = 一个矩阵乘一次 + 一次很简单的弯折。「1750 亿参数」数的就是这些矩阵里的格子数。讲完这一节,「参数」「权重」「层」三个词应该都变成能指着说的东西。
四个数字就能旋转、拉伸、压扁一个平面;几千 × 几千个数字,就是模型的一层
拿一个二维点 (x, y),乘一个 2×2 的矩阵,得到一个新点:x′ = a·x + b·y,y′ = c·x + d·y。就这两行算式。它的妙处在于对平面上所有点用的是同一套 a b c d——所以它不是挪一个点,是把整张平面一起旋转、拉伸、剪切。模型里的每一层,本质上就是拿一个几千 × 几千的矩阵,给所有 token 的向量集体换一套坐标。
拖动 a b c d 四个滑块,或点预设。网格、两根基向量和四个词一起变——它们用的是同一个矩阵。矩阵乘法是真算的;词的坐标沿用第 3 节的示意位置。最后勾上「弯折」,看为什么只有矩阵不够。
拿 GPT-3(2020 年论文,结构公开)算一遍。它的每一层有两部分:注意力(让每个 token 的向量去看其他 token 的向量,用四个 d×d 的矩阵)和前馈(两个矩阵,先把维度放大四倍再缩回来)。数格子:
| 部件 | 形状 | 格子数 | × | 小计 |
|---|---|---|---|---|
| 嵌入表(第 1 节) | 50,257 × 12,288 | 6.18 亿 | 1 | 6.2 亿 |
| 注意力 · 每层四个矩阵 | 4 × (12,288 × 12,288) | 6.04 亿 | 96 层 | 580 亿 |
| 前馈 · 每层两个矩阵 | 2 × (12,288 × 49,152) | 12.08 亿 | 96 层 | 1,160 亿 |
| 最后一步:向量 → 词表分数(第 5 节) | 12,288 × 50,257 | 6.18 亿 | 1(常与嵌入表共用) | 0 – 6.2 亿 |
| 合计 | ≈ 1,750 亿 |
加上位置编码、偏置、归一化系数这些零头,正好是论文报的 175B。「参数」这个词从此可以直译为「矩阵里的格子总数」。当前一代商用模型的数字不公开,但结构是同一套:一张嵌入表 + 几十到上百层「矩阵 + 弯折」+ 一张回词表的表。
训练大模型和 PROC LOGISTIC 迭代拟合是同一件事。LOGISTIC 从一组初始 β 出发,每次沿着让似然更大的方向挪一步,日志里那几行 Iteration History 就是它。大模型没有闭式解,也是这么迭代——区别只是 β 从十几个变成几千亿个,「拟合的目标」是猜对下一个 token,迭代几十万步,跑几个月,烧掉几万块显卡。「权重」= β,「训练」= 拟合,「损失」= 拟合得多差。
表里的「注意力」是这一代模型区别于旧模型的核心部件,但机制并不神秘:每个 token 的向量和句子里其他 token 的向量做点积(第 2 节的「像不像」),得分高的就多搬一点它的信息过来。所以「上下文」对模型的作用是字面意义的:前面每个词的向量都被按相关度加权、混进当前词的向量里。1.1 说「每生成一个 token,前面所有 token 都要重算一遍」,重算的就是这批点积。板块 3 的「中间丢失」也是从这里来的——不展开,知道它是点积就够。
几十层矩阵之后,句子最后一个位置手里有一个向量。1.1 那张「概率表」就是从这个向量来的:拿它和词表里每一行做点积,谁的分数高谁概率大。这一节把循环闭上。
这一步用的表,和第 1 节的嵌入表形状一样、常常就是同一张
最后那个向量叫「隐状态」,它的方向大致指向「接下来该出现什么样的词」。把它和词表里每个词的向量做点积——方向越一致分数越高——得到 5 万个分数,再用 softmax 把分数压成加起来等于 1 的概率。1.1 Demo 2 里你拉温度时重算的那张表,就是这样来的。
拖左图的箭头尖(或用滑块)改变隐状态的方向和长度,右边的概率表实时重算。词的坐标是第 2 节的示意位置;点积和 softmax 是真算的。三个预设对应三种上下文。
嵌入是查表;训练把常在相似上下文里出现的词推到一起。相似度可以算,用的是夹角余弦——第二讲的 RAG 检索靠它。
第 1、2 节同一种关系是同一根箭头,所以类比能成立、跨语言能成立。但「找最近的词」永远有答案——这是幻觉的几何版。
第 3 节一层 = 矩阵 + 弯折;1750 亿是格子总数。训练 = 迭代拟合。最后一层和词表逐行点积,长度管自信,方向管内容,两者无关。
第 4、5 节这一段讲的全部是原理层:向量、点积、矩阵、softmax。它们从 2013 年的 word2vec 到今天没有变过,各家模型的差别在矩阵的大小、层数和训练数据,不在这套算术本身。所以这一段的内容不用标日期——除了那几个 GPT-3 的具体数字。
只列这一段新出现的词。第一讲讲义的术语表里已有的(token、上下文窗口、温度)不重复。
真实的向量几千维,你画的是二维,这算不算骗人?
是投影,不是编造。几千维空间里的「挨得近」「平行」「夹角小」这些关系,投到二维仍然是这些关系——就像三维物体的影子仍能看出形状。但要说清两点:投影会丢信息(几千维里分得开的两团,二维里可能重叠);本页所有坐标是我手摆的,不是从真实模型里降维出来的。真要看真实数据,可以用开源模型的嵌入表配合 t-SNE / UMAP 画,结论一致。
这些坐标是谁定的?维度有名字吗?
没人定,也没名字。出厂前是随机数,训练中被「猜下一个 token 猜错了就挪一点」推到现在的位置。单独看一列几乎不可解释——「第 3071 列」不对应「疼痛程度」这样的东西;意思散在几千列的组合里。这也是「知识没法指着某一条说存在哪」的根源。
两个不同模型的向量能拿来比吗?
不能直接比。每个模型有自己的坐标系,同一个词在 A 模型和 B 模型里的数字毫无关系。所以第二讲做 RAG 时有一条铁律:存文档时用哪个嵌入模型,检索时必须用同一个,中途换模型要全部重算。
既然是查表加矩阵乘法,为什么它能「推理」?
诚实的回答是:这个问题目前没有完整的理论答案。能说清的是机制——几十层「矩阵 + 弯折」叠起来可以拟合极复杂的函数,而「猜下一个 token」这个任务逼着它把语法、常识、逻辑的规律都压进参数里,因为不压进去就猜不准。它表现出的「推理」是这种拟合的结果,不是另外装了一个推理模块。1.4 讲的所有边界(算数不准、会编造)也都从这里来。
这和第二讲的 RAG 到底什么关系?
RAG 的检索环节就是第 2 节:把你的文档切块(第一讲 3.2 的切块),每块过一次嵌入模型变成一个向量存起来;提问时问题也变成向量,算余弦相似度,取最像的几块塞进上下文。「向量数据库」就是一张存了很多向量、能快速找最近邻的表。听完这一段,第二讲的 RAG 应该没有新概念。
「弯折」为什么这么重要?多叠几层矩阵不行吗?
不行,这是线性代数的一条定理:矩阵乘矩阵还是矩阵。叠一百层纯矩阵,等价于一层。它们只能做旋转、拉伸、剪切、投影这一类「直的」变换,画不出任何弯的边界。层间加一次极简单的非线性(负数归零),叠起来就能逼近任意函数。Demo V4 勾上那个复选框,看网格怎么被折起来,就是这件事的最小版本。