"""Read-only, local Checkpoint samples. Never submit a generation job.""" from functools import lru_cache import json from pathlib import Path from int8_backend import MODEL_ALIASES ROOT = Path(__file__).resolve().parent / "assets/model_samples/anima" AESTHETIC = "anima-aestheticV11_INT8.safetensors" NOTES = { "anima-turbo-v1.1_INT8.safetensors": "公式Turbo系のINT8版。サンプルは8 steps / CFG 1.0、Turbo LoRAなしで生成しています。", AESTHETIC: "高品質画像で追加学習されたAesthetic系のINT8版。下に共通設定と推奨プロンプトの一例を併記しています。", "fnMixAnimaTurbo_baseNoTurbo_INT8.safetensors": "非Turbo版(baseNoTurbo)のINT8版です。名前にTurboを含みますが、まず通常(非Turbo)プリセットで確認してください。", "fwaunAnima_v11_INT8.safetensors": "Fwaun Anima v1.1のINT8版。サンプルは通常(非Turbo)プリセット、LoRAなしの作例です。", "tekitoMix_v32_INT8.safetensors": "tekitoMix v3.2のINT8版。サンプルは通常(非Turbo)プリセット、LoRAなしの作例です。", } AESTHETIC_NOTE = ( "**Aestheticのプロンプトについて**\n\n" "[配布元の説明](https://huggingface.co/circlestone-labs/Anima#aesthetic-version-prompting)では、" "ポジティブのクオリティタグは不要ですが、`masterpiece, best quality`を残してもよいとされています。" "`score_*`はポジティブ・ネガティブとも非推奨です。\n\n" "追加サンプルは、共通設定からポジティブ先頭の`masterpiece, best quality`だけを省略したものです。" "元の共通設定にもscoreタグは含まれません。Seed・Steps・CFG・ネガティブなどは同一です。" "タグを省略すれば必ず改善する、という意味ではありません。" ) @lru_cache(maxsize=2) def records(recommended=False): directory = ROOT / "aesthetic-recommended" if recommended else ROOT return json.loads((directory / "manifest.json").read_text(encoding="utf-8"))["images"] def image_path(record, recommended=False): directory = ROOT / "aesthetic-recommended" if recommended else ROOT path = (directory / record["file"]).resolve() if not path.is_relative_to(directory.resolve()) or not path.is_file(): raise ValueError("Missing or unsafe model sample path") return str(path) def conditions(items): if not items: return "このCheckpointのサンプルはまだありません。" first = items[0] text = ( f"**実際のモデル:** `{first['model']}`(非公式INT8量子化版)\n\n" f"{first['width']}×{first['height']} / {first['steps']} steps / CFG {first['cfg']} / " f"`{first['sampler']}` / `{first['scheduler']}`\n\n" "LoRA・Embeddingはすべて無効。VAE: `qwen_image_vae.safetensors`。画像の選別・後加工なし。\n\n" ) for item in items: text += f"**{item['label']} — Seed: {item['seed']}**\n\n```text\n{item['prompt']}\n```\n\n" return text + f"**共通Negative prompt**\n\n```text\n{first['negative_prompt']}\n```" def sample_data(model): model = MODEL_ALIASES.get(model, model) common = [r for r in records() if r["model"] == model] recommended = [r for r in records(True) if r["model"] == model] note = NOTES.get(model, "このCheckpointのサンプルはまだありません。") if model == AESTHETIC: note += "\n\n" + AESTHETIC_NOTE note += ("\n\n比較用の作例です。モデル別の描写・プロンプト追従の違いをご確認ください。" "Turboと非TurboではSteps・CFGが異なります。現在の生成設定を変更する機能ではありません。") def paths(items, is_recommended=False): by_kind = {r["kind"]: r for r in items} return [image_path(by_kind[k], is_recommended) if k in by_kind else None for k in ("portrait", "garden")] return note, paths(common), conditions(common), paths(recommended, True), conditions(recommended), bool(recommended) def build_model_samples(model_input): import gradio as gr def update(model): note, common, details, recommended, rec_details, visible = sample_data(model) return note, *common, details, gr.update(visible=visible), *recommended, rec_details note, common, details, recommended, rec_details, visible = sample_data(model_input.value) with gr.Accordion("モデルの特徴・サンプルはこちら", open=False, elem_classes="checkpoint-samples"): description = gr.Markdown(note) gr.Markdown("### 共通設定でのサンプル") with gr.Row(): portrait = gr.Image(common[0], label="人物・上半身", interactive=False, format="png", height=280, min_width=200) garden = gr.Image(common[1], label="人物+背景", interactive=False, format="png", height=280, min_width=200) with gr.Accordion("共通設定:生成条件・プロンプト", open=False): common_details = gr.Markdown(details) with gr.Group(visible=visible) as extra: gr.Markdown("### Aesthetic推奨設定でのサンプル(クオリティタグ省略)") with gr.Row(): rec_portrait = gr.Image(recommended[0], label="推奨設定・上半身", interactive=False, format="png", height=280, min_width=200) rec_garden = gr.Image(recommended[1], label="推奨設定・人物+背景", interactive=False, format="png", height=280, min_width=200) with gr.Accordion("推奨設定:生成条件・プロンプト", open=False): recommended_details = gr.Markdown(rec_details) model_input.change( update, inputs=model_input, outputs=[description, portrait, garden, common_details, extra, rec_portrait, rec_garden, recommended_details], queue=False, api_visibility="private", show_progress="hidden", )