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
Files changed (1) hide show
  1. app.py +34 -23
app.py CHANGED
@@ -27,7 +27,8 @@ from transformers import (
27
  # CONFIG
28
  # ============================================================
29
  MODEL_NAME = "Salesforce/blip-image-captioning-base"
30
- FINE_TUNED_PATH = "./flickr8k_blip_output/best_model"
 
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
- if os.path.exists(FINE_TUNED_PATH) and os.path.isdir(FINE_TUNED_PATH):
 
96
  has_files = any(
97
- os.path.exists(os.path.join(FINE_TUNED_PATH, f))
98
  for f in ["pytorch_model.bin", "model.safetensors", "config.json"]
99
  )
100
  if has_files:
101
- print(f"[INFO] Loading Fine-Tuned model from {FINE_TUNED_PATH}...")
102
- processors["fine-tuned"] = BlipProcessor.from_pretrained(FINE_TUNED_PATH)
103
- models["fine-tuned"] = BlipForConditionalGeneration.from_pretrained(FINE_TUNED_PATH).to(DEVICE)
 
 
 
 
 
 
 
 
 
 
 
 
104
  models["fine-tuned"].eval()
105
- print("[INFO] Fine-Tuned model loaded successfully!")
106
- else:
107
- print("[WARN] Fine-Tuned path exists but model files are missing.")
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
- allowed_types = {"image/jpeg", "image/jpg", "image/png", "image/gif", "image/webp", "image/bmp"}
180
- if file.content_type not in allowed_types:
 
 
181
  raise HTTPException(
182
  status_code=400,
183
- detail=f"Unsupported file type: {file.content_type}. Please upload JPEG, PNG, GIF, or WebP.",
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
- elif model_choice == "fine-tuned":
204
- raise HTTPException(status_code=400, detail="Fine-tuned model is not available.")
 
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 {