25 Oct

圆内随机n点在同一个圆心角为θ的扇形的概率

这几天网上热传了一道“四鸭共半圆”题目:

四鸭共半圆问题

四鸭共半圆问题

可能有不少读者看到后也尝试做过,就连李永乐老师也专门开了一节课讲这道题(参考《圆形水池四只鸭子在同一个半圆里,概率有多大?》)。就这道题目本身而言,答案并不算困难,可以有很多方法算出来。稍微有难度的是它的推广版本,也就是本文标题所描述的,将鸭子的数目一般化为$n$只,将半圆一般化为圆心角为$\theta$的扇形。更有趣的是,当$\theta \leq \pi$时,依然有比较初等的解法,但是当$\theta > \pi$后,复杂度开始“剧增”...

点击阅读全文...

31 May

关于NBCE方法的一些补充说明和分析

上周在《NBCE:使用朴素贝叶斯扩展LLM的Context处理长度》中,我们介绍了一种基于朴素贝叶斯来扩展LLM的Context长度的方案NBCE(Naive Bayes-based Context Extension)。由于它有着即插即用、模型无关、不用微调等优点,也获得了一些读者的认可,总的来说目前大家反馈的测试效果还算可以。

当然,部分读者在使用的时候也提出了一些问题。本文就结合读者的疑问和笔者的后续思考,对NBCE方法做一些补充说明和分析。

方法回顾

假设$T$为要生成的token序列,$S_1,S_2,\cdots,S_n$是给定的若干个Context,我们需要根据$S_1,S_2,\cdots,S_n$生成$T$,那么就需要估计$p(T|S_1, S_2,\cdots,S_n)$。根据朴素贝叶斯思想,我们得到
\begin{equation}\log p(T|S_1, S_2,\cdots,S_n) = \color{red}{(\beta + 1)\overline{\log p(T|S)}} - \color{green}{\beta\log p(T)} + \color{skyblue}{\text{常数}}\label{eq:nbce-2}\end{equation}

点击阅读全文...

20 Jul

语言模型输出端共享Embedding的重新探索

预训练刚兴起时,在语言模型的输出端重用Embedding权重是很常见的操作,比如BERT、第一版的T5、早期的GPT,都使用了这个操作,这是因为当模型主干部分不大且词表很大时,Embedding层的参数量很可观,如果输出端再新增一个独立的同样大小的权重矩阵的话,会导致显存消耗的激增。不过随着模型参数规模的增大,Embedding层的占比相对变小了,加之《Rethinking embedding coupling in pre-trained language models》等研究表明共享Embedding可能会有些负面影响,所以现在共享Embedding的做法已经越来越少了。

本文旨在分析在共享Embedding权重时可能遇到的问题,并探索如何更有效地进行初始化和参数化。尽管共享Embedding看起来已经“过时”,但这依然不失为一道有趣的研究题目。

点击阅读全文...

28 Aug

Lion/Tiger优化器训练下的Embedding异常和对策

打从在《Tiger:一个“抠”到极致的优化器》提出了Tiger优化器之后,Tiger就一直成为了我训练模型的“标配”优化器。最近笔者已经尝试将Tiger用到了70亿参数模型的预训练之中,前期效果看上来尚可,初步说明Tiger也是能Scale Up的。不过,在查看训练好的模型权重时,笔者发现Embedding出现了一些异常值,有些Embedding的分量达到了$\pm 100$的级别。

经过分析,笔者发现类似现象并不会在Adam中出现,这是Tiger或者Lion这种带符号函数$\text{sign}$的优化器特有的问题,对此文末提供了两种参考解决方案。本文将记录笔者的分析过程,供大家参考。

现象

接下来,我们的分析都以Tiger优化器为例,但分析过程和结论同样适用于Lion。

点击阅读全文...

14 Aug

Transformer升级之路:13、逆用Leaky ReRoPE

上周在《Transformer升级之路:12、无限外推的ReRoPE?》中,笔者提出了ReRoPE和Leaky ReRoPE,诸多实验结果表明,它们能够在几乎不损失训练效果的情况下免微调地扩展LLM的Context长度,并且实现了“longer context, lower loss”的理想特性,此外跟NTK-aware Scaled RoPE不同的是,其中ReRoPE似乎还有表现出了无限的Context处理能力。

总之,ReRoPE看起来相当让人满意,但美中不足的是会增加推理成本,具体表现为第一步推理需要算两次Attention,以及后续每步推理需要重新计算位置编码。本文试图通过在训练中逆用Leaky ReRoPE的方法来解决这个问题。

回顾

让我们不厌其烦地重温一下:RoPE形式上是一种绝对位置编码,但实际达到的效果是相对位置编码,对应的相对位置矩阵是:
\begin{equation}\begin{pmatrix}0 & \\
1 & 0 & \\
2 & 1 & 0 &\\
3 & 2 & 1 & 0 & \\
\ddots & 3 & 2 & 1 & 0 & \\
\ddots & \ddots & 3 & 2 & 1 & 0 & \\
\ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots \\
\tiny{L - 2} & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots \\
\tiny{L - 1} & \tiny{L - 2} & \ddots & \ddots & \ddots & 3 & 2 & 1 & 0 & \\
\end{pmatrix}\label{eq:rope}\end{equation}

点击阅读全文...

16 Sep

随机分词浅探:从Viterbi Decoding到Viterbi Sampling

上一篇文章《大词表语言模型在续写任务上的一个问题及对策》发布后,很快就有读者指出可以在训练阶段引入带有随机性的分词结果来解决同样的问题,并且已经有论文和实现。经过进一步查阅学习,笔者发现这是一个名为Subword Regularization的技巧,最早应用在NMT(机器翻译)中,目前SentencePiece也有相应的实现。看起来这个技巧确实能缓解前述问题,甚至有助于增强语言模型的容错能力,所以就有了将它加进去BytePiece的想法。

那么问题来了,如何将确定性分词改为随机性分词呢?BytePiece是基于Unigram模型的,它通过Viterbi算法找最大概率的分词方案,既然有概率,是否就可以自然地导出随机采样?本文来讨论这个问题,并分享自己的解决方案。

点击阅读全文...

14 Jan

旁门左道之如何让Python的重试代码更加优雅

这篇文章我们讨论一个编程题:如何更优雅地在Python中实现重试。

在文章《新年快乐!记录一下 Cool Papers 的开发体验》中,笔者分享了开发Cool Papers的一些经验,其中就提到了Cool Papers所需要的一些网络通信步骤。但凡涉及到网络通信,就有失败的风险(谁也无法保证网络不会间歇性抽风),所以重试是网络通信的基本操作。此外,当涉及到多进程、数据库、硬件交互等操作时,通常也需要引入重试机制。

在Python中,实现重试并不难,但如何更加简单而又不失可读性地实现重试,还是有一定技巧的。接下来笔者分享一下自己的尝试。

循环重试

完整的重试流程大致上包含循环重试、异常处理、延时等待、后续操作等部分,其标准写法就是用for循环,用“try ... except ...”来捕捉异常,一个参考代码是:

点击阅读全文...

2 Feb

更便捷的Cool Papers打开方式:Chrome重定向扩展

一些铺垫

自Cool Papers上线以来,很多用户就建议笔者加入搜索功能,后面也确实在前端用JS简单做了个页面内搜索,解决了部分用户的需求,但仍有读者希望引入更完整的全局搜索。诚然,笔者理解这个需求确实是存在,但Cool Papers的数据是逐天累积的,目前才上线一个月,论文数并不多,建立一个大而全的搜索引擎意义不大,其次做搜索也不是笔者的强项,以及并没有很好的利用LLM优化搜索的思路,等等。总而言之,暂时没有条件实现一个全面而又有特色的搜索,所以不如不做(也欢迎大家在评论区集思广益)。

后来,经过和同事讨论,想出了一个“借花献佛”的思路——写一个Chrome的重定向扩展,可以从任意页面重定向到Cool Papers。这样我们可以用任意方式(如Google搜索或者直接Arxiv官方搜索)找到Arxiv上的论文,然后右击一下就转到Cool Papers了。前两周这个扩展已经在Chrome应用商店上线,上周服务器配合做了一些调整,如今大家可以尝试使用了。

扩展地址:Cool Papers Redirector

点击阅读全文...