首页 / 资讯中心 / 文章详情

【LLM】LitBench 创意文本评估 Benchmark:用 TaoToken 统一 Key 跑通 reward model 打分链路

【LLM】LitBench 创意文本评估 Benchmark:用 TaoToken 统一 Key 跑通 reward model 打分链路 ★ FEATURED ARTICLE
1. 为什么创意文本评估总在“我觉得还行”里打转创意写作评估这件事做过的人都知道有多别扭。你让模型写一段小说开头它给你三个版本你想判断哪个更好第一反应是“读起来感觉不一样”但具体哪里不一样、哪个更符合人类偏好很难说清楚。传统做法要么拉几个同事人工打分要么直接拿 GPT-4 或 Claude 当 judge 让它选。前者成本高、不可复现后者看起来省事但位置偏差、长度偏好、风格偏见一堆问题同一对文本换个顺序问答案可能就反过来了。LitBench 这个 Benchmark 想解决的就是这个痛点。它是什么一句话说LitBench 是第一个专门用来评测“创意写作 judge 靠不靠谱”的标准化基准和数据集。它能做什么给你一套带人类偏好标注的 pairwise 数据让你训练和对比 reward model、生成式 reward model、零样本 LLM judge 三类评测器看谁和人类偏好一致率更高。适合谁适合做 LLM 对齐、reward model 训练、创意写作生成评估的工程师和研究者尤其是那些想验证“我训的 RM 到底有没有比直接调闭源 API 当 judge 更强”的人。我试过直接拿强闭源模型当创意写作 judge短文本还行一旦故事超过一千字模型就开始抓不住重点经常被华丽的辞藻带偏忽略了情节推进和人物动机。LitBench 论文里的结论也印证了这一点最强的零样本 judge Claude-3.7-Sonnet 和人类偏好一致率大约 73%而用 LitBench 训练集微调出来的 Bradley-Terry reward model 和 GenRM 都能到 78%。更反直觉的是给 GenRM 加上 CoT 推理后准确率反而掉到 72% 左右——创意写作评判不是那种“越想越对”的任务解释性文本多了反而引入噪声。所以这篇不是论文复述而是一份可跟做的落地流程从数据集加载、reward model 打分到结果复现用 TaoToken 统一 Key 把整条链路跑通。你不需要自己训模型先用现成的 reward model 验证评估链路是否工作再决定要不要微调。2. TaoToken 前置统一 Key 与接入地址在跑 LitBench 评估链路之前先把模型调用这一层统一掉。TaoToken 在这里的角色是提供一个兼容 OpenAI 接口的 API 入口让你用同一个 Key 调用不同模型省去在多个平台之间切换、管理多套密钥的麻烦。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 注意 API 地址不带 UTM 参数。你需要准备的东西不多一个 TaoToken API KeyPython 3.9 以上的环境以及几个常用库。Key 在控制台的 API Keys 页面创建地址是 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。创建后复制出来后面用环境变量管理不要硬编码在脚本里。环境变量这样设置Linux/macOS 下直接 exportWindows 用 set 或写进 .env 文件export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/api如果你用 python-dotenv可以建一个 .env 文件TAOTOKEN_API_KEYsk-你的key TAOTOKEN_BASE_URLhttps://taotoken.net/api模型 ID 这块要注意TaoToken 的模型列表在文档里能查到地址是 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。跑 LitBench 评估时你至少需要两类模型一类是 reward model 或 judge 模型用来给故事对打分另一类是生成模型用来产生待评估的创意文本。如果你只是想验证链路可以直接用现成的强模型当 zero-shot judge比如 Claude 系列或 GPT 系列模型 ID 按文档里的写法填。依赖安装pip install openai datasets pandas numpy scipy python-dotenv这里用 openai 库是因为 TaoToken 兼容 OpenAI 的 chat completions 接口你不需要额外装 SDK。datasets 用来加载 LitBench 数据集pandas 和 numpy 做结果统计scipy 算一致性指标。有一点要提醒TaoToken 是 API 接入层不是模型训练平台。你在这里做的是调用模型推理reward model 的训练如果要做得在本地或别的算力环境跑。但评估链路的验证完全可以在本地完成这也是这篇的重点。3. 可复制配置LitBench 数据加载与 reward model 打分脚本这一节给你一份可以直接跑的配置和脚本。先看目录结构建议这样组织litbench-eval/ ├── .env ├── config.json ├── load_litbench.py ├── judge_client.py └── run_eval.pyconfig.json 放模型和评估参数路径和字段名保持和下面一致{ base_url: https://taotoken.net/api, api_key_env: TAOTOKEN_API_KEY, judge_model: claude-3-7-sonnet, generator_model: gpt-4-1, dataset_name: litbench/litbench, test_split: test, max_samples: 200, temperature: 0.0, max_tokens: 512 }注意 judge_model 和 generator_model 的 ID 要按 TaoToken 文档里的实际写法填不同平台模型命名有差异。temperature 设 0 是为了让 judge 输出稳定减少随机性对一致性指标的影响。load_litbench.py 负责加载数据集。LitBench 的数据在 Hugging Face 上格式是 pairwise 比较每条样本包含 prompt、chosen story、rejected story 三个核心字段import os from datasets import load_dataset from dotenv import load_dotenv load_dotenv() def load_litbench(splittest, max_samplesNone): ds load_dataset(litbench/litbench, splitsplit) if max_samples: ds ds.select(range(min(max_samples, len(ds)))) return ds if __name__ __main__: ds load_litbench(splittest, max_samples5) print(ds[0].keys()) print(prompt:, ds[0][prompt][:200]) print(chosen:, ds[0][chosen][:200]) print(rejected:, ds[0][rejected][:200])如果数据集名称有变化去 Hugging Face 上搜 LitBench 确认最新路径。跑通这一步你会看到每条样本的 prompt 是写作提示chosen 和 rejected 是两个故事版本chosen 是人类偏好更高的那个。judge_client.py 封装 TaoToken 调用核心是用 OpenAI 兼容接口发请求import os from openai import OpenAI from dotenv import load_dotenv load_dotenv() client OpenAI( api_keyos.getenv(TAOTOKEN_API_KEY), base_urlos.getenv(TAOTOKEN_BASE_URL, https://taotoken.net/api), ) def judge_pair(prompt, story_a, story_b, modelclaude-3-7-sonnet): system 你是一个创意写作评审。根据写作提示判断哪个故事更好。只输出 A 或 B不要解释。 user f写作提示{prompt}\n\n故事A{story_a}\n\n故事B{story_b}\n\n哪个更好 resp client.chat.completions.create( modelmodel, messages[ {role: system, content: system}, {role: user, content: user}, ], temperature0.0, max_tokens8, ) return resp.choices[0].message.content.strip()这里有个关键点位置偏差。同一对故事A 在前和 B 在前judge 可能给出不同答案。LitBench 论文里的做法是对两组顺序都跑一遍然后平均。你在 run_eval.py 里要处理这个import json from load_litbench import load_litbench from judge_client import judge_pair def run_eval(config_pathconfig.json): with open(config_path) as f: cfg json.load(f) ds load_litbench(splitcfg[test_split], max_samplescfg[max_samples]) correct 0 total 0 for sample in ds: prompt sample[prompt] chosen sample[chosen] rejected sample[rejected] # 顺序1chosen 在前 r1 judge_pair(prompt, chosen, rejected, cfg[judge_model]) # 顺序2rejected 在前 r2 judge_pair(prompt, rejected, chosen, cfg[judge_model]) # 两次都选 chosen 才算对 vote_chosen 0 if r1 A: vote_chosen 1 if r2 B: vote_chosen 1 if vote_chosen 1: correct 1 total 1 acc correct / total print(f一致率: {acc:.4f} ({correct}/{total})) return acc if __name__ __main__: run_eval()这段逻辑是简化版的位置偏差消除两次调用中只要有一次选中 chosen 就算对。更严格的做法是两次都选 chosen 才算对你可以根据评估目的调整。跑 200 条样本每条两次调用总共 400 次请求按 TaoToken 的计费方式成本可控。4. 验证请求与成功结果一次完整评估调用与指标核对配置写好后先做一次最小验证确认 API 通、数据能加载、judge 能返回结果。先跑单条python -c from load_litbench import load_litbench from judge_client import judge_pair ds load_litbench(splittest, max_samples1) s ds[0] r judge_pair(s[prompt], s[chosen], s[rejected]) print(judge 返回:, r) 如果返回 A 或 B说明链路通了。如果报错看第 5 节的排查。单条通过后跑完整评估python run_eval.py成功输出类似一致率: 0.7350 (147/200)这个数字的含义是你的 judge 模型在 200 条测试样本上和人类偏好的一致率是 73.5%。对照 LitBench 论文的基线零样本 Claude-3.7-Sonnet 大约 73%训练后的 BT RM 和 GenRM 能到 78%。如果你用的是零样本 judge跑到 73% 左右是正常水平如果明显低于 65%检查是不是模型 ID 填错、prompt 模板有问题或者位置偏差处理逻辑有 bug。指标核对这块除了整体一致率建议再算两个东西。一是按故事长度分组的一致率看 judge 是不是偏向长文本import numpy as np from collections import defaultdict def eval_by_length(ds, judge_model): buckets defaultdict(lambda: [0, 0]) for sample in ds: prompt sample[prompt] chosen sample[chosen] rejected sample[rejected] len_bucket short if len(chosen.split()) 300 else long r1 judge_pair(prompt, chosen, rejected, judge_model) r2 judge_pair(prompt, rejected, chosen, judge_model) vote (1 if r1 A else 0) (1 if r2 B else 0) buckets[len_bucket][0] 1 if vote 1 else 0 buckets[len_bucket][1] 1 for k, (c, t) in buckets.items(): print(f{k}: {c/t:.4f} ({c}/{t}))二是算一下 judge 在两次顺序调用中答案不一致的比例这个指标反映位置偏差的严重程度def position_bias_rate(ds, judge_model): inconsistent 0 total 0 for sample in ds: prompt sample[prompt] chosen sample[chosen] rejected sample[rejected] r1 judge_pair(prompt, chosen, rejected, judge_model) r2 judge_pair(prompt, rejected, chosen, judge_model) # r1 选 A 表示选 chosenr2 选 B 表示选 chosen pick1 chosen if r1 A else rejected pick2 chosen if r2 B else rejected if pick1 ! pick2: inconsistent 1 total 1 print(f位置不一致率: {inconsistent/total:.4f} ({inconsistent}/{total}))如果位置不一致率超过 20%说明你的 judge prompt 需要优化或者考虑用两次平均的方式强制消除偏差。LitBench 论文里对位置偏差的处理就是两组顺序平均这个做法在工程上简单有效。跑完这些你手里就有了一份可复现的评估报告整体一致率、长度分组一致率、位置不一致率。这三个指标足够判断你的创意文本评估链路是否健康。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth跑这条链路最容易撞的几个报错我按实际遇到的频率排一下。401 Unauthorized。最常见的原因是 API Key 没设对。检查 .env 文件里 TAOTOKEN_API_KEY 的值是不是完整复制了有没有多余空格或换行。另一个原因是 base_url 写错比如写成了 https://taotoken.net/api/ 带尾斜杠有些库会拼出双斜杠导致鉴权失败。正确写法是 https://taotoken.net/api 不带尾斜杠。如果你在代码里硬编码了 Key确认没有把 Key 和 base_url 搞混。local proxy failed / connection error。这个报错通常和网络环境有关。先确认你的机器能正常访问 https://taotoken.net/api 用 curl 测一下curl -s -o /dev/null -w %{http_code} https://taotoken.net/api如果返回 401 或 404说明网络通问题在鉴权或路径如果超时或连接拒绝检查本地网络配置。注意不要在代码里设置任何代理相关的环境变量比如 HTTP_PROXY、HTTPS_PROXY这些会干扰请求。如果你之前设过用 unset 清掉unset HTTP_PROXY HTTPS_PROXY http_proxy https_proxyreading choices 报错 / KeyError: choices。这个通常出现在 API 返回了非预期结构时。比如模型 ID 填错接口返回了错误信息而不是正常的 chat completion 结构你的代码去取 resp.choices[0] 就会 KeyError。解决办法是在 judge_client.py 里加一层错误处理resp client.chat.completions.create(...) if not resp.choices: print(API 返回异常:, resp) return ERROR return resp.choices[0].message.content.strip()同时把模型 ID 和 TaoToken 文档里的列表核对一遍确认拼写完全一致。模型 ID 大小写敏感claude-3-7-sonnet 和 Claude-3.7-Sonnet 可能不一样。OAuth / authentication 相关报错。如果你用的是某些需要 OAuth 流程的工具比如 Claude Code 或 Codex 的 CLI它们有自己的认证机制。但在这条链路里我们用的是 API Key 方式不涉及 OAuth。如果你在配置 Claude Code 时遇到 OAuth 报错检查是不是把 API Key 和 OAuth token 混用了。Claude Code 接入 TaoToken 时需要配置三件套Base URL 填 https://taotoken.net/api Key 填你的 TaoToken API KeyModel ID 填文档里对应的模型名。这三项在 settings.json 或环境变量里都要写全缺一个就会报认证失败。还有一个容易忽略的点如果你用 Cline 或 CC Switch 这类工具MCP 配置里的 Base URL 和 Key 要单独设不要和全局环境变量冲突。Cline 的 MCP 配置里如果写了 localhost 或 127.0.0.1 的代理地址会直接报 local proxy failed。把 MCP server 的地址改成 TaoToken 的 API 地址或者干脆先关掉 MCP用纯 Python 脚本跑通再说。最后如果你在加载 LitBench 数据集时报错检查 datasets 库版本太老的版本可能不支持某些数据集格式。升级到最新版pip install -U datasets6. 把评估链路固定下来下一步才是调优链路跑通之后你手里有一套可复现的评估流程加载 LitBench 测试集、用 TaoToken 统一 Key 调 judge 模型、处理位置偏差、算一致率。这套流程的价值在于你换任何模型、任何 prompt 模板都能用同一套指标对比而不是凭感觉说“这个好像好一点”。如果你要长期做创意写作评估或 reward model 训练建议把评估脚本做成 CLI 工具参数化模型 ID、样本数、prompt 模板每次实验记录配置和结果。Coding Plan 适合这种需要反复跑实验的场景地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。如果你只是想快速验证某个模型当 judge 的效果直接用模型对话页面手动测几条也行地址是 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite API Key 管理在 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。跑评估时如果遇到接口层面的问题先查文档里的模型列表和参数说明大部分报错都是模型 ID 或 base_url 写法不对导致的。实测下来LitBench 这套数据最适合用来做一件事验证你的 judge 是不是真的比随机猜强。随机猜的一致率是 50%零样本强模型大概 73%训练过的 RM 能到 78%。如果你的 judge 跑出来只有 60% 出头别急着换模型先检查 prompt 模板和位置偏差处理这两个因素对结果的影响比模型本身还大。
阅读完成 · 觉得有帮助?
咨询建站