一位程序员误以为句子嵌入空间存在大量空洞,试图用物理学中的弯曲时空和光线追踪来寻找更优插值路径。折腾数周后发现,真实嵌入空间是密度均匀的圆锥点流形,最简单的Slerp已经是最优路径。

我向Claude解释了我的想法——嵌入空间里有些区域是空的,像沙滩上的螃蟹壳,里面什么都没有。Claude热情地附和,并开始帮我干活。
我训练了一个解码器,将嵌入向量还原成文本,想看看空间不同位置到底发生了什么。当我在两个嵌入点之间插值时,发现输出仍然混乱不堪。我认定原因是插值路径穿过了“虚空”。

Slerp(球形线性插值)是标准的插值方法。由于句子嵌入被归一化到单位长度,它们全部落在768维超球面的表面上。Slerp沿着球面弧线运动,几何上简洁自然,但它根本不关心真实句子到底分布在哪些区域,会无差别地穿过人群或空地。
于是我决心找一条更好的路径。接下来几周,我深入探索了嵌入空间的几何——黎曼度量张量、光线步进、一个500万节点的k近邻图……
如果把500万个句子嵌入到768维空间,每个句子就是一个点。这些点不是均匀分布的——它们会聚集,有结构。如果要在两个句子之间插值,难道不应该顺着这种结构走,而不是硬拉一条直线吗?
在广义相对论中,质量弯曲时空,光和物体自然地沿最短路径穿行。我想为嵌入空间定义类似的规则。

我分析了每个区域中真实句子嵌入的密度,让密度作为“质量”弯曲嵌入空间。为此,我们抽取了500万个句子并全部嵌入,试图充分描绘空间密度。
在任何一点,找出最邻近的50个真实句子,在该邻域内进行主成分分析(PCA)。特征值告诉你真实句子在每个方向的变化程度——变化大表示该方向拥挤,移动代价低;变化小表示你在朝空白处走,代价高。这样你就得到了一个度量张量:一把因地制宜的尺子。沿着这个度量张量走测地线,就能始终待在人口稠密的区域,避开空白地带。

这种方法的优点在于:度量张量可以测量空间任意位置的嵌入密度,告诉你每条路径要消耗多少“能量”。穿过空白的路径代价高,穿过密集区域的路径代价低。这让我们能比较不同插值方法的质量。

在插图中,密度越高的地方向量越长。同理,我们期望穿过高密度区域的路径能花更少能量走更远。
听起来够复杂的。不过我想可能有更简单的办法——用图遍历代替复杂的数学计算。我们有500万个节点,局部密度定义的代价可以作为边权。节点数这么多,图应该能很好地逼近真实最优路径。

直接跑Dijkstra算法,在图上找最短路径,从嵌入点到嵌入点。

我用34.5万个节点做了第一次实验。结果很惊人:Dijkstra的代价比Slerp低了20到30倍。我这叫一个兴奋——要是图近似都这么好,密度场方法岂不是更棒?
我最初的灵感来自光线在弯曲时空中的传播,我想把它贯彻到底。我想到光线投射(raycasting)——就是高级游戏里模拟光线散射的算法。光线经过大质量物体会弯曲,这就是引力透镜效应。也许我可以用光线步进(raymarching),每次沿代价最低的方向走一小步,直到到达目的地。我简直觉得自己发明了穿越密度场的高效新方法!结果发现这算法早就有了,就叫光线步进。

Claude干活,我在500万句子上预计算了10万个网格点的密度,然后开始光线步进。
结果:代价和Slerp差不多,有时好6%,有时更差。没有显著改进。
奇怪了……按理应该至少和Dijkstra一样好才对。我百思不解。
我深挖下去,尝试各种方法找错误。终于发现:计算能量消耗的代码只考虑了每步起点和终点的场密度,而没有计算沿整条边途中的完全代价!空白地带根本没收钱!
我让Claude重写一个函数,对整条边都采样度量张量。这下整段路径都要计费了。结果图遍历的代价比密度场测地线高了3到4倍……
因为图走的是蜿蜒曲折的路径,覆盖的地面比光线步进多得多,而光线步进可以走更精细的路线。

但这不是我期望的发现。我本以为光线步进有问题,而不是Dijkstra有问题。而且Slerp居然还经常比两者都好!到底怎么回事?
答案来得干脆。我在和Claude讨论时灵光一闪。
嵌入空间是一个点云流形啊!很明显!根本没有什么虚空!
啥?既是点云又是曲面?
Claude平静地解释:绝大多数嵌入空间实际上是超球面上的圆锥形点云。我懵了。我问Claude最后一个问题:“什么是流形?”
这时我才明白,我对流形的理解一直是错的。
带着挫败感,我继续探索。Claude告诉我并向我证明,nomic嵌入形成了圆锥点云。它通过刻画嵌入空间中句子的形状,揭示了圆锥分布的所有特征。详细探索请见这个Notebook。
在圆锥内部,密度是均匀的。没有需要避开的巨大空白。在任何两点之间做Slerp,弧线都穿过圆锥内部——最密集的区域——永远不会跨越空空间。密度场分析解决的是一个根本不存在的问题。
在机器学习这个奇妙而复杂的世界里,我从未想到会遇到这么多几何问题。恰恰是这种“语义流形存在于高维空间并编码意义”的想法,把我拉回了机器学习(距离上次做项目已经8年了)。这太美了,而且和我学物理时的直觉很好地吻合。
我这辈子大多数业余项目都失败了,它们常常远远超出我的能力范围。但正因为如此,它们才有意思。有了AI辅助编码,我可以飞快地探索最有趣的算法和几何问题。缺点是我的理解能力只是渐进式增长。
不过,嵌入空间的工作方式已经刻进了我的骨头里。当有人说“句子嵌入在高维空间中形成一个圆锥点云流形,其内在维度其实很低,可以利用这一点简化计算”时,我清楚知道那是什么意思。这种直觉在上手LoRA(低秩适配)时直接派上了用场——LoRA正是利用了这种低内在维度,让微调再大的模型也变得经济可行。
希望我下次失败也能这么有教益。
免费获取企业 AI 成熟度诊断报告,发现转型机会
关注公众号

扫码关注,获取最新 AI 资讯
3 步完成企业诊断,获取专属转型建议
已有 200+ 企业完成诊断