当你问一个大语言模型"法国的首都是哪里?",它回答"巴黎"。这个看似简单的过程背后,模型经历了一系列复杂的计算。在最终的文字出现之前,模型首先要给出一个答案:对于词表中的每一个词,它认为这个词作为下一个输出的可能性有多大。这个"可能性"的原始形式,就是logits。
Logits是神经网络输出的最原始数据,是所有后续处理——概率转换、采样、解码——的起点。理解logits,就是理解神经网络如何"思考"的第一步。
一个被误解的概念
在深度学习社区,“logits"这个词的使用常常让初学者困惑。如果你去翻阅PyTorch的CrossEntropyLoss文档,会发现它明确要求输入是"logits”,而不是经过softmax的概率值。TensorFlow的softmax_cross_entropy_with_logits函数名称更是直接把两个概念绑在了一起。
那么,logits到底是什么?
从最直观的角度理解:logits是神经网络最后一层的原始输出值,它们代表了模型对每个类别的"偏好程度",但还不是概率。
考虑一个简单的三分类问题:猫、狗、鸟。神经网络最后一层可能输出三个数值:[2.3, -0.5, 1.1]。这三个数就是logits。数值越高,代表模型认为这个类别越可能是正确答案。但如果你问"猫的概率是多少",这个2.3并不能直接回答——它不是概率,没有归一化,也不在[0, 1]区间内。
这个原始输出值有两个关键特性:
无界性:logits可以是任意实数,从负无穷到正无穷。一个logit值为-100并不意味着"绝对不可能",同样100也不代表"绝对确定"。
相对性:logits的意义在于它们的相对大小关系。[2.0, 1.0, 0.5]和[20.0, 10.0, 5.0]代表了相同的偏好顺序,经过softmax后会得到完全相同的概率分布。
从统计学继承的名字
“Logit"这个词并非深度学习的发明,它来自统计学领域,是"log-odds"的缩写形式。
在统计学中,给定一个事件发生的概率$p$,它的odds(几率)定义为:
$$\text{odds} = \frac{p}{1-p}$$几率表示的是"事件发生"与"事件不发生"的比率。如果下雨的概率是0.75,那么odds就是0.75/(1-0.75) = 3,意味着"下雨的可能性是不下雨的3倍”。
而logit,就是对几率取对数:
$$\text{logit}(p) = \log\left(\frac{p}{1-p}\right)$$这个变换有一个美妙的性质:它把范围在$[0, 1]$的概率,映射到了整个实数域$(-\infty, +\infty)$。概率为0.5时,logit是0;概率趋近于0时,logit趋向负无穷;概率趋近于1时,logit趋向正无穷。
这个变换在逻辑回归中至关重要。逻辑回归本质上是在线性模型的输出上套一个sigmoid函数,将线性预测值(logits)转换为概率。深度学习继承了这套术语,但含义已经泛化——在现代神经网络语境中,“logits"泛指最后一层线性变换的输出,无论后续是否真的对应于log-odds。
graph LR
subgraph 概率空间
A["p = 0.01"] --> B["p = 0.5"]
B --> C["p = 0.99"]
end
subgraph Logit空间
D["logit ≈ -4.6"] --> E["logit = 0"]
E --> F["logit ≈ 4.6"]
end
A -.->|logit变换| D
B -.->|logit变换| E
C -.->|logit变换| F
style A fill:#ffcccc
style C fill:#ccffcc
style D fill:#ffcccc
style F fill:#ccffcc
神经网络中的Logits:架构视角
理解logits在神经网络中的位置,需要看清整个网络的"数据流”。
graph LR
A[输入层] --> B[隐藏层]
B --> C[最后一层隐藏状态]
C --> D[线性投影层]
D --> E[Logits向量]
E --> F[Softmax/Sigmoid]
F --> G[概率分布]
G --> H[采样/解码]
H --> I[最终输出]
style E fill:#ffeb3b
style G fill:#4caf50
对于一个语言模型,这个过程更加具体:
隐藏状态维度:假设模型最后一层输出的隐藏状态维度是$d$(比如GPT-2 small是768,GPT-3是12288)。
词表大小:模型的词表包含$V$个token(比如GPT-2是50257,LLaMA是32000)。
线性投影:最后一层隐藏状态通过一个线性层,将$d$维向量投影到$V$维空间:
$$\text{logits} = h \cdot W_{lm\_head} + b_{lm\_head}$$其中$W_{lm\_head}$的形状是$[d, V]$,$b_{lm\_head}$的形状是$[V]$。
输出结果:得到的logits向量长度为$V$,每个元素对应词表中一个token的"原始得分"。
这个线性投影层是模型参数量最大的层之一。以LLaMA-70B为例,隐藏状态维度是8192,词表大小是32000,这一层就包含了约2.6亿个参数,占整个模型参数量的相当大比例。
从Logits到概率:Softmax的数学
有了logits,下一步是将其转换为有意义的概率。这正是softmax函数的工作。
Softmax的定义:
$$\text{softmax}(z_i) = \frac{e^{z_i}}{\sum_{j=1}^{V} e^{z_j}}$$这个公式做了三件事:
指数化:$e^{z_i}$将可能为负的logits转换为严格正值。这也是为什么叫"soft"max——它在取最大值的同时,保留了非最大值的信息。
归一化:除以总和$\sum e^{z_j}$确保所有概率之和为1。
放大差异:指数函数具有放大效果。如果两个logits相差1,它们的概率比值约为$e \approx 2.7$倍;相差2,比值约为$e^2 \approx 7.4$倍。
graph TB
subgraph Logits空间
L1["Token A: 2.0"]
L2["Token B: 1.0"]
L3["Token C: 0.5"]
end
subgraph 指数化后
E1["e^2.0 = 7.39"]
E2["e^1.0 = 2.72"]
E3["e^0.5 = 1.65"]
end
subgraph 概率空间
P1["P = 0.628"]
P2["P = 0.231"]
P3["P = 0.141"]
end
L1 -->|"exp()"| E1
L2 -->|"exp()"| E2
L3 -->|"exp()"| E3
E1 -->|归一化| P1
E2 -->|归一化| P2
E3 -->|归一化| P3
考虑一个具体例子:
Logits: [2.0, 1.0, 0.5]
exp: [7.39, 2.72, 1.65]
Sum: 11.76
Probabilities: [0.628, 0.231, 0.141]
第一个token的logit比第二个高1.0,但概率却是后者的2.7倍。这就是softmax的"赢家通吃"效应——微小的logit差异会被放大成显著的概率差异。
二分类的特殊情况:Sigmoid
对于二分类问题,softmax可以简化为sigmoid函数:
$$\sigma(z) = \frac{1}{1 + e^{-z}}$$在二分类中,通常只需要一个logit值,表示"正类"的得分。概率计算如下:
- $P(\text{正类}) = \sigma(z) = \frac{1}{1+e^{-z}}$
- $P(\text{负类}) = 1 - \sigma(z) = \frac{e^{-z}}{1+e^{-z}}$
这种简化在某些场景下很有用,比如多标签分类,每个标签的判断都是独立的二分类问题。
温度参数:控制Logits的"性格"
直接对logits应用softmax会产生一个"自信"的分布——最高的概率会非常高,其他选项被压制。但在某些场景下,我们希望模型更"开放",给其他选项更多机会。
温度参数$T$的引入改变了softmax的计算方式:
$$\text{softmax}(z_i, T) = \frac{e^{z_i/T}}{\sum_{j=1}^{V} e^{z_j/T}}$$温度的效果:
$T = 1$:标准softmax,保持原始分布。
$T \rightarrow 0$:分布变得极端尖锐,接近于取最大值(argmax)。模型变得非常"确定"和"保守"。
$T \rightarrow \infty$:分布变得非常平坦,接近于均匀分布。模型变得非常"随机"和"创造"。
graph LR
subgraph 原始Logits
A["[4.0, 2.0, 1.0]"]
end
subgraph "T = 0.5 低温"
B["[0.975, 0.022, 0.003]"]
end
subgraph "T = 1.0 标准"
C["[0.844, 0.114, 0.042]"]
end
subgraph "T = 2.0 高温"
D["[0.628, 0.231, 0.141]"]
end
subgraph "T = 10.0 极高温"
E["[0.390, 0.332, 0.278]"]
end
A --> B
A --> C
A --> D
A --> E
style B fill:#ffcdd2
style E fill:#c8e6c9
用一个例子说明:
原始Logits: [4.0, 2.0, 1.0]
T = 1.0: 概率 = [0.844, 0.114, 0.042] # 很确定第一个
T = 0.5: 概率 = [0.975, 0.022, 0.003] # 几乎只选第一个
T = 2.0: 概率 = [0.628, 0.231, 0.141] # 第二、三个有更多机会
T = 10.0: 概率 = [0.390, 0.332, 0.278] # 接近均匀,几乎随机选
温度参数的实际意义:
代码生成、数学推理:通常使用较低温度(0.1-0.3),减少随机性,追求准确。
创意写作、头脑风暴:使用较高温度(0.7-1.0),增加多样性。
科学论文生成:使用中等温度(0.4-0.6),平衡准确性和流畅性。
温度的数学本质是对logits进行整体缩放。logits / T意味着:当T>1时,所有logits被缩小,它们的差异也被缩小,分布变得更平;当T<1时,logits被放大,差异被扩大,分布变得更尖锐。
Logits处理技术
在实际应用中,我们常常需要对logits进行干预,以控制模型的输出行为。
Logit Bias:直接干预概率
Logit bias是一种简单但强大的技术:在softmax之前,给特定token的logit加上一个偏置值。
$$z'_i = z_i + b_i$$如果$b_i > 0$,token $i$被选中的概率会增加;如果$b_i < 0$,概率会减少。当$b_i$是一个很大的负数(如-100),该token几乎不可能被选中。
graph LR
A[原始Logits] --> B[应用Logit Bias]
B --> C[调整后Logits]
C --> D[Softmax]
D --> E[采样]
subgraph Logit Bias示例
F["token: 暴力"] --> G["bias = -100"]
H["token: 和平"] --> I["bias = +5"]
end
style B fill:#fff3e0
style G fill:#ffcdd2
style I fill:#c8e6c9
应用场景:
-
禁止特定词汇:在内容过滤场景,将敏感词的logit设为极低值。
-
强制JSON格式:增加
{、}、"等token的logit,减少换行符的logit,引导模型生成结构化输出。 -
领域适应:在特定领域生成中,增加领域相关词汇的概率。
Top-k和Top-p采样:限制候选空间
即使设置了温度,模型仍然可能选择概率很低但内容不合适的token。Top-k和Top-p采样提供了额外的控制手段。
Top-k采样:只保留概率最高的k个token,将其余的logit设为负无穷。
def top_k_filtering(logits, k):
# 找到第k大的值
top_k = torch.topk(logits, k)
# 将低于第k大的值设为负无穷
indices_to_remove = logits < top_k.values[-1]
logits[indices_to_remove] = -float('inf')
return logits
Top-p(Nucleus)采样:保留累积概率达到p的最小token集合。
def top_p_filtering(logits, p):
# 按概率降序排列
sorted_logits, sorted_indices = torch.sort(logits, descending=True)
sorted_probs = torch.softmax(sorted_logits, dim=-1)
# 计算累积概率
cumulative_probs = torch.cumsum(sorted_probs, dim=-1)
# 找到累积概率超过p的位置
sorted_indices_to_remove = cumulative_probs > p
# 保留第一个超过p的token(确保至少有一个候选)
sorted_indices_to_remove[..., 1:] = sorted_indices_to_remove[..., :-1].clone()
sorted_indices_to_remove[..., 0] = False
# 将要移除的token设为负无穷
indices_to_remove = sorted_indices_to_remove.scatter(0, sorted_indices, sorted_indices_to_remove)
logits[indices_to_remove] = -float('inf')
return logits
graph TB
subgraph Top-k采样 k=3
A1["原始概率分布"]
A2["保留前3个"]
A3["其余设为-inf"]
A1 --> A2 --> A3
end
subgraph Top-p采样 p=0.9
B1["原始概率分布"]
B2["按概率排序"]
B3["累积概率达到0.9"]
B4["动态保留候选"]
B1 --> B2 --> B3 --> B4
end
style A3 fill:#c8e6c9
style B4 fill:#c8e6c9
Top-p的优势在于自适应性:如果分布很集中(一个token概率0.9),只需要很少的token就达到p;如果分布很分散,会保留更多候选。
重复惩罚
模型有时会陷入重复生成相同内容的模式。重复惩罚通过动态调整logits来缓解这个问题:
$$z'_i = z_i - \alpha \cdot \text{count}(i)$$其中$\alpha$是惩罚系数,$\text{count}(i)$是token $i$在已生成文本中出现的次数。
Logits与训练:交叉熵损失
在训练阶段,logits是损失函数的直接输入。交叉熵损失是最常用的选择:
$$\mathcal{L} = -\sum_{i=1}^{V} y_i \log(p_i) = -\log(p_{\text{target}})$$其中$y$是真实标签的one-hot编码,$p$是softmax后的概率。
为什么用logits而不是概率?
PyTorch的CrossEntropyLoss文档明确要求输入是logits,内部会自动应用log_softmax。这是因为:
- 数值稳定性:分开计算softmax和log会导致数值问题。当某个logit非常大时,$e^{z_i}$会溢出。
log_softmax使用LogSumExp技巧避免这个问题:
其中$a = \max_i z_i$。
- 梯度计算简化:softmax + 交叉熵的组合有一个优雅的梯度公式:
这个公式极其简洁:梯度就是预测概率与真实标签的差值。这大大简化了反向传播的实现。
graph LR
subgraph 正确方式
A1[Logits] --> B1["CrossEntropyLoss"]
B1 --> C1[Loss]
D1["内部: log_softmax + nll_loss"]
end
subgraph 错误方式
A2[Logits] --> B2[Softmax]
B2 --> C2[Log]
C2 --> D2[手动计算损失]
D2 --> E2["数值不稳定!"]
end
style B1 fill:#c8e6c9
style E2 fill:#ffcdd2
# 错误方式:分开计算
probs = softmax(logits) # 可能有数值问题
loss = cross_entropy(log(probs), labels)
# 正确方式:合并计算
loss = cross_entropy_with_logits(logits, labels) # 内部使用log_softmax
数值稳定性:一个被忽视的关键问题
Logits的计算看起来简单,但在实际工程中,数值稳定性是必须面对的挑战。
溢出与下溢
当logits范围很大时,指数运算会产生问题:
logits = torch.tensor([1000.0, 100.0, 10.0])
exp_logits = torch.exp(logits) # 溢出!变成 [inf, inf, 22026.5]
Max-Trick解决方案
标准的解决方案是在指数化之前,减去logits的最大值:
def stable_softmax(logits):
max_logit = logits.max()
shifted = logits - max_logit
exp_shifted = torch.exp(shifted)
return exp_shifted / exp_shifted.sum()
这个变换不改变softmax的结果(因为分子分母同时除以了$e^{\max}$),但避免了溢出问题。
混合精度训练中的Logits
在FP16混合精度训练中,logits的范围可能超出FP16的表示范围(约±65504)。常见的解决方案:
-
Loss Scaling:在计算损失前对logits进行缩放,反向传播后再反缩放。
-
FP32 Master Weights:在输出层保持FP32精度的权重副本。
-
BF16替代:BF16虽然精度更低,但范围与FP32相同,避免了溢出问题。
Logits的实际应用场景
知识蒸馏:暗知识的载体
知识蒸馏的核心思想是:让小模型(学生)学习大模型(教师)的"暗知识"——不仅仅是最终分类,还有各类别之间的相对关系。
教师的logits包含了丰富的类别间关系信息。考虑一个图像分类任务:
输入:一张狗的照片
教师的logits:[猫: 2.1, 狗: 8.5, 汽车: -5.0, 卡车: -4.2]
学生的logits:[猫: 0.5, 狗: 5.0, 汽车: 2.0, 卡车: 1.8]
即使两个模型都正确预测"狗",教师知道"猫比汽车更相似"(logit值2.1 vs -5.0),而学生没有学到这一点。
graph LR
subgraph 教师模型
A[输入] --> B[大模型]
B --> C["软标签 Logits"]
end
subgraph 学生模型
D[输入] --> E[小模型]
E --> F["预测 Logits"]
end
C --> G["蒸馏损失<br/>KL散度"]
F --> G
H[真实标签] --> I["硬标签损失"]
F --> I
G --> J["总损失"]
I --> J
style C fill:#ffeb3b
style F fill:#ffeb3b
蒸馏损失使用温度缩放:
$$\mathcal{L}_{KD} = -\sum_i p_i^T \log q_i^T$$其中$p^T$是教师的高温softmax输出,$q^T$是学生的高温softmax输出。高温使分布更平滑,保留更多"暗知识"。
模型校准:让置信度可信
神经网络的softmax概率往往不能真实反映预测的置信度——模型可能以99%的概率给出错误答案。这就是校准问题。
Expected Calibration Error (ECE) 是常用的校准度量:
$$\text{ECE} = \sum_{m=1}^{M} \frac{|B_m|}{n} |\text{acc}(B_m) - \text{conf}(B_m)|$$其中$B_m$是置信度落在第$m$个区间的样本集合。
graph TB
A[原始模型] --> B["计算验证集Logits"]
B --> C[应用温度缩放]
C --> D["优化温度参数T"]
D --> E[校准后模型]
subgraph 校准前
F["置信度 0.9<br/>准确率 0.6"]
end
subgraph 校准后
G["置信度 0.65<br/>准确率 0.63"]
end
style F fill:#ffcdd2
style G fill:#c8e6c9
温度缩放校准是一个简单有效的方法:
- 在验证集上,固定模型参数。
- 学习一个标量温度$T$,使得校准误差最小。
- 推理时使用这个温度。
这个方法之所以有效,是因为温度参数只改变概率分布的"尖锐度",不改变预测类别。
困惑度:语言模型的"惊讶程度"
困惑度是语言模型评估的核心指标,直接从logits计算:
$$\text{PPL} = \exp\left(-\frac{1}{N}\sum_{t=1}^{N} \log p(x_t|x_{从logits的角度理解:
- 计算真实token的logit值$z_t$。
- 计算softmax,得到概率$p_t = e^{z_t} / \sum e^{z_j}$。
- 取负对数:$-\log p_t$。
- 对所有token取平均,再指数化。
不确定性量化:Logits作为置信信号
在需要高可靠性的应用中,估计模型预测的不确定性至关重要。Logits提供了多种不确定性信号:
最大概率:最简单的置信度估计。
$$\text{confidence} = \max_i p_i = \max_i \frac{e^{z_i}}{\sum_j e^{z_j}}$$Logit Gap:最高和次高logit的差距。
$$\text{gap} = z_{\text{max}} - z_{\text{second\_max}}$$较大的gap表示模型更确定。这个度量不依赖于softmax,直接使用logits。
熵:概率分布的不确定性。
$$H = -\sum_i p_i \log p_i$$熵越高,模型越不确定。
Logits与Logprobs:两个密切相关但不同的概念
在实际工程中,经常会遇到"logprobs"这个概念,它和logits容易混淆。
Logits:线性层的原始输出,未归一化的分数。
Logprobs:概率的对数值,$\log p_i$。
两者的关系:
$$\text{logprob}_i = \log p_i = \log \frac{e^{z_i}}{\sum_j e^{z_j}} = z_i - \log\sum_j e^{z_j}$$graph LR
subgraph Logits
A["原始输出<br/>范围: (-∞, +∞)"]
B["未归一化"]
C["相对大小有意义"]
end
subgraph Logprobs
D["概率的对数<br/>范围: (-∞, 0]"]
E["可用于累加"]
F["数值稳定"]
end
A -->|"softmax + log"| D
B -.-> E
C -.-> F
style A fill:#ffeb3b
style D fill:#bbdefb
这是一个关键洞察:logprob等于logit减去一个常数(LogSumExp)。这意味着:
- 所有logprob都是负数(因为概率小于1,对数小于0)。
- Logprob最大的token就是logit最大的token。
- 但logprob的和没有特殊含义,而概率和必须为1。
为什么要用logprobs?
-
数值稳定性:直接存储和计算概率可能导致下溢(概率很小时)。log空间避免了这个问题。
-
累乘变累加:计算序列概率时,$P(x_1, x_2, ..., x_n) = \prod P(x_i|x_{
# 计算困惑度
log_probs = model(input_ids).log_probs # [batch, seq_len, vocab]
target_log_probs = log_probs.gather(-1, target_ids.unsqueeze(-1))
perplexity = torch.exp(-target_log_probs.mean())
工程实践:vLLM中的Logits处理
vLLM是当前最流行的大模型推理引擎之一,它对logits的处理体现了工业级实现的考量。
Logits Processors架构
vLLM提供了一个可扩展的logits处理器框架:
class LogitsProcessor:
def __call__(self, token_ids: List[int], logits: torch.Tensor) -> torch.Tensor:
# 修改logits
return modified_logits
处理器按顺序应用:
graph LR
A[原始Logits] --> B[LogitBiasProcessor]
B --> C[RepetitionPenaltyProcessor]
C --> D[TopKProcessor]
D --> E[TopPProcessor]
E --> F[TemperatureProcessor]
F --> G[采样]
style A fill:#ffeb3b
style G fill:#c8e6c9
高效Logit Bias实现
对于大规模词表(如32000),逐token遍历设置bias会很慢。vLLM使用向量化实现:
def apply_logit_bias(logits: torch.Tensor, bias: Dict[int, float]) -> torch.Tensor:
if not bias:
return logits
token_ids = torch.tensor(list(bias.keys()), device=logits.device)
bias_values = torch.tensor(list(bias.values()), device=logits.device)
logits[:, token_ids] += bias_values
return logits
批量处理优化
在批量推理中,不同请求可能需要不同的logits处理。vLLM使用padding和mask来高效处理:
# 假设batch_size=4, vocab_size=32000
# 每个请求的logit_bias不同
# 使用scatter操作批量应用
bias_matrix = torch.zeros(batch_size, vocab_size)
for i, bias_dict in enumerate(batch_logit_bias):
for token_id, bias_value in bias_dict.items():
bias_matrix[i, token_id] = bias_value
logits += bias_matrix
调试与分析:窥视模型的"思考过程"
Logits提供了一个窗口,让我们能够观察模型的决策过程。
Logit Lens技术
“Logit Lens"是一种可解释性技术,它将模型中间层的隐藏状态映射到词表空间:
def logit_lens(hidden_states, lm_head):
"""
hidden_states: [layers, batch, seq_len, hidden_dim]
lm_head: 线性投影层
"""
layer_logits = []
for layer_hidden in hidden_states:
logits = lm_head(layer_hidden) # [batch, seq_len, vocab]
layer_logits.append(logits)
return layer_logits
通过观察每一层的logits,可以了解模型在哪个阶段开始"形成"答案。研究发现,某些能力(如事实回忆)在较早的层就表现出来,而复杂的推理能力需要更深的层。
Top-k Logits可视化
对于调试生成问题,查看top-k logits是非常有用的:
def print_top_k_logits(logits, tokenizer, k=10):
top_k = torch.topk(logits, k)
for i in range(k):
token = tokenizer.decode([top_k.indices[i].item()])
logit = top_k.values[i].item()
prob = torch.softmax(logits, dim=-1)[top_k.indices[i]].item()
print(f"{token:15s} | logit: {logit:7.2f} | prob: {prob:.4f}")
这可以帮助诊断:
- 为什么模型选择了错误的token?是分数太接近还是确实学错了?
- 模型是否在"犹豫”?(多个token概率接近)
- 是否有"异常高"的token?(可能是训练数据问题)
Logits作为安全信号
在安全敏感的应用中,logits可以帮助检测异常:
置信度异常:如果模型对某个输出过于自信(某个token概率>99.9%),可能是在"背诵"训练数据,而非真正推理。
分布异常:正常情况下,top-1和top-2的logit差距应该有一定的分布。如果差距过大或过小,可能是异常输入或攻击。
OOD检测:将logits的熵与阈值比较,识别分布外输入:
def is_out_of_distribution(logits, threshold=3.0):
probs = torch.softmax(logits, dim=-1)
entropy = -torch.sum(probs * torch.log(probs + 1e-10))
max_entropy = torch.log(torch.tensor(logits.size(-1)))
normalized_entropy = entropy / max_entropy
return normalized_entropy > threshold
总结
Logits是神经网络输出最原始的形式,是连接模型"思考"与最终行为的桥梁。理解logits,意味着理解:
数学本质:它们是未归一化的分数,可以取任意实数值,通过softmax(或sigmoid)转换为概率。
工程角色:它们是训练时损失函数的输入,推理时采样的基础,各种干预手段(logit bias、temperature、top-k/p)的作用对象。
信息载体:它们编码了模型对所有类别的偏好,包含比最终预测更丰富的信息(“暗知识”)。
实用工具:通过分析logits,可以评估模型置信度、检测异常、理解模型决策过程。
在大模型时代,logits的重要性更加凸显。每一次与AI的对话,背后都是数万个token的logits在流动;每一个温度参数的调整,都在重塑这些logits的分布;每一次logit bias的应用,都在精确控制模型的输出边界。
Logits不是什么神秘的内部状态,它只是模型对世界的一个最朴素的表达:在所有可能的输出中,我对每一个有多大的"偏好"。这个简单的数字,承载着神经网络对任务的理解,也为我们提供了干预和理解的接口。
下次当你调整一个模型的温度参数,或者设置某个词的惩罚系数时,你知道你正在做什么——你正在重塑那一个个logits,改变模型的"思考"方向。这就是理解的开始。
参考文献
-
Goodfellow, I., Bengio, Y., & Courville, A. (2016). Deep Learning. MIT Press.
-
Hinton, G., Vinyals, O., & Dean, J. (2015). Distilling the Knowledge in a Neural Network. arXiv preprint arXiv:1503.02531.
-
Guo, C., Pleiss, G., Sun, Y., & Weinberger, K. Q. (2017). On Calibration of Modern Neural Networks. ICML 2017.
-
Holtzman, A., Buys, J., Du, L., Forbes, M., & Choi, Y. (2020). The Curious Case of Neural Text Degeneration. ICLR 2020.
-
Radford, A., et al. (2019). Language Models are Unsupervised Multitask Learners. OpenAI Technical Report.
-
Brown, T., et al. (2020). Language Models are Few-Shot Learners. NeurIPS 2020.
-
Touvron, H., et al. (2023). LLaMA: Open and Efficient Foundation Language Models. arXiv preprint arXiv:2302.13971.
-
Kwon, W., et al. (2023). Efficient Memory Management for Large Language Model Serving with PagedAttention. SOSP 2023.
-
Naeini, M. P., Cooper, G., & Hauskrecht, M. (2015). Obtaining Well Calibrated Probabilities Using Bayesian Binning. AAAI 2015.
-
Xiao, Y., & Wang, W. Y. (2019). Quantifying Uncertainties in Natural Language Processing Tasks. AAAI 2019.