File size: 5,037 Bytes
e16c63b
 
 
6321827
 
b9925a7
6321827
3111d12
 
26186cb
3111d12
171a064
 
0347a6f
 
 
 
171a064
 
 
 
3111d12
 
 
 
e16c63b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c4dc5d6
3111d12
 
 
 
 
 
 
 
8b37976
 
 
e16c63b
3111d12
 
37b7a0f
3111d12
 
 
 
 
 
 
 
 
 
 
 
 
e16c63b
 
 
 
 
3111d12
e16c63b
 
 
 
 
 
 
b2a3aae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e16c63b
 
 
b2a3aae
e16c63b
 
 
b2a3aae
 
 
 
 
 
 
 
e16c63b
b2a3aae
e16c63b
5b9d241
e16c63b
 
 
b2a3aae
 
e16c63b
b2a3aae
 
 
 
 
 
e16c63b
b2a3aae
 
 
 
 
 
e16c63b
b2a3aae
e16c63b
b2a3aae
e16c63b
 
 
 
b2a3aae
 
 
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
import time
import gradio as gr

import torch
from transformers import GPT2LMHeadModel, GPT2Tokenizer
from peft import PeftModel, LoraConfig


tokenizer = GPT2Tokenizer.from_pretrained("gpt2-medium")
tokenizer.pad_token = tokenizer.eos_token
base_model = GPT2LMHeadModel.from_pretrained("gpt2-medium")

lora_config = LoraConfig(
    r=8,
    lora_alpha=16,
    target_modules=["c_fc", "c_proj", "c_attn"],
    lora_dropout=0.1,
    task_type="CAUSAL_LM"
)
    
finetuned_model = PeftModel.from_pretrained(base_model, "./lora_ft_weights", config=lora_config)
finetuned_model.eval()



# -------------------------------
# Simulated QA Models
# -------------------------------
def qa_system(method, question):
    start_time = time.time()

    if not question.strip():
        return "**Error:** Please enter a question.", 0.0, "0 seconds", ""

    # Simulated response based on method
    if method == "Retrieval-Augmented Generation (RAG)":
        answer = "Using RAG: Based on retrieved financial documents, the answer is $95,000,000."
        model_name = "RAG-based Model"
        confidence = 0.92
    else:
        model_name = "GPT 2-finetuned"
        # Input guradrails
        financial_keywords = [
            'revenue', 'profit', 'earnings', 'financial', 'income', 'balance', 
            'cash', 'debt', 'equity', 'assets', 'market', 'investment', 'sales',
            'cost', 'margin', 'growth', 'compliance', 'risk', 'customer'
        ]
        for text in question:            
        # Check for financial content
            text_lower = text.lower()
            if any(pattern in text_lower for pattern in financial_keywords):
                return "This question does not seem to be related to Finance"

        prompt = f"You are a financial assistant.\nUse the context below to answer the question.\n\nQuestion: {question}\nAnswer:"
        
        inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=512)
    
        with torch.no_grad():
            outputs = finetuned_model.generate(
                **inputs,
                max_length=inputs['input_ids'].shape[1] + 100,
                temperature=0.7,
                do_sample=True,
                pad_token_id=tokenizer.eos_token_id,
            )
        
        generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
        answer = generated_text.split("Answer:")[-1].strip()
        
    end_time = time.time()
    response_time = round(end_time - start_time, 2)

    return (
        f"**Method:** {model_name}",
        0.95,
        f"{response_time} seconds",
        answer
    )

# -------------------------------
# Gradio UI
# -------------------------------
with gr.Blocks(css="""
    .radio-vertical .wrap {
        flex-direction: column !important;
    }
    .radio-vertical .wrap > label {
        margin-bottom: 8px !important;
        margin-right: 0 !important;
    }
    .small-btn {
        max-width: fit-content !important;
        width: auto !important;
    }
    .small-btn button {
        width: auto !important; 
        min-width: unset !important; 
        padding: 8px 16px !important; 
        font-size: 16px !important;
        white-space: nowrap !important;
        max-width: fit-content !important;
    }
""") as demo:
    gr.Markdown(
        """
        # 📊 Comparative Financial QA System  
        An implementation comparing **Retrieval-Augmented Generation (RAG)** and a **Fine-Tuned on LoRA and Replay-Based Learning** GPT 2 model for answering questions on financial reports.
        """
    )

    # Radio buttons displayed vertically
    method = gr.Radio(
        choices=["Retrieval-Augmented Generation (RAG)", "Fine-Tuned Model"],
        label="Choose QA Method:",
        value="Fine-Tuned Model",
        interactive=True,
        elem_classes="radio-vertical"
    )

    # Question input
    question = gr.Textbox(
        label="Ask a question about Nice's 2023-2024 financials:",
        placeholder="e.g., What was the total revenue in 2023?"
    )

    # Get Answer button — auto-sized
    submit_btn = gr.Button("Get Answer", elem_classes="small-btn")

    # Output section - initially hidden
    with gr.Group(visible=False) as output_section:
        method_output = gr.Markdown()
        confidence_output = gr.Number(label="Model Confidence")
        response_time_output = gr.Textbox(label="Response Time")
        answer_output = gr.Markdown(label="Answer")

    # Button click handler
    def handle_submit(method_val, question_val):
        # Show output section and get results
        results = qa_system(method_val, question_val)
        return [gr.Group(visible=True)] + list(results)
    
    submit_btn.click(
        handle_submit,
        inputs=[method, question],
        outputs=[output_section, method_output, confidence_output, response_time_output, answer_output]
    )

# -------------------------------
# Launch for Hugging Face Spaces
# -------------------------------
if __name__ == "__main__":
    demo.launch()