Spaces:
Running
Running
Commit
·
888b837
1
Parent(s):
4864457
3.50
Browse files
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
|
109 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
# Initialize default return values
|
111 |
impact = "Неопределенный эффект"
|
112 |
-
reasoning = "Не удалось
|
113 |
|
114 |
try:
|
115 |
-
|
116 |
-
|
117 |
-
|
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 |
-
|
131 |
-
|
132 |
-
return_tensors="pt",
|
133 |
-
padding=True,
|
134 |
-
truncation=True,
|
135 |
-
max_length=512
|
136 |
-
).to(self.device)
|
137 |
|
138 |
-
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
147 |
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
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 |
-
|
|
|
168 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
169 |
except Exception as e:
|
170 |
-
st.warning(f"
|
171 |
-
|
|
|
|
|
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("
|
334 |
-
|
335 |
-
|
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.
|
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 |
|