1. 大模型是如何生成答案的?
大模型生成答案的本质,是一个「根据上文预测下一个词」的循环过程。模型并不会像人一样先构思完整答案再输出,而是逐字逐词地生成,每一步都基于已经生成的内容和输入的问题,计算下一个最可能的词。
以「请介绍一下北京」为例,模型会先接收问题,然后依次预测「北京」「是」「中国」「的」「首都」......直到遇到结束符或达到长度上限。这个过程依赖模型内部的注意力机制,让模型能够关注到问题中的关键信息。
**案例:**假设你问大模型「1 加 1 等于几」,模型并不是在数据库里查答案,而是根据训练时见过的海量数学问答,推断出「2」是最合理的下一个词。这也是为什么模型对训练数据中高频出现的问题回答更稳定。
下面用一段 Python 代码演示「逐词预测」的循环过程。这里使用一个极简的字符级模型,模拟每一步根据上文预测下一个字符的逻辑:
python
import random
模拟一个极简的字符级语言模型
vocab = ["北", "京", "是", "中", "国", "的", "首", "都"]
def predict_next(context):
# 真实场景中这里会调用大模型,此处用随机模拟
return random.choice(vocab)
question = "请介绍一下北京"
context = question
answer = ""
for _ in range(6):
token = predict_next(context)
answer += token
context += token
print(f"当前上下文:{context}")
print(f"预测下一个词:{token}")
print("---")
print(f"最终生成:{answer}")
这段代码把「根据上文预测下一个词」的循环过程直观地展示出来:每一步都把新生成的词拼回上下文,再继续预测下一个词,直到达到长度上限。真实的大模型正是以类似的方式逐字生成答案。
输出结果:
text
当前上下文:请介绍一下北京
预测下一个词:北
---
当前上下文:请介绍一下北京北
预测下一个词:京
---
当前上下文:请介绍一下北京北京
预测下一个词:是
---
当前上下文:请介绍一下北京北京是
预测下一个词:中
---
当前上下文:请介绍一下北京北京是中
预测下一个词:国
---
当前上下文:请介绍一下北京北京是中
预测下一个词:国
---
最终生成:北京北京是中
可以看到,模型每一步都基于当前上下文预测下一个词,并把新词拼回上下文继续循环,直到达到长度上限。这就是大模型逐词生成答案的直观过程。
2. 控制大模型输出
为了让模型输出更符合预期,我们可以通过多种方式控制生成过程,常见手段包括提示词设计、温度参数、采样策略以及结构化输出约束。
2.1 概率是怎么来的?
模型在每一步生成时,都会为词表中的每个词计算一个概率分数,这些分数经过 softmax 归一化后形成概率分布。概率最高的词就是模型「最倾向」输出的词,但最终选择哪个词,还取决于采样策略。
下面用 Python 演示 softmax 归一化,直观展示「概率是怎么来的」:
python
import math
def softmax(scores):
exp_scores = [math.exp(s) for s in scores]
total = sum(exp_scores)
return [s / total for s in exp_scores]
假设模型对三个候选词给出的原始分数
scores = [2.0, 1.0, 0.1]
probs = softmax(scores)
words = ["北京", "上海", "南京"]
for word, prob in zip(words, probs):
print(f"{word}:{prob:.2%}")
运行后可以看到,原始分数经过 softmax 归一化后变成了和为 1 的概率分布,分数最高的「北京」获得最大的概率,这就是模型每一步生成时概率分布的来源。
输出结果:
text
北京:67.07%
上海:24.24%
南京:8.69%
可以看到,原始分数经过 softmax 归一化后变成了和为 1 的概率分布,分数最高的「北京」获得最大的概率,这就是模型每一步生成时概率分布的来源。
2.2 调整概率分布
直接使用概率最高的词(贪心解码)虽然稳定,但容易让输出变得机械、重复。为了让输出更自然,我们需要对概率分布进行调整,常见手段包括温度缩放和候选词过滤。
2.3 Temperature 温度:调整概率分布
温度参数(temperature)控制概率分布的「尖锐」程度。温度越低,概率分布越集中,模型越倾向于选择高概率词,输出更稳定;温度越高,概率分布越平坦,低概率词也有机会被选中,输出更多样。
**案例:**在写代码场景中,通常把温度设为 0,保证代码逻辑稳定;而在创意写作场景中,可以把温度调到 0.8 以上,让文案更有变化。比如用「温度 0」让模型生成一段 Python 排序代码,两次结果几乎一致;用「温度 1.2」生成同一段文案,两次结果会有明显差异。
下面用 Python 演示温度参数如何改变概率分布:
python
import math
def softmax_with_temperature(scores, temperature):
scores = [s / temperature for s in scores]
exp_scores = [math.exp(s) for s in scores]
total = sum(exp_scores)
return [s / total for s in exp_scores]
scores = [2.0, 1.0, 0.1]
words = ["北京", "上海", "南京"]
for temp in [0.2, 1.0, 2.0]:
probs = softmax_with_temperature(scores, temp)
print(f"温度 {temp}:")
for word, prob in zip(words, probs):
print(f" {word}:{prob:.2%}")
print()
可以看到:温度越低,概率分布越集中,「北京」几乎被锁定;温度越高,分布越平坦,低概率词也有机会被选中。这就是温度参数控制输出稳定性和多样性的原理。
输出结果:
text
温度 0.2:
北京:98.66%
上海:1.31%
南京:0.03%
温度 1.0:
北京:67.07%
上海:24.24%
南京:8.69%
温度 2.0:
北京:47.06%
上海:31.30%
南京:21.64%
可以看到:温度越低,概率分布越集中,「北京」几乎被锁定;温度越高,分布越平坦,低概率词也有机会被选中。这就是温度参数控制输出稳定性和多样性的原理。
2.4 Top-P / Top-K:过滤可选词
Top-K 只保留概率最高的 K 个词作为候选;Top-P(核采样)则保留累计概率达到 P 的最小候选词集合。两者都能过滤掉大量低概率的「噪声词」,让输出更聚焦。
**案例:**当模型回答「中国的首都是____」时,Top-P 设为 0.9 会让模型只在「北京」等少数高概率词中选择,避免输出「上海」「南京」等低概率干扰项。
下面用 Python 演示 Top-K 和 Top-P 的过滤逻辑:
python
def top_k_filter(probs, k):
# 按概率从高到低排序,只保留前 k 个
sorted_idx = sorted(range(len(probs)), key=lambda i: probs[i], reverse=True)
keep = sorted_idx[:k]
filtered = [probs[i] if i in keep else 0.0 for i in range(len(probs))]
return filtered
def top_p_filter(probs, p):
# 按概率从高到低累加,直到累计概率达到 p
sorted_idx = sorted(range(len(probs)), key=lambda i: probs[i], reverse=True)
cumulative = 0.0
keep = []
for i in sorted_idx:
keep.append(i)
cumulative += probs[i]
if cumulative >= p:
break
filtered = [probs[i] if i in keep else 0.0 for i in range(len(probs))]
return filtered
probs = [0.5, 0.2, 0.15, 0.1, 0.05]
words = ["北京", "上海", "南京", "广州", "深圳"]
print("Top-K(k=2):")
for w, p in zip(words, top_k_filter(probs, 2)):
print(f" {w}:{p:.2%}")
print("Top-P(p=0.8):")
for w, p in zip(words, top_p_filter(probs, 0.8)):
print(f" {w}:{p:.2%}")
Top-K 直接砍掉概率排名靠后的词,Top-P 则按累计概率动态决定保留哪些词。两者都能过滤掉低概率的「噪声词」,让模型输出更聚焦。
输出结果:
text
Top-K(k=2):
北京:71.43%
上海:28.57%
南京:0.00%
广州:0.00%
深圳:0.00%
Top-P(p=0.8):
北京:71.43%
上海:28.57%
南京:0.00%
广州:0.00%
深圳:0.00%
Top-K 直接砍掉概率排名靠后的词,Top-P 则按累计概率动态决定保留哪些词。两者都能过滤掉低概率的「噪声词」,让模型输出更聚焦。
2.5 如何配合使用这些参数
实际应用中,温度和 Top-P/Top-K 通常配合使用:先用 Top-P/Top-K 过滤掉明显不合理的候选词,再用温度调节剩余候选词的分布。这样既能保证输出的合理性,又能控制多样性。
下面用 Python 演示温度和 Top-P 配合使用的完整采样流程:
python
import math
import random
def sample_with_params(scores, temperature, top_p):
# 1. 温度缩放
scores = [s / temperature for s in scores]
exp_scores = [math.exp(s) for s in scores]
total = sum(exp_scores)
probs = [s / total for s in exp_scores]
# 2. Top-P 过滤
sorted_idx = sorted(range(len(probs)), key=lambda i: probs[i], reverse=True)
cumulative = 0.0
keep = []
for i in sorted_idx:
keep.append(i)
cumulative += probs[i]
if cumulative >= top_p:
break
filtered = [probs[i] if i in keep else 0.0 for i in range(len(probs))]
3. 从过滤后的候选词中采样
total_filtered = sum(filtered)
r = random.uniform(0, total_filtered)
acc = 0.0
for i, p in enumerate(filtered):
acc += p
if r <= acc:
return i
return len(filtered) - 1
scores = [2.0, 1.0, 0.5, 0.2, 0.1]
words = ["北京", "上海", "南京", "广州", "深圳"]
for _ in range(5):
idx = sample_with_params(scores, temperature=0.8, top_p=0.9)
print(f"采样结果:{words[idx]}")
这段代码完整演示了「先 Top-P 过滤、再温度缩放、最后采样」的配合流程。实际应用中,正是通过这样的组合,既保证输出合理,又保留一定的多样性。
输出结果(每次运行可能略有不同):
text
采样结果:北京
采样结果:上海
采样结果:北京
采样结果:南京
采样结果:北京
这段代码完整演示了「先 Top-P 过滤、再温度缩放、最后采样」的配合流程。实际应用中,正是通过这样的组合,既保证输出合理,又保留一定的多样性。
3. 大模型为什么会有幻觉?
幻觉是指模型生成了看似合理、实则与事实不符的内容。产生幻觉的原因主要有三点:一是训练数据本身存在噪声或错误;二是模型在生成时过度依赖概率推断,而非真实知识检索;三是模型缺乏对自身不确定性的判断能力。
3.1 让人又爱又恨的幻觉问题
幻觉是一把双刃剑。一方面,它让模型具备「创造性」,能够生成训练数据中不存在的合理内容;另一方面,它也让模型在事实性问题上「一本正经地胡说八道」,给实际应用带来风险。
3.2 AI 为什么一定会有幻觉?
当问题超出模型训练数据的覆盖范围,或问题本身带有误导性时,模型更容易「编造」答案。它并不是故意撒谎,而是为了生成连贯文本,被迫在不确定的地方补全内容。只要模型依赖概率生成,幻觉就无法完全消除。
**案例:**如果你问模型「某位虚构人物的生平」,模型可能会一本正经地编造出完整的经历、时间和地点,因为这些内容在概率上「看起来合理」。
3.3 如何控制 AI 的幻觉
虽然无法彻底消除幻觉,但可以通过以下方式显著降低其影响:一是使用检索增强生成(RAG),让模型基于真实资料回答;二是要求模型标注不确定的内容;三是在医疗、法律等高风险场景中引入人工审核。
4. 大模型记忆管理
大模型的「记忆」分为两类:一类是训练时固化在参数里的长期知识,另一类是对话过程中临时保存的上下文记忆。上下文记忆通常受窗口大小限制,超出窗口的早期内容会被截断或遗忘。
4.1 记忆的真相
模型本身并不具备「记忆」能力,它只是在每次生成时重新读取上下文。所谓记忆,其实是把历史对话内容拼接到当前输入中,让模型「看起来」记得之前说过的话。
4.2 记忆不是随便用的
上下文窗口是有限资源,塞入过多历史内容不仅会占用窗口,还可能稀释模型对当前问题的注意力。因此,记忆管理需要在「保留有用信息」和「节省窗口空间」之间做权衡。
4.3 管理记忆的常见思路
常见的做法包括滑动窗口、摘要压缩和向量检索记忆。滑动窗口只保留最近若干轮对话;摘要压缩把早期对话提炼成要点;向量检索则把历史内容存入向量数据库,需要时按语义召回。
**案例:**在客服机器人场景中,用户先咨询了订单问题,又聊到退款政策。如果采用滑动窗口,模型可能忘记订单号;而采用向量检索记忆,模型可以在后续回答中重新召回订单信息,给出更准确的答复。这就是记忆管理在实际产品中的价值。