pentarosarium commited on
Commit
888b837
·
1 Parent(s): 4864457
Files changed (1) hide show
  1. app.py +89 -70
app.py CHANGED
@@ -55,18 +55,18 @@ class FallbackLLMSystem:
55
  try:
56
  prompt = f"""<s>Analyze news about company {entity}:
57
 
58
- {text}
59
 
60
- Classify event type as one of:
61
- - Отчетность (financial reports)
62
- - РЦБ (securities market events)
63
- - Суд (legal actions)
64
- - Нет (no significant events)
65
 
66
- Format response as:
67
- Тип: [type]
68
- Краткое описание: [summary]</s>"""
69
-
70
  inputs = self.tokenizer(
71
  prompt,
72
  return_tensors="pt",
@@ -105,70 +105,84 @@ Format response as:
105
  st.warning(f"Event detection error: {str(e)}")
106
  return "Нет", "Ошибка анализа"
107
 
108
- def estimate_impact(self, text, entity):
109
- """Estimate impact using MT5"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  # Initialize default return values
111
  impact = "Неопределенный эффект"
112
- reasoning = "Не удалось определить влияние"
113
 
114
  try:
115
- prompt = f"""<s>Analyze impact of news about company {entity}:
116
-
117
- {text}
118
-
119
- Classify impact as one of:
120
- - Значительный риск убытков
121
- - Умеренный риск убытков
122
- - Незначительный риск убытков
123
- - Вероятность прибыли
124
- - Неопределенный эффект
125
-
126
- Format response as:
127
- Impact: [category]
128
- Reasoning: [explanation]</s>"""
129
 
130
- inputs = self.tokenizer(
131
- prompt,
132
- return_tensors="pt",
133
- padding=True,
134
- truncation=True,
135
- max_length=512
136
- ).to(self.device)
137
 
138
- outputs = self.model.generate(
139
- **inputs,
140
- max_length=200,
141
- num_return_sequences=1,
142
- do_sample=False,
143
- pad_token_id=self.tokenizer.pad_token_id
144
- )
145
 
146
- response = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
 
 
 
 
 
147
 
148
- if "Impact:" in response and "Reasoning:" in response:
149
- parts = response.split("Reasoning:")
150
- impact_part = parts[0]
151
- if "Impact:" in impact_part:
152
- impact = impact_part.split("Impact:")[1].strip()
153
- # Validate impact category
154
- valid_impacts = [
155
- "Значительный риск убытков",
156
- "Умеренный риск убытков",
157
- "Незначительный риск убытков",
158
- "Вероятность прибыли",
159
- "Неопределенный эффект"
160
- ]
161
- if impact not in valid_impacts:
162
- impact = "Неопределенный эффект"
163
-
164
- if len(parts) > 1:
165
- reasoning = parts[1].strip()
166
 
167
- return impact, reasoning
 
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  except Exception as e:
170
- st.warning(f"Impact estimation error: {str(e)}")
171
- return "Неопределенный эффект", "Ошибка анализа"
 
 
172
 
173
 
174
  class TranslationSystem:
@@ -257,6 +271,11 @@ def process_file(uploaded_file, model_choice, translation_method=None):
257
  fallback_llm = FallbackLLMSystem() if model_choice != "Local-MT5" else llm
258
  translator = TranslationSystem(batch_size=5)
259
 
 
 
 
 
 
260
  # Initialize all required columns first
261
  df['Translated'] = ''
262
  df['Sentiment'] = ''
@@ -324,17 +343,17 @@ def process_file(uploaded_file, model_choice, translation_method=None):
324
  if sentiment == "Negative":
325
  try:
326
  impact, reasoning = estimate_impact(
327
- llm,
328
  translated_text,
329
  row['Объект']
330
  )
 
 
331
  except Exception as e:
332
  if 'rate limit' in str(e).lower():
333
- st.warning("Rate limit reached. Using fallback model for impact estimation.")
334
- impact, reasoning = fallback_llm.estimate_impact(
335
- translated_text,
336
- row['Объект']
337
- )
338
 
339
  df.at[idx, 'Impact'] = impact
340
  df.at[idx, 'Reasoning'] = reasoning
@@ -779,7 +798,7 @@ def create_output_file(df, uploaded_file, llm):
779
  return output
780
  def main():
781
  with st.sidebar:
782
- st.title("::: AI-анализ мониторинга новостей (v.3.49):::")
783
  st.subheader("по материалам СКАН-ИНТЕРФАКС ")
784
 
785
 
 
55
  try:
56
  prompt = f"""<s>Analyze news about company {entity}:
57
 
58
+ {text}
59
 
60
+ Classify event type as one of:
61
+ - Отчетность (financial reports)
62
+ - РЦБ (securities market events)
63
+ - Суд (legal actions)
64
+ - Нет (no significant events)
65
 
66
+ Format response as:
67
+ Тип: [type]
68
+ Краткое описание: [summary]</s>"""
69
+
70
  inputs = self.tokenizer(
71
  prompt,
72
  return_tensors="pt",
 
105
  st.warning(f"Event detection error: {str(e)}")
106
  return "Нет", "Ошибка анализа"
107
 
108
+ def ensure_groq_llm():
109
+ """Initialize Groq LLM for impact estimation"""
110
+ try:
111
+ if 'groq_key' not in st.secrets:
112
+ st.error("Groq API key not found in secrets. Please add it with the key 'groq_key'.")
113
+ return None
114
+
115
+ return ChatOpenAI(
116
+ base_url="https://api.groq.com/openai/v1",
117
+ model="llama-3.1-70b-versatile",
118
+ openai_api_key=st.secrets['groq_key'],
119
+ temperature=0.0
120
+ )
121
+ except Exception as e:
122
+ st.error(f"Error initializing Groq LLM: {str(e)}")
123
+ return None
124
+
125
+ def estimate_impact(llm, news_text, entity):
126
+ """
127
+ Estimate impact using Groq LLM regardless of the main model choice.
128
+ Falls back to the provided LLM if Groq initialization fails.
129
+ """
130
  # Initialize default return values
131
  impact = "Неопределенный эффект"
132
+ reasoning = "Не удалось получить обоснование"
133
 
134
  try:
135
+ # Always try to use Groq first
136
+ groq_llm = ensure_groq_llm()
137
+ working_llm = groq_llm if groq_llm is not None else llm
 
 
 
 
 
 
 
 
 
 
 
138
 
139
+ template = """
140
+ You are a financial analyst. Analyze this news piece about {entity} and assess its potential impact.
 
 
 
 
 
141
 
142
+ News: {news}
 
 
 
 
 
 
143
 
144
+ Classify the impact into one of these categories:
145
+ 1. "Значительный риск убытков" (Significant loss risk)
146
+ 2. "Умеренный риск убытков" (Moderate loss risk)
147
+ 3. "Незначительный риск убытков" (Minor loss risk)
148
+ 4. "Вероятность прибыли" (Potential profit)
149
+ 5. "Неопределенный эффект" (Uncertain effect)
150
 
151
+ Provide a brief, fact-based reasoning for your assessment.
152
+
153
+ Format your response exactly as:
154
+ Impact: [category]
155
+ Reasoning: [explanation in 2-3 sentences]
156
+ """
157
+
158
+ prompt = PromptTemplate(template=template, input_variables=["entity", "news"])
159
+ chain = prompt | working_llm
160
+ response = chain.invoke({"entity": entity, "news": news_text})
 
 
 
 
 
 
 
 
161
 
162
+ # Extract content from response
163
+ response_text = response.content if hasattr(response, 'content') else str(response)
164
 
165
+ if "Impact:" in response_text and "Reasoning:" in response_text:
166
+ impact_part, reasoning_part = response_text.split("Reasoning:")
167
+ impact_temp = impact_part.split("Impact:")[1].strip()
168
+
169
+ # Validate impact category
170
+ valid_impacts = [
171
+ "Значительный риск убытков",
172
+ "Умеренный риск убытков",
173
+ "Незначительный риск убытков",
174
+ "Вероятность прибыли",
175
+ "Неопределенный эффект"
176
+ ]
177
+ if impact_temp in valid_impacts:
178
+ impact = impact_temp
179
+ reasoning = reasoning_part.strip()
180
+
181
  except Exception as e:
182
+ st.warning(f"Error in impact estimation: {str(e)}")
183
+
184
+ return impact, reasoning
185
+
186
 
187
 
188
  class TranslationSystem:
 
271
  fallback_llm = FallbackLLMSystem() if model_choice != "Local-MT5" else llm
272
  translator = TranslationSystem(batch_size=5)
273
 
274
+ # Pre-initialize Groq for impact estimation
275
+ groq_llm = ensure_groq_llm()
276
+ if groq_llm is None:
277
+ st.warning("Failed to initialize Groq LLM for impact estimation. Using fallback model.")
278
+
279
  # Initialize all required columns first
280
  df['Translated'] = ''
281
  df['Sentiment'] = ''
 
343
  if sentiment == "Negative":
344
  try:
345
  impact, reasoning = estimate_impact(
346
+ groq_llm if groq_llm is not None else llm,
347
  translated_text,
348
  row['Объект']
349
  )
350
+ df.at[idx, 'Impact'] = impact
351
+ df.at[idx, 'Reasoning'] = reasoning
352
  except Exception as e:
353
  if 'rate limit' in str(e).lower():
354
+ st.warning("Groq rate limit reached. Waiting before retry...")
355
+ time.sleep(240) # Wait 4 minutes
356
+ continue
 
 
357
 
358
  df.at[idx, 'Impact'] = impact
359
  df.at[idx, 'Reasoning'] = reasoning
 
798
  return output
799
  def main():
800
  with st.sidebar:
801
+ st.title("::: AI-анализ мониторинга новостей (v.3.50):::")
802
  st.subheader("по материалам СКАН-ИНТЕРФАКС ")
803
 
804