大模型的问答工作流程

下面以“ACP is a very”为输入文本向大模型发起一个提问,下图展示从发起提问到输出文本的完整流程。
在这里插入图片描述

大模型问答流程分为5个阶段:

  1. 第一阶段:输入文本分词化
    分词(Token)是大模型处理文本的基本单元,通常是词语,词组或者符号。我们需要将"ACP is a very"这个句子分割成更小且具有独立语义的词语(Token),并且为每个Token分配一个ID。下图以通义千问示例:(通义千问的tokenizer实现细节:Tokenization
    在这里插入图片描述

  2. 第二阶段:Token向量化
    计算机只能理解数字,无法直接理解Token的含义。因此需要将Token进行数字化转换(即转化为向量),使其可以被计算机所理解。Token向量化会将每个Token转化为固定维度的向量。

  3. 第三阶段:大模型推理
    大模型通过大量已有的训练数据来学习知识,当我们输入新内容,比如“ACP is a very”时,大模型会结合所学知识进行推测。它会计算所有可能Token的概率,得到候选Token的概率集合。最后,大模型通过计算选出一个Token作为下一个输出。

  4. 第四阶段:输出Token
    由于大模型会根据候选Token的概率进行随机挑选,这就会导致“即使问题完全相同,每次的回答都略有不同”。为了控制生成内容的随机性,目前普遍是通过temperature和top_p这来调整的。
    例如,下图中大模型输出 的第一个候选Token集合为“informative(50%)”、“fun(25%)”、“enlightening(20%)”、“boring(5%)”。通过top_p参数,将影响大模型在候选Token集合中的选择倾向,如选择概率最高为“informative”。
    在这里插入图片描述
    特别地,“informative”会将继续送入大模型,用于生成候选Token。这个过程被称为自回归,它会利用到输入文本和已生成文本的信息。大模型采用这种方法依次生成候选Token。

  5. 输出文本
    循环第三阶段和第四阶段的过程,直到输出特殊Token(如,end of sentence,即“句子结束”标记)或输出长度达到阈值,从而结束本次问答。大模型会将所有生成的内容输出。当然你可以使用大模型的流式输出能力,即预测一些Token立即进行返回。这个例子最终输出“ACP is a very informative course.”。

影响大模型内容生成的随机生成参数

假设在一个对话问答场景中,用户提问为:“在大模型ACP课程中,你可以学习什么?”。为了模拟大模型生成内容的过程,我们预设了一个候选Token集合,这些Token分别为:“RAG”、“提示词”、“模型”、“写作”、“画画”。大模型会从这5个候选Token中选择一个作为结果输出(next-token),如下所示。

用户提问:在大模型ACP课程中,你可以学习什么?
大模型回答:RAG

在这个过程中,有两个重要参数会影响大模型的输出:temperature和top_p,它们用来控制大模型生成内容的随机性和多样性。下面介绍这两个参数的工作原理和使用方式。

temperature:调整候选Token集合的概率分布

在大模型生成下一个(next-token)之前,它会先为候选Token计算一个初始概率分布。这个分布表示每个候选Token作为next-token的概率。temperature是一个调节器,它通过改变候选Token的概率分布,影响大模型的内容生成。通过调节这个参数,你可以灵活地控制生成文本的多样性和创造性。
为了更直观地理解,下图展示了不同temperature值对候选Token概率分布的影响。
在这里插入图片描述
图中的低、中、高温度基于通义千问Max模型的范围[0,2]划分。
由上图可知,温度从低到高(0.1->0.7->1.2),概率分布从陡峭趋于平滑,候选Token“RAG”从出现的概率0.8->0.6->0.3,虽然依然是出现概率最高的,但是已经和其它的候选Token概率接近 ,最终输出也会从相对固定到逐渐多样化。
针对不同使用场景,可参考以下建议设置temperature参数:

  1. 明确答案(生成代码):调低温度

  2. 创意多样(如广告文案):调高温度

  3. 无特殊需求:使用默认温度(通常为中温度范围)

    需要注意的是当temperature=0时,虽然会最大限度降低随机性,但无法保证每次输出完全一致。下方示例在temperatur为0.7和1.9时的区别。如果想深入了解,可查阅(temperature的底层算法实现

temprature为0.7

import time

def get_qwen_stream_response(user_prompt, system_prompt, temperature, top_p):
    response = client.chat.completions.create(
        model="qwen-max",
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt}
        ],
        temperature=temperature,
        top_p=top_p,
        stream=True
    )
    
    for chunk in response:
        yield chunk.choices[0].delta.content

# temperature,top_p的默认值使用通义千问Max模型的默认值
def print_qwen_stream_response(user_prompt, system_prompt, temperature=0.7, top_p=0.8, iterations=10):
    for i in range(iterations):
        print(f"输出 {i + 1} : ", end="")
        ## 防止限流,添加延迟
        time.sleep(0.5)
        response = get_qwen_stream_response(user_prompt, system_prompt, temperature, top_p)
        output_content = ''
        for chunk in response:
            output_content += chunk
        print(output_content)

# 通义千问Max模型:temperature的取值范围是[0, 2),默认值为0.7
# 设置temperature=0
print_qwen_stream_response(user_prompt="马也可以叫做", system_prompt="请帮我续写内容,字数要求是4个汉字以内。", temperature=0)
输出 1 : 骏马
输出 2 : 骏马
输出 3 : 骏马
输出 4 : 骏马
输出 5 : 骏马
输出 6 : 骏马、坐骑。
输出 7 : 骏马
输出 8 : 骏马
输出 9 : 骏马
输出 10 : 骏马

temperature为1.3

# 设置temperature=1.9
print_qwen_stream_response(user_prompt="马也可以叫做", system_prompt="请帮我续写内容,字数要求是4个汉字以内。", temperature=1.9)
输出 1 : 骏马、坐骑。
输出 2 : 骏马。
输出 3 : 骏马
输出 4 : 马儿
输出 5 : 千里马。
输出 6 : 良驹、骏马
输出 7 : 骏马
输出 8 : 骏马、良驹
输出 9 : 骏马、驹。
输出 10 : 良驹或骏马。

从实验中可以明显观察到,温度值越高,模型生成的内容更具变化和多样性

top_p:控制候选Token集合的采样范围

top_p是一种筛选机制,用于从候选Token集合中选出符合特定条件的“小集合”。具体方法是:按概率从高到低排序,选取累计概率达到设定阈值的Token组成 新的候选集合,从而缩小选择范围。
下图展示了不同top_p值对候选Token集合的采样效果。
在这里插入图片描述
图示中蓝色部分表示累计概率达到top_p阈值(如0.5或0.9)的Token,它们组成新的候选集合;灰色部分则是未选中的Token。
当top_p=0.5时,模型优先选择最高概率的Token,即“RAG”;而当top_p=0.9时,模型会在“RAG”、“提示词”、“模型”这三个Token中随机选择一个生成输出。
由此可见,top_p值对大模型生成 内容的影响可总为:

  • 值越大:候选范围越广,内容更多样化,适合创意写作、诗生成等场景。
  • 值越小:候选范围越窄,输出更稳定,适合新闻初稿,代码生成等需要明确答案的场景。
  • 极小值(如:0.00001):理论上模型只选择概率最高的Token,输出非常稳定。但实际上,由于分布式系统、模型输出的额外调整等因素可能引入的微小随机性,仍无法保证每次输出完全一致。
    下面体验top_p的效果。通过调整top_p值,对同一问题提问10次,观察回答内容的波动情况。
# 通义千问Max模型:top_p取值范围为(0,1],默认值为0.8。
# 设置top_p=0.001
print_qwen_stream_response(user_prompt="为一款智能游戏手机取名,可以是", system_prompt="请帮我取名,字数要求是4个汉字以内。", top_p=0.001)
输出 1 : "智玩无界"
输出 2 : "智玩无界"
输出 3 : "智玩无界"
输出 4 : "智玩无界"
输出 5 : "智玩无界"
输出 6 : "智玩无界"
输出 7 : "智玩无界"
输出 8 : "智玩无界"
输出 9 : "智玩无界"
输出 10 : "智玩无界"
# 设置top_p=0.8
print_qwen_stream_response(user_prompt="为一款智能游戏手机取名,可以是",system_prompt="请帮我取名,字数要求是4个汉字以内。", top_p=0.8)
输出 1 : "智玩无界" 

这个名字既突出了手机的智能化特点,又强调了游戏体验的无限可能性。"智"代表智能,"玩"代表游戏,"无界"则寓意着使用这款手机玩游戏时,用户可以享受到无边界、无限制的乐趣与自由。同时,“无界”也暗示了这款手机在性能上没有界限,能够满足各种游戏需求。整体而言,这个名字简洁明了,易于记忆,并且富有吸引力。
输出 2 : "智玩无限" 

这个名字既突出了手机的智能特性,又强调了游戏的乐趣无边界。希望你喜欢!如果需要更多的建议,请随时告诉我。
输出 3 : "智游者Z1"
输出 4 : "智游者Z1"
输出 5 : "智玩无界" 

这个名字既突出了手机的智能特性,也强调了游戏功能带来的无限乐趣。同时,“无界”二字还寓意着使用这款手机可以打破常规限制,享受更加自由畅快的游戏体验。希望你喜欢!如果需要进一步调整或有其他要求,请随时告诉我。
输出 6 : "智玩无界"
输出 7 : "智游精灵"
输出 8 : "智游精灵"
输出 9 : "智玩魔方"
输出 10 : "智游精灵"

根据实验结果可以发现,top_p值越高,大模型的输出结果随机性越高。

小结

  • 是否需要同时调整temperature和top_p?
    为了确保生成 内容的可控性,vfyq不要同时调整top_p和temperature,同时调整可能导致输出结果不可预测。你可以优先调整其中一种参数,观察其对结果的影响,再逐步微调。

知识延展:top_k
在通义千问系列模型中,参数top_k也有类似top_p的能力,可查阅通义千问API文档。它是一种采样机制,从概率排名前k的Token中随机 选择一个进行输出。一般来说,top_k越大,生成内容越多样;top_k越小,内容则更固定。当top_k设置为1时,模型仅选择概率最高的Token,输出会更加稳定,但也会导致缺乏变化和创意。
知识延展:seed
在通义千问系列模型中,参数seed也支持控制生成内容的确定性,可查阅通义千问API文档。在每次模型调用时传入相同的seed值,并保持其他参数不变,模型会尽最大可能返回相同结果,但无法保证每次结果完全致。

  • 设置temperature、top_p、seed控制大模型输出,为何仍存在随机性?
    即使将temprature设置为0、top_p设置为极小值(如0.00001),并使用相同的seed,同一个问题的生成结果仍可能出现不一致。这是因为一些复杂因素可能引入微小的随机性,例如大模型运行在分布式系统中,或模型输出引入了优化
    举个例子:分布式系统就像用不同的机器切面包。虽然每台机器都按照相同的设置操作,但由于设备之间的细微差异,切出来的而面包片可能还是会略有不同。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐