VigneshVS2005 commited on
Commit
7e2a824
·
1 Parent(s): f09a85f

Add Hugging Face Serverless API option (Option 3)

Browse files
ai_router.py CHANGED
@@ -1,6 +1,7 @@
1
  from models.blip_model import blip_answer
2
  from models.reasoning_model import reasoning_answer
3
  from models.gemini_vision import gemini_vision_answer
 
4
 
5
  try:
6
  from deep_translator import GoogleTranslator
@@ -21,6 +22,8 @@ def route_model(model_choice, image, question, lang="en"):
21
  cap, ans, exp = reasoning_answer(image, question)
22
  elif model_choice == "gemini":
23
  cap, ans, exp = gemini_vision_answer(image, question, lang)
 
 
24
  else:
25
  cap, ans, exp = "Unknown", "Invalid", "Invalid"
26
 
 
1
  from models.blip_model import blip_answer
2
  from models.reasoning_model import reasoning_answer
3
  from models.gemini_vision import gemini_vision_answer
4
+ from models.hf_api_model import hf_api_reasoning
5
 
6
  try:
7
  from deep_translator import GoogleTranslator
 
22
  cap, ans, exp = reasoning_answer(image, question)
23
  elif model_choice == "gemini":
24
  cap, ans, exp = gemini_vision_answer(image, question, lang)
25
+ elif model_choice == "hf_api":
26
+ cap, ans, exp = hf_api_reasoning(image, question, lang)
27
  else:
28
  cap, ans, exp = "Unknown", "Invalid", "Invalid"
29
 
config.py CHANGED
@@ -12,4 +12,5 @@ GEMINI_API_KEY = os.getenv("GEMINI_API_KEY", "AIzaSyB1fMfnnp2etuOVWiLrecdMp3_0Gb
12
 
13
  # ===== Security Limits =====
14
  MAX_IMAGE_SIZE_MB = 5
15
- RATE_LIMIT_PER_MINUTE = 30
 
 
12
 
13
  # ===== Security Limits =====
14
  MAX_IMAGE_SIZE_MB = 5
15
+ RATE_LIMIT_PER_MINUTE = 30
16
+ HF_TOKEN = os.getenv("HF_TOKEN", "")
models/hf_api_model.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import io
3
+ import base64
4
+ import requests
5
+ from config import HF_TOKEN
6
+
7
+ def encode_image(image):
8
+ buffered = io.BytesIO()
9
+ # Convert image to RGB if not already to prevent JPEG save errors
10
+ if image.mode != "RGB":
11
+ image = image.convert("RGB")
12
+ image.save(buffered, format="JPEG")
13
+ return base64.b64encode(buffered.getvalue()).decode('utf-8')
14
+
15
+ def hf_api_reasoning(image, question, lang="en"):
16
+ # Using Llama 3.2 11B Vision Instruct via Serverless
17
+ model_id = "meta-llama/Llama-3.2-11B-Vision-Instruct"
18
+ api_url = f"https://api-inference.huggingface.co/models/{model_id}/v1/chat/completions"
19
+
20
+ token = HF_TOKEN or os.getenv("HF_TOKEN")
21
+
22
+ if not token:
23
+ return "Setup Required", "Hugging Face Access Token is missing.", "Please ensure HF_TOKEN is set in your environment or config.py"
24
+
25
+ headers = {
26
+ "Authorization": f"Bearer {token}",
27
+ "Content-Type": "application/json"
28
+ }
29
+
30
+ base64_img = f"data:image/jpeg;base64,{encode_image(image)}"
31
+
32
+ payload = {
33
+ "model": model_id,
34
+ "messages": [
35
+ {
36
+ "role": "user",
37
+ "content": [
38
+ {"type": "image_url", "image_url": {"url": base64_img}},
39
+ {"type": "text", "text": f"Please provide an accurate answer to the following question. First, provide a very short, direct final answer. Second, provide a detailed explanation.\\nQuestion: {question}"}
40
+ ]
41
+ }
42
+ ],
43
+ "max_tokens": 250
44
+ }
45
+
46
+ try:
47
+ response = requests.post(api_url, headers=headers, json=payload, timeout=60)
48
+
49
+ if response.status_code == 429:
50
+ return "Rate Limited", "Hugging Face Serverless API is currently busy.", "You have hit the free tier rate limit. Please try again in a few minutes."
51
+ elif response.status_code == 503:
52
+ return "Model Loading", "The AI model is currently booting up on Hugging Face servers.", "It takes about 20-30 seconds to wake up the 11-Billion parameter model. Try again in 20 seconds!"
53
+
54
+ response.raise_for_status()
55
+ data = response.json()
56
+
57
+ raw_text = data["choices"][0]["message"]["content"]
58
+
59
+ return "Llama-3.2-11B-Vision", raw_text, "Processed via Hugging Face Serverless GPU API"
60
+
61
+ except requests.exceptions.Timeout:
62
+ return "Timeout", "The Hugging Face server took too long to respond.", "This can happen if the model is waking up. Please try again."
63
+ except Exception as e:
64
+ error_msg = str(e)
65
+ try:
66
+ # Attempt to parse detailed error from huggingface
67
+ error_data = response.json()
68
+ if "error" in error_data:
69
+ error_msg = error_data["error"]
70
+ except:
71
+ pass
72
+ return "API Error", "Connection failed.", f"{error_msg}"
requirements.txt CHANGED
@@ -6,3 +6,4 @@ torch==2.2.1
6
  transformers==4.38.2
7
  google-genai==0.3.0
8
  deep-translator==1.11.4
 
 
6
  transformers==4.38.2
7
  google-genai==0.3.0
8
  deep-translator==1.11.4
9
+ requests>=2.28.0
static/app.js CHANGED
@@ -354,7 +354,7 @@ async function fetchLogs() {
354
  appState.logs = data.logs || [];
355
  appState.stats.total = appState.logs.length;
356
  appState.stats.local = appState.logs.filter(l => ['local', 'blip', 'reasoning'].includes(l.model.toLowerCase())).length;
357
- appState.stats.gemini = appState.logs.filter(l => ['gemini', 'external'].includes(l.model.toLowerCase())).length;
358
 
359
  updateDashboardView();
360
  } catch(err) {
@@ -378,7 +378,7 @@ function renderLogs(filter = '') {
378
  tr.innerHTML = `
379
  <td>${log.timestamp}</td>
380
  <td><span class="user-badge" style="color: var(--text-secondary);"><i class="fa-solid fa-user"></i> ${log.user}</span></td>
381
- <td><span style="color: ${log.model.includes('gemini') ? 'var(--accent)' : 'var(--success)'}">${log.model.toUpperCase()}</span></td>
382
  <td>${log.question.length > 50 ? log.question.substring(0, 50) + '...' : log.question}</td>
383
  `;
384
  els.logsBody.appendChild(tr);
 
354
  appState.logs = data.logs || [];
355
  appState.stats.total = appState.logs.length;
356
  appState.stats.local = appState.logs.filter(l => ['local', 'blip', 'reasoning'].includes(l.model.toLowerCase())).length;
357
+ appState.stats.gemini = appState.logs.filter(l => ['gemini', 'external', 'hf_api'].includes(l.model.toLowerCase())).length;
358
 
359
  updateDashboardView();
360
  } catch(err) {
 
378
  tr.innerHTML = `
379
  <td>${log.timestamp}</td>
380
  <td><span class="user-badge" style="color: var(--text-secondary);"><i class="fa-solid fa-user"></i> ${log.user}</span></td>
381
+ <td><span style="color: ${['gemini', 'hf_api'].some(m => log.model.includes(m)) ? 'var(--accent)' : 'var(--success)'}">${log.model.toUpperCase().replace('_', ' ')}</span></td>
382
  <td>${log.question.length > 50 ? log.question.substring(0, 50) + '...' : log.question}</td>
383
  `;
384
  els.logsBody.appendChild(tr);
templates/index.html CHANGED
@@ -97,6 +97,7 @@
97
  <select id="model-selector">
98
  <option value="local">BLIP + FLAN (Local)</option>
99
  <option value="gemini" id="gemini-option">Gemini 3.1 Flash Vision (High Quota)</option>
 
100
  </select>
101
  </div>
102
  <div class="control-group" style="flex: 1;">
 
97
  <select id="model-selector">
98
  <option value="local">BLIP + FLAN (Local)</option>
99
  <option value="gemini" id="gemini-option">Gemini 3.1 Flash Vision (High Quota)</option>
100
+ <option value="hf_api" id="hf_api-option">HF Llama 3.2 Vision API (Flawless)</option>
101
  </select>
102
  </div>
103
  <div class="control-group" style="flex: 1;">