温度、Top P 与采样参数

要点

  • Temperature(温度)控制输出的随机性,值越高越随机,越低越确定
  • Top P(核采样)控制候选 token 的范围,与 temperature 配合使用
  • 不同场景需要不同的参数设置:代码生成用低温度,创意写作用高温度
  • 其他参数:Top K、Frequency Penalty、Presence Penalty
  • 参数调优需要实验和测试,没有银弹
  • AI 项目应该提供参数配置接口,让用户根据需求调整

1. Temperature(温度)

1.1 概念

Temperature 控制 LLM 输出的随机性:

Temperature = 0: 确定性输出,总是选择概率最高的 token
Temperature = 1: 标准随机性
Temperature > 1: 更高的随机性和创造性

1.2 工作原理

LLM 输出的是 token 的概率分布:

输入: "今天天气"
 
概率分布:
- "很好": 0.4
- "不错": 0.3
- "晴朗": 0.2
- "糟糕": 0.1
 
Temperature = 0: 总是选择 "很好"
Temperature = 0.5: 更倾向选择高概率的 token
Temperature = 1: 按原始概率随机选择
Temperature = 2: 低概率的 token 也有机会被选中

1.3 使用示例

const response = await fetch('https://api.openai.com/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
  },
  body: JSON.stringify({
    model: 'gpt-4',
    messages: [{ role: 'user', content: '写一首诗' }],
    temperature: 0.8,  // 高温度,更有创造性
  }),
})

1.4 温度选择

Temperature适用场景特点
0 - 0.3代码生成、事实问答确定性强,可重复
0.3 - 0.7一般对话、摘要平衡创造性和一致性
0.7 - 1.0创意写作、头脑风暴更多样化
> 1.0极端创造性可能不连贯

2. Top P(核采样)

2.1 概念

Top P(也叫 nucleus sampling)控制候选 token 的范围:

Top P = 0.1: 只从概率最高的 10% token 中选择
Top P = 0.9: 从累积概率达到 90% 的 token 中选择
Top P = 1.0: 从所有 token 中选择(等同于不用 Top P)

2.2 工作原理

概率分布:
- "很好": 0.4
- "不错": 0.3
- "晴朗": 0.2
- "糟糕": 0.1
 
Top P = 0.5:
累积概率: 0.4 + 0.3 = 0.7 > 0.5
候选 token: ["很好", "不错"]
 
Top P = 0.9:
累积概率: 0.4 + 0.3 + 0.2 = 0.9
候选 token: ["很好", "不错", "晴朗"]

2.3 使用示例

const response = await fetch('https://api.openai.com/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
  },
  body: JSON.stringify({
    model: 'gpt-4',
    messages: [{ role: 'user', content: '讲故事' }],
    top_p: 0.9,
  }),
})

2.4 Temperature vs Top P

  • Temperature:调整整个概率分布的平滑度
  • Top P:限制候选 token 的范围

通常建议:

// 方式 1: 只用 Temperature
{ temperature: 0.7 }
 
// 方式 2: 只用 Top P
{ top_p: 0.9 }
 
// 方式 3: 同时使用(不推荐,可能冲突)
{ temperature: 0.7, top_p: 0.9 }

3. 其他采样参数

3.1 Top K

只从概率最高的 K 个 token 中选择:

// 某些模型支持(如 Claude)
{ top_k: 50 }  // 只从 top 50 个 token 中选择

3.2 Frequency Penalty

惩罚已经出现过的 token,降低重复:

{
  frequency_penalty: 0.5,  // -2.0 到 2.0
}
  • 正值:减少重复
  • 负值:鼓励重复
  • 0:不惩罚

3.3 Presence Penalty

鼓励新话题,惩罚已出现的内容:

{
  presence_penalty: 0.5,  // -2.0 到 2.0
}
  • 正值:鼓励新话题
  • 负值:鼓励重复话题
  • 0:不惩罚

3.4 参数对比

参数作用适用场景
Temperature控制随机性所有场景
Top P限制候选范围需要多样化输出
Frequency Penalty减少重复长文本生成
Presence Penalty鼓励新话题多话题对话

4. 场景化参数配置

4.1 代码生成

{
  temperature: 0.2,  // 低温度,确保代码正确
  top_p: 0.1,
  frequency_penalty: 0,
  presence_penalty: 0,
}

4.2 创意写作

{
  temperature: 0.9,  // 高温度,更多创造性
  top_p: 0.95,
  frequency_penalty: 0.3,  // 减少重复
  presence_penalty: 0.3,
}

4.3 事实问答

{
  temperature: 0,  // 确定性输出
  top_p: 0.1,
}

4.4 对话

{
  temperature: 0.7,  // 平衡
  top_p: 0.9,
}

4.5 摘要

{
  temperature: 0.3,  // 较低,保持一致性
  top_p: 0.5,
}

5. 动态参数调整

5.1 根据任务类型

function getSamplingParams(taskType: string) {
  const configs = {
    code: { temperature: 0.2, top_p: 0.1 },
    creative: { temperature: 0.9, top_p: 0.95 },
    factual: { temperature: 0, top_p: 0.1 },
    chat: { temperature: 0.7, top_p: 0.9 },
    summary: { temperature: 0.3, top_p: 0.5 },
  }
 
  return configs[taskType as keyof typeof configs] || configs.chat
}
 
app.post('/api/chat', async (c) => {
  const { message, taskType } = await c.req.json()
 
  const params = getSamplingParams(taskType)
 
  const response = await callLLM({
    messages: [{ role: 'user', content: message }],
    ...params,
  })
 
  return c.json(response)
})

5.2 根据用户偏好

// 用户设置
const userPreferences = {
  creativity: 'high',  // low, medium, high
}
 
function getParamsForUser(preference: string) {
  switch (preference) {
    case 'low':
      return { temperature: 0.3, top_p: 0.5 }
    case 'high':
      return { temperature: 0.9, top_p: 0.95 }
    default:
      return { temperature: 0.7, top_p: 0.9 }
  }
}

5.3 根据模型

function getParamsForModel(model: string) {
  // 不同模型可能需要不同的参数
  const configs = {
    'gpt-4': { temperature: 0.7, top_p: 0.9 },
    'gpt-3.5-turbo': { temperature: 0.7, top_p: 0.9 },
    'claude-3': { temperature: 0.7, top_p: 0.9 },
  }
 
  return configs[model as keyof typeof configs] || { temperature: 0.7 }
}

6. 参数调优

6.1 A/B 测试

// 测试不同的 temperature
async function testTemperature(message: string) {
  const temperatures = [0, 0.3, 0.5, 0.7, 0.9, 1.0]
 
  for (const temp of temperatures) {
    const response = await callLLM({
      messages: [{ role: 'user', content: message }],
      temperature: temp,
    })
 
    console.log(`Temperature ${temp}:`, response.choices[0].message.content)
    console.log('---')
  }
}

6.2 多次采样评估

async function evaluateTemperature(
  message: string,
  temperature: number,
  samples: number = 5
) {
  const responses = await Promise.all(
    Array(samples).fill(null).map(() =>
      callLLM({
        messages: [{ role: 'user', content: message }],
        temperature,
      })
    )
  )
 
  // 评估多样性
  const uniqueResponses = new Set(
    responses.map(r => r.choices[0].message.content)
  )
 
  const diversity = uniqueResponses.size / samples
 
  return {
    temperature,
    diversity,
    responses: responses.map(r => r.choices[0].message.content),
  }
}

6.3 自动调优

async function autoTuneParams(
  message: string,
  taskType: string
): Promise<{ temperature: number; top_p: number }> {
  // 根据任务类型和历史数据自动调整
  const history = await getTaskHistory(taskType)
 
  // 找到历史上效果最好的参数
  const bestParams = history
    .sort((a, b) => b.score - a.score)
    .slice(0, 10)
    .reduce((acc, item) => {
      acc.temperature += item.temperature
      acc.top_p += item.top_p
      return acc
    }, { temperature: 0, top_p: 0 })
 
  return {
    temperature: bestParams.temperature / 10,
    top_p: bestParams.top_p / 10,
  }
}

7. 最佳实践

7.1 默认值

// 通用默认值
const DEFAULT_PARAMS = {
  temperature: 0.7,
  top_p: 0.9,
  frequency_penalty: 0,
  presence_penalty: 0,
}

7.2 参数验证

function validateParams(params: any) {
  if (params.temperature < 0 || params.temperature > 2) {
    throw new Error('Temperature must be between 0 and 2')
  }
 
  if (params.top_p < 0 || params.top_p > 1) {
    throw new Error('Top P must be between 0 and 1')
  }
}

7.3 文档化

/**
 * 采样参数说明
 *
 * @param temperature - 控制随机性 (0-2)
 *   - 0: 确定性输出
 *   - 0.7: 平衡创造性和一致性
 *   - 1+: 高度随机和创造性
 *
 * @param top_p - 核采样范围 (0-1)
 *   - 0.1: 只从最可能的 token 中选择
 *   - 0.9: 从累积概率 90% 的 token 中选择
 *   - 1: 从所有 token 中选择
 */
interface SamplingParams {
  temperature?: number
  top_p?: number
  frequency_penalty?: number
  presence_penalty?: number
}

总结

Temperature、Top P 等采样参数控制 LLM 输出的随机性和创造性。不同场景需要不同的参数设置。

这一节涉及到的几个实践:

  1. Temperature:控制随机性,0 确定性,1+ 高创造性
  2. Top P:限制候选 token 范围,与 Temperature 配合
  3. 其他参数:Top K、Frequency Penalty、Presence Penalty
  4. 场景配置:代码用低温度,创意用高温度
  5. 动态调整:根据任务、用户、模型调整参数
  6. 参数调优:A/B 测试、多次采样、自动调优

采样参数是 AI 应用调优的关键。好的参数设置能让 AI 输出更符合预期。建议从默认值开始,根据实际效果逐步调整。

下一篇看结构化输出——让 AI 返回 JSON 等结构化数据。