量化评估 MMLU 噪声大?TaoToken 这样配:让 Codex 按 KL 散度对照

Llama 3.1 发布之后,量化方案又吵成了一锅粥:有人跟风跑 MMLU,发现量化模型分数比 FP16 参考模型还高,于是宣布“量化还能提精度”;另一拨人换几个任务,结论又反过来。Fireworks 在一篇技术文章里把这个现象归结为基于任务的指标噪声太大,并给出一个更细的做法:用 KL 散度观察量化前后词元概率分布的变化。我顺着这个思路想复现一次,却卡在第一步:手头模型的 logprobs 拿不到,通道也不支持自选档位。后来我把 Codex 接到 TaoToken,从 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 创建 API Key,再把 Base URL 填成 https://taotoken.net/api,终于把这套散度对照流程跑通。这篇文章记录的是这套流程,重点放在怎么让 Codex 写脚本、怎么读结果,而不是替任何一家量化方案背书。

1. MMLU 的分差为什么不能信:量化评估要从“对错”换到“分布”

1.1 全有或全无的评分把模型的“犹豫”丢掉了

Fireworks 在文章里举过一个很典型的例子:一个位置上,参考模型认为正确答案概率是 0.51,错误答案是 0.49;量化模型略为扰动,变成正确答案 0.49、错误答案 0.51。两个模型对这个 token 的真实看法只差了 2%,但落到 MMLU 的评分上,参考模型这题得 1 分,量化模型直接 0 分。

这种“全有或全无”的评分方式,就是任务指标噪声大的根源。MMLU 本质上是把一道题的正确性当成阶跃函数来打分,模型内部那 0.51 和 0.49 的分布差异全部丢掉了。连续几十道题都这样,量化模型和参考模型之间那 1% 的分差,绝大部分不是能力差距,而是对“不确定答案”的不同舍入。Fireworks 在自家 Llama 3.1 8B 的量化测试里就看到过这种现象:某个更激进的量化级别,MMLU 分数反而比 FP16 参考模型高几个百分点。这不是量化让模型变聪明了,而是基准测试里的噪声恰好偏向了它。

所以,当你只想回答“这个量化版本能不能上线”时,MMLU 并不是合适的尺子。它适合分析基础模型的一般能力,却不适合比较两个行为已经很接近的模型。比较两个高度相似的模型,需要看它们在同一段文本上预测下一个词元时,概率分布到底偏离了多远。

1.2 散度才是能量化分布的尺子:KLD 和词元拒绝率

Fireworks 推荐的两个指标都直接建立在词元概率分布上。

第一个是 KL 散度(KLD),衡量量化前后每个位置词元概率分布的变化程度。就算两个模型每个位置选出的最高概率词元完全相同,只要这个词元背后的概率大小变了,KL 散度也会反映出来。

第二个是词元拒绝率,统计“量化模型最高概率词元 ≠ 参考模型最高概率词元”的位置比例。换个角度看,它就像把量化模型当作草稿模型时,参考模型每次校验后的拒绝比例。拒绝率越高,量化模型在投机解码场景下的收益就越低。

这两个指标不是算一个总数就结束,还要按推理阶段拆分。Fireworks 把散度和拒绝率都分成预填充阶段、生成阶段两组,因为推理的不同部分可能采用不同的量化技术:预填充阶段大量并行计算,对注意力部分的量化更敏感;生成阶段逐步自回归,QKV 投影和 KV 缓存的量化误差会不断累积。如果不拆开看,两个阶段的退化会被平均掉,最后得到一个“看起来还行”的假象。

2. 先配一条能拿 logprobs 的通道:从 TaoToken 官网创建 Key 到 Codex 的 config.toml

2.1 打开官网创建 Key,再把 Base URL 填进 Codex

复现这套评估的前提,是模型接口愿意把 logprobs 还给你。Fireworks 在原文里也专门提了一句“我们鼓励其他提供商公开对数概率值”。TaoToken 的定位是统一 API 兼容通道,把不同模型的调用方式收敛成同一套 OpenAI 风格接口;在做散度评估时,它最有用的一点就是能按标准格式返回 logprobs。

先去 TaoToken 注册,在控制台创建一个 API Key。创建后拿到的字符串就是下面所有配置里的 YOUR_API_KEY。需要注意:这个网址是给人注册、建 Key、看用量、查模型广场用的。真正填进 Codex 或 Python SDK 的接口地址是 https://taotoken.net/api,末尾不要加 /v1,也不要带 ?utm_source=... 那一串,那串参数是网页统计用的,加进接口请求会让地址直接失效。

模型 ID 也不要靠猜。打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 的模型广场,找到你想对比的参考模型和量化模型,复制它们完整的 ID。每个模型的 logprobs 支持情况可能不同,优先选模型卡片里明确写了支持 logprobs 的档位。

2.2 ~/.codex/config.toml 里新增一个名为 taotoken 的 provider

Codex 的配置放在 ~/.codex/config.toml。打开这个文件,在 [model_providers] 下新增一段:

model = "MODEL_ID_FROM_TAOTOKEN"  # 以模型广场为准
model_provider = "taotoken"

[model_providers.taotoken]
name = "TaoToken"
base_url = "https://taotoken.net/api"
env_key = "TAOTOKEN_API_KEY"
wire_api = "chat"

保存后先设置环境变量,再启动 Codex:

export TAOTOKEN_API_KEY=YOUR_API_KEY
codex

env_key 的意思是 Codex 会从同名环境变量读取 API Key。这样 Key 不会写死在配置里,也方便后面在 Python 脚本里复用同一个环境变量。配置好后随便问 Codex 一句话,确认它已经能通过 TaoToken 通道拿到模型响应。这一步不做散度计算,只验证链路通不通。

3. 复现 Fireworks 的散度方法:让 Codex 写出“强制跟读”脚本

3.1 参考模型先自由生成:收集 top-16 logprob 分布

Fireworks 的方法第一步,是让参考模型根据各种提示自由生成,直到完整结束。这里参考模型指的是原始精度版本,通常也叫 FP16、BF16 或带 -hf 后缀的档位。生成时在每个位置记录前 N 个词元的对数概率。原文给的经验值是 N=16,理由是前 16 个词元大约能覆盖分布 0.99 的质量。

在 Codex 会话里描述这个需求,它会生成类似下面的脚本骨架:

from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://taotoken.net/api",
)

REFERENCE_MODEL = "MODEL_ID_FROM_TAOTOKEN"  # 模型广场里的原始精度模型
QUANT_MODEL = "MODEL_ID_FROM_TAOTOKEN"      # 模型广场里的量化模型
TOP_N = 16

def free_generate(prompt, model=REFERENCE_MODEL):
    resp = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": prompt}],
        temperature=0,
        logprobs=True,
        top_logprobs=TOP_N,
    )
    content = resp.choices[0].logprobs.content
    return content  # 每个元素包含 token、logprob、top_logprobs

提示集不要只放一两道 MMLU 题。原文特别指出,量化对代码生成的影响和对函数调用的影响可能完全不同。所以至少准备四类提示:代码补全、函数调用、JSON 结构输出、多步数学。每类 5 到 10 条,总共 20 到 40 条即可。数量不需要太大,散度指标对提示集的选择比任务指标稳定得多。

3.2 量化模型不许自由发挥:用参考输出前缀强制跟读

直接让量化模型重新生成一遍,然后计算最终文本的差异,是不行的。原因在原文里写得很清楚:量化模型可能生成一条完全不同但困惑度很低的路径,比如不断输出重复词元,最后整体概率看起来还不错,实际上已经偏离了任务。

正确做法是“强制”量化模型跟读参考模型。所谓跟读,就是在每个位置上,把参考模型已经生成的前缀作为上下文,让量化模型只预测下一个词元的概率分布;无论量化模型更想选哪个词元,脚本都继续使用参考模型的前缀,不让它把话题带偏。

def forced_next_distribution(prompt, reference_prefix, model=QUANT_MODEL):
    resp = client.chat.completions.create(
        model=model,
        messages=[
            {"role": "user", "content": prompt},
            {"role": "assistant", "content": reference_prefix},
        ],
        max_tokens=1,
        temperature=0,
        logprobs=True,
        top_logprobs=TOP_N,
    )
    content = resp.choices[0].logprobs.content
    return content[0].top_logprobs  # 词元 + logprob 列表

这里的 reference_prefix 是参考模型已经生成的那段文本。由于 logprobs 返回的是 token 文本,直接拼接可能引入一点边界误差。想更严格,可以让服务端返回 token ID 或偏移量来做精确前缀,但这取决于 TaoToken 上游端点是否提供这些字段。对量化对比来说,两个模型吃的是同一套前缀,边界误差的方向是一致的,不会颠覆结论。

3.3 预填充 / 生成分桶:KL 散度与拒绝率的计算入口

拿到两个模型在每个位置上的 top-16 分布后,接下来的计算就简单了。

KL 散度需要对齐两个分布的词元集合。参考模型的 top-16 里有某些词元,量化模型的 top-16 里不一定有。脚本里把缺失概率设为一个很小的值,比如 1e-12,然后只取参考分布支撑集求和。拒绝率更直接:比较两个模型 top-1 词元是否相同,统计不同位置的比例。

import math

def kl_from_logprobs(ref_top, quant_top, eps=1e-12):
    qmap = {item.token: math.exp(item.logprob) for item in quant_top}
    total = 0.0
    for item in ref_top:
        p = math.exp(item.logprob)
        q = qmap.get(item.token, eps)
        total += p * math.log(p / q)
    return total

最后把结果拆成两组:参考模型输出序列里前 20 个新词元归入预填充阶段,其余归入生成阶段。如果上游接口支持 prompt logprobs,那就更精确;拿不到时用这个近似也足够,因为两个模型面对的是同样的位置偏移。

脚本跑完后会输出一张表,结构类似这样,数字以你这次实际跑出的结果为准:

模型档位预填充 KL生成 KL预填充拒绝率生成拒绝率
量化档位 A以脚本输出为准以脚本输出为准以脚本输出为准以脚本输出为准
量化档位 B以脚本输出为准以脚本输出为准以脚本输出为准以脚本输出为准

把 stdout 贴回 Codex 会话,让它帮你解释哪一档散度增长异常,再决定要不要继续对比。

4. 结果怎么读:叠量化等级跑,看散度是否单调,别被 MMLU 的 1% 带走

4.1 从模型广场挑几个量化档位,由低到高排成序列

原文用 Llama 3.1 8B Instruct 做了四档量化,从只量化 MLP 矩阵乘法,到逐步叠加 QKV、KV 缓存、预填充注意力。TaoToken 模型广场不一定提供一模一样的分层档位,但你可以选两到四个粒度不同的版本。原则是让它们构成一条“激进程度递增”的序列,例如建议:

  • 档位 1:原始精度版本,作为参考基线
  • 档位 2:常见 8bit 量化版本
  • 档位 3:更激进的 4bit 或 AWQ 版本
  • 档位 4:如果广场有 KV 缓存也被量化的版本,再往上叠一档

排好序后,对每个档位跑一遍第 3 节的脚本,得到各自的预填充 KL、生成 KL、预填充拒绝率、生成拒绝率。这一步的关键动作是“同一套提示集、同一个参考前缀”,量化档位之间只允许模型 ID 不同,其他参数全部固定。

4.2 散度单调递增而 MMLU 忽上忽下,才是 Fireworks 说的噪声

正常情况下,你会看到 KL 散度和词元拒绝率都随量化激进程度单调上升。这是 Fireworks 原文明确提到的规律:散度指标彼此之间、以及与量化级别之间保持单调关系。如果某个更激进的档位反而 KL 散度大幅下降,先怀疑是不是模型 ID 填反了,或者服务端对那个模型做了不同处理。

相比之下,MMLU 这类任务指标不会给你这么干净的曲线。它会在两个档位之间突然上升 1%,又在下一档跌回去。原文里那个“量化级别 2 的 MMLU 高于 FP16”的现象,就是为了提醒你:任何基于任务的基准,在比较两个接近的模型时,1% 之内的分差都落在噪声范围内。你复现时如果也看到量化模型某个任务分数比参考模型高,不要急着高兴,先看同档位的 KL 散度是不是也环比上升了。散度上升而 MMLU 上升,说明基准噪声大于量化影响;散度几乎不变而 MMLU 大起大落,说明基准本身不可复现。

4.3 分段归因:MLP 影响小、QKV 影响大、预填充和生成要分开判断

把散度拆成预填充和生成两个桶之后,还能回答“量化到底伤在哪”的问题。Fireworks 的测试结论是:量化 MLP 层对模型整体质量影响相对较小;量化 QKV 投影的影响更明显;量化 KV 缓存对长生成场景的影响比对短输入更显著;而量化预填充里的注意力操作,对长预填充模型的延迟收益最大,对质量的影响也要单独盯。

这些规律不能直接套用到所有模型上,但可以指导你下一步怎么选。比如你的业务是长文档总结,预填充占比很大,那就优先关注预填充 KL 散度;如果你的业务是代码补全,生成阶段很长,那就把生成 KL 散度当作上线阈值。Fireworks 给过一个经验值:KL 散度小于 0.007 时,量化质量通常可以接受。但这个阈值不是金标准,最终还是要拿你自己的业务提示集跑一轮。

5. 排障:Codex 接到 TaoToken 后最常见的三类错

5.1 401 Unauthorized:Key 没创建或带到了 URL 上

Codex 报 401,第一件事是确认 TAOTOKEN_API_KEY 环境变量是否真的设置成了你在官网创建的那一串完整 Key。很多复制操作会漏掉末尾字符,或者把终端里的引号也带进去。第二件事是检查请求目标:接口地址必须是 https://taotoken.net/api,不要在后面拼 /v1,也不要带上网页的 UTM 参数。UTM 那串是给人点链接做归因用的,放进 API 请求只会得到无效地址,甚至被网关直接拒绝。

5.2 404 Model Not Found:模型 ID 要从模型广场复制

如果 Codex 或 Python 脚本返回 404,大概率是 config.toml 里的 model 字段和 TaoToken 模型广场列出的 ID 不一致。不要凭记忆写模型名,也不要在标准模型名后面自己加日期后缀或量化标记。回到模型广场,打开目标模型的详情页,复制完整 ID 再填进去。

5.3 logprobs 返回 null:端点不支持,换模型而不是改参数

脚本里 logprobs=Truetop_logprobs=16 都写了,响应里却拿不到 logprobs.content,这通常是模型端点本身不返回 logprobs,不是参数格式的问题。Fireworks 在原文里也提过,希望更多提供商公开对数概率值;现实是并非所有模型服务都会开启这个能力。遇到这种情况,换一个模型广场里标注支持 logprobs 的模型,而不是反复调参数。

另外,散度脚本跑得慢是正常的。每个位置都要把参考前缀重新发给量化模型,位置一多调用次数就上去了。可以抽样位置,比如每隔 5 个 token 计算一次,这样能把总调用量降下来,同时保留趋势判断。

6. 跑通之后:用模型对话先验证,再去 Coding Plan 和 API Keys 对账

6.1 在模型对话里用同一把 Key 发一条测试消息

散度脚本得到第一份结果后,先用 TaoToken 模型对话 做一次人工验证:从你的提示集里挑一条,用参考模型和量化模型各跑一次,直接看输出质量的直观差异。这一步把“散度数字”和“真实体感”对上。

尤其是当你发现某个档位 KL 散度很低,但对话里量化模型已经明显出现重复或漏字时,说明你的提示集没有覆盖到那个退化方向。回到第 3 节,往提示集里补这一类业务样本,再跑第二轮。这个闭环才是 Fireworks 原文说的“开发者是质量最佳评判者”的落地方式。

6.2 长期写代码再看 Coding Plan 与用量核对

散度评估不是一次性任务。模型换了、量化档位换了、业务提示集变了,都需要重新跑。确认这套流程稳定后,可以回到 控制台 API Keys 看这次跑批一共消耗了多少调用量;如果准备把 Codex 长期用作日常写码工具,再打开 Coding Plan 估一下套餐够不够覆盖后续的散度跑批与日常开发。量化的结论不该由别人替你拍板,你自己跑的散度曲线,比任何博客里的 MMLU 榜单都更能说明问题。

相关推荐

RÓÑSCINature»ÍİSCI¿Ñ»Í-ROCÇÏ

RÓÑSCINature»ÍİSCI¿Ñ»Í--ROCÇÏ

技术转移机构如何提高项目转化效率?.docx

科易网基于40亿+科创知识图谱数据库,深探索AI技术在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,研究科技创新领域的AI+数智化解决方案,推动科技创新与产业创新智能化发展。

国央企如何规范化管理R&D项目投资决策?.docx

科易网基于40亿+科创知识图谱数据库,深探索AI技术在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,研究科技创新领域的AI+数智化解决方案,推动科技创新与产业创新智能化发展。

计算机房电图.dwg.rar

计算机房电图.dwg.rar

教师活动中心电气图纸.pdf.rar

教师活动中心电气图纸.pdf.rar

Q + 桌面(桌面管理软件)

Q + 桌面是一款桌面增强软件,可接管系统桌面并在原生桌面与 Q + 桌面之间自由切换。使用 QQ 账号登录,自带应用市场,能够添加网页应用、小游戏、天气、资讯等各类插件。支持桌面图标智能分类整理,内置海量在线壁纸,可设置自动更换壁纸,还集成消息中心,聚合 QQ 动态、邮箱提醒。

垃圾站图纸.dwg.rar

垃圾站图纸.dwg.rar

TOP-EA黄金双向对冲

TOP-EA黄金双向对冲

某电厂用400V电系统图一套.pdf.rar

某电厂用400V电系统图一套.pdf.rar

高校如何提升科研项目评价质量和申报成功率?.docx

科易网基于40亿+科创知识图谱数据库,深探索AI技术在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,研究科技创新领域的AI+数智化解决方案,推动科技创新与产业创新智能化发展。

国央企如何优化科技投入的ROI与成果转化效率?.docx

国央企如何优化科技投入的ROI与成果转化效率?

宽城文化会展中心826.pdf.rar

宽城文化会展中心826.pdf.rar

高校如何提升科研项目评价的科学性与效率?.docx

科易网基于40亿+科创知识图谱数据库,深探索AI技术在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,研究科技创新领域的AI+数智化解决方案,推动科技创新与产业创新智能化发展。

高校如何科学评价科研项目质量以优化资源置?.docx

科易网基于40亿+科创知识图谱数据库,深探索AI技术在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,研究科技创新领域的AI+数智化解决方案,推动科技创新与产业创新智能化发展。

教育小区A区车库电图.pdf.rar

教育小区A区车库电图.pdf.rar

空调电系统图.pdf.rar

空调电系统图.pdf.rar

上一篇: vsce publish 认证失败,把 Codex 的 Base URL 改到 TaoToken 之后发布成功
下一篇: Cursor 跑 Excel 填 Word 模版:Key 用 TaoToken
BlueTiger92
博客等级 码龄2年 534粉丝 1047原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BlueTiger92

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值