BlenderWorld 跑出来的分数对不上 / 是任务难度还是评分脚本在起作用?

文章导读
分数对不上时,先把“任务变难了”这个解释放到最后。可复核的做法是按固定顺序排除:先确认两次运行用的是同一份任务集,再把判分脚本单独跑在已保存的固定输出上确认判分自身稳定,然后对照 Blender 版本与渲染设置排除环境差异,最后按难度分档看差距是集中在某一档还是整体平移。顺序不能颠倒,因为任务集被换掉时,分档统计看起来也像“难度变了”;判分脚本不稳定时,环境对照也解释不了波动。
📋 目录
  1. Ⅰ 确认两次运行用的是同一份任务集
  2. Ⅱ 把判分脚本单独跑在固定输出上
  3. Ⅲ 按难度分档统计得分分布
  4. Ⅳ 对照 Blender 版本与渲染设置
  5. Ⅴ 写出结论:问题落在任务集、判分脚本还是环境
A A

分数对不上时,先把“任务变难了”这个解释放到最后。可复核的做法是按固定顺序排除:先确认两次运行用的是同一份任务集,再把判分脚本单独跑在已保存的固定输出上确认判分自身稳定,然后对照 Blender 版本与渲染设置排除环境差异,最后按难度分档看差距是集中在某一档还是整体平移。顺序不能颠倒,因为任务集被换掉时,分档统计看起来也像“难度变了”;判分脚本不稳定时,环境对照也解释不了波动。

BlenderWorld 分数与预期差距大,先判断输入是否一致,再判断判分是否确定性,最后才谈难度。执行上:比对任务清单哈希 → 用同一份 Agent 输出重复判分 → 按档位统计偏移形态 → 对照 Blender 版本与渲染参数。若任务清单哈希不同,问题在任务集;重复判分分项不一致,问题在判分脚本;两者都稳定而分档整体平移,再回到环境与难度。以上判断只对可保存输出、可重跑判分的配置成立,随机采样类指标需结合环境确认。

确认两次运行用的是同一份任务集

这一步的目标是排除最容易被忽略的情况:两次对比之间任务集被替换、增删或重新生成过。不要只看目录名,要看清单内容。建议在两次运行各自的任务集目录下执行同样的命令,把结果存成文件再比对。

# 清单条目数(确认有没有增删任务)
find . -name "*.yaml" | sort | wc -l

# 整个清单的聚合哈希(文件名顺序固定后再算)
find . -name "*.yaml" -print0 | sort -z | xargs -0 sha256sum | sha256sum

# 逐条哈希,便于定位到底改动了哪一条
find . -name "*.yaml" -print0 | sort -z | xargs -0 sha256sum > /tmp/tasks_run_A.sha256
diff /tmp/tasks_run_A.sha256 /tmp/tasks_run_B.sha256

条目数和聚合哈希都一致,基本可以认为任务集没变;条目数一致但哈希不同,用 diff 的输出定位到具体文件,再判断是任务描述、初始场景文件还是评分参考值被改过。评分参考值一旦变动,分数偏移和“难度变了”在表面上没有区别,所以这一步必须先做。替换项:*.yaml 换成你实际的任务清单后缀,文件名排序方式在两次运行中要保持一致。

把判分脚本单独跑在固定输出上

第二步验证判分环节本身是否稳定。做法是取一份已经落盘、不会再变的 Agent 输出文件,用同一份任务集重复判分两次,比较各分项是否逐项相同。判分脚本如果依赖时间戳、随机数、浮点比较容差或者遍历顺序不固定的字典,同一份输出可能给出不同的分数。

BlenderWorld 跑出来的分数对不上 / 是任务难度还是评分脚本在起作用?
python eval_score.py \
  `--task-set` ./tasks \
  `--agent-output` ./runs/agent_out_runA.jsonl \
  `--out` ./score/repeat_1.json

# 同一份输出再判一次
python eval_score.py \
  `--task-set` ./tasks \
  `--agent-output` ./runs/agent_out_runA.jsonl \
  `--out` ./score/repeat_2.json

diff <(jq -S . ./score/repeat_1.json) <(jq -S . ./score/repeat_2.json)

把结果按分项填进下表,逐行确认。jq -S 的作用是把键排序后再比较,避免输出顺序造成的假差异。

判分分项第一次分值第二次分值是否一致不一致时的可疑点
几何/结构匹配待填待填待填浮点容差、顶点顺序
材质/颜色匹配待填待填待填色彩空间、采样噪声
渲染图像相似度待填待填待填渲染器与采样设置
脚本/操作合规性待填待填待填遍历顺序、超时阈值
总分待填待填待填—

全部分项一致,说明判分是确定性的,可以把注意力转回任务集和环境;出现某一项反复抖动,就先修判分脚本里的不确定性来源,在此之前任何跨运行的分差都不可信。

按难度分档统计得分分布

把两次运行的逐题结果按难度档分组,看差值的形态。差距只出现在高难度档,倾向于任务难度或高难度任务本身对渲染细节敏感;所有档位平移相近的幅度,更像是判分口径或环境参数整体变了。下面是一个通用骨架,字段名按你的结果文件替换。

BlenderWorld 跑出来的分数对不上 / 是任务难度还是评分脚本在起作用?
import json, collections

rows = [json.loads(l) for l in open("score/result.jsonl")]
stat = collections.defaultdict(lambda: [0, 0.0, 0])
for r in rows:
    n, s, z = stat[r["difficulty"]]
    stat[r["difficulty"]] = [n + 1, s + r.get("score", 0.0),
                              z + (1 if r.get("score", 0) != r.get("prev_score", r.get("score", 0)) else 0)]

print(f"{'档位':<10}{'题数':>6}{'得分合计':>12}{'平均分':>10}{'分差非零题数':>14}")
for k in sorted(stat):
    n, s, z = stat[k]
    print(f"{k:<10}{n:>6}{s:>12.3f}{s / n:>10.3f}{z:>14}")

输出表头建议固定为:档位、题数、得分合计、平均分、分差非零题数。读表时先看“分差非零题数”在各档的分布,再看平均分差的方向;某档题数很少时,平均值容易波动,这种情况需要结合具体题目逐条看,不建议直接下结论。

对照 Blender 版本与渲染设置

前两步都稳定、但分档仍呈整体平移时,回到运行环境。需要逐项对照的参数清单如下,两次运行各记录一份:

  • Blender 版本号(blender `--version`)
  • 渲染引擎:CYCLES 或 EEVEE,以及引擎的子模式
  • 采样数与降噪开关
  • 输出分辨率与像素宽高比
  • 色彩管理与视图变换(Filmic / AgX / Standard)
  • 随机种子与是否开启自适应采样
  • Python 版本及 bpy 相关依赖版本

确认位置:运行日志开头通常会打印一段环境信息,Blender 版本一般出现在第一行或紧随启动参数的 Blender 字样行;渲染引擎和采样数通常在渲染任务开始前的设置回显里;色彩管理与视图变换有时不打印,需要在渲染前主动输出一次场景设置并写进日志。日志里找不到的参数,建议在脚本启动时统一打印,而不是靠事后回忆。

BlenderWorld 跑出来的分数对不上 / 是任务难度还是评分脚本在起作用?

版本号小版本不一致、引擎或视图变换不同,都会让图像相似度类判分项产生偏移;这类偏移在分档统计上表现为整体平移,与难度无关。改动渲染参数用于对齐时,要连带说明对历史分数的影响,不要把它当成提高分数的办法。

写出结论:问题落在任务集、判分脚本还是环境

把前面三步的证据拼起来,写成他人能照着复核的结论。建议用三段式,每段只放一个归属判断加一条证据。

结论一(任务集):两次运行的任务清单条目数为 __,聚合哈希 / 逐条 diff 结果为 __,
因此分数差异 [排除 / 归因于] 任务集变动。证据文件:/tmp/tasks_run_*.sha256

结论二(判分脚本):同一份 Agent 输出重复判分 __ 次,分项 __ 一致 / __ 不一致,
因此判分环节 [稳定 / 存在不确定性]。证据文件:score/repeat_*.json 及 diff 输出

结论三(环境与难度):Blender 版本 __ 与 __,引擎/采样/视图变换 __,
分档统计显示差异集中在 __ 档,整体平移幅度为 __,因此 [环境差异 / 难度分布 / 判分口径]
更可能是主因。证据文件:分档统计脚本输出

填写时保留三个边界:一是结论只覆盖已保存输出和已复跑判分的那部分任务,未覆盖的题目要单独说明;二是版本或渲染参数无法回溯时,结论写成“待确认”,不要补推测;三是分差非零题数很少的档位,不作为独立结论的依据。这样写出来的判断,别人按同样的命令和日志行就能复核。