深入理解大模型采样:Temperature、Top-K、Top-P 的原理与实战

深入理解大模型采样:Temperature、Top-K、Top-P 的原理与实战

本文从大模型"下一个词预测"的本质出发,结合 LangChain 代码实战,帮你彻底搞懂这三个控制生成随机性的核心参数。


参数 一句话 调小 调大
Temperature 控制概率分布的锐利程度 输出更确定、更保守 输出更随机、更有创意
Top-K 只保留概率最高的 K 个候选 候选越少越保守 候选越多越自由
Top-P 保留累积概率超过 P 的最小集合 候选越少越保守 候选越多越自由

核心原则:不要同时调 Temperature 和 Top-P,选一个调即可。


前言

你有没有好奇过:

  • 为什么同一个问题问 ChatGPT 两次,答案可能完全不同?
  • 为什么有时候 AI 回答很严谨,有时候又很"发散"?
  • 为什么写代码时建议用低 temperature,写小说时又建议用高 temperature?

这一切的答案,都藏在大模型的采样策略里。

读完本文,你将理解:

  1. 大模型"说话"的本质是概率采样
  2. 三个核心参数各自的数学原理和直觉理解
  3. 如何在实际项目中选择合适的参数组合
  4. 通过 LangChain 代码亲身感受不同参数的效果差异

一、大模型是怎么"说话"的?

1.1 下一个词预测

大语言模型(LLM)的核心任务其实很简单:预测下一个词

arduino 复制代码
输入:  "你好"
输出:  概率分布
        "吗"  → 0.6
        "啊"  → 0.15
        "呀"  → 0.1
        "美"  → 0.05
        "坏"  → 0.01
        ...(词表中所有 token 都有概率)

模型会对词表中每一个 token 计算一个概率(logit),然后通过 softmax 归一化为概率分布,最后从中采样一个 token 作为输出。

1.2 采样 = 选择的艺术

如果每次都选概率最高的那个词(贪心解码),输出会非常确定但单调

如果我们想让 AI 的回答更有创意、更自然,就需要引入随机性

Temperature、Top-K、Top-P 就是控制这种随机性的三个旋钮。下面我们逐一拆解。

1.3 采样流程全景图

在深入每个参数之前,先看一张完整的流程图,建立全局认知:

css 复制代码
模型输出 logits(未归一化的分数)
    │
    ▼
┌─────────────────────────┐
│  1. Temperature 缩放     │  ← 除以 T,调整分布的"锐利程度"
│     logits_i = logits_i / T │
└─────────────────────────┘
    │
    ▼
┌─────────────────────────┐
│  2. Softmax 归一化       │  ← 转为概率分布(所有 token 概率之和 = 1)
└─────────────────────────┘
    │
    ▼
┌─────────────────────────┐
│  3. Top-K 截断           │  ← 只保留前 K 个高概率 token
└─────────────────────────┘
    │
    ▼
┌─────────────────────────┐
│  4. Top-P 截断           │  ← 在剩余 token 中,保留累积概率 ≥ P 的最小集合
└─────────────────────────┘
    │
    ▼
┌─────────────────────────┐
│  5. 采样                 │  ← 从最终候选集中随机选一个 token
└─────────────────────────┘

注意:Temperature 在 Softmax 之前作用于 logits,Top-K 和 Top-P 在 Softmax 之后作用于概率分布。理解这个顺序很重要。


二、Temperature(温度):控制随机性的总开关

2.1 数学原理

Temperature 的公式非常优雅:

r 复制代码
P_i = exp(logit_i / T) / Σ exp(logit_j / T)

其中 T 就是温度参数。核心操作是:在 Softmax 之前,将每个 logit 除以 T

  • 当 T < 1 时,logit 之间的差距被放大,概率分布变得更"尖锐"
  • 当 T > 1 时,logit 之间的差距被缩小,概率分布变得更"平坦"

特殊情况:T = 0

当 T 趋近于 0 时,概率分布退化为 one-hot 向量(最高概率的 token 概率趋近 1,其余趋近 0),等价于贪心解码(Greedy Decoding)。很多框架(如 Hugging Face Transformers)在 temperature=0 时会直接切换为贪心解码,跳过采样。

2.2 直觉理解

你可以把 Temperature 想象成概率分布的"锐化/模糊"滤镜

Temperature 效果 比喻
T = 0 概率分布趋向 one-hot,等价于贪心解码 精准的手术刀
T = 1 保持原始概率分布 原图
T > 1 趋向均匀分布,每个词概率相等 万花筒

2.3 实际效果对比

假设原始概率分布是:[猫:0.4, 狗:0.3, 鱼:0.1, 鸟:0.05, 蛇:0.03, ...]

ini 复制代码
T = 0.2(低温)
→ [猫:0.85, 狗:0.12, 鱼:0.02, 鸟:0.005, ...]
→ 几乎必选"猫",非常确定

T = 1.0(原始)
→ [猫:0.4, 狗:0.3, 鱼:0.1, 鸟:0.05, ...]
→ 保持原始分布

T = 2.0(高温)
→ [猫:0.25, 狗:0.22, 鱼:0.15, 鸟:0.12, ...]
→ 分布变平,选到"鸟""蛇"的概率大大增加

用柱状图直观感受:

erlang 复制代码
原始分布 (T=1.0):
猫 ████████████████████ 40.0%
狗 ██████████████       30.0%
鱼 █████                10.0%
鸟 ██                    5.0%
蛇 █                     3.0%

低温 (T=0.2):
猫 █████████████████████████████████████████ 85.0%
狗 ██████                                    12.0%
鱼 █                                          2.0%
鸟 ▏                                          0.5%
蛇 ▏                                          0.2%

高温 (T=2.0):
猫 ████████████         25.0%
狗 ██████████           22.0%
鱼 ███████              15.0%
鸟 ██████               12.0%
蛇 █████                10.0%

可以看到:温度越低,概率越集中在最高概率的 token 上;温度越高,分布越平坦。

2.4 使用建议

场景 推荐 Temperature 理由
代码生成 0.0 ~ 0.2 代码需要精确,一个字符错了就报错
数据分析 0.1 ~ 0.3 数字和事实不能"创造"
通用对话 0.7 ~ 0.9 自然但不失准确
创意写作 0.8 ~ 1.2 需要发散思维和新颖表达
诗歌生成 1.0 ~ 1.5 越高越有"灵感"

三、Top-K 采样:限定候选池

3.1 原理

Top-K 的思路很直接:只保留概率最高的 K 个词,其他的全部丢弃

ini 复制代码
原始分布:[猫:0.4, 狗:0.3, 鱼:0.1, 鸟:0.05, 蛇:0.03, 虾:0.02, ...]

Top-K = 3
→ 只保留 [猫, 狗, 鱼]
→ 重新归一化:[猫:0.5, 狗:0.375, 鱼:0.125]
→ 从这三个词中采样

3.2 优点与局限

优点:

  • 有效过滤掉不合理的低概率 token(比如"你好"后面接"量子力学")
  • 简单直观

局限:

  • K 是固定的,无法自适应
  • 当模型很确定时(某个词概率 0.95),K=10 仍然保留 9 个不太合理的候选
  • 当模型不确定时(概率分布很平),K=10 可能砍掉很多合理的候选

3.3 什么时候用 Top-K?

Top-K 通常不单独使用,而是配合 Temperature 一起使用:

css 复制代码
先用 Top-K 过滤掉离谱的词 → 再用 Temperature 控制剩余词的随机性

四、Top-P(核采样):自适应的智能筛选

4.1 原理

Top-P(也叫 Nucleus Sampling)的策略更聪明:

按概率从高到低排序,选择累积概率刚好超过阈值 P 的最小 token 集合。

scss 复制代码
原始分布:[猫:0.4, 狗:0.3, 鱼:0.1, 鸟:0.05, 蛇:0.03, 虾:0.02, ...]

Top-P = 0.8
累积概率:
  猫       → 0.4  (未达 0.8)
  猫+狗    → 0.7  (未达 0.8)
  猫+狗+鱼 → 0.8  (达到 0.8 ✓)
→ 选择 [猫, 狗, 鱼] 作为候选集

4.2 Top-P vs Top-K 的核心区别

特性 Top-K Top-P
候选集大小 固定 K 个 动态,取决于概率分布
模型很确定时 仍保留 K 个候选 可能只保留 1 个候选
模型不确定时 可能砍掉合理候选 自动扩大候选集
自适应性

例子:

css 复制代码
场景 A:模型很确定
分布:[猫:0.95, 狗:0.03, 鱼:0.01, ...]

Top-K=5  → 保留 5 个候选(多余)
Top-P=0.9 → 只保留 [猫](自适应!)

场景 B:模型不确定
分布:[猫:0.2, 狗:0.2, 鱼:0.2, 鸟:0.2, 蛇:0.2]

Top-K=3  → 只保留 3 个(可能漏掉好选择)
Top-P=0.8 → 保留 4 个(自适应!)

4.3 推荐设置

场景 推荐 Top-P
精确任务(代码、数学) 0.1 ~ 0.3
通用对话 0.8 ~ 0.95
创意写作 0.9 ~ 1.0
不使用 Top-P(等价于关闭) 1.0

Top-P = 1.0 的含义:累积概率达到 100% 才停止,等价于不排除任何 token。这也是大多数 API 的默认值。


五、三者的组合使用

5.1 采样流程

在实际的 LLM 推理中,三个参数通常按顺序应用(与 1.3 节的全景图一致):

css 复制代码
原始 logits
    ↓
Temperature 缩放(除以 T,调整分布的锐利程度)
    ↓
Softmax(转为概率分布)
    ↓
Top-K 截断(只保留前 K 个高概率 token)
    ↓
Top-P 截断(在 Top-K 基础上,保留累积概率 ≥ P 的最小集合)
    ↓
采样(从最终候选集中随机选一个 token)

5.2 最佳实践:不要同时调多个

⚠️ 重要提示 :OpenAI 官方建议,temperaturetop_p 不要同时调优,选择一个即可。

原因很简单:两个参数都在控制随机性,同时调会互相干扰,让行为变得不可预测。

推荐策略:

yaml 复制代码
方案 A:只调 Temperature(最简单)
  - temperature: 0.7, top_p: 1.0(默认)

方案 B:只调 Top-P(推荐)
  - temperature: 1.0(默认), top_p: 0.9

方案 C:Temperature + Top-P(精细控制)
  - temperature: 0.8, top_p: 0.5
  - 高温度激发创意,低 Top-P 限制候选范围

5.3 参数组合速查表

场景 Temperature Top-P 效果
代码生成 0.0 0.1 最严谨,等价于贪心解码
数据分析 0.2 0.3 保守准确,不"创造"数据
通用对话 0.7 0.9 自然平衡,安全起点
创意写作 0.8 0.5 有创意但不跑偏
诗歌/故事 1.2 1.0 高度发散,随机性最大

六、LangChain 实战:用代码感受差异

理论讲完了,让我们用 LangChain 来实际感受一下不同参数的效果。

6.1 项目结构

bash 复制代码
t-demo/
├── main.mjs          # 主程序
├── .env              # 环境变量(API Key)
├── package.json
└── node_modules/

6.2 核心代码

javascript 复制代码
import 'dotenv/config';
import { ChatOpenAI } from '@langchain/openai';
import { StringOutputParser } from '@langchain/core/output_parsers';
import { PromptTemplate } from '@langchain/core/prompts';

// 创意模式:高温度 + 低 Top-P
const creativeModel = new ChatOpenAI({
    model: process.env.MIMO_MODEL,
    temperature: 0.8,   // 高随机性,激发创意
    topP: 0.5,          // 只保留累积概率 50% 的候选,更聚焦
    maxTokens: 600,
    apiKey: process.env.MIMO_API_KEY,
    configuration: {
        baseURL: process.env.MIMO_API_BASE_URL,
    }
});

// 严谨模式:低温度 + 低 Top-P
const preciseModel = new ChatOpenAI({
    model: process.env.MIMO_MODEL,
    temperature: 0.2,   // 低随机性,保守准确
    topP: 0.9,          // 保留更多候选,保证信息完整
    maxTokens: 600,
    apiKey: process.env.MIMO_API_KEY,
    configuration: {
        baseURL: process.env.MIMO_API_BASE_URL,
    }
});

// 提示词模板
const storyPrompt = PromptTemplate.fromTemplate(`
    请写一篇短篇散文,主题:{theme}
    风格温柔治愈,篇幅200字左右,不要分段,文字细腻有画面感。
`);

const outputParse = new StringOutputParser();

// 组装工作流(Chain)
const creativeChain = storyPrompt.pipe(creativeModel).pipe(outputParse);
const preciseChain = storyPrompt.pipe(preciseModel).pipe(outputParse);

// 运行对比
async function runWriteDemo() {
    const theme = "秋日山野晚风";

    console.log('--- 创意写作模式(temperature=0.8, topP=0.5)---');
    const creativeText = await creativeChain.invoke({ theme });
    console.log(creativeText);

    console.log('\n--- 严谨写作模式(temperature=0.2, topP=0.9)---');
    const preciseText = await preciseChain.invoke({ theme });
    console.log(preciseText);
}

runWriteDemo().catch(err => console.error(err));

代码说明

  • topP 是 OpenAI API 原生支持的参数。而 topK 不是 OpenAI 标准参数,部分模型提供商(如 Google Gemini)支持,但 OpenAI 和大多数兼容 API 不支持。如果你使用的是非 OpenAI 供应商,请查阅其文档确认支持的采样参数。
  • maxTokens 注意是复数形式 Tokens,不是 maxToken

6.3 运行结果对比

创意模式(temperature=0.8, topP=0.5)输出:

秋日的山野,晚风裹挟着桂花的甜香,从山谷深处缓缓涌来。夕阳把天边染成橘红,像打翻了调色盘。树叶沙沙作响,像是大自然在低语。远处炊烟袅袅,归鸟掠过金色的稻田...

严谨模式(temperature=0.2, topP=0.9)输出:

秋日的山野间,晚风轻拂过金黄的稻田,带来一丝凉意。远处的山峦在夕阳下呈现出深浅不一的轮廓,天边的云彩被染成了橙红色。山脚下的村庄升起袅袅炊烟,归鸟在空中盘旋...

对比分析:

维度 创意模式 严谨模式
修辞手法 大量比喻("打翻了调色盘"、"大自然在低语") 以白描为主("轻拂"、"深浅不一的轮廓")
用词风格 大胆、文学化 平实、注重事实描写
意象密度 高,画面感强 中等,叙述为主
适合场景 散文、诗歌、故事 报告、说明文、新闻稿

你也可以尝试修改参数,运行代码感受不同组合的效果。比如把 creativeModel 的 temperature 改为 1.2,看看输出会变得更"天马行空"还是更混乱。


七、高级话题:其他采样策略

7.1 Min-P 采样

Min-P 是一种较新的采样策略:

ini 复制代码
设定最小概率阈值 = p_min × max_prob

如果 max_prob = 0.4, p_min = 0.1
则阈值 = 0.04
所有概率 < 0.04 的 token 都被过滤

优点是阈值会随最高概率自适应调整

7.2 Repetition Penalty(重复惩罚)

防止模型陷入重复循环:

arduino 复制代码
已经生成过的 token,其概率会被乘以一个惩罚系数(如 0.9)
→ 生成过"的" → "的"的概率 × 0.9
→ 再次生成"的" → "的"的概率 × 0.9 × 0.9

7.3 Beam Search(束搜索)

保留多个候选序列,选择整体概率最高的:

arduino 复制代码
序列1: "秋日山野晚风轻拂"  → 总概率 0.35
序列2: "秋日山野晚风徐来"  → 总概率 0.32
序列3: "秋日山野晚风送爽"  → 总概率 0.28
→ 选择序列1

常用于翻译等需要全局最优的任务。


八、总结

8.1 一句话理解

参数 一句话 核心原理
Temperature 控制概率分布的"锐利程度" logits 除以 T,影响 Softmax 输出的集中度
Top-K 只保留概率最高的 K 个词 截断概率分布,丢弃低概率 token
Top-P 保留累积概率超过 P 的最小集合 自适应截断,分布集中时少选、分散时多选

8.2 最终建议

  1. 新手入门:只调 Temperature(0.0~1.5),其他用默认值
  2. 进阶使用:Temperature + Top-P 组合,覆盖大多数场景
  3. 生产环境:根据业务场景反复测试,找到最佳参数组合
  4. 切记:不要同时调 Temperature 和 Top-P,会互相干扰
  5. 调试技巧 :如果不确定选什么,从 temperature=0.7, top_p=0.9 开始,这是业界公认的"安全起点"

参考资料


互动话题:你在实际项目中用过哪些采样策略?在调参过程中踩过什么坑?欢迎在评论区分享交流。


觉得有用的话,点赞 + 收藏是对创作者最好的支持。

相关推荐
cd_949217211 小时前
2026 AI Agent 落地指南:除了搭建工具,你还需要配套的搜索基础设施
人工智能
武子康1 小时前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端
大模型码小白1 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
雪碧聊技术1 小时前
力扣 LCR 091. 粉刷房子 —— 动态规划入门详解
算法·动态规划
麻雀飞吧2 小时前
最新量化学习路径,交易认知和技术实现要并行
人工智能·python
北辰alk2 小时前
我用Seed Evolving做了个“代码遗产抢救者”和“旅行规划师”——一个开发者的双面实战日记
人工智能
腾渊信息科技公司2 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
人间凡尔赛2 小时前
WAIC 2026 落幕,AI Agent 开发已进入 Harness 架构时代
人工智能·架构