refactor(sampler): replace family_spec param with level+constraint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-14 05:38:14 -04:00
parent b6b6a48503
commit e2325b6535
3 changed files with 100 additions and 56 deletions
+19 -19
View File
@@ -1,16 +1,17 @@
"""v2 素材采样器 — 基于家族约束的树节点采样与上下文收集。
"""v2 素材采样器 — 基于采样约束的树节点采样与上下文收集。
在 v1 synthesizer 的基础上引入 QuestionFamilySpec 约束验证,
在 v1 synthesizer 的基础上引入 SamplingConstraint 约束验证,
为每次出题提供更丰富的素材上下文(字幕、跨 L2 上下文、帧路径)。
典型调用路径::
material = sample_material_v2(
tree=tree_index,
family_spec=REASONING_FAMILY,
task_type="Causal Reasoning",
task_type="Action Reasoning",
used_node_ids=already_used,
rng=rng,
level=2,
constraint=my_constraint,
)
"""
@@ -24,7 +25,7 @@ from loguru import logger
if TYPE_CHECKING:
import random
from app.question_gen.families import QuestionFamilySpec, SamplingConstraint
from app.question_gen.families import SamplingConstraint
from app.tree.index import L1Node, L2Node, TreeIndex
# ---------------------------------------------------------------------------
@@ -35,18 +36,18 @@ _TASK_TYPE_TO_LEVEL: dict[str, int] = {
# Level 3(细粒度帧级)
"Action Recognition": 3,
"Object Recognition": 3,
"Attribute Perception": 3,
"OCR Problems": 3,
# Level 2(片段/事件级)
"Action Reasoning": 2,
"Action Prediction": 2,
"Action Sequence": 2,
"Object Reasoning": 2,
"Object Interaction": 2,
"Scene Understanding": 2,
"Event Reasoning": 2,
"Causal Reasoning": 2,
"Information Synopsis": 2,
"Counting Problem": 2,
# Level 1(段落/场景级)
"Temporal Reasoning": 1,
"Temporal Perception": 1,
"Spatial Reasoning": 1,
"Spatial Perception": 1,
}
@@ -494,17 +495,18 @@ def _collect_source_nodes(tree: TreeIndex, node_id: str) -> tuple[str, ...]:
def sample_material_v2(
tree: TreeIndex,
family_spec: QuestionFamilySpec,
task_type: str,
used_node_ids: set[str],
rng: random.Random,
*,
level: int,
constraint: SamplingConstraint,
max_attempts: int = 10,
) -> MaterialContext:
"""基于家族约束从视频树中采样素材上下文。
"""基于采样约束从视频树中采样素材上下文。
采样流程:
1. 根据 task_type 确定采样层级
1. 按指定 level 确定采样层级
2. 随机选取候选节点(排除 used_node_ids
3. 验证 SamplingConstraint 约束
4. 约束不满足则重试(最多 max_attempts 次)
@@ -512,10 +514,11 @@ def sample_material_v2(
参数:
tree: 三层树索引。
family_spec: 问题家族规格(含采样约束)。
task_type: 任务类型字符串。
used_node_ids: 本轮已用节点 ID 集合。
rng: 可控随机数生成器。
level: 采样层级(1/2/3)。
constraint: 采样约束条件。
max_attempts: 最大尝试次数。
返回:
@@ -523,10 +526,7 @@ def sample_material_v2(
异常:
RuntimeError: 耗尽 max_attempts 次尝试仍无法满足约束。
KeyError: task_type 不在 _TASK_TYPE_TO_LEVEL 映射中。
"""
level = _TASK_TYPE_TO_LEVEL[task_type]
constraint = family_spec.sampling
for attempt in range(max_attempts):
# Phase 1: 按层级采样候选节点
@@ -589,5 +589,5 @@ def sample_material_v2(
raise RuntimeError(
f"sample_material_v2: 耗尽 max_attempts={max_attempts} 次尝试,"
f"无法为 task_type='{task_type}' 满足家族 '{family_spec.name}'采样约束"
f"无法为 task_type='{task_type}' (level={level}) 满足采样约束"
)