大模型原理探究0x00:大模型每次给出的答案为什么都有所不同?

42 阅读7分钟

你想过吗

我们在使用DeepSeek、豆包等AI软件时,是否发现每次输入同样的问题,得到的输出可能略有不同。这是为什么呢?明明我两次的输入都是一样的啊。

为什么

要去探究这个问题,就不得不回归到本质:是什么控制着大模型的内容生成?

在上一篇文章:站在AI风口的第一个AI程序:helloAI 中,我们实现了用Python连接通义千问大模型的简单chat。现在,我们再来看看发起大模型请求时的局部代码:

# 2. 发起流式请求
completion = client.chat.completions.create(
    # 模型名字,不可乱填!!!可参考各模型官网
    # model="qwen-plus",    # 阿里千问
    model="deepseek-v3.2",  # deepseek
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "iOS开发转型AI大模型应用开发该怎么学习?"}
    ],
    # 通过 extra_body 设置 enable_thinking 开启思考模式
    # extra_body={"enable_thinking": True},
    stream=True,
    stream_options={"include_usage": True}
)

显然,client.chat.completions.create中有很多配置,除了我们写的还有哪些配置呢?我们可以打开通义千问文档-OpenAI Chat作参考:

image.png

top_k 非OpenAI标准参数这里先不讨论,那么其他几个参数:什么采样温度、采样阈值看着都认识,但是到底什么意思?在大模型处理中怎么发挥作用的呢?

作为初学者看着晦涩难懂很正常,好在我们有一个heeloAI程序。我们可以实践一下看看他们的区别,这本身就会加深我们对这几个参数的理解。Talk is cheap,show you the code!

实践出真知

撸起袖子就是干

根据参数解释,temperaturetop_p控制文本多样性,我们重点关注这两个参数。presence_penalty控制重复度,显然很好理解。

在操作之前,带着问题去实践是一个很好的思路。至少,我看到这两个参数会有以下疑问:

  1. temperature到底怎么决定文本多样性的?

  2. 既然已经有了temperature,为什么还有个top_p参数?没有可以吗?如果不可以,他们之间是怎么协作的?

  3. 如果temperature=0,top_p=0.01,理论上生成的文本接近一个确定值,那么多次运行同一提示词,大模型输出会一定一致吗?

  4. 3的拓展:如果同一提示词两次的temperature和top_p一致,大模型输出会一定一致吗?

OK,接下来我们固定提示词:雨天的街道... 要求续写这个故事,得到的故事总字数在30字左右。 记录下我们程序运行的结果:

序号temperaturetop_poutputcomment
00.10.2雨天的街道,伞下两人相遇,水花轻溅,脚步却未停低t低p_1
10.10.2雨天的街道,伞下两人相遇,水花轻溅,脚步却未停低t低p_2
20.10.2雨天的街道,伞下两人相遇,水花轻溅,脚步却未停低t低p_3
30.10.8雨天的街道,伞下两人相遇,水花轻溅,脚步却未停低t高p-1
40.10.8雨天的街道,一把红伞下,两个身影渐渐靠近。低t高p-2
510.5雨天的街道,她撑伞走过,水洼里映出模糊的霓虹中t中p_1
610.5雨天的街道,一把红伞下,两颗心悄然靠近中t中p_2
71.60.2雨天的街道,伞下两人并肩,水洼映着朦胧街灯与渐远的背影高p低t-1
81.60.2雨天的街道,伞下偶然相遇,水洼映出两张模糊笑脸。高p低t-2
91.60.2雨天的街道,湿漉漉的街道,路灯映着水洼,一个撑红伞的身影渐行渐远高p低t-3
101.60.9雨天的街道,我看到了不该看的事情高p高t-1
111.60.9雨天的街道,迟归少年静静看水,那头是他走散的整个童年高p高t-2
121.60.9雨天的街道,孩童于涟漪的轻笑倒映中微笑着踩着水滩而过,恍如一地搖曳太陽。高p高t-3

思考ing

仔细观察上表的结果差异,显然我们可以得出:

  1. 低t低p时,故事意象:伞、人、水花、脚步,比较常见且多次生成结果一致
  2. 低t高p时,故事意象和1差不多,但是多次运行会有不同的结果
  3. 中t中p时,故事意象:新增霓虹、人物数量、心,且更加有故事性了(两颗心、她),同时逻辑也不混乱
  4. 高t低p时,更有故事感和画面感,叙事也比较自然;每次结果都不同
  5. 高t高p时,故事更加发散具有创意,但是好像也会有意料之外的问题
    • 我看了不该看的事情 ??什么鬼,和前面的文风直接大变
    • 少年静静看水,那头是他走散的整个童年 写得好有诗意,有创意
    • 孩童于涟漪的轻笑倒映中微笑着踩着水滩而过,恍如一地搖曳太陽 ?? 什么鬼?创意过头了吧,前面还勉强能读,后面直接繁体字而且句意不通啊

结合以上分析和API文档参数解释,我们可以大概反推出temperaturetop_p的意义(个人理解):

  • temperature:采样温度,是给全局定调

    • 值越高,产出越丰富越随机
    • 如果很低,即使top_p再高也不管用(见1-4)
    • 本质:大模型生成Token前,会计算候选词得分(logits),通过softMax函数得到概率分布。temperature本质是对logits进行了“缩放” (了解即可)
  • top_p:核采样阈值,是基于temperature做范围限制

    • 值越高,候选池越大,结果越多样、丰富
    • 基于temperature限制候选范围,结合使用防止混乱、无意义词加入
    • 本质:在选择下一个词时,会将候选词概率累加,只从概率总和为top_p的前n个词中选择概率最大的
  • Top_k:结合top_p,这里也不难理解。

    • 在候选池中选择生成的前k个词中选择概率最大的

综上,temperaturetop_p的互补性大于替代性:

  • 若只用temperature,高t可能导致无边界随机,一些意想不到甚至乱码的东西也可能被选中

  • 若只用top_p,低p可能导致单调重复,没有创意

  • 📢📢📢OpenAI GPT-4中建议:优先使用top_p(0.8-0.95),再使用temperature(0.5-1)进行微调

回到DeepSeek、豆包等AI软件

了解了大模型生成内容丰富性原理后,那么问题又来了:我们开头的疑问,DeepSeek、豆包等AI软件我们直接使用并没有设置temperature和top_p,为什么还是每次输出的结果不同???

我猜测哈:

  1. deepseek使用的是Moe机制,就是多专家协同处理一个问题。当第一次提出时,分析有专家A、B、C处理,当再次运行时本来也应该是A、B、C,但B在处理其他事情,这个时候让职责类似的F参与处理,也就是第2次是A、C、F处理的结果。所以可能有所不同。(个人猜测,未验证!!!)

  2. 生成策略的“最后1km”的不确定性,即使我们设置再使用temperature=0,每一步选择最高概率。但因为链路长度和计算复杂性,最终可能有相等概率的几个词,这里多选一的机制可能会造成差异。

    • 理由:硬件层的“浮点幽灵👻”问题,像OpenAI的词向量维度有12288,多重矩阵计算下必然存在小数点误差。这样就会使得(A+B)+C ≠ A+(B+C),产生蝴蝶效应继而引发上述问题
  3. 哈哈,关于这点,你有更好更确切的解释吗?欢迎👏大家评论讨论哈区🏻