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) | |