Spaces:
Sleeping
Sleeping
Pokkhrong Rasee commited on
Commit ·
7f25521
1
Parent(s): 9be7989
Fix 400 Bad Request: add HF Hub model loading, robust image validation, and graceful fallback
Browse files
app.py
CHANGED
|
@@ -27,7 +27,8 @@ from transformers import (
|
|
| 27 |
# CONFIG
|
| 28 |
# ============================================================
|
| 29 |
MODEL_NAME = "Salesforce/blip-image-captioning-base"
|
| 30 |
-
|
|
|
|
| 31 |
TRANSLATION_MODEL_NAME = "facebook/nllb-200-distilled-600M"
|
| 32 |
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 33 |
|
|
@@ -77,7 +78,6 @@ def translate_to_thai(texts: list[str]) -> list[str]:
|
|
| 77 |
return translations
|
| 78 |
|
| 79 |
|
| 80 |
-
|
| 81 |
def load_models():
|
| 82 |
"""Preload both Pretrained and Fine-Tuned BLIP models if available."""
|
| 83 |
global models, processors
|
|
@@ -90,23 +90,34 @@ def load_models():
|
|
| 90 |
models["pretrained"].eval()
|
| 91 |
print("[INFO] Pretrained model loaded successfully!")
|
| 92 |
|
| 93 |
-
# 2. Load Fine-Tuned BLIP
|
| 94 |
if "fine-tuned" not in models:
|
| 95 |
-
|
|
|
|
| 96 |
has_files = any(
|
| 97 |
-
os.path.exists(os.path.join(
|
| 98 |
for f in ["pytorch_model.bin", "model.safetensors", "config.json"]
|
| 99 |
)
|
| 100 |
if has_files:
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
models["fine-tuned"].eval()
|
| 105 |
-
print("[INFO] Fine-Tuned model loaded successfully!")
|
| 106 |
-
|
| 107 |
-
print("[WARN] Fine-Tuned
|
| 108 |
-
else:
|
| 109 |
-
print("[WARN] Fine-Tuned model directory not found.")
|
| 110 |
|
| 111 |
|
| 112 |
def generate_captions_for_model(model_key: str, image: Image.Image, num_captions: int = 5):
|
|
@@ -176,17 +187,16 @@ async def predict(
|
|
| 176 |
"""
|
| 177 |
load_models()
|
| 178 |
|
| 179 |
-
|
| 180 |
-
|
|
|
|
|
|
|
| 181 |
raise HTTPException(
|
| 182 |
status_code=400,
|
| 183 |
-
detail=f"
|
| 184 |
)
|
| 185 |
|
| 186 |
try:
|
| 187 |
-
image_bytes = await file.read()
|
| 188 |
-
image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
|
| 189 |
-
|
| 190 |
results = {}
|
| 191 |
|
| 192 |
def process_model(key: str, label: str):
|
|
@@ -196,16 +206,17 @@ async def predict(
|
|
| 196 |
data["captions_th"] = translate_to_thai(en_captions)
|
| 197 |
results[key] = data
|
| 198 |
|
| 199 |
-
# 1. Fine-tuned model inference
|
| 200 |
if model_choice in ["both", "fine-tuned"]:
|
| 201 |
if "fine-tuned" in models:
|
| 202 |
process_model("fine-tuned", "Fine-Tuned BLIP (Flickr8k)")
|
| 203 |
-
|
| 204 |
-
|
|
|
|
| 205 |
|
| 206 |
# 2. Pretrained model inference
|
| 207 |
if model_choice in ["both", "pretrained"]:
|
| 208 |
-
if "pretrained" in models:
|
| 209 |
process_model("pretrained", "Pretrained BLIP (Base)")
|
| 210 |
|
| 211 |
return {
|
|
|
|
| 27 |
# CONFIG
|
| 28 |
# ============================================================
|
| 29 |
MODEL_NAME = "Salesforce/blip-image-captioning-base"
|
| 30 |
+
FINE_TUNED_LOCAL_PATH = "./flickr8k_blip_output/best_model"
|
| 31 |
+
FINE_TUNED_HUB_NAME = "Pokzy/flickr8k-finetuned"
|
| 32 |
TRANSLATION_MODEL_NAME = "facebook/nllb-200-distilled-600M"
|
| 33 |
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 34 |
|
|
|
|
| 78 |
return translations
|
| 79 |
|
| 80 |
|
|
|
|
| 81 |
def load_models():
|
| 82 |
"""Preload both Pretrained and Fine-Tuned BLIP models if available."""
|
| 83 |
global models, processors
|
|
|
|
| 90 |
models["pretrained"].eval()
|
| 91 |
print("[INFO] Pretrained model loaded successfully!")
|
| 92 |
|
| 93 |
+
# 2. Load Fine-Tuned BLIP (Local directory or Hugging Face Model Hub)
|
| 94 |
if "fine-tuned" not in models:
|
| 95 |
+
# Priority A: Check local directory
|
| 96 |
+
if os.path.exists(FINE_TUNED_LOCAL_PATH) and os.path.isdir(FINE_TUNED_LOCAL_PATH):
|
| 97 |
has_files = any(
|
| 98 |
+
os.path.exists(os.path.join(FINE_TUNED_LOCAL_PATH, f))
|
| 99 |
for f in ["pytorch_model.bin", "model.safetensors", "config.json"]
|
| 100 |
)
|
| 101 |
if has_files:
|
| 102 |
+
try:
|
| 103 |
+
print(f"[INFO] Loading Fine-Tuned model from local directory {FINE_TUNED_LOCAL_PATH}...")
|
| 104 |
+
processors["fine-tuned"] = BlipProcessor.from_pretrained(FINE_TUNED_LOCAL_PATH)
|
| 105 |
+
models["fine-tuned"] = BlipForConditionalGeneration.from_pretrained(FINE_TUNED_LOCAL_PATH).to(DEVICE)
|
| 106 |
+
models["fine-tuned"].eval()
|
| 107 |
+
print("[INFO] Local Fine-Tuned model loaded successfully!")
|
| 108 |
+
except Exception as e:
|
| 109 |
+
print(f"[WARN] Could not load local Fine-Tuned model: {e}")
|
| 110 |
+
|
| 111 |
+
# Priority B: Download from Hugging Face Hub (Pokzy/flickr8k-finetuned)
|
| 112 |
+
if "fine-tuned" not in models:
|
| 113 |
+
try:
|
| 114 |
+
print(f"[INFO] Attempting to load Fine-Tuned model from Hugging Face Hub ({FINE_TUNED_HUB_NAME})...")
|
| 115 |
+
processors["fine-tuned"] = BlipProcessor.from_pretrained(FINE_TUNED_HUB_NAME)
|
| 116 |
+
models["fine-tuned"] = BlipForConditionalGeneration.from_pretrained(FINE_TUNED_HUB_NAME).to(DEVICE)
|
| 117 |
models["fine-tuned"].eval()
|
| 118 |
+
print("[INFO] Fine-Tuned model loaded successfully from Hugging Face Hub!")
|
| 119 |
+
except Exception as e:
|
| 120 |
+
print(f"[WARN] Fine-Tuned model on HF Hub ({FINE_TUNED_HUB_NAME}) not loaded yet: {e}")
|
|
|
|
|
|
|
| 121 |
|
| 122 |
|
| 123 |
def generate_captions_for_model(model_key: str, image: Image.Image, num_captions: int = 5):
|
|
|
|
| 187 |
"""
|
| 188 |
load_models()
|
| 189 |
|
| 190 |
+
try:
|
| 191 |
+
image_bytes = await file.read()
|
| 192 |
+
image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
|
| 193 |
+
except Exception as e:
|
| 194 |
raise HTTPException(
|
| 195 |
status_code=400,
|
| 196 |
+
detail=f"Invalid image file: {str(e)}. Please upload a valid image file (JPEG, PNG, WebP, etc.)."
|
| 197 |
)
|
| 198 |
|
| 199 |
try:
|
|
|
|
|
|
|
|
|
|
| 200 |
results = {}
|
| 201 |
|
| 202 |
def process_model(key: str, label: str):
|
|
|
|
| 206 |
data["captions_th"] = translate_to_thai(en_captions)
|
| 207 |
results[key] = data
|
| 208 |
|
| 209 |
+
# 1. Fine-tuned model inference (with graceful fallback to pretrained if fine-tuned model weights not present)
|
| 210 |
if model_choice in ["both", "fine-tuned"]:
|
| 211 |
if "fine-tuned" in models:
|
| 212 |
process_model("fine-tuned", "Fine-Tuned BLIP (Flickr8k)")
|
| 213 |
+
else:
|
| 214 |
+
# Graceful fallback: use pretrained if fine-tuned is missing
|
| 215 |
+
process_model("pretrained", "Pretrained BLIP (Base — Fine-Tuned Model Loading/Pending)")
|
| 216 |
|
| 217 |
# 2. Pretrained model inference
|
| 218 |
if model_choice in ["both", "pretrained"]:
|
| 219 |
+
if "pretrained" in models and "pretrained" not in results:
|
| 220 |
process_model("pretrained", "Pretrained BLIP (Base)")
|
| 221 |
|
| 222 |
return {
|