作者: admin

  • 增大Tokenizer词表:LLM续写任务的新挑战与解决方案

    语言模型(LLM)在自然语言处理中的应用越来越广泛,而通过增大Tokenizer的词表来提高压缩率,从而缩短串行长度、降低解码成本,是大家都喜闻乐见的事情。然而,这种方法在带来诸多优点的同时,也可能产生一些问题。本文将探讨增大词表后语言模型在续写任务中遇到的问题,并提出解决方案。

    优劣分析

    优点

    1. 解码速度提升:由于LLM是自回归的,解码过程会随着序列长度的增加变得越来越慢。通过“增大词表 → 提高压缩率 → 缩短串行长度”,可以减少相同文本对应的tokens数量,从而减少解码步数,提升解码速度。
    2. 缓解Exposure Bias:语言模型的训练方式通常是Teacher Forcing,缩短串行长度能够缓解Teacher Forcing带来的Exposure Bias问题,从而可能提升模型效果。

    缺点

    1. 割裂字符联系:增大词表可能会割裂token与token之间在字符层面的联系,影响模型的泛化能力。例如,“太阳能”和“太阳”都是词表中的一个词时,模型可能不知道“太阳能”是由“太阳”和“能”组成,从而难以完成一些子词相关的任务。
    2. 续写问题:增大词表后,常见的命令或短语可能被视为单个token,导致模型在续写时无法正确生成。例如,“import numpy as np”被当作一个token,用户输入“import numpy”时,模型无法续写出“ as np”。

    续写问题

    Armen Aghajanyan分享了一个典型的例子:在训练代码模型时使用超大词表,导致“import numpy as np”变成了一个token。当用户输入“import numpy”时,模型无法续写出“ as np”。这种现象在自然语言模型中也很常见。例如,“太阳能”和“太阳”都是独立的token时,用户输入“太阳”后,模型续写出的内容可能不符合用户的期望。

    参考对策

    虽然Armen Aghajanyan提到的问题确实存在,但笔者认为通过适当的处理,这个问题不仅可以解决,还能转化为增大词表的优点。以下是一个可行的解决方案:

    基于词表的前缀搜索

    假设用户输入了“广州的白云”,Tokenizer将其分为“广州/的/白云”。此时,如果直接将这三个词转换为id输入模型,模型可能无法续写出“广州/的/白云机场”等结果。因此,我们可以进行以下步骤:

    1. 前缀搜索:对“白云”进行词表的前缀搜索,假设搜索结果为“白云”、“白云机场”、“白云山”、“白云路”四个词。
    2. 计算条件概率:用LLM计算以下条件概率:
      [p(\text{白云}|\text{广州, 的})p(\text{白云机场}|\text{广州, 的})p(\text{白云山}|\text{广州, 的})p(\text{白云路}|\text{广州, 的})]
    3. 归一化与采样:将条件概率归一化后进行采样,决定续写内容。例如,采样结果为“白云机场”,则输出“机场”,并按照“广州/的/白云机场”进行续写。

    这种方法不仅解决了Armen Aghajanyan所提到的问题,还能在词表压缩率高的情况下,一次性生成更多的字。特别地,回退操作只需在采样第一步进行,从第二步开始就不需要回退操作,计算量很少。

    文章小结

    本文介绍了增大词表后LLM在续写任务中可能出现的问题,并分享了参考的解决方案。通过结合基于LLM的续写和基于词表的前缀搜索,可以有效地解决续写问题,并将增大词表的缺点转化为优点。希望这些思路能为语言模型的进一步优化提供参考。

  • Viterbi Sampling算法的改进与完善

    在自然语言处理领域,分词是一个至关重要的步骤。最近,一篇名为《随机分词浅探:从Viterbi Decoding到Viterbi Sampling》的文章中,作者提出了一种名为“Viterbi Sampling”的随机分词算法。本文将详细讨论该算法的改进,并从数学上证明其效果可以与Subword Regularization等价。

    问题分析

    在知乎的评论中,用户 @鹤舞 指出,当前的采样算法可能会在多次二选一的过程中“稀释”了部分方案的出现概率,导致原本分数最高的切分并不是以最高概率出现。

    例如,假设有三种切分方案,每种方案的得分都一样,理应每种方案的出现概率都是1/3。然而,Viterbi Sampling算法将多选一的过程拆分成多步的二选一,从而导致概率分布发生偏移。

    示例分析

    以单词“watching”为例,有三种切分方案:watch ing, wat ching, 和 w atching。按照Viterbi Sampling的操作,先在前两种方案中选择,概率均为1/2;然后再与第三种方案比较,概率依然为1/2。最终,前两种方案的出现概率为1/4,而第三种方案的出现概率变为了1/2。

    解决办法

    为了解决上述问题,可以采用“水塘采样(Reservoir sampling)”的算法。具体来说,每次进行二选一后,同时缓存累积概率,并在后续的二选一过程中使用累积概率进行比较。

    具体实现

    假设前两种切分方案的概率均为1/3,选择其中一种后,总的累积概率为2/3。接下来,新方案被选中的概率为1/3,而不是1/2。这保证了每种方案的出现概率均保持为1/3。

    在实际计算时,为避免指数爆炸问题,可以缓存对数形式的概率,并利用logsumexp函数避免溢出。

    Zlogi = logsumexp(Zlogi-1, αsi)

    相应的实现已经内置在bytepiece>=0.5.0中。

    完美采样的证明

    为了证明改进后的Viterbi Sampling算法是“完美采样”,我们需要回顾Viterbi Decoding的基本原理。Viterbi Decoding通过动态规划找出最优的分词方案,其子串也必须是对应子字节串的最优切分方案。

    数学推导

    通过动态规划,可以计算出每个位置的最优切分方案及其得分。而在Viterbi Sampling中,我们需要对所有切分方案进行采样,其采样概率应与得分成正比。

    Z(c1, c2, ..., cl) = ∑ Z(c1, ..., ck) * e^(α * s(ck+1, ..., cl))

    通过逐步计算累积权重Z,可以实现对所有切分方案的完美采样。

    递归式转换

    在实际计算中,使用对数形式的累积权重Zlog,并通过logsumexp函数进行累积计算。

    Zlog(c1, c2, ..., cl) = logsumexp(Zlog(c1, ..., ck) + α * s(ck+1, ..., cl))

    这样可以避免直接计算指数导致的溢出问题。

    文章小结

    本文通过详细分析和数学推导,完善了之前提出的Viterbi Sampling算法。改进后的算法不仅解决了概率“稀释”问题,而且在效果上与Subword Regularization等价,同时在使用效率上更具优势。

    通过这些改进,Viterbi Sampling算法在实际应用中将具备更高的可靠性和效率,为自然语言处理领域的分词任务提供了更优的解决方案。

人生梦想 - 关注前沿的计算机技术 acejoy.com 🐾 步子哥の博客 🐾 背多分论坛 🐾 借一步网 沪ICP备2024052574号-1