fix: 优化裤装上身图裤长与景别

This commit is contained in:
hh
2026-07-15 00:22:36 +08:00
parent 1a40a8cb4b
commit ca3b09c62e
4 changed files with 612 additions and 83 deletions
+165 -23
View File
@@ -434,7 +434,7 @@ class StandaloneImageReferenceTests(TestCase):
for index, task in enumerate(tasks):
trace = task.request_payload["tryon_prompt"]
self.assertTrue(trace["applied"])
self.assertEqual(trace["version"], "v2.5")
self.assertEqual(trace["version"], "v2.6")
self.assertEqual(trace["rollout_source"], "global")
self.assertEqual(trace["effective_prompt"], used_prompts[index])
self.assertEqual(trace["shot_index"], index)
@@ -445,9 +445,10 @@ class StandaloneImageReferenceTests(TestCase):
self.assertEqual(trace["reference_roles"]["model_portrait_number"], 2)
self.assertIsNone(trace["reference_roles"]["model_triview_number"])
self.assertEqual(task.request_payload["tryon_classification"]["kind"], "lower")
self.assertEqual(trace["trouser_facts"], task.request_payload["tryon_trouser_facts"])
@override_settings(MODEL_TRYON_PROMPT_V2_ENABLED=True)
def test_model_tryon_v25_zero_cost_model_count_ratio_matrix(self):
def test_model_tryon_v26_zero_cost_model_count_ratio_matrix(self):
"""Mock 全矩阵:两个模型都覆盖 1/2/4 张与预设/自定义比例,不调用真实供应商。"""
CreditAccount.objects.filter(team=self.team).update(balance="5000.0000")
self.product.title = "舒适柔软面料女裤"
@@ -538,7 +539,7 @@ class StandaloneImageReferenceTests(TestCase):
trace = task.request_payload["tryon_prompt"]
effective_prompt = call.kwargs["prompt"]
self.assertEqual(task.model_config_id, model_config.id)
self.assertEqual(trace["version"], "v2.5")
self.assertEqual(trace["version"], "v2.6")
self.assertTrue(trace["applied"])
self.assertEqual(trace["rollout_source"], "global")
self.assertEqual(trace["shot_index"], index)
@@ -549,33 +550,174 @@ class StandaloneImageReferenceTests(TestCase):
self.assertEqual(trace["effective_prompt"], effective_prompt)
self.assertEqual(trace["reference_roles"]["product_numbers"], [1])
self.assertEqual(trace["reference_roles"]["model_portrait_number"], 2)
self.assertEqual(trace["trouser_facts"], task.request_payload["tryon_trouser_facts"])
self.assertEqual(trace["trouser_facts"]["length"], "unknown")
self.assertEqual(trace["trouser_facts"]["silhouette"], "unknown")
self.assertIn(f"严格使用 {ratio} 比例", effective_prompt)
self.assertIn("裤长人体落点", effective_prompt)
self.assertIn("裤装几何保真", effective_prompt)
self.assertNotIn("不得在九分裤、长裤、拖地裤之间变化", effective_prompt)
self.assertNotIn("背面", effective_prompt)
if count == 1:
self.assertIn("正面标准全身", effective_prompt)
elif count == 2:
expected_role = "正面标准全身" if index == 0 else "正面人物中景"
self.assertIn(expected_role, effective_prompt)
else:
expected_role = "全身" if index < 2 else "人物中景"
self.assertIn(expected_role, effective_prompt)
self.assertEqual(
call.kwargs[reference_key],
["http://x/cover.png", "http://x/matrix-model.png"],
)
for model_config, provider_method, _reference_key in models:
with self.subTest(model=model_config.name, explicit_back=True):
provider_method.reset_mock()
tasks = enqueue_standalone_images(
team=self.team,
user=self.user,
prompt="模特上身展示,完整展示后袋",
mode="model",
count=4,
product_id=str(self.product.id),
model_id=str(model_asset.id),
ratio="3:4",
image_model=f"{model_config.provider.name}:{model_config.name}",
)
prompts = [call.kwargs["prompt"] for call in provider_method.call_args_list]
self.assertEqual(len(tasks), 4)
self.assertEqual(len(prompts), 4)
self.assertTrue(all("背面全身站姿" not in prompt for prompt in prompts[:3]))
self.assertIn("背面全身站姿", prompts[3])
for count in (1, 2, 4):
with self.subTest(
model=model_config.name,
count=count,
default_ratio=True,
):
provider_method.reset_mock()
tasks = enqueue_standalone_images(
team=self.team,
user=self.user,
prompt="模特上身展示,自然光,真实质感,电商主图",
mode="model",
count=count,
product_id=str(self.product.id),
model_id=str(model_asset.id),
image_model=f"{model_config.provider.name}:{model_config.name}",
)
self.assertEqual(len(tasks), count)
for task, call in zip(tasks, provider_method.call_args_list):
task.refresh_from_db()
trace = task.request_payload["tryon_prompt"]
self.assertIsNone(trace["requested_ratio"])
self.assertEqual(trace["resolved_ratio"], "3:4")
self.assertEqual(trace["ratio_source"], "default")
self.assertIn("严格使用 3:4 比例", call.kwargs["prompt"])
for model_config, provider_method, _reference_key in models:
for count in (1, 2, 4):
for ratio in ratios:
with self.subTest(
model=model_config.name,
count=count,
ratio=ratio,
explicit_full_body=True,
):
provider_method.reset_mock()
tasks = enqueue_standalone_images(
team=self.team,
user=self.user,
prompt="每张全身站姿,从头到脚完整展示,双腿完整露出",
mode="model",
count=count,
product_id=str(self.product.id),
model_id=str(model_asset.id),
ratio=ratio,
image_model=f"{model_config.provider.name}:{model_config.name}",
)
prompts = [call.kwargs["prompt"] for call in provider_method.call_args_list]
self.assertEqual(len(tasks), count)
self.assertEqual(len(prompts), count)
for task, effective_prompt in zip(tasks, prompts):
task.refresh_from_db()
trace = task.request_payload["tryon_prompt"]
self.assertEqual(task.model_config_id, model_config.id)
self.assertEqual(trace["version"], "v2.6")
self.assertEqual(trace["resolved_ratio"], ratio)
self.assertIn(f"严格使用 {ratio} 比例", effective_prompt)
self.assertIn("全身站姿", effective_prompt)
self.assertIn("从头到脚完整入镜", effective_prompt)
self.assertNotIn("人物中景", effective_prompt)
self.assertNotIn("背面", effective_prompt)
self.assertNotIn("不得在九分裤、长裤、拖地裤之间变化", effective_prompt)
for model_config, provider_method, _reference_key in models:
for count in (1, 2, 4):
for ratio in ratios:
with self.subTest(
model=model_config.name,
count=count,
ratio=ratio,
explicit_back=True,
):
provider_method.reset_mock()
tasks = enqueue_standalone_images(
team=self.team,
user=self.user,
prompt="模特上身展示,完整展示后袋",
mode="model",
count=count,
product_id=str(self.product.id),
model_id=str(model_asset.id),
ratio=ratio,
image_model=f"{model_config.provider.name}:{model_config.name}",
)
prompts = [call.kwargs["prompt"] for call in provider_method.call_args_list]
self.assertEqual(len(tasks), count)
self.assertEqual(len(prompts), count)
self.assertTrue(all("背面全身站姿" not in prompt for prompt in prompts[:-1]))
self.assertIn("背面全身站姿", prompts[-1])
for task, effective_prompt in zip(tasks, prompts):
task.refresh_from_db()
trace = task.request_payload["tryon_prompt"]
self.assertEqual(task.model_config_id, model_config.id)
self.assertEqual(trace["version"], "v2.6")
self.assertEqual(trace["resolved_ratio"], ratio)
self.assertIn(f"严格使用 {ratio} 比例", effective_prompt)
if count == 2:
self.assertTrue(all("全身" in prompt for prompt in prompts))
if count == 4:
self.assertTrue(all("全身" in prompt for prompt in prompts[:2]))
self.assertIn("人物中景", prompts[2])
cross_category_cases = (
("高腰半身裙", "服饰内衣", "lower"),
("宽松针织上衣", "服饰内衣", "upper"),
("法式收腰连衣裙", "女装", "full_body"),
("女式运动鞋", "鞋靴", "footwear"),
("智能运动手表", "数码配件", "wrist"),
("便携无线小风扇", "家电", "handheld"),
)
for title, category, expected_kind in cross_category_cases:
self.product.title = title
self.product.category = category
self.product.save(update_fields=["title", "category"])
for model_config, provider_method, _reference_key in models:
with self.subTest(
model=model_config.name,
product=title,
cross_category=True,
):
provider_method.reset_mock()
tasks = enqueue_standalone_images(
team=self.team,
user=self.user,
prompt="模特上身展示,自然光,真实质感,电商主图",
mode="model",
count=4,
product_id=str(self.product.id),
model_id=str(model_asset.id),
ratio="3:4",
image_model=f"{model_config.provider.name}:{model_config.name}",
)
prompts = [call.kwargs["prompt"] for call in provider_method.call_args_list]
self.assertEqual(len(tasks), 4)
self.assertEqual(len(prompts), 4)
self.assertTrue(all(task.model_config_id == model_config.id for task in tasks))
self.assertTrue(
all(
task.request_payload["tryon_classification"]["kind"] == expected_kind
for task in tasks
)
)
self.assertTrue(
all("tryon_trouser_facts" not in task.request_payload for task in tasks)
)
self.assertNotIn("裤装几何保真", "\n".join(prompts))
self.assertNotIn("人物中景", "\n".join(prompts))
@override_settings(
MODEL_TRYON_PROMPT_V2_ENABLED=False,
@@ -623,7 +765,7 @@ class StandaloneImageReferenceTests(TestCase):
task = AITask.objects.get(id=submitted[0].id)
trace = task.request_payload["tryon_prompt"]
self.assertTrue(trace["applied"])
self.assertEqual(trace["version"], "v2.5")
self.assertEqual(trace["version"], "v2.6")
self.assertEqual(trace["rollout_source"], "canary")
@override_settings(