"""内衣·真人上身:换火山 Seedream 生图模型,看会不会被审核拦(对照 gpt-image-2 的 sexual 拦截)。 跑法: .venv/bin/python tryon_volcano_test.py 产物: /Users/maidong/Desktop/zyc/volcano_test """ import os import django os.environ.setdefault("DJANGO_SETTINGS_MODULE", "airshelf.settings.development") django.setup() from apps.products.models import Product # noqa: E402 from apps.assets.models import Asset # noqa: E402 from apps.ai.models import ModelConfig # noqa: E402 from apps.ai.services import ( # noqa: E402 get_image_provider, build_model_tryon_prompt_refs, _product_reference_urls, _asset_preview_url, ) from apps.ai.providers.volcano import VolcanoArkProvider # noqa: E402 PRODUCT_ID = "42078cdc-8714-4fc7-be5c-6aa42b7fc995" # 棉居莫代尔无痕内衣 MODEL_ID = "ad362810-cf3e-49c0-9426-8142a74b75b2" # 真人模特 OUT_DIR = "/Users/maidong/Desktop/zyc/volcano_test" # 试两个版本(从新到旧),哪个可用用哪个 VOLCANO_MODELS = ["doubao-seedream-5-0-260128", "doubao-seedream-4-5-251128"] def main(): os.makedirs(OUT_DIR, exist_ok=True) p = Product.objects.get(id=PRODUCT_ID) product_urls = _product_reference_urls(p, limit=3) model_url = _asset_preview_url(Asset.objects.get(id=MODEL_ID)) images = product_urls + [model_url] prompt = build_model_tryon_prompt_refs(p, has_model=True, base_prompt="", index=0, n_product=len(product_urls)) print(f"商品: {p.title} | 类目: {p.category} | 商品图数: {len(product_urls)} + 模特图") print(f"提示词:\n{prompt}\n") for mname in VOLCANO_MODELS: mc = ModelConfig.objects.filter(capability="image", name=mname).first() if mc is None: print(f"⚠️ 库里没有模型配置 {mname},跳过") continue provider = get_image_provider(mc) print(f"\n━━━ 火山 {mc.provider.name}:{mname} ━━━") try: # Seedream 多图参考走 image 参数(可传 URL 列表);size 用 2K resp = provider.image_generation(model=mname, prompt=prompt, image=images, size="2K") media = provider.extract_first_media_url(resp) fileobj, ct = VolcanoArkProvider.media_to_bytes(media) ext = ".jpg" if "jpeg" in ct else (".webp" if "webp" in ct else ".png") path = os.path.join(OUT_DIR, f"volcano_{mname}{ext}") with open(path, "wb") as f: f.write(fileobj.getvalue()) print(f"✅ 出图成功 → {path}") break except Exception as exc: # noqa: BLE001 msg = str(exc) flagged = any(k in msg.lower() for k in ("moderation", "safety", "sexual", "blocked", "sensitive", "审核", "违规", "content")) print(f"❌ 失败{' · 命中内容审核' if flagged else ''}: {msg[:600]}") print(f"\n完成。产物: {OUT_DIR}") if __name__ == "__main__": main()