当你向ChatGPT连续两次提出相同的问题,大概率会得到两个不同的回答。很多人知道这是温度参数在作怪,但把温度调到0就能保证确定性吗?答案是否定的。即使temperature=0,OpenAI的API仍然可能返回不同的结果,而你自己部署的开源模型在vLLM或SGLang上推理时,输出同样不稳定。

这个问题的技术根源远比想象中复杂。它涉及概率论、采样算法、GPU并行计算、浮点数精度,以及一个被广泛忽视的概念——批次不变性(batch invariance)。理解这些底层机制,不仅能帮助你在调试时少走弯路,更是构建可靠LLM应用的工程基础。

大模型输出的本质:从Logits到概率分布

语言模型并不会直接输出文字。每次推理时,模型最后一层产生的是一组原始分数,称为logits。假设词表大小为V,模型会输出V个logit值,每个值对应词表中一个token的"得分"。

这些logit本身不是概率。它们可以是负数,可以超过1,求和也没有任何意义。要将其转换为概率分布,需要经过softmax函数:

$$P(w_i) = \frac{e^{z_i}}{\sum_{j=1}^{V} e^{z_j}}$$

其中$z_i$是第$i$个token的logit值,$P(w_i)$是选择该token的概率。softmax的关键特性是:指数运算让所有值变为正数,归一化保证概率之和为1。

有了概率分布,下一步就是选择token。最简单的策略是贪婪解码(greedy decoding)——永远选择概率最高的那个token。这听起来合理,但实践中会产生严重问题。Holtzman等人在ICLR 2020的研究中发现,贪婪解码容易陷入重复循环,生成"我觉得…我觉得…我觉得…“这样的退化文本。

flowchart TB
    subgraph 输入处理
        A[输入文本] --> B[Tokenizer]
        B --> C[Token IDs]
    end
    
    subgraph 模型推理
        C --> D[Transformer层]
        D --> E[Logits<br/>原始分数]
    end
    
    subgraph 概率转换
        E --> F[Softmax]
        F --> G[概率分布]
    end
    
    subgraph 采样策略
        G --> H{选择策略}
        H --> I[贪婪解码]
        H --> J[温度采样]
        H --> K[Top-K采样]
        H --> L[Top-P采样]
        H --> M[Min-P采样]
    end
    
    subgraph 输出生成
        I --> N[下一个Token]
        J --> N
        K --> N
        L --> N
        M --> N
        N --> O[循环直到结束]
    end

温度参数:概率分布的对比度旋钮

温度参数(temperature)是控制输出多样性的核心参数。它的作用机制非常直接:在softmax之前,将所有logit除以温度值T:

$$P(w_i) = \frac{e^{z_i / T}}{\sum_{j=1}^{V} e^{z_j / T}}$$

温度的作用就像照片的对比度调节。低温度(如0.1)提高对比度,让高概率token变得更突出,低概率token趋于消失。高温度(如2.0)降低对比度,让概率分布趋于平坦,原本不太可能的token也获得更多机会。

以一个具体例子说明。假设模型预测"The mouse ate the…“的下一个词,四个候选token的logit分别为:

Token Logit T=1.0概率 T=0.2概率 T=2.0概率
cheese 3.0 68.6% 99.3% 50.6%
crumb 2.0 25.3% 0.7% 30.7%
cable 0.5 5.6% ~0% 14.5%
moon -2.0 0.5% ~0% 4.2%

当T=0.2时,“cheese"占据了99.3%的概率质量,输出几乎确定。当T=2.0时,即使是荒谬的"moon"也获得了4.2%的概率。这就是为什么高温度会产生更有创意但也更不可预测的输出。

温度不会移除候选token。即使T=0.001,词表中每个token理论上仍保留非零概率。这正是为什么需要配合截断采样策略使用。

graph LR
    subgraph 低温度 T=0.2
        A1[cheese: 99.3%]
        B1[crumb: 0.7%]
        C1[其他: ~0%]
    end
    
    subgraph 标准温度 T=1.0
        A2[cheese: 68.6%]
        B2[crumb: 25.3%]
        C2[cable: 5.6%]
        D2[moon: 0.5%]
    end
    
    subgraph 高温度 T=2.0
        A3[cheese: 50.6%]
        B3[crumb: 30.7%]
        C3[cable: 14.5%]
        D3[moon: 4.2%]
    end
    
    style A1 fill:#2ecc71
    style A2 fill:#27ae60
    style A3 fill:#229954
    style D3 fill:#e74c3c

采样策略的五年演进:从Top-K到Min-P

Top-K采样:硬性截断

Top-K采样由Fan等人在ACL 2018年提出,方法简单粗暴:将所有token按概率降序排列,只保留前K个,其余概率置零,然后重新归一化。

这种方法的根本缺陷在于K值的选择与上下文无关。对于"法国的首都是…“这样的问题,可能只有1-2个合理答案,K=50会引入大量噪音。而对于"我最喜欢的食物是…“这样的开放问题,K=50又可能截断了合理的答案。

flowchart LR
    A[概率分布] --> B[按概率排序]
    B --> C[保留前K个]
    C --> D[其余置零]
    D --> E[重新归一化]
    E --> F[从K个中采样]
    
    style C fill:#3498db
    style D fill:#e74c3c

Top-P(核采样):动态窗口

Holtzman等人在ICLR 2020提出核采样(nucleus sampling),根据模型置信度动态调整候选池大小:

  1. 将token按概率降序排列
  2. 累加概率直到达到阈值p(如0.95)
  3. 保留这些token,丢弃其余
  4. 重新归一化

对于高置信场景(如"法国的首都是…"),可能只需要1个token就能达到95%阈值。对于低置信场景,可能需要数百个token。这种自适应性让Top-P成为业界标准,OpenAI、Anthropic、Google的API都将其作为主要参数。

但Top-P也有隐藏缺陷。当模型真正困惑时(概率分布平坦),达到95%阈值需要包含大量低质量token——模型越困惑,Top-P引入的噪音越多。

Min-P:置信度缩放过滤

Nguyen等人在ICLR 2025(Oral)提出Min-P采样,其核心思想是:筛选阈值应该随模型置信度缩放。

$$\text{threshold} = \max(P) \times \text{min\_p}$$

只有概率高于此阈值的token才会被保留。当模型高度确信(如最大概率90%)时,阈值很高(min_p=0.1时为9%),只有强候选能通过。当模型困惑(最大概率只有5%)时,阈值很低(0.5%),允许更多选项。

场景 最高概率token P(max) 阈值(min_p=0.1) 效果
高置信 “Paris” 0.90 0.09 严格——只有强候选通过
低置信 “maybe” 0.05 0.005 宽松——保留更多选项

Min-P现已集成到llama.cpp、vLLM、HuggingFace Transformers、Ollama等主流推理框架,成为开源生态的默认选择。推荐的min_p值在0.05到0.1之间。

graph TB
    subgraph 高置信场景
        A1["Paris: 90%"]
        B1["London: 8%"]
        C1["Berlin: 2%"]
        D1["阈值 = 90% × 0.1 = 9%"]
        E1["结果: 只保留Paris"]
    end
    
    subgraph 低置信场景
        A2["maybe: 5%"]
        B2["perhaps: 4%"]
        C2["possibly: 3%"]
        D2["阈值 = 5% × 0.1 = 0.5%"]
        E2["结果: 保留所有候选"]
    end
    
    A1 --> D1
    B1 --> D1
    C1 --> D1
    D1 --> E1
    
    A2 --> D2
    B2 --> D2
    C2 --> D2
    D2 --> E2
    
    style D1 fill:#27ae60
    style E1 fill:#2ecc71
    style D2 fill:#f39c12
    style E2 fill:#f1c40f

Top-n-sigma:温度不变截断

Tang等人在ACL 2025提出Top-n-sigma,解决了一个被忽视的问题:温度耦合。

使用Top-P或Min-P时,改变温度会间接改变哪些token通过截断。更高的温度使概率分布更平坦,导致Top-P包含更多token——即使你的本意只是在相同候选中增加随机性。

Top-n-sigma直接在logit空间操作:

$$\text{threshold} = z_{\max} - n \times \sigma_z$$

其中$z_{\max}$是最大logit,$\sigma_z$是所有logit的标准差。由于最大值和标准差在除以温度时缩放相同,通过截断的token集合与温度无关。温度只影响幸存者之间的相对概率。

threshold = logits.max() - n * logits.std()
logits[logits < threshold] = float('-inf')

推荐默认值n=3.0。此方法已集成到llama.cpp的采样链中。

采样链的执行顺序:为什么同一参数在不同框架表现不同

当多个采样策略组合使用时,执行顺序会影响输出。llama.cpp的默认采样链(2026年初)是:

logits → penalties → dry → top_n_sigma → top_k → typical → top_p → min_p → xtc → temperature → sample

三个关键观察:

惩罚优先执行。重复惩罚、频率惩罚、存在惩罚在任何截断之前应用。这确保被惩罚的token在被Top-K或Top-P重新分配概率质量之前就已经被降权。

温度最后执行。在llama.cpp中,温度在最终随机采样之前应用。这意味着你可以使用高温度而不必担心引入噪音token——它们已经被上游截断采样器移除了。设置temperature=0会产生贪婪输出,无论Top-P或Min-P如何设置。

HuggingFace Transformers温度优先。这正是问题所在:同一参数值在不同框架产生不同输出。如果你在OpenAI API上调参,然后部署到vLLM或llama.cpp,行为会改变。必须在实际部署框架上验证。

flowchart LR
    subgraph llama.cpp采样链
        L1[Logits] --> L2[Penalties]
        L2 --> L3[DRY]
        L3 --> L4[Top-n-sigma]
        L4 --> L5[Top-K]
        L5 --> L6[Typical]
        L6 --> L7[Top-P]
        L7 --> L8[Min-P]
        L8 --> L9[XTC]
        L9 --> L10[Temperature]
        L10 --> L11[Sample]
    end
    
    subgraph HuggingFace采样链
        H1[Logits] --> H2[Temperature]
        H2 --> H3[Top-K]
        H3 --> H4[Top-P]
        H4 --> H5[Sample]
    end
    
    style L10 fill:#e74c3c
    style H2 fill:#e74c3c

种子参数:伪随机数生成器的状态控制

当温度大于0时,token选择涉及随机采样。种子(seed)参数控制这个随机过程的起点。

计算机中的"随机"实际上是伪随机(PRNG,Pseudo-Random Number Generator)。给定相同的种子,PRNG会产生完全相同的随机数序列。最常用的算法是Mersenne Twister(Python默认)和Xorshift。

以Python为例:

import random
random.seed(42)
print(random.random())  # 总是输出 0.6394267984578837
random.seed(42)
print(random.random())  # 再次输出 0.6394267984578837

在LLM推理中,种子决定了从概率分布中采样的结果。设置相同的种子、相同的温度、相同的输入,理论应该得到相同输出。

OpenAI的API通过seed参数和system_fingerprint字段配合使用:

response = client.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Hello"}],
    temperature=0,
    seed=42
)
print(response.system_fingerprint)  # 追踪后端配置变化

system_fingerprint是一个哈希值,反映模型后端的配置状态。如果OpenAI更新了后端,这个值会改变,提示你可能得到不同结果。

Temperature=0的谎言:为什么你的LLM仍然随机

到这里,一切似乎都说得通:设置temperature=0,模型执行贪婪解码,输出应该确定。但现实是,即使temperature=0,LLM API和开源推理服务器仍然可能返回不同结果。

一个普遍接受的解释是"并发+浮点数"假设:GPU高度并行化,多个线程同时计算,浮点加法不满足结合律$(a+b)+c \neq a+(b+c)$,累加顺序取决于哪个线程先完成,因此产生不确定性。

这个假设听起来合理,但Thinking Machines Lab在2025年的深度分析揭示了一个更惊人的真相。

浮点数的原罪:非结合性

首先理解浮点数为什么会"撒谎”。浮点数使用有限精度表示实数,加法不满足结合律:

(0.1 + 1e20) - 1e20  # 结果是 0.0
0.1 + (1e20 - 1e20)  # 结果是 0.1

使用3位有效数字的十进制类比:1230 + 23.4 = 1253.4,但只能保留3位,结果是1250。信息在每次不同量级数字相加时都会丢失。

一个极端例子:对于数组[1e-10, 1e-5, 1e-2, 1, -1, -1e-2, -1e-5, -1e-10],根据相加顺序不同,可以产生102种不同结果。

并发真的导致非确定性吗?

在GPU上执行相同的矩阵乘法,重复1000次:

A = torch.randn(2048, 2048, device='cuda', dtype=torch.bfloat16)
B = torch.randn(2048, 2048, device='cuda', dtype=torch.bfloat16)
ref = torch.mm(A, B)
for _ in range(1000):
    assert (torch.mm(A, B) - ref).abs().max().item() == 0  # 总是通过

结果完全一致。GPU确实高度并行,浮点加法确实不满足结合律,但每次运行结果相同

原因是现代GPU内核设计时已考虑确定性问题。大多数神经网络操作不需要原子加法(atomic add),而是使用确定性规约策略:每个核心独立完成计算,然后通过固定的层次结构(warp → block → 全局)合并结果。顺序是固定的,所以结果确定。

LLM前向传播涉及的所有内核(矩阵乘法、RMSNorm、Attention前向)都是运行到运行确定性的。

真正的元凶:批次不变性缺失

那么非确定性从何而来?

Thinking Machines Lab的分析指出了关键:内核是确定性的,但不具备批次不变性(batch invariance)

批次不变性意味着:对于批次中的每个元素,输出不应取决于批次大小,也不应取决于其他批次元素是什么。

实验验证:

import torch
torch.set_default_device('cuda')
B, D = 2048, 4096
a = torch.linspace(-1000, 1000, B*D).reshape(B, D)
b = torch.linspace(-1000, 1000, D*D).reshape(D, D)

# 单元素批次
out1 = torch.mm(a[:1], b)

# 完整批次
out2 = torch.mm(a, b)[:1]

print((out1 - out2).abs().max())  # tensor(1669.25) —— 差异巨大

同样的矩阵乘法,同样的第一个元素,批次大小不同导致结果不同。这是运行到运行确定性的——同一脚本多次运行结果相同——但当批次大小变化时,结果改变。

在推理服务中,服务器负载是用户不可控的变量。负载决定批处理大小,批处理大小决定内核执行配置,配置影响数值精度,最终导致同一请求得到不同结果。

flowchart TB
    subgraph 用户请求
        A[用户请求<br/>同样的问题]
    end
    
    subgraph 服务器状态
        B{当前负载}
        B -->|低负载| C[batch_size=1]
        B -->|高负载| D[batch_size=100]
    end
    
    subgraph 内核执行
        C --> E[数据并行策略<br/>单核处理]
        D --> F[Split-K策略<br/>多核分割规约]
    end
    
    subgraph 数值差异
        E --> G[规约顺序A]
        F --> H[规约顺序B]
        G --> I[结果X]
        H --> J[结果Y<br/>X≠Y]
    end
    
    A --> B

为什么内核会失去批次不变性?

核心原因是GPU性能优化。当批次大小很小时,内核需要调整并行策略以充分利用GPU算力。

RMSNorm的例子:标准策略是每个批次元素分配一个核心。当批次大小=2000时,GPU饱和,策略稳定。当批次大小=2时,大部分核心空闲,高效的实现会切换到"分割规约"策略——将单个元素的规约分散到多个核心。

分割规约改变了加法顺序,浮点非结合性导致数值差异。策略选择取决于批次大小,所以批次不变性被破坏。

矩阵乘法的例子:Tensor Core指令操作固定大小的块(如64×128×16)。当批次维度很小时,可能无法填充一个块,最优实现会切换到不同的指令或完全禁用Tensor Core。不同指令有不同的内部规约顺序。

Attention的例子:FlashAttention的标准策略是沿Query维度并行化。在解码阶段,Query长度=1,并行度不足,需要沿Key/Value维度分割(Split-KV/FlashDecoding)。同样,分割策略破坏了批次不变性。

flowchart TB
    subgraph RMSNorm
        R1[批次=2000<br/>每元素独立核心] --> R2[规约顺序固定]
        R3[批次=2<br/>分割规约] --> R4[规约顺序改变]
        R2 --> R5[结果确定]
        R4 --> R6[结果不同]
    end
    
    subgraph 矩阵乘法
        M1[大批次<br/>Tensor Core 64x128] --> M2[内部规约顺序A]
        M3[小批次<br/>标准指令] --> M4[内部规约顺序B]
        M2 --> M5[结果A]
        M4 --> M6[结果B]
    end
    
    subgraph Attention
        A1[Prefill<br/>Q维度并行] --> A2[单核规约]
        A3[Decode<br/>Split-KV] --> A4[多核规约]
        A2 --> A5[结果确定]
        A4 --> A6[结果不同]
    end
    
    style R5 fill:#27ae60
    style R6 fill:#e74c3c
    style M5 fill:#27ae60
    style M6 fill:#e74c3c
    style A5 fill:#27ae60
    style A6 fill:#e74c3c

学术研究的量化发现:非确定性有多严重

Breck Baldwin等人在arXiv论文中对temperature=0的非确定性问题进行了系统研究。他们对5个LLM、8个任务、zero-shot和few-shot两种设置各进行10次运行,发现:

准确率波动可达15%。同一模型、同一任务、相同输入,10次运行的最高准确率与最低准确率之差可达15%。

最佳与最差差距可达70%。如果为每个问题取10次运行中的最佳结果,与取最差结果相比,准确率差距最高达70%。

没有任何模型在所有任务上稳定。GPT-3.5 Turbo相对更稳定,Llama-3-70B则波动较大。

他们定义了两个量化指标:

  • TARr@N:N次运行中原始输出完全相同的比例
  • TARa@N:N次运行中解析后答案相同的比例

研究发现TARr@10(原始输出一致性)普遍很低,但TARa@10(答案一致性)较高。这意味着输出文本会有变化,但最终答案往往相同——不过这取决于任务类型,数学任务比导航任务更不稳定。

一个有趣的发现:输出长度与非确定性强负相关。输出越长,越不稳定。这暗示限制max_tokens可能是控制稳定性的实用方法。

graph LR
    subgraph 非确定性影响
        A[准确率波动<br/>最高15%] --> B[基准测试可信度下降]
        C[最佳最差差距<br/>最高70%] --> D[单一指标无意义]
        E[任务相关性] --> F[数学>导航>逻辑]
    end
    
    subgraph 相关性发现
        G[输出长度↑] --> H[稳定性↓]
        I[准确率↑] --> J[答案一致性↑]
    end
    
    style B fill:#e74c3c
    style D fill:#e74c3c
    style H fill:#f39c12

生产环境中的确定性解决方案

OpenAI API

response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages,
    temperature=0,
    seed=42
)
# 检查 system_fingerprint 是否变化
print(response.system_fingerprint)

记住:即使设置种子,OpenAI仍可能因后端更新返回不同结果。system_fingerprint变化是唯一提示。

PyTorch本地推理

import torch
import random
import numpy as np

# 设置所有随机种子
torch.manual_seed(42)
random.seed(42)
np.random.seed(42)

# 启用确定性算法
torch.use_deterministic_algorithms(True)

# 禁用cuDNN benchmark
torch.backends.cudnn.benchmark = False

# 可选:启用cuDNN确定性
torch.backends.cudnn.deterministic = True

torch.use_deterministic_algorithms(True)会让PyTorch在可能时使用确定性算法,在不可能时抛出错误。性能代价通常是10-30%。

vLLM推理服务

vLLM的实现已经注意到批次不变性问题:

# 禁用多进程调度,减少批次变化
VLLM_ENABLE_V1_MULTIPROCESSING=0 python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3-8b \
    --seed 42

关键是理解:vLLM的贪婪采样本身是确定性的,但批次不变性问题源于内核调度。

自定义内核实现批次不变性

要实现真正的批次不变性,需要确保:

  1. RMSNorm:始终使用数据并行策略,避免分割规约。对于小批次,接受部分核心空闲。

  2. 矩阵乘法:固定Tensor Core指令配置,避免根据批次大小切换。对大模型,N维度(模型维度)通常足够大,问题主要出在M维度(批次维度)很小时。

  3. Attention:在prefill阶段,确保KV cache和当前token一起处理,而不是分开。分开处理会改变规约顺序。

flowchart TB
    subgraph 确定性方案
        A[设置随机种子<br/>torch.manual_seed] --> B[启用确定性算法<br/>use_deterministic_algorithms]
        B --> C[禁用benchmark<br/>cudnn.benchmark=False]
        C --> D[固定批次大小<br/>避免动态调度]
    end
    
    subgraph 性能代价
        E[确定性算法] --> F[10-30%性能损失]
        G[固定批次大小] --> H[GPU利用率下降]
    end
    
    subgraph 适用场景
        I[调试/测试] --> J[完全确定性]
        K[生产推理] --> L[部分确定性<br/>接受一定波动]
    end
    
    style F fill:#f39c12
    style H fill:#f39c12
    style J fill:#27ae60
    style L fill:#3498db

实践建议:按场景选择参数

场景 温度 截断策略 理由
代码生成 0.0-0.2 Min-P 0.1 或 Top-P 0.95 语法要求精确,错误token导致编译失败
数学推理 0.0-0.3 Top-P 0.95 逻辑链需要一致性
事实问答 0.3-0.7 Min-P 0.1 平衡准确性与自然变化
一般对话 0.7-1.0 Min-P 0.05 或 Top-P 0.9 自然对话需要一些不可预测性
创意写作 1.0-1.5 Min-P 0.05 高多样性且不引入噪音
头脑风暴 1.2-1.8 Min-P 0.02-0.05 最大化多样性

开源部署的最佳实践:使用温度 + Min-P组合(Min-P 0.05-0.1),跳过Top-K和Top-P。这是llama.cpp和vLLM高级用户的共识。

商业API的最佳实践:温度 + Top-P(Top-P 0.9-0.95),因为OpenAI等不暴露Min-P。

推理模型(o1/o3)的特殊规则:OpenAI的推理模型锁定temperature=1.0和top_p=1.0,API请求中必须省略这些参数,否则报错。原因是推理模型运行多条思维链然后选择最佳,温度=0会导致所有路径坍缩到相同的贪婪路径。

非确定性的哲学思考

从工程视角看,非确定性是性能与一致性权衡的结果。分割规约、动态Tensor Core选择、Split-KV策略都是为了榨取GPU的每一点性能。放弃这些优化意味着10-30%的性能损失,在大规模部署中成本惊人。

从科学视角看,非确定性挑战了基准测试的有效性。如果同一模型在同一任务上的准确率可以波动15%,那么报告单一准确率数字有什么意义?研究者建议报告多次运行的置信区间,而不是单点估计。

从产品视角看,非确定性给下游系统带来了复杂性。解析器需要容忍格式变化,单元测试需要接受多样性,错误处理需要考虑"通常正确但这次错误"的情况。一个有4个95%稳定分类器的对话系统,期望性能仅为$0.95^4 = 81.5\%$——还没有计入分类器本身的准确率。

技术演进的时间线

timeline
    title LLM采样策略与确定性研究演进
    2018 : Top-K采样 (Fan et al., ACL)
    2019 : 重复惩罚 (CTRL论文)
    2020 : 核采样Top-P (Holtzman et al., ICLR)
         : 贪婪解码退化问题发现
    2021 : Mirostat自适应采样
    2022 : Typical采样
    2023 : 对比解码
         : 推测解码加速
    2024 : OpenAI引入seed参数
         : system_fingerprint机制
    2025 : Min-P采样 (Nguyen et al., ICLR Oral)
         : Top-n-sigma (Tang et al., ACL)
         : 批次不变性问题揭示 (Thinking Machines Lab)
         : 非确定性系统研究 (Baldwin et al.)

写在最后

LLM输出的随机性,表面看是温度参数控制的采样过程,深层则是GPU并行计算与浮点精度的碰撞,最底层的根源是批次不变性这一被忽视的工程现实。

理解这些机制的意义不仅在于调试,更在于建立正确的预期。LLM本质上是概率系统,即使temperature=0也无法保证完全确定性。在生产系统中,应该设计容忍多样性的架构,而不是追求绝对的输出一致性。

当你在API文档中看到seed参数时,记住它只能控制PRNG的起点,无法控制GPU内核的调度策略。当你在本地部署模型时,记住确定性需要牺牲性能。当你评估模型性能时,记住单次运行的准确率可能有15%的波动。

随机性不是bug,而是LLM作为概率系统的特性。学会与它共处,而不是试图消灭它。


参考文献

  1. Holtzman, A., et al. (2020). The Curious Case of Neural Text Degeneration. ICLR 2020.
  2. Fan, A., et al. (2018). Hierarchical Neural Story Generation. ACL 2018.
  3. Nguyen, T., et al. (2025). Min-P Sampling for Creative and Coherent LLM Outputs. ICLR 2025 (Oral).
  4. Tang, X., et al. (2025). Top-n-sigma: Temperature-Invariant Truncation. ACL 2025.
  5. Thinking Machines Lab. (2025). Defeating Nondeterminism in LLM Inference.
  6. Baldwin, B., et al. (2025). Non-Determinism of “Deterministic” LLM Settings. arXiv:2408.04667.
  7. NVIDIA. (2025). Controlling Floating-Point Determinism in NVIDIA CCCL.
  8. OpenAI. (2024). Advanced Usage Documentation - Reproducible Outputs.
  9. PyTorch. (2025). Reproducibility Documentation.
  10. Keskar, N.S., et al. (2019). CTRL: A Conditional Transformer Language Model. arXiv:1909.05858.
  11. Basu, S., et al. (2021). Mirostat: A Neural Text Decoding Algorithm. ICLR 2021.
  12. Meister, C., et al. (2022). Typical Sampling. TACL 2022.
  13. Li, X., et al. (2023). Contrastive Decoding. ACL 2023.
  14. Leviatan, Y., et al. (2023). Speculative Decoding. ICML 2023.
  15. Chen, C., et al. (2023). Accelerating LLM Inference with Speculative Decoding.
  16. Matsumoto, M., & Nishimura, T. (1997). Mersenne Twister.
  17. Marsaglia, G. (2003). Xorshift RNGs.
  18. vLLM Documentation. (2025). Reproducibility.
  19. HuggingFace. (2024). Decoding Strategies in Large Language Models.
  20. Dylan Castillo. (2024). Understanding Seed and Temperature in LLMs.
  21. NVIDIA CUDA Documentation. (2024). Floating Point and IEEE 754 Compliance.
  22. Biderman, S., et al. (2024). Lessons from Reproducible Evaluation of LLMs.
  23. Hendrycks, D., et al. (2021). Measuring Massive Multitask Language Understanding (MMLU).
  24. Suzgun, M., et al. (2023). Challenging BIG-Bench Tasks (BBH).
  25. Vaswani, A., et al. (2017). Attention Is All You Need (Transformer原论文).
  26. Dao, T. (2023). FlashAttention-2.
  27. Kwon, W., et al. (2023). Efficient Memory Management for LLM Serving (vLLM论文).
  28. NVIDIA. (2025). cuDNN Determinism.
  29. OpenAI Cookbook. (2024). Reproducible Outputs with Seed.
  30. llama.cpp Documentation. (2025). Sampler Chain.
  31. Ollama Documentation. (2025). Sampling Parameters.
  32. DeepSeek API Documentation. (2025). Temperature Mapping.
  33. Anthropic API Documentation. (2025). Claude Parameters.
  34. Google Gemini API Documentation. (2025). Sampling Settings.
  35. Meta. (2024). Llama 3 Technical Report.
  36. Wang, X., et al. (2023). Effect of Temperature on LLM Performance.
  37. Song, H., et al. (2024). LLM Variance Analysis.
  38. Ouyang, Z., et al. (2025). Instability Analysis of ChatGPT.
  39. NVIDIA GTC 2024. Reproducible Parallel Reductions.
  40. Brown, T., et al. (2020). Language Models are Few-Shot Learners (GPT-3论文).
  41. Wei, J., et al. (2022). Chain-of-Thought Prompting.
  42. Zhang, C., et al. (2024). Output Length and Stability Correlation.