Fetii commited on
Commit
93a9f60
·
verified ·
1 Parent(s): fbec1e4

Update backend.py

Browse files
Files changed (1) hide show
  1. backend.py +216 -214
backend.py CHANGED
@@ -1,214 +1,216 @@
1
- # ==========================================
2
- # FinTalk - Backend (llama-cpp + GPT summary)
3
- # ==========================================
4
-
5
- import os
6
- import re
7
- from typing import Dict
8
- from dotenv import load_dotenv
9
- from llama_cpp import Llama
10
- from openai import OpenAI
11
- import edge_tts
12
- import asyncio
13
- import reportlab
14
-
15
- load_dotenv()
16
-
17
- # -----------------------------------------------------
18
- # 1) MODEL YOLU (GGUF) - KENDİ YOLUNU YAZ
19
- # -----------------------------------------------------
20
- model_path = r"C:/Users/cagri/.lmstudio/models/QuantFactory/Llama-3-8B-Instruct-Finance-RAG-GGUF/Llama-3-8B-Instruct-Finance-RAG.Q4_K_S.gguf"
21
- # -----------------------------------------------------
22
- # 2) LLAMA-CPP MODEL YÜKLEME
23
- # n_ctx=4096 yeterli; 8192 istersen RAM artar. Uyarı görürsen önemsemeyebilirsin.
24
- # -----------------------------------------------------
25
- llm = Llama(
26
- model_path=model_path,
27
- n_ctx=4096,
28
- n_threads=6,
29
- n_batch=512,
30
- verbose=False
31
- )
32
-
33
- # -----------------------------------------------------
34
- # 3) OPENAI (Özetleme)
35
- # -----------------------------------------------------
36
- OPENAI_API_KEY = os.getenv("API_KEY")
37
- if not OPENAI_API_KEY:
38
- raise RuntimeError("API_KEY bulunamadı. Lütfen .env veya sistem değişkenlerine ekleyin.")
39
- client = OpenAI(api_key=OPENAI_API_KEY)
40
- SUMMARY_MODEL = os.getenv("SUMMARY_MODEL", "gpt-4o-mini")
41
-
42
- # -----------------------------------------------------
43
- # 4) PERSONA PROMPTLAR (sade)
44
- # -----------------------------------------------------
45
- SYSTEM_MODERATOR = (
46
- "You are Selin, the moderator of an economics roundtable. "
47
- "Be neutral, brief, and structured. Guide the flow without giving opinions."
48
- )
49
-
50
- SYSTEM_BULLISH = (
51
- """You are Bullish Investor, an optimistic economist who focuses on growth, market confidence, and positive catalysts.
52
- Be analytical and persuasive. Mention at least two concrete macro or market factors that support your optimism
53
- (e.g., improved investor sentiment, fiscal stimulus, or sector resilience).
54
- Respond in 2–3 detailed paragraphs and conclude with one confident takeaway."""
55
- )
56
-
57
- SYSTEM_BEARISH = (
58
- "You are Bearish Economist, a cautious macroeconomist who highlights downside risks "
59
- "(inflation persistence, liquidity stress, policy uncertainty). Be analytical; end with one cautionary insight."
60
- )
61
-
62
- # -----------------------------------------------------
63
- # 5) YARDIMCI: Post-process (meta notları, personayı ifşa eden satırları temizle)
64
- # -----------------------------------------------------
65
- _META_PATTERNS = [
66
- r"(?i)\bnote:\b.*", # "Note:" ile başlayan meta
67
- r"(?i)\bi am (selin|bullish|bearish).*$", # "I am ..." persona ifşaları
68
- r"(?i)\bthis response was written\b.*",
69
- r"(?i)\bplease review\b.*",
70
- r"(?i)\bclarity and readability\b.*",
71
- ]
72
- def _clean(text: str) -> str:
73
- cleaned = text.strip()
74
- for pat in _META_PATTERNS:
75
- cleaned = re.sub(pat, "", cleaned, flags=re.MULTILINE)
76
- # aşırı boşlukları toparla
77
- cleaned = re.sub(r"\n{3,}", "\n\n", cleaned).strip()
78
- return cleaned
79
-
80
- # -----------------------------------------------------
81
- # 6) TEK PERSONA CEVABI (chat completion + context reset)
82
- # -----------------------------------------------------
83
- def generate_as(system_prompt: str, user_text: str, max_tokens: int = 480, temperature: float = 0.7) -> str:
84
- """
85
- Her çağrıda temiz context: create_chat_completion kullanıyoruz.
86
- """
87
- # olası KV cache etkisini azaltmak için reset
88
- llm.reset()
89
- out = llm.create_chat_completion(
90
- messages=[
91
- {"role": "system", "content": system_prompt},
92
- {"role": "user", "content": user_text}
93
- ],
94
- max_tokens=max_tokens,
95
- temperature=temperature,
96
- top_p=0.9,
97
- repeat_penalty=1.1,
98
- )
99
- text = out["choices"][0]["message"]["content"]
100
- return _clean(text)
101
-
102
- # -----------------------------------------------------
103
- # 7) TARTIŞMA AKIŞI
104
- # -----------------------------------------------------
105
- def fintalk_discussion(news_text: str) -> Dict[str, str]:
106
- print("🧩 FinTalk simulation started...\n")
107
-
108
- # Ortak mesaj zinciri (tek context)
109
- messages = []
110
-
111
- # 1️⃣ Selin başlatıyor
112
- selin_intro = generate_as(SYSTEM_MODERATOR, f"Open the discussion about: {news_text}.")
113
- messages.append(f"Selin: {selin_intro}")
114
- print("Moderator Intro:\n", selin_intro, "\n")
115
-
116
- # 2️⃣ Bullish konuşuyor
117
- bullish_view = generate_as(
118
- SYSTEM_BULLISH,
119
- f"The moderator introduced the topic: {news_text}. Respond with your opening bullish perspective."
120
- )
121
- messages.append(f"Bullish Investor: {bullish_view}")
122
- print("Bullish Investor:\n", bullish_view, "\n")
123
-
124
- # 3️⃣ Bearish karşılık veriyor
125
- bearish_view = generate_as(
126
- SYSTEM_BEARISH,
127
- f"The moderator introduced the topic: {news_text}. "
128
- f"The bullish economist said: {bullish_view}\n"
129
- "Now respond with your cautious analysis."
130
- )
131
- messages.append(f"Bearish Economist: {bearish_view}")
132
- print("Bearish Economist:\n", bearish_view, "\n")
133
-
134
- # 4️⃣ Selin toparlıyor (konuya referans ver)
135
- selin_wrap = generate_as(
136
- SYSTEM_MODERATOR,
137
- f"Based on the debate about {news_text}, summarize their main differences and close the panel politely."
138
- )
139
- messages.append(f"Selin: {selin_wrap}")
140
- print("Moderator Wrap-up:\n", selin_wrap, "\n")
141
-
142
- # 5️⃣ GPT özetleme
143
- debate_text = "\n".join(messages)
144
- summary_prompt = (
145
- "Summarize this debate between a bullish and a bearish economist in 5 bullet points. "
146
- "Keep it grounded in the topic and add a balanced conclusion.\n\n"
147
- f"{debate_text}"
148
- )
149
-
150
- summary_resp = client.chat.completions.create(
151
- model=SUMMARY_MODEL,
152
- messages=[
153
- {"role": "system", "content": "You are an expert economic summarizer."},
154
- {"role": "user", "content": summary_prompt}
155
- ]
156
- )
157
- final_summary = summary_resp.choices[0].message.content.strip()
158
- print("📊 GPT Summary:\n", final_summary)
159
-
160
- return {
161
- "moderator_intro": selin_intro,
162
- "bullish_view": bullish_view,
163
- "bearish_view": bearish_view,
164
- "moderator_wrap": selin_wrap,
165
- "summary": final_summary
166
- }
167
-
168
- def export_to_pdf(result: dict, filename="FinTalk_Report.pdf"):
169
- from reportlab.lib.pagesizes import A4
170
- from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
171
- from reportlab.lib.styles import getSampleStyleSheet
172
-
173
- styles = getSampleStyleSheet()
174
- doc = SimpleDocTemplate(filename, pagesize=A4)
175
- story = []
176
-
177
- def add(title, text):
178
- story.append(Paragraph(f"<b>{title}</b>", styles["Heading3"]))
179
- story.append(Paragraph(text.replace("\n", "<br/>"), styles["BodyText"]))
180
- story.append(Spacer(1, 12))
181
-
182
- add("Topic", result.get("topic", "—"))
183
- add("Moderator Intro", result["moderator_intro"])
184
- add("Bullish Investor", result["bullish_view"])
185
- add("Bearish Economist", result["bearish_view"])
186
- add("Moderator Wrap-up", result["moderator_wrap"])
187
- add("GPT-4 Summary", result["summary"])
188
-
189
- story.append(Paragraph("<i>Generated by FinTalk – AI Economic Roundtable</i>", styles["Normal"]))
190
- doc.build(story)
191
-
192
- async def generate_tts_files(result):
193
- voices = {
194
- "moderator_intro": "en-US-AriaNeural",
195
- "bullish_view": "en-US-GuyNeural",
196
- "bearish_view": "en-GB-RyanNeural",
197
- "moderator_wrap": "en-US-AriaNeural"
198
- }
199
- for key, voice in voices.items():
200
- filename = f"{key}.mp3"
201
- text = result[key]
202
- await edge_tts.Communicate(text, voice=voice, rate="+0%").save(filename)
203
- print(f"✅ {filename} oluşturuldu")
204
-
205
- # -----------------------------------------------------
206
- # 8) Hızlı Test
207
- # -----------------------------------------------------
208
- if __name__ == "__main__":
209
- topic = input("What's discussion topic ?\n>")
210
- result = fintalk_discussion(topic)
211
- result["topic"] = topic
212
- export_to_pdf(result)
213
- asyncio.run(generate_tts_files(result))
214
-
 
 
 
1
+ # ==========================================
2
+ # FinTalk - Backend (llama-cpp + GPT summary)
3
+ # ==========================================
4
+
5
+ import os
6
+ import re
7
+ from typing import Dict
8
+ from llama_cpp import Llama
9
+ from openai import OpenAI
10
+ import edge_tts
11
+ import asyncio
12
+ import reportlab
13
+ from huggingface_hub import hf_hub_download
14
+
15
+
16
+ # -----------------------------------------------------
17
+ # 1) MODEL YOLU (GGUF) - KENDİ YOLUNU YAZ
18
+ # -----------------------------------------------------
19
+ MODEL_REPO = "QuantFactory/Llama-3-8B-Instruct-Finance-RAG-GGUF"
20
+ MODEL_FILE = "Llama-3-8B-Instruct-Finance-RAG.Q4_K_S.gguf"
21
+
22
+ model_path = hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_FILE)
23
+
24
+ # -----------------------------------------------------
25
+ # 2) LLAMA-CPP MODEL YÜKLEME
26
+ # -----------------------------------------------------
27
+ llm = Llama(
28
+ model_path=model_path,
29
+ n_ctx=4096,
30
+ n_threads=6,
31
+ n_batch=512,
32
+ verbose=False
33
+ )
34
+
35
+ # -----------------------------------------------------
36
+ # 3) OPENAI (Özetleme)
37
+ # -----------------------------------------------------
38
+ OPENAI_API_KEY = os.getenv("API_KEY")
39
+ if not OPENAI_API_KEY:
40
+ raise RuntimeError("API_KEY bulunamadı. Lütfen .env veya sistem değişkenlerine ekleyin.")
41
+ client = OpenAI(api_key=OPENAI_API_KEY)
42
+ SUMMARY_MODEL = os.getenv("SUMMARY_MODEL", "gpt-4o-mini")
43
+
44
+ # -----------------------------------------------------
45
+ # 4) PERSONA PROMPTLAR (sade)
46
+ # -----------------------------------------------------
47
+ SYSTEM_MODERATOR = (
48
+ "You are Selin, the moderator of an economics roundtable. "
49
+ "Be neutral, brief, and structured. Guide the flow without giving opinions."
50
+ )
51
+
52
+ SYSTEM_BULLISH = (
53
+ """You are Bullish Investor, an optimistic economist who focuses on growth, market confidence, and positive catalysts.
54
+ Be analytical and persuasive. Mention at least two concrete macro or market factors that support your optimism
55
+ (e.g., improved investor sentiment, fiscal stimulus, or sector resilience).
56
+ Respond in 2–3 detailed paragraphs and conclude with one confident takeaway."""
57
+ )
58
+
59
+ SYSTEM_BEARISH = (
60
+ "You are Bearish Economist, a cautious macroeconomist who highlights downside risks "
61
+ "(inflation persistence, liquidity stress, policy uncertainty). Be analytical; end with one cautionary insight."
62
+ )
63
+
64
+ # -----------------------------------------------------
65
+ # 5) YARDIMCI: Post-process (meta notları, personayı ifşa eden satırları temizle)
66
+ # -----------------------------------------------------
67
+ _META_PATTERNS = [
68
+ r"(?i)\bnote:\b.*", # "Note:" ile başlayan meta
69
+ r"(?i)\bi am (selin|bullish|bearish).*$", # "I am ..." persona ifşaları
70
+ r"(?i)\bthis response was written\b.*",
71
+ r"(?i)\bplease review\b.*",
72
+ r"(?i)\bclarity and readability\b.*",
73
+ ]
74
+ def _clean(text: str) -> str:
75
+ cleaned = text.strip()
76
+ for pat in _META_PATTERNS:
77
+ cleaned = re.sub(pat, "", cleaned, flags=re.MULTILINE)
78
+ # aşırı boşlukları toparla
79
+ cleaned = re.sub(r"\n{3,}", "\n\n", cleaned).strip()
80
+ return cleaned
81
+
82
+ # -----------------------------------------------------
83
+ # 6) TEK PERSONA CEVABI (chat completion + context reset)
84
+ # -----------------------------------------------------
85
+ def generate_as(system_prompt: str, user_text: str, max_tokens: int = 480, temperature: float = 0.7) -> str:
86
+ """
87
+ Her çağrıda temiz context: create_chat_completion kullanıyoruz.
88
+ """
89
+ # olası KV cache etkisini azaltmak için reset
90
+ llm.reset()
91
+ out = llm.create_chat_completion(
92
+ messages=[
93
+ {"role": "system", "content": system_prompt},
94
+ {"role": "user", "content": user_text}
95
+ ],
96
+ max_tokens=max_tokens,
97
+ temperature=temperature,
98
+ top_p=0.9,
99
+ repeat_penalty=1.1,
100
+ )
101
+ text = out["choices"][0]["message"]["content"]
102
+ return _clean(text)
103
+
104
+ # -----------------------------------------------------
105
+ # 7) TARTIŞMA AKIŞI
106
+ # -----------------------------------------------------
107
+ def fintalk_discussion(news_text: str) -> Dict[str, str]:
108
+ print("🧩 FinTalk simulation started...\n")
109
+
110
+ # Ortak mesaj zinciri (tek context)
111
+ messages = []
112
+
113
+ # 1️⃣ Selin başlatıyor
114
+ selin_intro = generate_as(SYSTEM_MODERATOR, f"Open the discussion about: {news_text}.")
115
+ messages.append(f"Selin: {selin_intro}")
116
+ print("Moderator Intro:\n", selin_intro, "\n")
117
+
118
+ # 2️⃣ Bullish konuşuyor
119
+ bullish_view = generate_as(
120
+ SYSTEM_BULLISH,
121
+ f"The moderator introduced the topic: {news_text}. Respond with your opening bullish perspective."
122
+ )
123
+ messages.append(f"Bullish Investor: {bullish_view}")
124
+ print("Bullish Investor:\n", bullish_view, "\n")
125
+
126
+ # 3️⃣ Bearish karşılık veriyor
127
+ bearish_view = generate_as(
128
+ SYSTEM_BEARISH,
129
+ f"The moderator introduced the topic: {news_text}. "
130
+ f"The bullish economist said: {bullish_view}\n"
131
+ "Now respond with your cautious analysis."
132
+ )
133
+ messages.append(f"Bearish Economist: {bearish_view}")
134
+ print("Bearish Economist:\n", bearish_view, "\n")
135
+
136
+ # 4️⃣ Selin toparlıyor (konuya referans ver)
137
+ selin_wrap = generate_as(
138
+ SYSTEM_MODERATOR,
139
+ f"Based on the debate about {news_text}, summarize their main differences and close the panel politely."
140
+ )
141
+ messages.append(f"Selin: {selin_wrap}")
142
+ print("Moderator Wrap-up:\n", selin_wrap, "\n")
143
+
144
+ # 5️⃣ GPT özetleme
145
+ debate_text = "\n".join(messages)
146
+ summary_prompt = (
147
+ "Summarize this debate between a bullish and a bearish economist in 5 bullet points. "
148
+ "Keep it grounded in the topic and add a balanced conclusion.\n\n"
149
+ f"{debate_text}"
150
+ )
151
+
152
+ summary_resp = client.chat.completions.create(
153
+ model=SUMMARY_MODEL,
154
+ messages=[
155
+ {"role": "system", "content": "You are an expert economic summarizer."},
156
+ {"role": "user", "content": summary_prompt}
157
+ ]
158
+ )
159
+ final_summary = summary_resp.choices[0].message.content.strip()
160
+ print("📊 GPT Summary:\n", final_summary)
161
+
162
+ return {
163
+ "moderator_intro": selin_intro,
164
+ "bullish_view": bullish_view,
165
+ "bearish_view": bearish_view,
166
+ "moderator_wrap": selin_wrap,
167
+ "summary": final_summary
168
+ }
169
+
170
+ def export_to_pdf(result: dict, filename="FinTalk_Report.pdf"):
171
+ from reportlab.lib.pagesizes import A4
172
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
173
+ from reportlab.lib.styles import getSampleStyleSheet
174
+
175
+ styles = getSampleStyleSheet()
176
+ doc = SimpleDocTemplate(filename, pagesize=A4)
177
+ story = []
178
+
179
+ def add(title, text):
180
+ story.append(Paragraph(f"<b>{title}</b>", styles["Heading3"]))
181
+ story.append(Paragraph(text.replace("\n", "<br/>"), styles["BodyText"]))
182
+ story.append(Spacer(1, 12))
183
+
184
+ add("Topic", result.get("topic", "—"))
185
+ add("Moderator Intro", result["moderator_intro"])
186
+ add("Bullish Investor", result["bullish_view"])
187
+ add("Bearish Economist", result["bearish_view"])
188
+ add("Moderator Wrap-up", result["moderator_wrap"])
189
+ add("GPT-4 Summary", result["summary"])
190
+
191
+ story.append(Paragraph("<i>Generated by FinTalk – AI Economic Roundtable</i>", styles["Normal"]))
192
+ doc.build(story)
193
+
194
+ async def generate_tts_files(result):
195
+ voices = {
196
+ "moderator_intro": "en-US-AriaNeural",
197
+ "bullish_view": "en-US-GuyNeural",
198
+ "bearish_view": "en-GB-RyanNeural",
199
+ "moderator_wrap": "en-US-AriaNeural"
200
+ }
201
+ for key, voice in voices.items():
202
+ filename = f"{key}.mp3"
203
+ text = result[key]
204
+ await edge_tts.Communicate(text, voice=voice, rate="+0%").save(filename)
205
+ print(f"✅ {filename} oluşturuldu")
206
+
207
+ # -----------------------------------------------------
208
+ # 8) Hızlı Test
209
+ # -----------------------------------------------------
210
+ if __name__ == "__main__":
211
+ topic = input("What's discussion topic ?\n>")
212
+ result = fintalk_discussion(topic)
213
+ result["topic"] = topic
214
+ export_to_pdf(result)
215
+ asyncio.run(generate_tts_files(result))
216
+