Gaston895 commited on
Commit
ff725d4
·
verified ·
1 Parent(s): 1a0449d

Upload Flask app

Browse files
Files changed (1) hide show
  1. app.py +172 -0
app.py ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, jsonify, stream_template
2
+ import torch
3
+ from transformers import AutoTokenizer, AutoModelForCausalLM
4
+ import re
5
+ import gc
6
+ import json
7
+ import threading
8
+ import time
9
+
10
+ app = Flask(__name__)
11
+
12
+ # Global variables for model and tokenizer
13
+ model = None
14
+ tokenizer = None
15
+ model_loaded = False
16
+ loading_status = "Initializing..."
17
+
18
+ def load_model():
19
+ """Load the model and tokenizer optimized for CPU"""
20
+ global model, tokenizer, model_loaded, loading_status
21
+
22
+ try:
23
+ loading_status = "Loading tokenizer..."
24
+ print("Loading AEGIS Conduct Economic Analysis Model for CPU...")
25
+
26
+ # Load tokenizer first
27
+ tokenizer = AutoTokenizer.from_pretrained(
28
+ "Gaston895/aegisconduct",
29
+ trust_remote_code=True
30
+ )
31
+
32
+ loading_status = "Loading model (this may take a few minutes)..."
33
+
34
+ # Load model optimized for CPU
35
+ model = AutoModelForCausalLM.from_pretrained(
36
+ "Gaston895/aegisconduct",
37
+ torch_dtype=torch.float16,
38
+ device_map="cpu",
39
+ trust_remote_code=True,
40
+ low_cpu_mem_usage=True
41
+ )
42
+
43
+ # Force garbage collection
44
+ gc.collect()
45
+
46
+ loading_status = "Model loaded successfully!"
47
+ print("Model loaded successfully on CPU!")
48
+ model_loaded = True
49
+ return True
50
+
51
+ except Exception as e:
52
+ loading_status = f"Error loading model: {str(e)}"
53
+ print(f"Error loading model: {e}")
54
+ model_loaded = False
55
+ return False
56
+
57
+ def format_response(text):
58
+ """Clean and format the model response"""
59
+ # Remove thinking tags if present
60
+ text = re.sub(r'<thinking>.*?</thinking>', '', text, flags=re.DOTALL)
61
+
62
+ # Clean up extra whitespace
63
+ text = re.sub(r'\n\s*\n', '\n\n', text)
64
+ text = text.strip()
65
+
66
+ return text
67
+
68
+ def generate_response(message, history=None, temperature=0.7, max_tokens=128):
69
+ """Generate response from the model optimized for CPU"""
70
+ global model, tokenizer, model_loaded
71
+
72
+ if not model_loaded or model is None or tokenizer is None:
73
+ return "Model is still loading... Please wait a moment and try again."
74
+
75
+ try:
76
+ # Build conversation context
77
+ conversation = ""
78
+ if history:
79
+ # Only use last 2 exchanges to save memory
80
+ recent_history = history[-2:] if len(history) > 2 else history
81
+ for exchange in recent_history:
82
+ conversation += f"User: {exchange['user']}\nAssistant: {exchange['assistant']}\n\n"
83
+
84
+ # Add current message
85
+ conversation += f"User: {message}\nAssistant:"
86
+
87
+ # Tokenize input with strict length limit for CPU
88
+ inputs = tokenizer(conversation, return_tensors="pt", truncation=True, max_length=512)
89
+
90
+ # Generate response with CPU-optimized settings
91
+ with torch.no_grad():
92
+ outputs = model.generate(
93
+ **inputs,
94
+ max_new_tokens=max_tokens,
95
+ temperature=temperature,
96
+ do_sample=True,
97
+ top_p=0.9,
98
+ top_k=50,
99
+ repetition_penalty=1.1,
100
+ pad_token_id=tokenizer.eos_token_id,
101
+ eos_token_id=tokenizer.eos_token_id,
102
+ use_cache=True,
103
+ num_beams=1
104
+ )
105
+
106
+ # Decode response
107
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
108
+
109
+ # Extract only the new response
110
+ response = response[len(conversation):].strip()
111
+
112
+ # Format and clean response
113
+ response = format_response(response)
114
+
115
+ # Clean up memory after generation
116
+ gc.collect()
117
+
118
+ return response if response else "I apologize, but I couldn't generate a proper response. Please try rephrasing your question."
119
+
120
+ except Exception as e:
121
+ return f"Error generating response: {str(e)}. Please try a shorter question."
122
+
123
+ @app.route('/')
124
+ def index():
125
+ """Main chat interface"""
126
+ return render_template('index.html')
127
+
128
+ @app.route('/status')
129
+ def status():
130
+ """Get model loading status"""
131
+ return jsonify({
132
+ 'loaded': model_loaded,
133
+ 'status': loading_status
134
+ })
135
+
136
+ @app.route('/chat', methods=['POST'])
137
+ def chat():
138
+ """Handle chat messages"""
139
+ data = request.json
140
+ message = data.get('message', '').strip()
141
+ history = data.get('history', [])
142
+ temperature = float(data.get('temperature', 0.7))
143
+ max_tokens = int(data.get('max_tokens', 128))
144
+
145
+ if not message:
146
+ return jsonify({'error': 'No message provided'}), 400
147
+
148
+ # Generate response
149
+ response = generate_response(message, history, temperature, max_tokens)
150
+
151
+ return jsonify({
152
+ 'response': response,
153
+ 'timestamp': time.time()
154
+ })
155
+
156
+ @app.route('/clear', methods=['POST'])
157
+ def clear_chat():
158
+ """Clear chat history and free memory"""
159
+ gc.collect()
160
+ return jsonify({'status': 'cleared'})
161
+
162
+ # Start model loading in background thread
163
+ def start_model_loading():
164
+ load_model()
165
+
166
+ if __name__ == '__main__':
167
+ # Start model loading in background
168
+ loading_thread = threading.Thread(target=start_model_loading)
169
+ loading_thread.daemon = True
170
+ loading_thread.start()
171
+
172
+ app.run(host='0.0.0.0', port=7860, debug=False)