Spaces:
Sleeping
Sleeping
| import os | |
| import gradio as gr | |
| from fastapi import FastAPI, HTTPException | |
| from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM | |
| import uvicorn | |
| # β Load Model Configuration | |
| MODEL_NAME = "hpyapali/tinyllama-workout" | |
| HF_TOKEN = os.getenv("HF_TOKEN", "your_huggingface_api_key") # Replace with your actual Hugging Face API key | |
| app = FastAPI() | |
| try: | |
| print("π Loading Model...") | |
| tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, token=HF_TOKEN) | |
| model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, token=HF_TOKEN) | |
| pipe = pipeline("text-generation", model=model, tokenizer=tokenizer) | |
| print("β Model Loaded Successfully!") | |
| except Exception as e: | |
| print(f"β Error loading model: {e}") | |
| pipe = None | |
| # β AI Function - Generates Structured Workout Recommendations | |
| def recommend_next_workout(last_workouts: str): | |
| """ | |
| Analyzes and ranks workouts based on intensity and heart rate drop. | |
| Provides a recommendation for the next workout. | |
| """ | |
| if pipe is None: | |
| return "β AI model not loaded." | |
| instruction = ( | |
| "You are a fitness AI assistant specializing in analyzing workout effectiveness. " | |
| "Based on the last 7 workouts, rank them from the most to least effective based on:\n" | |
| "- Heart rate drop after workout (faster drop = better recovery)\n" | |
| "- Workout intensity (higher effort = more impact)\n" | |
| "- Duration (longer workouts generally contribute more)\n" | |
| "- Calories burned (higher calories = higher impact)\n" | |
| "- Variability (mixing workout types is important)\n\n" | |
| "### Last 7 Workouts:\n" | |
| ) | |
| full_prompt = instruction + last_workouts + "\n\n### Ranking (Best to Least Effective):\n" | |
| try: | |
| print(f"π§ AI Processing: {full_prompt}") | |
| result = pipe( | |
| full_prompt, | |
| max_new_tokens=150, # πΌ Increased token limit for full ranking | |
| do_sample=True, # πΌ Enabled sampling for variability | |
| temperature=0.7, # πΌ Slight randomness for better insights | |
| top_p=0.9 # πΌ Limits unlikely outputs while keeping diversity | |
| ) | |
| print(f"π Raw AI Output: {result}") | |
| if not result or not result[0]["generated_text"].strip(): | |
| return "β AI did not generate any output." | |
| response_text = result[0]["generated_text"].strip() | |
| # β Remove repeated prompt if AI echoes it | |
| if full_prompt in response_text: | |
| response_text = response_text.replace(full_prompt, "").strip() | |
| print(f"β AI Recommendation: {response_text}") | |
| return response_text | |
| except Exception as e: | |
| print(f"β AI Processing Error: {e}") | |
| return "β Error generating workout recommendation." | |
| # β FastAPI Route - Returns AI Response Directly | |
| async def predict(data: dict): | |
| try: | |
| last_workouts = data.get("data", [""])[0] | |
| if not last_workouts: | |
| raise HTTPException(status_code=400, detail="Invalid input") | |
| ai_response = recommend_next_workout(last_workouts) | |
| return {"data": [ai_response]} # β Directly returning structured response | |
| except Exception as e: | |
| return {"error": str(e)} | |
| # β Gradio UI (Optional for Testing) | |
| iface = gr.Interface( | |
| fn=recommend_next_workout, | |
| inputs="text", | |
| outputs="text", | |
| title="TinyLlama Workout Recommendations", | |
| description="Enter workout data to receive AI-powered recommendations." | |
| ) | |
| # β Ensure Proper Gradio Launch | |
| iface.launch(server_name="0.0.0.0", server_port=7860) | |
| # β FastAPI Server Execution | |
| if __name__ == "__main__": | |
| uvicorn.run(app, host="0.0.0.0", port=7860) | |