Guanghu Domestic Migration d1e47f4565
Some checks are pending
自动更新代码和重启 / update-and-restart (push) Waiting to run
CI检查 + 自动部署 / check (push) Waiting to run
CI检查 + 自动部署 / deploy (push) Blocked by required conditions
重启聊天服务 / restart (push) Waiting to run
chore: import sanitized domestic snapshot for REPO-002
Source snapshot: ca48d3ddf926d79aa138306164169baf764bb829
2026-07-17 15:54:41 +08:00

88 lines
4.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""CHAR-003 V2 R9 QC · 去麻子 · Qwen-VL"""
import sys, os, json, base64, subprocess
from pathlib import Path
ROOT = Path('D:/WorkBuddy/guanghulab/video-ai-system')
env = {}
for line in open(ROOT/".env"):
line = line.strip()
if line and not line.startswith("#") and "=" in line:
k, v = line.split("=", 1)
env[k.strip()] = v.strip()
AK = env.get("ALIYUN_QWEN_VL_KEY", "")
EP = env.get("ALIYUN_QWEN_VL_ENDPOINT", "")
FE = "https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"
DIR = ROOT / "assets/candidates/D158-VA-05-001-V2/CHAR-003-SuBai/R9"
CS = [DIR / f"CHAR-003-V2-R9-candidate-{i:02d}-1080x1920.png" for i in range(1, 5)]
PROMPT = """检查CHAR-003苏白立绘。设定18岁男性白色长衫青色腰带黑色长发半束半披双手叉腰自信开朗俊秀略带痞气穷但不自卑。
判定JSON布尔小写
1. male: 是否为男性?
2. young: 是否看起来17-18岁年轻少年
3. white_robe: 是否白色长衫?
4. cyan_sash: 是否有青色/深色腰带?
5. hair_half_tied: 是否黑色长发半束半披(头顶束发带)?
6. hands_on_hips: 是否双手叉腰?
7. intact: 服装是否完整干净无破损?
8. beggar: 是否有乞丐感/寒酸感true=有,一票否决)
9. handsome_confident: 是否俊秀自信?
10. like_zhuge: 是否与诸葛风长相相似true=相似,一票否决)
11. face_ok: 五官是否清晰无崩坏?
12. full_body: 是否全身完整?
13. freckles: 脸上是否有雀斑/麻子/斑点true=有,一票否决)
14. sleeves_ok: 袖子是否完整(非无袖背心)?
pass = 男性且年轻且白衫且腰带且半束发且叉腰且完整且俊秀且五官清晰且全身完整且无麻子且无袖正常,且 beggar=false 且 like_zhuge=false。
输出格式:{{"candidate": N, "pass": bool, "score": 0-100, "male": bool, "young": bool, ...}} 以及 "summary": "一句话"""
def enc(p):
with open(p, "rb") as f:
return f"data:image/png;base64,{base64.b64encode(f.read()).decode()}"
def q(img):
b = json.dumps({"model": "qwen-vl-max", "input": {"messages": [{"role": "user", "content": [{"image": img}, {"text": PROMPT}]}]}})
for ep in [EP, FE]:
try:
r = subprocess.run(["curl", "-s", "-m", "90", "--noproxy", "*", "-X", "POST", ep,
"-H", f"Authorization: Bearer {AK}", "-H", "Content-Type: application/json", "--data-binary", "@-"],
input=b, capture_output=True, text=True, timeout=95)
d = json.loads(r.stdout)
if "output" in d:
c = d["output"]["choices"][0]["message"]["content"][0]["text"]
if "```" in c:
c = c.split("```")[1]
c = c[4:] if c.startswith("json") else c
c = c.replace("```", "").strip()
return json.loads(c)
except Exception as e:
print(e)
continue
return None
rs = []
for i, p in enumerate(CS):
print(f"[{i+1}/4]", end=" ", flush=True)
qc = q(enc(p))
if qc:
qc["candidate"] = i + 1
print(f"pass={qc.get('pass')} s={qc.get('score')}")
rs.append(qc)
else:
print("")
rs.append({"candidate": i+1, "pass": False, "error": "api"})
ok = sum(1 for r in rs if r.get("pass"))
print(f"\n通过: {ok}/4")
for r in rs:
if not r.get("pass") and "error" not in r:
iss = [k for k, v in r.items() if isinstance(v, bool) and v and k in ["beggar", "like_zhuge", "freckles"]]
iss += [k for k, v in r.items() if isinstance(v, bool) and not v and k in ["male", "young", "white_robe", "cyan_sash", "hair_half_tied", "hands_on_hips", "intact", "handsome_confident", "face_ok", "full_body", "sleeves_ok"]]
print(f"{r['candidate']} ✗: {','.join(iss) if iss else '其他'} s={r.get('score')}")
with open(DIR / "QC-R9-BATCH.json", "w", encoding="utf-8") as f:
json.dump({"spec": "VA-05-001-V2-R9", "method": "qwen-vl-auto", "results": rs, "summary": {"passed": ok, "total": 4}}, f, ensure_ascii=False, indent=2)
print("报告: QC-R9-BATCH.json")