被忽视的LLM伪随机性问题,贪心解码为什么无法消除它 【2023Q3】
TLDR
高质量、非创意性的场景下,尽量抑制策略的随机性问题很重要。
设置 temperature=0或者使用 贪心解码 等方式并不能解决该问题。
0、前言
LLM 解码decode的temperature参数其实是个老生常谈的问题了,很多人都知道,很多人也都觉得通过把temperature设置为0(或等价地使用贪心解码)能够消除LLM输出结果的随机性问题。
这让很多人觉得LLM输出结果的随机性是一个已经被解决的问题,但本文就是要批判这种观点。
那么策略有随机性是否是一个需要投大力气解决的问题呢?这个问题似乎并没有被认真讨论过,特别是放在现在Agent热潮下,开发高准确场景Agent的人可能注意到了幻觉问题,但并没有重视策略随机性的问题。这也是本文所要提醒的点。
1、什么场景排斥随机性
在很多场景(尤其是非效率目标的ChatBot)之中,用户讨厌一个死板、固定、每次一样的回答。在这些场景下用户期望多样性的回答。
但当我们使用一个顾问性质的专家系统时,我们期望系统给出一个准确且稳定的回答。我们可以接受一个医生有一定的误诊率,但不能接受一个医生现在的诊断和下一次独立session的诊断结果有显著不同。这就好像带了多块手表,每个表的时间都不同,让用户无所适从。作为系统的用户,一般只会开始怀疑系统的准确性。
想象两个系统,这两个系统的诊断准确率都是80%。但系统A每次都给出同样的回答,系统B每次给出的是有一定随机结果的回答,而总准确率仍然是80%。如果没有一个很理性、量化的评估,很多人还是会偏向更确定性的系统A的。可以说这是人类的一种认知偏误,或者说非理性偏好。
例如当开发一个法务虚拟员工Agent时候,客户是否能接受发现两次同样的询问结果不同呢?对于所有顾问类的场景,我自己是不太能接受每次使用时候得到的结果不同的方案。一般的用户也懒得(或者意识不到要)多次询问,然后综合这些结果。
2、temperature(和贪心解码)
按照简单的公式中,temperature只能取>0。但当temperature趋向于0的时候,输出的分布的极限就是概率最大(或logit最大)token的单值分布。当存在多个并列最大token时,是这些token的均匀离散分布。这时就是贪心解码方式。所以贪心解码只是temperature趋向于0的极限情况,为了简化行文,以下省略贪心解码。这个数学推导过程网上并没有看到科普文,考虑到本文读者也不在乎原理,更在乎使用,所以本文减少数学公式,略去这个的说明过程。
我们知道,在给定输入token序列的时候,如果设定temperature=0,那么输出(几乎)是确定的,只有少量正好碰到并列最大概率token的情况。当模型的量化程度加深时,更容易碰到这种并列最大概率的情况。
但这能够从应用的角度上来说解决策略的随机性问题么?不能。
用户的输入虽然是文本,但用户是按照语义对于输入的相似性进行判定的。只要是同样的意思,那么就可以认为是相同的输入。但同样意思的两个不同的token序列都输入到模型中并按temperature=0进行采样,结果仍然是语义上一致的么?这个问题并不显然,大家可以自己在自己的场景上进行实验。
结论是,一般都不是。输出的结果对于输入的token序列的细节比较敏感,输入上对语义没有影响的少量变化就可能在输出中导致影响语义的变化。我把这种随机性表现称之为LLM的【伪随机性】。这跟伪随机数生成算法是类似的,虽然算法是确定的,但输出却表现出随机性。一般输出越长、问题描述越模糊,就越容易出现这种伪随机性的表现。
我测试了gpt-3.5-turbo-0613和gpt-4-0613版本,它们都仍然对于输入的微小措辞调整有些敏感。虽然不至于完全不同,但足以通过偏差逐步累计的方式显著影响需要多次调用LLM模型的复杂策略的最终结果。
2.1、多样性 与 确定性 的平衡
大家已经知道:如果希望增加结果的多样性,那么应该适当增大temperature。
但是否存在既需要确定性,也需要足够的探索宽度(也是一种多样性)的场景呢?是存在的。例如说,希望能够完整地考虑分析某个问题的各方面视角,进行分析讨论,最终输出一个高质量观点的场景。
这个时候就比较两难。
一种常见的思路是:使用temperature=0,并在后续不断追问【还其他XX么?】的方式让模型增加多样性观点输出。但目前的LLM更倾向于输入与之前类似的内容,多样性差于“使用更大的temperature开新的session进行回答”。这种方式的多样性不足,同时也没能解决用户输入微小改变导致的结果变化的伪随机性问题。
3、通过平均 来抑制随机性和伪随机性
从科学或数学的角度上其实有一种应对该问题的方式:多次采样取平均。在这里也可以借鉴这个思路。
不过会有个问题,我们是否能够对LLM的输出结果进行平均或者加权?两种情况都有。
如果我们能把LLM输出的语义对应到固定一些选项或者情况上,那么就可以采用投票vote的方式来聚合多次调用LLM的结果。
但在很多情况下,做不到这么简单。LLM的输出仍然是一个非结构化的语义文本。为了聚合多次采样的不同结果,我们仍然只能依赖LLM进行聚合。而这个聚合的过程本身也会面对LLM自身伪随机性的问题,这个聚合过程的伪随机性抑制,我们还需要再加一层(甚至几层)类似多次采样和聚合,期望聚合的结果能够越来越稳定。
但这个方式会导致对于LLM的调用量快速飞涨。我自己在一个问题尝试上的结果是:原本1次的LLM调用,可能需要2层聚合,总计接近30次左右的调用。如果实现的策略再精细一些,总调用量还会成倍增长。这种策略如果是调用gpt-3.5-turbo跑一次就可能花费几RMB,一般人真的未必想花这么多钱去用,开发人员的测试成本也高的吓人。
目前在我来看,现状是勉强能通过这种方式来做,但成本可能上升2个数量级。一般的场景都无法接受。不得不说,这对于做高准确率LLM-native应用的场景都是一个打击。
交流与合作
如果希望和我交流讨论,或参与相关的讨论群,或者建立合作,请私信联系,见 联系方式。
希望留言可以到知乎对应文章下留言。
本文于2023.9.19首发于微信公众号与知乎。
知乎链接 https://zhuanlan.zhihu.com/p/657136667