import os import gc import gradio as gr from PIL import Image from transformers import pipeline import gradio, gradio_client print("Gradio versions =>", gradio.__version__, "/", gradio_client.__version__) # 環境變數:減少警告與執行緒開銷 os.environ["TRANSFORMERS_NO_ADVISORY_WARNINGS"] = "true" os.environ["TOKENIZERS_PARALLELISM"] = "false" os.environ["PIP_DISABLE_PIP_VERSION_CHECK"] = "1" # 嘗試偵測 torch(若沒裝也能跑,僅用 CPU) try: import torch _HAS_TORCH = True except Exception: torch = None _HAS_TORCH = False # 懶載入 _captioner = None def get_device_id(): if _HAS_TORCH: try: return 0 if torch.cuda.is_available() else -1 except Exception: return -1 return -1 def get_captioner(): global _captioner if _captioner is None: print("📦 載入模型中(BLIP base)...") _captioner = pipeline( task="image-to-text", model="Salesforce/blip-image-captioning-base", device=get_device_id(), ) print("✅ 模型載入完成。") return _captioner def do_caption(image: Image.Image): if image is None: return "請先上傳圖片。" pipe = get_captioner() out = pipe(image) gc.collect() return out[0]["generated_text"] def clear_all(): return None, "" # ========= UI ========= with gr.Blocks(title="Vision Language AI 應用(Caption 版)") as demo: gr.Markdown("# 🎨 Vision Language AI 應用展示 · Caption") gr.Markdown("上傳圖片後按下按鈕,產生文字描述。此版本僅啟用 **Image Captioning**,以確保在免費 CPU 環境穩定執行。") with gr.Row(): img = gr.Image(type="pil", label="上傳圖片", height=320) out = gr.Textbox(label="AI 產生的描述", lines=6, show_copy_button=True) with gr.Row(): run_btn = gr.Button("🚀 產生描述", variant="primary") clear_btn = gr.Button("🧹 清除", variant="secondary") # ⚙️ 事件綁定:放在 Blocks 區塊內 run_btn.click(fn=do_caption, inputs=img, outputs=out) clear_btn.click(fn=clear_all, inputs=None, outputs=[img, out]) demo.queue(max_size=10) if __name__ == "__main__": demo.queue(max_size=10).launch()