File size: 3,736 Bytes
6d79528
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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
@app.post("/gradio_api/call/predict")
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)