feat(question_gen): loader 按 unit 分层采样 + load_benchmark 读回 pair 字段
stratified_sample 先 build_units 聚合,以 QuestionUnit 为采样原子做 分层/去重/补足/rng.sample,返回前 flatten_units 展开为逐题列表; size/correct_ratio/min_per_class 均按 unit 计数,单元正确性走成员 AND, 孪生对两题永不被劈开。纯 single 输入下 build_units 1:1 折叠、顺序不变, rng 消耗与旧逐题实现字节级一致(新增回归测试守护)。 _backfill_per_class candidates 改按 unit 枚举去重;build_units/flatten_units 函数内延迟导入以规避 question_gen<->harness 循环依赖(沿用 adversarial_filter)。 load_benchmark 反序列化补 pair_id/question_role/flip_axis/unit_id 四字段, 用 .get 兼容旧 JSON(缺失退化为 single,unit_id 由 __post_init__ 回填)。 pools._sample_excluding 随之改为透传 flatten_units(candidates) 给已单元化的 stratified_sample(不再用 lone pair-original 代表),行为对 single-only 保持等价。
This commit is contained in:
+7
-12
@@ -214,16 +214,16 @@ def _sample_excluding(
|
||||
) -> list[GeneratedQuestion]:
|
||||
"""排除已选 unit 后,以 unit 为原子按 cfg 分层采样,返回展开后的逐题列表。
|
||||
|
||||
每个单元以其首题作为分层采样的代表参与 stratified_sample,correct_ratio /
|
||||
size 因此按 unit 计数(pair 计 1 个 unit);命中的单元整体展开,孪生对两题
|
||||
永远同进同出。single-only 输入下 unit 与 question 一一对应、顺序不变,采样
|
||||
结果与逐题采样完全一致。
|
||||
候选单元展开为逐题列表后透传给 stratified_sample,后者内部重新 build_units
|
||||
做单元原子采样:correct_ratio / size 按 unit 计数(pair 计 1 个 unit),单元级
|
||||
正确性由 stratified_sample 内部对成员取 AND,命中的孪生对两题永远同进同出。
|
||||
single-only 输入下 unit 与 question 一一对应、顺序不变,采样结果与逐题采样一致。
|
||||
|
||||
参数:
|
||||
units: 单元全集(single 单封、pair 成对聚合)。
|
||||
exclude_unit_ids: 已被其他池选走的 unit_id,从候选中剔除以保证三池互斥。
|
||||
correctness: question_id -> 基线是否答对;单元级正确性取成员的 AND
|
||||
(缺失按 False,与 stratified_sample 的宽松口径一致)。
|
||||
correctness: question_id -> 基线是否答对;单元级正确性由 stratified_sample
|
||||
对成员取 AND(缺失按 False,宽松口径)。
|
||||
cfg: 透传给 stratified_sample 的采样配置
|
||||
(size/correct_ratio/task_types[/seed/min_per_class])。
|
||||
|
||||
@@ -231,12 +231,7 @@ def _sample_excluding(
|
||||
采样命中单元展开后的题目列表。
|
||||
"""
|
||||
candidates = [u for u in units if u.unit_id not in exclude_unit_ids]
|
||||
rep_to_unit = {u.questions[0].question_id: u for u in candidates}
|
||||
reps = [u.questions[0] for u in candidates]
|
||||
unit_correct = {u.questions[0].question_id: _unit_correct(u, correctness) for u in candidates}
|
||||
sampled_reps = stratified_sample(reps, unit_correct, **cfg)
|
||||
sampled_units = [rep_to_unit[rep.question_id] for rep in sampled_reps]
|
||||
return flatten_units(sampled_units)
|
||||
return stratified_sample(flatten_units(candidates), correctness, **cfg)
|
||||
|
||||
|
||||
def _q_to_dict(q: GeneratedQuestion) -> dict:
|
||||
|
||||
Reference in New Issue
Block a user