import os import json import streamlit as st import faiss import numpy as np import torch from transformers import AutoModelForSeq2SeqLM, AutoTokenizer from sentence_transformers import SentenceTransformer from reportlab.lib.pagesizes import A4 from reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer from reportlab.lib.styles import getSampleStyleSheet # Load milestones data with open('milestones.json', 'r') as f: milestones = json.load(f) # Age categories for dropdown selection age_categories = { "Up to 2 months": 2, "Up to 4 months": 4, "Up to 6 months": 6, "Up to 9 months": 9, "Up to 1 year": 12, "Up to 15 months": 15, "Up to 18 months": 18, "Up to 2 years": 24, "Up to 30 months": 30, "Up to 3 years": 36, "Up to 4 years": 48, "Up to 5 years": 60 } # Initialize FAISS and Sentence Transformer embedding_model = SentenceTransformer('all-MiniLM-L6-v2') def create_faiss_index(data): descriptions, age_keys = [], [] for age, categories in data.items(): for entry in categories: descriptions.append(entry['description']) age_keys.append(int(age)) # Convert age to int embeddings = embedding_model.encode(descriptions, convert_to_numpy=True) index = faiss.IndexFlatL2(embeddings.shape[1]) index.add(embeddings) return index, descriptions, age_keys index, descriptions, age_keys = create_faiss_index(milestones) # Function to retrieve the closest milestone def retrieve_milestone(user_input): user_embedding = embedding_model.encode([user_input], convert_to_numpy=True) _, indices = index.search(user_embedding, 1) return descriptions[indices[0][0]] if indices[0][0] < len(descriptions) else "No relevant milestone found." # Load IBM Granite 3.1 model and tokenizer model_name = "ibm-granite/granite-3.1-8b-instruct" tokenizer = AutoTokenizer.from_pretrained(model_name) granite_model = AutoModelForSeq2SeqLM.from_pretrained( model_name, torch_dtype=torch.float16, device_map="auto" ) def generate_response(user_input, child_age): relevant_milestone = retrieve_milestone(user_input) prompt = ( f"The child is {child_age} months old. Based on the given traits: {user_input}, " f"determine whether the child is meeting expected milestones. " f"Relevant milestone: {relevant_milestone}. " "If there are any concerns, suggest steps the parents can take." ) inputs = tokenizer(prompt, return_tensors="pt").to("cuda" if torch.cuda.is_available() else "cpu") output = granite_model.generate(**inputs, max_length=512) return tokenizer.decode(output[0], skip_special_tokens=True) # Streamlit UI Styling st.set_page_config(page_title="Tiny Triumphs Tracker", page_icon="👶", layout="wide") st.markdown(""" """, unsafe_allow_html=True) st.markdown("