当前位置: 首页 > news >正文

大词表语言模型在续写任务上的一个问题及对策

bf42b09cdbee4ccf6b48d86e41b8a553.gif

©PaperWeekly 原创 · 作者 | 苏剑林

单位 | 科学空间

研究方向 | NLP、神经网络

对于 LLM 来说,通过增大 Tokenizer 的词表来提高压缩率,从而缩短序列长度、降低解码成本,是大家都喜闻乐见的事情。毕竟增大词表只需要增大 Embedding 层和输出的 Dense 层,这部分增加的计算量几乎不可感知,但缩短序列长度之后带来的解码速度提升却是实打实的。

当然,增加词表大小也可能会对模型效果带来一些负面影响,所以也不能无节制地增加词表大小。本文就来分析增大词表后语言模型在续写任务上会出现的一个问题,并提出参考的解决方案。

86ca52ab8f089cf97cd4699c6151b534.png

优劣分析

增加词表大小的好处是显而易见的。一方面,由于 LLM 是自回归的,它的解码会越来越慢,而“增大词表 → 提高压缩率 → 缩短序列长度”,换言之相同文本对应的 tokens 数变少了,也就是解码步数变少了,从而解码速度提升了;另一方面,语言模型的训练方式是 Teacher Forcing,缩短序列长度能够缓解 Teacher Forcing 带来的 Exposure Bias 问题,从而可能提升模型效果。

不过增大词表的缺点也很明显,最直接的就是会割裂 token 与 token 之间在字符层面之间的联系,从而可能会影响泛化,甚至会损失做某些任务的能力。比如“太阳能”和“太阳”都是词表中的一个词的话,模型是不知道“太阳能”是由“太阳”和“能”组成,也不知道“太阳”是“太”和“阳”,这样如果要做一些子词相关的任务就会比较艰难,比如最经典的问“‘太阳能’反过来怎么读?”,期望回答时“能阳太”,但由于模型不知道它是“太”、“阳”、“能”三个字组成,从而很难回答正确。

f681f650e9afefc91a374191f00e60aa.png

续写问题

近日 @Armen Aghajanyan 分享了另一个问题。他们在训练代码模型时使用了超大词表,结果就是常见的命令如 “import numpy as np” 都变成了一个 token,然后发现当用户输入 “import numpy” 时,模型无法续写出 “as np”。原因很简单,“import numpy as np” 被当作了一个 token,于是当 “import numpy” 单独出现时,模型会发现它后面永远不会接 “as np”(接 “as np” 的都被合并成单独的 “import numpy as np” 了),自然也无法完成续写。

这个现象确实很经典,其实不单是代码模型,常见的自然语言模型也会出现。比如当“太阳能”和“太阳”都成为了一个独立的 token 时,用户输入“太阳”后,接下来续写的字就基本不会是“能”了,这可能不符合用户的分布期望;又比如“白云”、“白云山”、“白云机场”都是一个独立的 token 时,用户输入“广州的白云”后,接下来也几乎不会续写出“广州的白云机场”、“广州的白云山”,等等。

69b537b533daa99430ae8854e43c27ae.png

参考对策

然而,笔者认为 Armen Aghajanyan 所提的现象,并不能构成增大词表的缺点,反而稍微处理一下之后,它还有可能成为增大词表的优点。其实这个问题很简单,以前没有 LLM 的时候,基于“词表+前缀搜索”我们也能做一定的补全任务,现在有了 LLM,难道我们就一定要囿于 LLM,不能将基于 LLM 的续写和基于词表的续写结合起来吗?

还是刚才的例子,假设用户输入了“广州的白云”,Tokenizer 将它分为“广州/的/白云”,现在如果将这三个词直接转为 id 输入到模型中,就会无法续写出“广州/的/白云机场”等结果。

这本质上是因为 Tokenizer 无法提前预估未来的文本,从而导致分词结果出错(当然,也可以考虑在训练阶段就使用带有随机性的 tokenize 算法,这种情况下“白云机场”可能作为一个词出现,也可能作为“白云/机场”出现,此时分词结果不至于严重影响后续效果,甚至能增强泛化能力,参考《Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates》)。

那么,我们是否可以预估一下未来的文本呢?假设分词为“广州/的/白云”后,我们回退一步,拿“白云”去词表做前缀搜索,不妨再假设搜索结果为“白云”、“白云机场”、“白云山”、“白云路”四个词,这步搜索是纯粹基于词表做的,相比 LLM 的计算量可以忽略不计。有了搜索结果后,我们用 LLM 计算:

d2853b822bb3a41f4ae8339282213b9d.png

由于输入都是相同的,所以计算这四个条件概率只需要运行一次 LLM。有了这四个条件概率后,我们将它们重新归一化然后进行采样。假如采样结果是“白云”,那么我们就按照“广州/的/白云”来做续写;如果采样到“白云机场”,那么就可以输出“机场”,并按照“广州/的/白云机场”来做续写;依此类推。

这就轻松解决了 Armen Aghajanyan 所提到的问题,并且将缺点转化为优点了(压缩率高时,即便回退了一步,但是前缀搜索出来的词可能很长,可以一次性生成更多的字)。特别地,回退操作只需要在采样第一步进行,它只是为了避免输入不完整导致的分词错误,从第二步开始就不需要回退操作了,因此新增的计算量是非常少的。

值得一提的是,微软有一个名为 “guidance” 的库,也提出了同样的技巧(参考这里)。此外,考虑更一般的场景,有时候回退一步也不够,比如 “import numpy as np” 的例子,单输入 “import numpy” 时,可能被分为 “import/ numpy” 了,这时候起码要回退两步才能完整合理的序列。但这没有本质的区别,只是细节上稍微复杂一些,这里就不展开了,读者部署推理模型的时候自行构造就好。

fb8a346bad9cc46de221662dfc1a8555.png

文章小结

本文介绍了超大词表的 LLM 在做文本续写任务时可能出现的一个问题,并分享了参考的解决方案。

outside_default.png

参考文献

outside_default.png

[1] https://arxiv.org/abs/1804.10959

[2] https://github.com/guidance-ai/guidance#token-healing-notebook

更多阅读

ba29e5d532daf5d517f5fc38c37b0e6e.png

877be88b1c9b473473b6c18046643a11.png

5eeacdafc00a73793c96dd5c6be9a686.png

56b7546647bcc7c5157d1595e3e4483f.gif

#投 稿 通 道#

 让你的文字被更多人看到 

如何才能让更多的优质内容以更短路径到达读者群体,缩短读者寻找优质内容的成本呢?答案就是:你不认识的人。

总有一些你不认识的人,知道你想知道的东西。PaperWeekly 或许可以成为一座桥梁,促使不同背景、不同方向的学者和学术灵感相互碰撞,迸发出更多的可能性。 

PaperWeekly 鼓励高校实验室或个人,在我们的平台上分享各类优质内容,可以是最新论文解读,也可以是学术热点剖析科研心得竞赛经验讲解等。我们的目的只有一个,让知识真正流动起来。

📝 稿件基本要求:

• 文章确系个人原创作品,未曾在公开渠道发表,如为其他平台已发表或待发表的文章,请明确标注 

• 稿件建议以 markdown 格式撰写,文中配图以附件形式发送,要求图片清晰,无版权问题

• PaperWeekly 尊重原作者署名权,并将为每篇被采纳的原创首发稿件,提供业内具有竞争力稿酬,具体依据文章阅读量和文章质量阶梯制结算

📬 投稿通道:

• 投稿邮箱:hr@paperweekly.site 

• 来稿请备注即时联系方式(微信),以便我们在稿件选用的第一时间联系作者

• 您也可以直接添加小编微信(pwbot02)快速投稿,备注:姓名-投稿

fd6e8a4457c6ee9bc8c673dda1ac0637.png

△长按添加PaperWeekly小编

🔍

现在,在「知乎」也能找到我们了

进入知乎首页搜索「PaperWeekly」

点击「关注」订阅我们的专栏吧

·

·

cea955ab1655285e9f497fd655ebb5a4.jpeg

http://www.lryc.cn/news/173212.html

相关文章:

  • Spark SQL【电商购买数据分析】
  • Google拟放弃博通自行研发AI芯片 | 百能云芯
  • 一百八十二、大数据离线数仓——离线数仓从Kafka采集、最终把结果数据同步到ClickHouse的完整数仓流程(待续)
  • 掌动智能:卓越性能的API接口测试工具
  • Flutter 基本概念
  • PHP包含读文件写文件
  • uniapp——实现base64格式二维码图片生成+保存二维码图片——基础积累
  • 【二叉树魔法:链式结构与递归的纠缠】
  • FL Studio21.0.3最新中文版下载安装详解
  • 【算法与数据结构】JavaScript实现十大排序算法(一)
  • IntelliJ IDEA使用——插件推荐
  • 编写一个会导致死锁的程序,将怎么解决?
  • Java JVM分析利器JProfiler 结合IDEA使用详细教程
  • 包含日志文件
  • 李航老师《统计学习方法》第2章阅读笔记
  • ruoyi框架修改左侧菜单样式
  • 【已解决】PyCharm里的黄色波浪线
  • 设计模式:策略模式(C++实现)
  • 网络安全深入学习第二课——热门框架漏洞(RCE—Thinkphp5.0.23 代码执行)
  • Pdf文件签名检查
  • web前端之float布局与flex布局
  • expected ‘,’ after expression in R【R错误】
  • 算法|图论 2
  • 使用C#实现服务端与客户端的简陋聊天
  • 生成式模型和判别式模型区别
  • 【kafka实战】03 SpringBoot使用kafka生产者和消费者示例
  • Only file and data URLs are supported by the default ESM loader
  • LeetCode01
  • 计算机网络高频面试题集锦
  • Linux启动过程详解 Xmind导图笔记