ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

235、【AI】【模型部署】基座模型研究:交叉熵

235、【AI】【模型部署】基座模型研究:交叉熵 【声明】本博客所有内容均为个人业余时间创作所述技术案例均来自公开开源项目如GithubApache基金会不涉及任何企业机密或未公开技术如有侵权请联系删除标题235、【AI】【模型部署】基座模型研究交叉熵背景上篇 blog【AI】【模型部署】基座模型研究预训练到底在做什么把预训练收敛成一句话文本切成 id模型预测下一个 token交叉熵算误差反向传播更新权重循环几百万到几万亿次并用微型模型实测到 loss 从 7.3883 降到 0.7821其中初始的 7.3883 约等于ln(1432)1432 个字符均匀乱猜。上篇反复出现的一行代码是x,ybatch()# y 是 x 右移一位logitsmodel(x)# 每个位置输出词表大小的分数lossF.cross_entropy(logits.view(-1,vocab_size),y.view(-1))opt.zero_grad();loss.backward();opt.step()上篇只说了这一步在算误差没有展开。本篇把循环里的第一步——交叉熵拆开它到底在算什么、为什么用它的形式、以及它在代码里对应哪一行。反向传播留到下一篇。模型部署上篇把预训练讲成预测下一个 token的循环而这个循环里最先要回答的问题是模型给每个 token 打了一堆分数怎么把猜得好不好变成一个可以往下传的数字这个数字就是交叉熵损失。从信息量说起越意外代价越大先看一个更小的概念——信息量self-information。一个事件发生的概率越小它一旦发生带来的惊讶越大。用概率p pp度量这种惊讶就是取它的负对数I ( x ) − log ⁡ p ( x ) I(x) -\log p(x)I(x)−logp(x)p 1 p1p1必然发生− log ⁡ 1 0 -\log 1 0−log10毫无信息量p 0.5 p0.5p0.5− log ⁡ 0.5 ≈ 0.69 -\log 0.5 \approx 0.69−log0.5≈0.69p → 0 p \to 0p→0几乎不可能− log ⁡ p → ∞ -\log p \to \infty−logp→∞信息量爆炸。把这个惊讶程度用到预测上模型给正确 token的概率越低说明它越没料到代价就越大。这就是交叉熵的直觉。交叉熵的定义衡量两个分布的差距交叉熵Cross-Entropy衡量预测分布Q QQ相对真实分布P PP差多远H ( P , Q ) − ∑ x P ( x ) log ⁡ Q ( x ) H(P,Q) -\sum_x P(x)\log Q(x)H(P,Q)−x∑​P(x)logQ(x)它把真实分布P PP当作权重对预测分布Q QQ的负对数概率做加权平均。Q QQ越贴近P PPH HH越小。在 next-token 预测里它会大幅简化语言模型每个位置的真实分布是一个one-hot独热向量正确 token 概率为 1其余为 0。代入上面的式子只有正确那一项被P 1 P1P1选中其余项被P 0 P0P0乘没于是交叉熵退化成负对数似然Negative Log-LikelihoodNLLloss − log ⁡ Q ( 正确 token ) \text{loss} -\log Q(\text{正确 token})loss−logQ(正确token)也就是说一个位置的损失只取决于模型给正确 token 的概率。图 1 画出了这条曲线横轴是给正确 token 的概率p pp纵轴是− ln ⁡ p -\ln p−lnp。概率越低惩罚越重概率接近 1损失趋于 0。乱猜的基线ln ⁡ V \ln VlnV如果模型对V VV个 token 完全均匀乱猜那么给正确 token 的概率是1 / V 1/V1/V损失为loss − log ⁡ 1 V ln ⁡ V \text{loss} -\log\frac{1}{V} \ln Vloss−logV1​lnV这正是上篇里初始 7.3883 ≈ln(1432)的来源微型模型字符表有1432个字符ln ⁡ 1432 ≈ 7.27 \ln 1432 \approx 7.27ln1432≈7.27实测首步7.3883 7.38837.3883略高一点随机初始化的打分并不严格均匀且已经过第 1 步更新。图 2 给出不同词表的乱猜基线词表越大起点越高。Qwen2 的 15 万词表ln ⁡ 152064 ≈ 11.93 \ln 152064 \approx 11.93ln152064≈11.93——这也解释了为什么大模型训练初期的 loss 看起来很大它只是词表大而已。困惑度把 loss 翻译成候选数loss 是不确定度但它是个对数尺度不直观。把它取指数就得到困惑度PerplexityPPLPPL e loss \text{PPL} e^{\text{loss}}PPLeloss困惑度可以粗略理解为模型平均在多少个候选之间犹豫阶段loss困惑度e loss e^{\text{loss}}eloss含义初始7.3883≈ 1617基本在乱猜100 步2.2884≈ 9.9已锁定常见字与格式1000 步0.7821≈ 2.2大致二选一图 4 把三个阶段画在一起从约在 1617 个候选里犹豫降到约 2 选 1就是 loss 下降的直观含义。softmax把分数变成概率交叉熵里的Q QQ是概率而模型最后一层吐出的是logits未归一化的分数二者之间隔着softmax归一化指数函数Q i e z i ∑ j e z j Q_i \frac{e^{z_i}}{\sum_j e^{z_j}}Qi​∑j​ezj​ezi​​softmax 保证所有概率非负、且和为 1。于是单个位置的交叉熵可以写成loss − log ⁡ e z 正确 ∑ j e z j log ⁡ ∑ j e z j − z 正确 \text{loss} -\log\frac{e^{z_{\text{正确}}}}{\sum_j e^{z_j}} \log\sum_j e^{z_j} - z_{\text{正确}}loss−log∑j​ezj​ez正确​​logj∑​ezj​−z正确​后一种写法就是log-sum-exp工程上更数值稳定——避免先算出一个极小概率、再取对数导致下溢。图 3 串起整条链路logits → softmax → 取正确 token 的概率 → 取负对数。为什么偏偏用交叉熵三个原因等价于最大似然估计Maximum Likelihood EstimationMLE让模型对正确答案的预测概率连乘最大取负对数后就等价于让交叉熵最小梯度形式漂亮softmax 与交叉熵组合后对 logits 的梯度恰好是预测概率减真实标签下一篇展开好训练数值稳定配合 log-sum-exp能安全处理极小概率。代码里它对应哪一行回到上篇那行loss F.cross_entropy(logits.view(-1, vocab_size), y.view(-1))把它的内部展开就是softmax 取正确项 负对数logitslogits.view(-1,vocab_size)# (批×序列, 词表)logpF.log_softmax(logits,dim-1)# 数值稳定的 log(softmax)loss-logp.gather(1,y.view(-1,1)).mean()# 取正确项求平均其中.view(-1, vocab_size)是把批次 × 序列位置展平成一批独立的预测点每个点都算一次交叉熵再取平均。一个具体例子假设某个位置词表只有 3 个 token模型给出的 logits 与 softmax 后的概率是tokenlogitsoftmax 概率A正确2.00.659B1.00.242C0.10.098正确答案是 A于是这个位置的损失为loss − ln ⁡ 0.659 ≈ 0.417 \text{loss} -\ln 0.659 \approx 0.417loss−ln0.659≈0.417给正确 token 的概率越高这个值越小如果模型只给 A 概率 0.098把 C 猜成了正确项loss 就会涨到− ln ⁡ 0.098 ≈ 2.32 -\ln 0.098 \approx 2.32−ln0.098≈2.32。每个位置都这么算一遍、再求平均就是一批数据的总损失。一句话记忆交叉熵衡量预测分布离真实分布有多远在 next-token 预测里真实标签是 one-hot所以它退化成给正确 token 的概率取负对数均匀乱猜的基线是ln ⁡ V \ln VlnV微型模型ln 1432 ≈ 7.27取指数即困惑度e loss e^{\text{loss}}eloss模型用 softmax 把 logits 变成概率F.cross_entropy内部就是log-softmax 取正确项 求平均。OK本篇先到这里如有疑问欢迎评论区留言讨论祝各位功力大涨技术更上一层楼更多内容见下篇 blog【数学】【基础】对数与自然对数从乘法到加法
返回列表