File size: 8,549 Bytes
3eaea0f
da4e68d
 
 
5340d71
 
 
32d29da
5340d71
 
 
 
 
 
32d29da
 
 
 
 
 
 
5340d71
 
 
 
 
32d29da
 
 
 
5340d71
da4e68d
5340d71
32d29da
 
 
5340d71
32d29da
5340d71
32d29da
 
 
 
5340d71
 
 
 
 
32d29da
 
 
 
 
 
 
da4e68d
5340d71
32d29da
da4e68d
5340d71
32d29da
 
1db4c59
32d29da
1db4c59
 
 
 
 
32d29da
 
 
 
5340d71
da4e68d
32d29da
5340d71
da4e68d
32d29da
da4e68d
5340d71
 
32d29da
da4e68d
5340d71
da4e68d
32d29da
 
5340d71
32d29da
5340d71
 
da4e68d
32d29da
 
 
5340d71
 
da4e68d
5340d71
da4e68d
5340d71
 
 
da4e68d
32d29da
da4e68d
3eaea0f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
'''import gradio as gr
import os
from inference import get_evo_response, get_gpt_response
from logger import log_feedback
import csv
import subprocess

# Helper to load Hall of Fame
def load_hall_of_fame():
    entries = []
    if os.path.exists("feedback_log.csv"):
        with open("feedback_log.csv", newline='', encoding='utf-8') as f:
            reader = csv.DictReader(f)
            for row in reader:
                try:
                    score = float(row.get("evo_was_correct", "0") == "yes")
                    if "πŸ‘" in row.get("feedback", "") or score > 0.85:
                        entries.append(row)
                except:
                    continue
    return entries[-10:][::-1]  # last 10, reverse order

def handle_query(question, option1, option2, context):
    options = [option1, option2]
    evo_answer, evo_reasoning, evo_score, evo_context = get_evo_response(question, options, context)
    gpt_answer = get_gpt_response(question, context)
    return (
        f"Answer: {evo_answer} (Confidence: {evo_score:.2f})\n\nReasoning: {evo_reasoning}\n\nContext used: {evo_context[:400]}...",
        gpt_answer,
        f"{question} | {context} | {evo_answer}"
    )

def handle_feedback(feedback_text, question, option1, option2, context, evo_output):
    evo_was_correct = "πŸ‘" in feedback_text
    log_feedback(question, option1, option2, context, evo_output, evo_was_correct)
    return "βœ… Feedback logged and Evo will improve."

def trigger_retrain():
    try:
        subprocess.run(["python", "retrain_from_feedback.py"], check=True)
        return "πŸ” Evo retraining completed."
    except subprocess.CalledProcessError:
        return "❌ Retraining failed. Check logs."

def render_hof():
    entries = load_hall_of_fame()
    if not entries:
        return "No Hall of Fame entries yet. Submit feedback!"
    result = "\n\n".join(
        [
            f"πŸ† **Q:** {e['question']}\n**A:** {e['evo_output']}\n**Feedback:** {e.get('feedback', 'N/A')}\n**Context:** {e['context'][:200]}..."
            for e in entries
        ]
    )
    return result

description = """
# 🧠 EvoRAG – Adaptive Reasoning AI

**What is Evo?**  
EvoTransformer is a lightweight, evolving neural network with ~28M parameters.  
It learns from feedback, adapts over time, and reasons using both web and context data.  

**Why Evo?**  
βœ… Evolves from human input  
βœ… Architecturally updatable  
βœ… Transparent and fine-tunable  
βœ… Efficient on modest hardware

**Hardware**: Trained on Google Colab CPU/GPU  
**Token limit**: 128  
**Benchmark**: PIQA, HellaSwag, ARC  
**Version**: Evo v2.2 (Memory + Web Retrieval + Feedback Learning)
"""

with gr.Blocks(title="EvoRAG") as demo:
    gr.Markdown(description)
    with gr.Row():
        question = gr.Textbox(label="πŸ“ Ask anything", placeholder="e.g., What’s the best way to escape a house fire?")
    with gr.Row():
        option1 = gr.Textbox(label="Option A", placeholder="e.g., Run outside")
        option2 = gr.Textbox(label="Option B", placeholder="e.g., Hide under bed")
    context = gr.Textbox(label="πŸ“‚ Optional Context", placeholder="Paste any extra background info here", lines=3)

    submit_btn = gr.Button("πŸ” Run Comparison")
    with gr.Row():
        evo_output = gr.Textbox(label="🧠 EvoRAG's Reasoned Answer", lines=6)
        gpt_output = gr.Textbox(label="πŸ€– GPT-3.5's Suggestion", lines=6)

    feedback = gr.Radio(["πŸ‘ Evo was correct. Retrain from this.", "πŸ‘Ž Evo was wrong. Don't retrain."], label="Was Evo’s answer useful?", value=None)
    submit_feedback = gr.Button("πŸ“¬ Submit Feedback")
    feedback_status = gr.Textbox(label="Feedback Status", interactive=False)

    retrain_button = gr.Button("πŸ”„ Retrain Evo Now")
    retrain_status = gr.Textbox(label="Retraining Status", interactive=False)

    with gr.Accordion("πŸ† Evo Hall of Fame (Top Reasoning Entries)", open=False):
        hof_display = gr.Markdown(render_hof())

    submit_btn.click(fn=handle_query, inputs=[question, option1, option2, context], outputs=[evo_output, gpt_output, feedback_status])
    submit_feedback.click(
        fn=lambda fb, q, o1, o2, ctx, eo: handle_feedback(fb, q, o1, o2, ctx, eo),
        inputs=[feedback, question, option1, option2, context, feedback_status],
        outputs=[feedback_status]
    )
    retrain_button.click(fn=trigger_retrain, inputs=[], outputs=[retrain_status])

demo.launch(server_name="0.0.0.0", server_port=7860, share=True)'''

import gradio as gr
import torch
import time
import os
from inference import load_model_and_tokenizer, infer
from logger import log_feedback
from retrain_from_feedback import train_evo
from datetime import datetime

# Globals
model, tokenizer = load_model_and_tokenizer("trained_model/evo_retrained.pt")

# Helper to reload model
def reload_model():
    global model, tokenizer
    model, tokenizer = load_model_and_tokenizer("trained_model/evo_retrained.pt")

# Get last update time
def get_last_update():
    if os.path.exists("last_updated.txt"):
        with open("last_updated.txt") as f:
            return f.read().strip()
    return "Never"

# Handle inference
def compare(question, option1, option2, context):
    evo_ans, evo_score, evo_reason, evo_ctx = infer(model, tokenizer, question, option1, option2, context)
    gpt_ans = "Coming soon via API"
    return (
        f"Answer: {evo_ans} (Confidence: {evo_score:.2f})\n\nReasoning: {evo_reason}\n\nContext used: {evo_ctx}",
        gpt_ans
    )

# Handle feedback
def handle_feedback(feedback_text, question, option1, option2, context, evo_output):
    evo_was_correct = feedback_text.strip().lower() == "πŸ‘ evo was correct. retrain from this."
    log_feedback(question, option1, option2, context, evo_output, evo_was_correct)
    return "βœ… Feedback logged and Evo will improve."

# Manual retrain
def manual_retrain():
    try:
        train_evo()
        reload_model()
        ts = datetime.utcnow().strftime("%Y-%m-%d %H:%M GMT")
        with open("last_updated.txt", "w") as f:
            f.write(ts)
        return f"βœ… Evo successfully evolved! Reloaded at {ts}"
    except Exception as e:
        return f"❌ Retraining failed: {str(e)}"

with gr.Blocks(title="EvoRAG – Adaptive Reasoning AI", theme=gr.themes.Soft()) as demo:
    gr.Markdown("""
    # EvoRAG – Adaptive Reasoning AI
    **What is Evo?**  
    EvoTransformer is a lightweight, evolving neural network with ~28M parameters.  
    It learns from feedback, adapts over time, and reasons using both web and context data.

    **Why Evo?**  
    βœ… Evolves from human input  
    βœ… Architecturally updatable  
    βœ… Transparent and fine-tunable  
    βœ… Efficient on modest hardware  

    **Hardware:** Trained on Google Colab CPU/GPU  
    **Token limit:** 128  
    **Benchmark:** PIQA, HellaSwag, ARC  
    **Version:** Evo v2.2 (Memory + Web Retrieval + Feedback Learning)  
    **πŸ•’ Last Evolution:** {get_last_update()}
    """)

    with gr.Row():
        question = gr.Textbox(label="Ask anything", placeholder="e.g. What’s the best way to boil water?")

    with gr.Row():
        option1 = gr.Textbox(label="Option A")
        option2 = gr.Textbox(label="Option B")

    context = gr.Textbox(label="πŸ“‚ Optional Context", lines=2, placeholder="Paste any extra background info here")

    run_btn = gr.Button("πŸ” Run Comparison")

    with gr.Row():
        evo_out = gr.Textbox(label="🧠 EvoRAG's Reasoned Answer")
        gpt_out = gr.Textbox(label="πŸ€– GPT-3.5's Suggestion")

    with gr.Row():
        feedback_dropdown = gr.Dropdown([
            "πŸ‘ Evo was correct. Retrain from this.",
            "πŸ‘Ž Evo was wrong. Don't retrain."
        ], label="Was Evo’s answer useful?")
        submit_btn = gr.Button("πŸ“¬ Submit Feedback")

    feedback_status = gr.Textbox(label="Feedback Status")

    with gr.Row():
        retrain_btn = gr.Button("πŸ”„ Retrain Evo Now")
        retrain_status = gr.Textbox(label="Retraining Status")

    hall = gr.Markdown("""
    ## πŸ† Evo Hall of Fame (Top Reasoning Entries)
    *(Coming soon)*
    """)

    run_btn.click(fn=compare, inputs=[question, option1, option2, context], outputs=[evo_out, gpt_out])
    submit_btn.click(fn=lambda fb, q, o1, o2, ctx, eo: handle_feedback(fb, q, o1, o2, ctx, eo),
                     inputs=[feedback_dropdown, question, option1, option2, context, evo_out],
                     outputs=feedback_status)
    retrain_btn.click(fn=manual_retrain, outputs=retrain_status)

demo.launch()