Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -41,6 +41,7 @@ class FinancialDataset(Dataset):
|
|
41 |
class FinancialAnalyzer:
|
42 |
def __init__(self):
|
43 |
print("Initializing Analyzer...")
|
|
|
44 |
self.initialize_models()
|
45 |
print("Initialization complete!")
|
46 |
|
@@ -323,33 +324,92 @@ Provide:
|
|
323 |
def generate_analysis(self, prompt):
|
324 |
"""Generate analysis using TinyLlama"""
|
325 |
try:
|
326 |
-
|
327 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
328 |
outputs = self.llama_model.generate(
|
329 |
inputs["input_ids"],
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
347 |
if len(analysis.split()) < 100:
|
348 |
-
|
|
|
349 |
|
350 |
return analysis
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
351 |
except Exception as e:
|
352 |
-
return f"Error generating analysis: {str(e)}"
|
353 |
|
354 |
def fine_tune_models(self, train_texts, train_labels, epochs=3):
|
355 |
"""Fine-tune the models with custom data"""
|
@@ -407,6 +467,7 @@ Provide:
|
|
407 |
income_data = self.parse_financial_data(income_stmt)
|
408 |
balance_data = self.parse_financial_data(balance_sheet)
|
409 |
metrics = self.extract_metrics(income_data, balance_data)
|
|
|
410 |
|
411 |
# Get sentiment analysis
|
412 |
sentiment_dict = self.get_sentiment_analysis(metrics)
|
|
|
41 |
class FinancialAnalyzer:
|
42 |
def __init__(self):
|
43 |
print("Initializing Analyzer...")
|
44 |
+
self.last_metrics = {}
|
45 |
self.initialize_models()
|
46 |
print("Initialization complete!")
|
47 |
|
|
|
324 |
def generate_analysis(self, prompt):
|
325 |
"""Generate analysis using TinyLlama"""
|
326 |
try:
|
327 |
+
# Format the prompt in TinyLlama's expected format
|
328 |
+
formatted_prompt = f"<human>: {prompt}\n<assistant>: Let me analyze these financial metrics in detail."
|
329 |
+
|
330 |
+
inputs = self.llama_tokenizer(
|
331 |
+
formatted_prompt,
|
332 |
+
return_tensors="pt",
|
333 |
+
truncation=True,
|
334 |
+
max_length=2048,
|
335 |
+
padding=True
|
336 |
+
)
|
337 |
+
|
338 |
+
# Generate with adjusted parameters
|
339 |
outputs = self.llama_model.generate(
|
340 |
inputs["input_ids"],
|
341 |
+
max_new_tokens=1024,
|
342 |
+
min_new_tokens=200, # Ensure minimum length
|
343 |
+
temperature=0.8, # Slightly increased creativity
|
344 |
+
top_p=0.92, # Slightly increased diversity
|
345 |
+
do_sample=True,
|
346 |
+
repetition_penalty=1.2,
|
347 |
+
length_penalty=1.5, # Encourage longer generations
|
348 |
+
num_return_sequences=1,
|
349 |
+
pad_token_id=self.llama_tokenizer.eos_token_id,
|
350 |
+
eos_token_id=self.llama_tokenizer.eos_token_id,
|
351 |
+
early_stopping=True
|
352 |
+
)
|
353 |
+
|
354 |
+
# Decode and clean up the response
|
355 |
+
analysis = self.llama_tokenizer.decode(outputs[0], skip_special_tokens=False)
|
356 |
+
|
357 |
+
# Extract only the assistant's response
|
358 |
+
if "<assistant>:" in analysis:
|
359 |
+
analysis = analysis.split("<assistant>:")[-1].strip()
|
360 |
+
|
361 |
+
# Clean up any remaining tags
|
362 |
+
analysis = analysis.replace("<human>:", "").replace("<assistant>:", "").strip()
|
363 |
+
|
364 |
+
# Validate output length and content
|
365 |
if len(analysis.split()) < 100:
|
366 |
+
# Fallback analysis if model generation is too short
|
367 |
+
analysis = self.generate_fallback_analysis(self.last_metrics)
|
368 |
|
369 |
return analysis
|
370 |
+
|
371 |
+
except Exception as e:
|
372 |
+
print(f"Detailed error in generate_analysis: {str(e)}")
|
373 |
+
return self.generate_fallback_analysis(self.last_metrics)
|
374 |
+
|
375 |
+
|
376 |
+
def generate_fallback_analysis(self, metrics):
|
377 |
+
"""Generate a basic analysis when the model fails"""
|
378 |
+
try:
|
379 |
+
revenue_growth = metrics['Ratios'].get('Revenue_Growth', 0)
|
380 |
+
net_margin = metrics['Ratios'].get('Net_Margin', 0)
|
381 |
+
current_ratio = metrics['Ratios'].get('Current_Ratio', 0)
|
382 |
+
debt_to_equity = metrics['Ratios'].get('Debt_to_Equity', 0)
|
383 |
+
|
384 |
+
analysis = f"""
|
385 |
+
Financial Analysis Summary:
|
386 |
+
|
387 |
+
1. Revenue and Growth:
|
388 |
+
The company shows a revenue growth of {revenue_growth:.1f}%, indicating {
|
389 |
+
'strong' if revenue_growth > 5 else 'moderate' if revenue_growth > 0 else 'weak'} growth performance.
|
390 |
+
|
391 |
+
2. Profitability:
|
392 |
+
With a net margin of {net_margin:.1f}%, the company demonstrates {
|
393 |
+
'strong' if net_margin > 10 else 'moderate' if net_margin > 5 else 'concerning'} profitability levels.
|
394 |
+
|
395 |
+
3. Liquidity Position:
|
396 |
+
The current ratio of {current_ratio:.2f}x suggests {
|
397 |
+
'very strong' if current_ratio > 2 else 'adequate' if current_ratio > 1 else 'concerning'} liquidity position.
|
398 |
+
|
399 |
+
4. Financial Leverage:
|
400 |
+
With a debt-to-equity ratio of {debt_to_equity:.2f}, the company maintains {
|
401 |
+
'conservative' if debt_to_equity < 0.5 else 'moderate' if debt_to_equity < 1 else 'aggressive'} leverage.
|
402 |
+
|
403 |
+
Key Recommendations:
|
404 |
+
1. {'Consider debt reduction' if debt_to_equity > 0.5 else 'Maintain current debt levels'}
|
405 |
+
2. {'Focus on improving profit margins' if net_margin < 5 else 'Maintain profit efficiency'}
|
406 |
+
3. {'Implement growth strategies' if revenue_growth < 2 else 'Sustain growth momentum'}
|
407 |
+
|
408 |
+
This analysis is based on key financial metrics and standard industry benchmarks.
|
409 |
+
"""
|
410 |
+
return analysis
|
411 |
except Exception as e:
|
412 |
+
return f"Error generating fallback analysis: {str(e)}"
|
413 |
|
414 |
def fine_tune_models(self, train_texts, train_labels, epochs=3):
|
415 |
"""Fine-tune the models with custom data"""
|
|
|
467 |
income_data = self.parse_financial_data(income_stmt)
|
468 |
balance_data = self.parse_financial_data(balance_sheet)
|
469 |
metrics = self.extract_metrics(income_data, balance_data)
|
470 |
+
self.last_metrics = metrics
|
471 |
|
472 |
# Get sentiment analysis
|
473 |
sentiment_dict = self.get_sentiment_analysis(metrics)
|