Pontonkid commited on
Commit
37b828a
·
verified ·
1 Parent(s): 0ad7393

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +82 -78
src/streamlit_app.py CHANGED
@@ -1,14 +1,13 @@
1
  import streamlit as st
2
  import os
3
- from datetime import datetime
4
  from PIL import Image
5
- from huggingface_hub import InferenceClient
6
 
7
  # -----------------------------------------------------------------------------
8
- # 0. AUTO-FIX FOR UPLOAD ERROR (RUNS FIRST)
9
  # -----------------------------------------------------------------------------
10
- # This creates the hidden folder and config file automatically.
11
- # You do NOT need to create folders manually.
12
  config_dir = ".streamlit"
13
  if not os.path.exists(config_dir):
14
  os.makedirs(config_dir)
@@ -16,20 +15,33 @@ with open(os.path.join(config_dir, "config.toml"), "w") as f:
16
  f.write("[server]\nenableXsrfProtection=false\nenableCORS=false\nmaxUploadSize=200\n")
17
 
18
  # -----------------------------------------------------------------------------
19
- # 1. SETUP & CONFIGURATION
20
  # -----------------------------------------------------------------------------
21
- st.set_page_config(page_title="SHINUI | Meta Llama AI", page_icon="✨", layout="wide")
22
 
23
- # RETRIEVE API KEY
24
- # Ensure you have accepted the license for Llama 3.2 on Hugging Face!
25
- HF_TOKEN = os.environ.get("HF_TOKEN")
26
-
27
- if not HF_TOKEN:
28
- st.error("⚠️ API Key missing! Please add 'HF_TOKEN' in Space Settings > Secrets.")
29
- st.stop()
 
 
 
 
 
 
 
30
 
31
- # INITIALIZE CLIENT
32
- client = InferenceClient(token=HF_TOKEN)
 
 
 
 
 
 
33
 
34
  # -----------------------------------------------------------------------------
35
  # 2. STATE MANAGEMENT
@@ -41,50 +53,39 @@ if 'history' not in st.session_state: st.session_state.history = []
41
  if 'result' not in st.session_state: st.session_state.result = None
42
 
43
  # -----------------------------------------------------------------------------
44
- # 3. THE BRAIN (Meta Llama 3.2 Vision Logic)
45
  # -----------------------------------------------------------------------------
46
- def get_llama_insight(input_type, content):
47
- """
48
- Handles analysis using Meta-Llama-3.2-11B-Vision-Instruct
49
- """
50
- # System instruction for the model
51
- prompt_text = "You are SHINUI, a medical AI assistant. Analyze the input provided. Structure your answer with: 1. Observation 2. Risk Assessment 3. Recommended Actions. Keep it concise and professional."
52
 
53
  try:
54
- # A. VISION (Image Analysis)
55
  if input_type == "Image":
56
- # The client handles the image object directly for this model
57
- messages = [
58
- {
59
- "role": "user",
60
- "content": [
61
- {"type": "image"},
62
- {"type": "text", "text": prompt_text}
63
- ]
64
- }
65
- ]
66
- response = client.chat_completion(
67
- model="meta-llama/Llama-3.2-11B-Vision-Instruct",
68
- messages=messages,
69
- max_tokens=500,
70
- image=content # Passing the PIL image here
71
- )
72
- return response.choices[0].message.content
73
 
74
- # B. TEXT (Clinical Notes)
75
  elif input_type == "Text":
76
- messages = [
77
- {"role": "user", "content": f"{prompt_text}\n\nPatient Notes: {content}"}
78
- ]
79
- response = client.chat_completion(
80
- model="meta-llama/Llama-3.2-11B-Vision-Instruct",
81
- messages=messages,
82
- max_tokens=500
83
- )
84
- return response.choices[0].message.content
85
 
86
  except Exception as e:
87
- return f"⚠️ Analysis Error: {str(e)}\n(Check if your HF Token has permission for Llama 3.2)"
88
 
89
  # -----------------------------------------------------------------------------
90
  # 4. UI STYLING (Clean Dark Theme)
@@ -111,7 +112,7 @@ st.markdown("""
111
  """, unsafe_allow_html=True)
112
 
113
  # -----------------------------------------------------------------------------
114
- # 5. NAVIGATION HELPERS
115
  # -----------------------------------------------------------------------------
116
  def nav_to(page):
117
  st.session_state.page = page
@@ -138,10 +139,10 @@ def show_landing():
138
  with c1:
139
  st.markdown("""
140
  <h1 style='font-size: 4rem; line-height: 1.1; margin-bottom: 20px;'>
141
- Medical Intelligence.<br><span style='color:#38bdf8;'>Powered by Meta Llama.</span>
142
  </h1>
143
  <p style='font-size: 1.2rem; color: #94a3b8; margin-bottom: 40px;'>
144
- Advanced multimodal analysis for medical imaging and clinical notes.
145
  </p>
146
  """, unsafe_allow_html=True)
147
  b1, b2 = st.columns([1, 2])
@@ -153,8 +154,8 @@ def show_landing():
153
  with c2:
154
  st.markdown("""
155
  <div class='shinui-card'>
156
- <h3>🧬 Llama 3.2 Vision</h3>
157
- <p style='color:#94a3b8;'>11B Parameter Multimodal Model.</p>
158
  </div>
159
  """, unsafe_allow_html=True)
160
 
@@ -166,14 +167,14 @@ def show_about():
166
  <div class='shinui-card'>
167
  <h2 style='color:#38bdf8'>About SHINUI</h2>
168
  <p style='font-size:1.1rem; line-height:1.6'>
169
- SHINUI leverages the <b>Meta Llama 3.2 11B Vision</b> model to provide state-of-the-art analysis.
170
- It allows healthcare professionals and individuals to interpret complex visual and textual data instantly.
171
  </p>
172
  <hr style='border-color:#333'>
173
  <h3>Capabilities</h3>
174
  <ul>
175
- <li><b>Visual Diagnostics:</b> Interpretation of X-rays, MRI scans, and visible symptoms.</li>
176
- <li><b>Clinical Notes:</b> Deep understanding of medical text and handwriting.</li>
177
  </ul>
178
  </div>
179
  """, unsafe_allow_html=True)
@@ -195,10 +196,9 @@ def show_login():
195
 
196
  # --- DASHBOARD ---
197
  def show_dashboard():
198
- # SIDEBAR (Sign Out is here)
199
  with st.sidebar:
200
  st.markdown(f"### 👤 {st.session_state.user_email}")
201
- if st.button("Internal About"): nav_to('about_internal')
202
  st.markdown("---")
203
  st.write("HISTORY")
204
  if st.session_state.history:
@@ -209,8 +209,7 @@ def show_dashboard():
209
  st.markdown("---")
210
  if st.button("Sign Out"): sign_out()
211
 
212
- # MAIN UI
213
- st.title("Llama 3.2 Vision Interface")
214
  t1, t2 = st.tabs(["📷 Image Scan", "📝 Text Analysis"])
215
 
216
  # TAB 1: IMAGE
@@ -218,12 +217,15 @@ def show_dashboard():
218
  st.markdown("<div class='shinui-card'>", unsafe_allow_html=True)
219
  img_file = st.file_uploader("Upload Medical Image", type=['png','jpg','jpeg'])
220
  if img_file and st.button("Analyze Visual"):
221
- image = Image.open(img_file)
222
- st.image(image, caption="Input", width=300)
223
- with st.spinner("Llama Vision Processing..."):
224
- res = get_llama_insight("Image", image)
225
- st.session_state.result = res
226
- st.session_state.history.append(f"Image: {res[:30]}...")
 
 
 
227
  st.markdown("</div>", unsafe_allow_html=True)
228
 
229
  # TAB 2: TEXT
@@ -231,13 +233,15 @@ def show_dashboard():
231
  st.markdown("<div class='shinui-card'>", unsafe_allow_html=True)
232
  txt = st.text_area("Clinical Notes / Symptoms")
233
  if txt and st.button("Analyze Notes"):
234
- with st.spinner("Llama Text Processing..."):
235
- res = get_llama_insight("Text", txt)
236
- st.session_state.result = res
237
- st.session_state.history.append(f"Text: {res[:30]}...")
 
 
 
238
  st.markdown("</div>", unsafe_allow_html=True)
239
 
240
- # RESULTS AREA
241
  if st.session_state.result:
242
  st.markdown(f"""
243
  <div class='shinui-card' style='border-left: 5px solid #38bdf8;'>
@@ -253,8 +257,8 @@ def show_about_internal():
253
  st.markdown("""
254
  <div class='shinui-card'>
255
  <h2 style='color:#38bdf8'>System Status</h2>
256
- <p><b>Model:</b> Meta Llama 3.2 11B Vision Instruct</p>
257
- <p><b>Status:</b> Online</p>
258
  </div>
259
  """, unsafe_allow_html=True)
260
 
 
1
  import streamlit as st
2
  import os
3
+ import torch
4
  from PIL import Image
5
+ from transformers import AutoModelForCausalLM, AutoProcessor
6
 
7
  # -----------------------------------------------------------------------------
8
+ # 0. AUTO-FIX FOR UPLOAD ERROR (RUNS INSTANTLY)
9
  # -----------------------------------------------------------------------------
10
+ # This creates the config.toml automatically so uploads work.
 
11
  config_dir = ".streamlit"
12
  if not os.path.exists(config_dir):
13
  os.makedirs(config_dir)
 
15
  f.write("[server]\nenableXsrfProtection=false\nenableCORS=false\nmaxUploadSize=200\n")
16
 
17
  # -----------------------------------------------------------------------------
18
+ # 1. SETUP & MODEL LOADING (AarambhAI Gemma)
19
  # -----------------------------------------------------------------------------
20
+ st.set_page_config(page_title="SHINUI | Gemma AI", page_icon="✨", layout="wide")
21
 
22
+ @st.cache_resource
23
+ def load_model():
24
+ model_id = "AarambhAI/gemma-like-multimodal-speech-vision-text"
25
+
26
+ # Load Processor and Model
27
+ # We use trust_remote_code=True because this is a custom architecture
28
+ processor = AutoProcessor.from_pretrained(model_id, trust_remote_code=True)
29
+ model = AutoModelForCausalLM.from_pretrained(
30
+ model_id,
31
+ torch_dtype=torch.float32, # float32 is safer for CPU
32
+ device_map="auto",
33
+ trust_remote_code=True
34
+ )
35
+ return model, processor
36
 
37
+ # Load Model on App Start
38
+ try:
39
+ with st.spinner("Initializing Gemma Multimodal Model..."):
40
+ model, processor = load_model()
41
+ MODEL_LOADED = True
42
+ except Exception as e:
43
+ st.error(f"⚠️ Model Load Error: {e}")
44
+ MODEL_LOADED = False
45
 
46
  # -----------------------------------------------------------------------------
47
  # 2. STATE MANAGEMENT
 
53
  if 'result' not in st.session_state: st.session_state.result = None
54
 
55
  # -----------------------------------------------------------------------------
56
+ # 3. THE BRAIN (Gemma Logic)
57
  # -----------------------------------------------------------------------------
58
+ def get_gemma_insight(input_type, content):
59
+ if not MODEL_LOADED:
60
+ return "Error: Model not loaded."
 
 
 
61
 
62
  try:
63
+ # A. VISION ANALYSIS
64
  if input_type == "Image":
65
+ text_prompt = "Analyze this medical image and list observations."
66
+
67
+ # Gemma format input
68
+ inputs = processor(text=text_prompt, images=content, return_tensors="pt")
69
+
70
+ # Generate
71
+ with torch.no_grad():
72
+ output = model.generate(**inputs, max_new_tokens=200)
73
+
74
+ return processor.batch_decode(output, skip_special_tokens=True)[0]
 
 
 
 
 
 
 
75
 
76
+ # B. TEXT ANALYSIS
77
  elif input_type == "Text":
78
+ text_prompt = f"Medical analysis for: {content}"
79
+
80
+ inputs = processor(text=text_prompt, return_tensors="pt")
81
+
82
+ with torch.no_grad():
83
+ output = model.generate(**inputs, max_new_tokens=200)
84
+
85
+ return processor.batch_decode(output, skip_special_tokens=True)[0]
 
86
 
87
  except Exception as e:
88
+ return f"⚠️ Processing Error: {str(e)}"
89
 
90
  # -----------------------------------------------------------------------------
91
  # 4. UI STYLING (Clean Dark Theme)
 
112
  """, unsafe_allow_html=True)
113
 
114
  # -----------------------------------------------------------------------------
115
+ # 5. NAVIGATION
116
  # -----------------------------------------------------------------------------
117
  def nav_to(page):
118
  st.session_state.page = page
 
139
  with c1:
140
  st.markdown("""
141
  <h1 style='font-size: 4rem; line-height: 1.1; margin-bottom: 20px;'>
142
+ Medical Intelligence.<br><span style='color:#38bdf8;'>Runs Locally.</span>
143
  </h1>
144
  <p style='font-size: 1.2rem; color: #94a3b8; margin-bottom: 40px;'>
145
+ SHINUI runs the specialized Gemma Multimodal model for secure analysis.
146
  </p>
147
  """, unsafe_allow_html=True)
148
  b1, b2 = st.columns([1, 2])
 
154
  with c2:
155
  st.markdown("""
156
  <div class='shinui-card'>
157
+ <h3>🧬 Gemma Multimodal</h3>
158
+ <p style='color:#94a3b8;'>Vision, Text & Speech capable.</p>
159
  </div>
160
  """, unsafe_allow_html=True)
161
 
 
167
  <div class='shinui-card'>
168
  <h2 style='color:#38bdf8'>About SHINUI</h2>
169
  <p style='font-size:1.1rem; line-height:1.6'>
170
+ SHINUI utilizes the <b>AarambhAI Gemma-like Multimodal</b> model.
171
+ This model is unique because it understands images, text, and speech natively in a single architecture.
172
  </p>
173
  <hr style='border-color:#333'>
174
  <h3>Capabilities</h3>
175
  <ul>
176
+ <li><b>Visual Diagnostics:</b> Reads medical images.</li>
177
+ <li><b>Clinical Text:</b> Analyzes symptoms and notes.</li>
178
  </ul>
179
  </div>
180
  """, unsafe_allow_html=True)
 
196
 
197
  # --- DASHBOARD ---
198
  def show_dashboard():
 
199
  with st.sidebar:
200
  st.markdown(f"### 👤 {st.session_state.user_email}")
201
+ if st.button("About System"): nav_to('about_internal')
202
  st.markdown("---")
203
  st.write("HISTORY")
204
  if st.session_state.history:
 
209
  st.markdown("---")
210
  if st.button("Sign Out"): sign_out()
211
 
212
+ st.title("Gemma Interface")
 
213
  t1, t2 = st.tabs(["📷 Image Scan", "📝 Text Analysis"])
214
 
215
  # TAB 1: IMAGE
 
217
  st.markdown("<div class='shinui-card'>", unsafe_allow_html=True)
218
  img_file = st.file_uploader("Upload Medical Image", type=['png','jpg','jpeg'])
219
  if img_file and st.button("Analyze Visual"):
220
+ if not MODEL_LOADED:
221
+ st.error("Model failed to load (Check Space Logs).")
222
+ else:
223
+ image = Image.open(img_file)
224
+ st.image(image, width=300)
225
+ with st.spinner("Gemma Processing..."):
226
+ res = get_gemma_insight("Image", image)
227
+ st.session_state.result = res
228
+ st.session_state.history.append(f"Image: {res[:30]}...")
229
  st.markdown("</div>", unsafe_allow_html=True)
230
 
231
  # TAB 2: TEXT
 
233
  st.markdown("<div class='shinui-card'>", unsafe_allow_html=True)
234
  txt = st.text_area("Clinical Notes / Symptoms")
235
  if txt and st.button("Analyze Notes"):
236
+ if not MODEL_LOADED:
237
+ st.error("Model failed to load.")
238
+ else:
239
+ with st.spinner("Gemma Processing..."):
240
+ res = get_gemma_insight("Text", txt)
241
+ st.session_state.result = res
242
+ st.session_state.history.append(f"Text: {res[:30]}...")
243
  st.markdown("</div>", unsafe_allow_html=True)
244
 
 
245
  if st.session_state.result:
246
  st.markdown(f"""
247
  <div class='shinui-card' style='border-left: 5px solid #38bdf8;'>
 
257
  st.markdown("""
258
  <div class='shinui-card'>
259
  <h2 style='color:#38bdf8'>System Status</h2>
260
+ <p><b>Model:</b> AarambhAI Gemma-like Multimodal</p>
261
+ <p><b>Backend:</b> Local Transformers</p>
262
  </div>
263
  """, unsafe_allow_html=True)
264