Broaden seed axis simulation checks
This commit is contained in:
@@ -93,6 +93,30 @@ def _character_cast(*, pov_man: bool = False) -> str:
|
||||
)["character_cast"]
|
||||
|
||||
|
||||
def _random_character_cast() -> str:
|
||||
cast = pb.build_character_slot_json(
|
||||
subject_type="woman",
|
||||
label="A",
|
||||
age="random",
|
||||
ethnicity="random",
|
||||
figure="random",
|
||||
body="random",
|
||||
hair_color="random",
|
||||
hair_length="random",
|
||||
hair_style="random",
|
||||
descriptor_detail="full",
|
||||
)["character_cast"]
|
||||
return pb.build_character_slot_json(
|
||||
subject_type="man",
|
||||
label="A",
|
||||
age="random",
|
||||
ethnicity="random",
|
||||
body="random",
|
||||
descriptor_detail="compact",
|
||||
character_cast=cast,
|
||||
)["character_cast"]
|
||||
|
||||
|
||||
def _coworking_location_config() -> str:
|
||||
return pb.build_location_pool_json(
|
||||
enabled=True,
|
||||
@@ -106,6 +130,32 @@ def _coworking_location_config() -> str:
|
||||
)
|
||||
|
||||
|
||||
def _seed_probe_location_config() -> str:
|
||||
return pb.build_location_pool_json(
|
||||
enabled=True,
|
||||
combine_mode="replace",
|
||||
preset="custom_only",
|
||||
custom_locations=(
|
||||
"seed_coworking_desk: coworking desk row with warm lamps and laptops\n"
|
||||
"seed_coworking_glass: coworking glass office with plants and partition seams\n"
|
||||
"seed_coworking_windows: coworking window lounge with repeated desks and city light"
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def _seed_probe_composition_config() -> str:
|
||||
return pb.build_composition_pool_json(
|
||||
enabled=True,
|
||||
combine_mode="replace",
|
||||
preset="custom_only",
|
||||
custom_compositions=(
|
||||
"seed composition near a desk edge\n"
|
||||
"seed composition through a glass partition\n"
|
||||
"seed composition down repeating desk rows"
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def _orbit_camera(horizontal_angle: int = 45, vertical_angle: int = 0, zoom: float = 6.0) -> str:
|
||||
return pb.build_camera_orbit_config_json(
|
||||
enabled=True,
|
||||
@@ -602,8 +652,8 @@ def _insta_pair_case(seed: int, *, pov: bool, position: str, focus: str, family:
|
||||
)
|
||||
|
||||
|
||||
def _seed_axis_check(seed: int) -> dict[str, Any]:
|
||||
base = pb.build_prompt(
|
||||
def _seed_probe_row(seed: int, *, reroll_axis: str = "none", reroll_seed: int = -1) -> dict[str, Any]:
|
||||
return pb.build_prompt(
|
||||
category="Hardcore sexual poses",
|
||||
subcategory="Penetrative sex",
|
||||
row_number=1,
|
||||
@@ -622,64 +672,146 @@ def _seed_axis_check(seed: int) -> dict[str, Any]:
|
||||
prepend_trigger_to_prompt=True,
|
||||
extra_positive="",
|
||||
extra_negative="",
|
||||
seed_config=pb.build_seed_lock_config_json(base_seed=seed),
|
||||
seed_config=pb.build_seed_lock_config_json(base_seed=seed, reroll_axis=reroll_axis, reroll_seed=reroll_seed),
|
||||
women_count=1,
|
||||
men_count=1,
|
||||
character_cast=_character_cast(),
|
||||
character_cast=_random_character_cast(),
|
||||
hardcore_position_config=_position_filter("penetration_only", "penetration", ["missionary", "doggy", "cowgirl"]),
|
||||
location_config=_coworking_location_config(),
|
||||
location_config=_seed_probe_location_config(),
|
||||
composition_config=_seed_probe_composition_config(),
|
||||
expression_intensity=0.75,
|
||||
)
|
||||
changed = False
|
||||
mismatches: list[str] = []
|
||||
for reroll_seed in range(seed + 1, seed + 10):
|
||||
rerolled = pb.build_prompt(
|
||||
category="Hardcore sexual poses",
|
||||
subcategory="Penetrative sex",
|
||||
row_number=1,
|
||||
start_index=1,
|
||||
seed=seed,
|
||||
clothing="random",
|
||||
ethnicity="any",
|
||||
poses="random",
|
||||
backside_bias=0.0,
|
||||
figure="random",
|
||||
no_plus_women=False,
|
||||
no_black=False,
|
||||
minimal_clothing_ratio=-1,
|
||||
standard_pose_ratio=-1,
|
||||
trigger=TRIGGER,
|
||||
prepend_trigger_to_prompt=True,
|
||||
extra_positive="",
|
||||
extra_negative="",
|
||||
seed_config=pb.build_seed_lock_config_json(base_seed=seed, reroll_axis="pose", reroll_seed=reroll_seed),
|
||||
women_count=1,
|
||||
men_count=1,
|
||||
character_cast=_character_cast(),
|
||||
hardcore_position_config=_position_filter("penetration_only", "penetration", ["missionary", "doggy", "cowgirl"]),
|
||||
location_config=_coworking_location_config(),
|
||||
)
|
||||
if rerolled.get("cast_descriptor_text") != base.get("cast_descriptor_text"):
|
||||
mismatches.append(f"cast changed on pose reroll {reroll_seed}")
|
||||
if rerolled.get("scene_text") != base.get("scene_text"):
|
||||
mismatches.append(f"scene changed on pose reroll {reroll_seed}")
|
||||
if (
|
||||
rerolled.get("position_key") != base.get("position_key")
|
||||
or rerolled.get("source_role_graph") != base.get("source_role_graph")
|
||||
or rerolled.get("item") != base.get("item")
|
||||
):
|
||||
changed = True
|
||||
break
|
||||
issues = list(mismatches)
|
||||
if not changed:
|
||||
issues.append("pose reroll did not change pose/action metadata within 9 attempts")
|
||||
|
||||
|
||||
def _seed_probe_snapshot(row: dict[str, Any]) -> dict[str, Any]:
|
||||
return {
|
||||
"name": "seed_axis.pose_reroll",
|
||||
"base": _row_summary(base),
|
||||
"changed": changed,
|
||||
"cast_descriptor_text": row.get("cast_descriptor_text"),
|
||||
"scene": row.get("scene"),
|
||||
"scene_text": row.get("scene_text"),
|
||||
"position_key": row.get("position_key"),
|
||||
"position_keys": row.get("position_keys") or [],
|
||||
"item": row.get("item"),
|
||||
"source_role_graph": row.get("source_role_graph"),
|
||||
"character_expression_text": row.get("character_expression_text"),
|
||||
"composition": row.get("composition"),
|
||||
}
|
||||
|
||||
|
||||
def _same_fields_issues(
|
||||
name: str,
|
||||
base: dict[str, Any],
|
||||
rerolled: dict[str, Any],
|
||||
fields: tuple[str, ...],
|
||||
reroll_seed: int,
|
||||
) -> list[str]:
|
||||
return [
|
||||
f"{name}: stable_field_changed:{field}:reroll_seed={reroll_seed}"
|
||||
for field in fields
|
||||
if base.get(field) != rerolled.get(field)
|
||||
]
|
||||
|
||||
|
||||
def _formatter_output_texts(row: dict[str, Any]) -> dict[str, str]:
|
||||
formatted = _format_metadata(row, "single")
|
||||
return {
|
||||
"krea": str(formatted["krea"].get("krea_prompt") or ""),
|
||||
"sdxl": str(formatted["sdxl"].get("sdxl_prompt") or ""),
|
||||
"caption": str(formatted["caption"].get("natural_caption") or ""),
|
||||
}
|
||||
|
||||
|
||||
def _seed_determinism_check(seed: int) -> dict[str, Any]:
|
||||
first = _seed_probe_row(seed)
|
||||
second = _seed_probe_row(seed)
|
||||
issues: list[str] = []
|
||||
if first != second:
|
||||
issues.append("locked seed config did not reproduce identical row metadata")
|
||||
if _formatter_output_texts(first) != _formatter_output_texts(second):
|
||||
issues.append("locked seed config did not reproduce identical formatter outputs")
|
||||
return {
|
||||
"name": "seed_axis.locked_determinism",
|
||||
"base": _row_summary(first),
|
||||
"changed": False,
|
||||
"issues": issues,
|
||||
}
|
||||
|
||||
|
||||
def _seed_reroll_check(
|
||||
seed: int,
|
||||
*,
|
||||
reroll_axis: str,
|
||||
changed_fields: tuple[str, ...],
|
||||
stable_fields: tuple[str, ...],
|
||||
) -> dict[str, Any]:
|
||||
name = f"seed_axis.{reroll_axis}_reroll"
|
||||
base = _seed_probe_row(seed)
|
||||
base_snapshot = _seed_probe_snapshot(base)
|
||||
changed = False
|
||||
changed_seed = None
|
||||
changed_field_names: list[str] = []
|
||||
issues: list[str] = []
|
||||
for reroll_seed in range(seed + 1, seed + 16):
|
||||
rerolled = _seed_probe_row(seed, reroll_axis=reroll_axis, reroll_seed=reroll_seed)
|
||||
rerolled_snapshot = _seed_probe_snapshot(rerolled)
|
||||
field_issues = _same_fields_issues(name, base_snapshot, rerolled_snapshot, stable_fields, reroll_seed)
|
||||
if field_issues:
|
||||
issues.extend(field_issues)
|
||||
break
|
||||
changed_field_names = [
|
||||
field for field in changed_fields if base_snapshot.get(field) != rerolled_snapshot.get(field)
|
||||
]
|
||||
if changed_field_names:
|
||||
changed = True
|
||||
changed_seed = reroll_seed
|
||||
break
|
||||
if not changed:
|
||||
issues.append(f"{reroll_axis} reroll did not change {', '.join(changed_fields)} within 15 attempts")
|
||||
return {
|
||||
"name": name,
|
||||
"base": _row_summary(base),
|
||||
"changed": changed,
|
||||
"changed_seed": changed_seed,
|
||||
"changed_fields": changed_field_names,
|
||||
"issues": issues,
|
||||
}
|
||||
|
||||
|
||||
def _seed_axis_checks(seed: int) -> list[dict[str, Any]]:
|
||||
return [
|
||||
_seed_determinism_check(seed),
|
||||
_seed_reroll_check(
|
||||
seed,
|
||||
reroll_axis="person",
|
||||
changed_fields=("cast_descriptor_text",),
|
||||
stable_fields=("scene_text", "position_key", "item", "source_role_graph", "character_expression_text", "composition"),
|
||||
),
|
||||
_seed_reroll_check(
|
||||
seed,
|
||||
reroll_axis="scene",
|
||||
changed_fields=("scene", "scene_text"),
|
||||
stable_fields=("cast_descriptor_text", "position_key", "item", "source_role_graph", "character_expression_text", "composition"),
|
||||
),
|
||||
_seed_reroll_check(
|
||||
seed,
|
||||
reroll_axis="pose",
|
||||
changed_fields=("position_key", "item", "source_role_graph"),
|
||||
stable_fields=("cast_descriptor_text", "scene_text", "character_expression_text", "composition"),
|
||||
),
|
||||
_seed_reroll_check(
|
||||
seed,
|
||||
reroll_axis="expression",
|
||||
changed_fields=("character_expression_text",),
|
||||
stable_fields=("cast_descriptor_text", "scene_text", "position_key", "item", "source_role_graph", "composition"),
|
||||
),
|
||||
_seed_reroll_check(
|
||||
seed,
|
||||
reroll_axis="composition",
|
||||
changed_fields=("composition",),
|
||||
stable_fields=("cast_descriptor_text", "scene_text", "position_key", "item", "source_role_graph", "character_expression_text"),
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def run_simulation(seed: int = 3901, *, include_prompts: bool = False) -> dict[str, Any]:
|
||||
cases: list[dict[str, Any]] = []
|
||||
regular = _regular_single_case(seed)
|
||||
@@ -705,7 +837,7 @@ def run_simulation(seed: int = 3901, *, include_prompts: bool = False) -> dict[s
|
||||
cases.extend(_pair_reports("insta_pair.penetration", penetration_pair, include_prompts=include_prompts))
|
||||
pov_pair = _insta_pair_case(seed + 2, pov=True, position="penis_licking", focus="outercourse_only", family="outercourse")
|
||||
cases.extend(_pair_reports("insta_pair.pov_outercourse", pov_pair, include_prompts=include_prompts))
|
||||
axis_checks = [_seed_axis_check(seed + 3)]
|
||||
axis_checks = _seed_axis_checks(seed + 3)
|
||||
issues = [
|
||||
{"case": case["name"], "issue": issue}
|
||||
for case in cases
|
||||
|
||||
Reference in New Issue
Block a user