Spaces:
Running
Running
File size: 4,762 Bytes
021e065 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | import os
import torch
import torch.nn as nn
import torch.nn.functional as F
from typing import Dict, Any
class CommunitySaccoClassifier(nn.Module):
def __init__(self, input_dim=10, hidden_dim=24):
super().__init__()
self.net = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, 3) # 3 classes: Stable, Caution, At Risk
)
def forward(self, x):
return self.net(x)
class SentiCommunityEngine:
def __init__(self, weights_path: str):
self.model = CommunitySaccoClassifier()
if os.path.exists(weights_path):
self.model.load_state_dict(torch.load(weights_path, map_location=torch.device('cpu')))
self.model.eval()
def predict(self, text: str) -> Dict[str, Any]:
raw = text.lower()
feat = [
len(raw) / 10000.0,
1.0 if "sacco" in raw else 0.0,
1.0 if "dividend" in raw else 0.0,
1.0 if "microfinance" in raw else 0.0,
1.0 if "literacy" in raw else 0.0,
1.0 if "expenditure" in raw else 0.0,
1.0 if "budget" in raw else 0.0,
1.0 if "swahili" in raw else 0.0,
1.0 if "sheng" in raw else 0.0,
1.0 if "behavioral" in raw else 0.0
]
with torch.no_grad():
x = torch.tensor([feat], dtype=torch.float32)
logits = self.model(x)
probs = F.softmax(logits, dim=1).numpy()[0]
pred_class = int(logits.argmax(dim=1).item())
health_states = ["Stable / Liquid", "Caution / Review dividend payouts", "At Risk / High NPLs"]
nudge = "Weka akiba leo kwa maisha bora ya baadaye."
if pred_class == 2:
nudge = "Chunga mfuko wako! Punguza madeni na ongeza hisa zako katika SACCO."
elif pred_class == 1:
nudge = "Tenga bajeti vizuri ili uweze kulipa mkopo wako bila shida."
return {
"sacco_health_status": health_states[pred_class],
"nudge_message": nudge,
"confidence": float(probs[pred_class]),
"framework": "SASRA Sacco Regulations & Financial Literacy Guidelines"
}
# ββ RLM Integration ββββββββββββββββββββββββββββββββββββββββββββββ
class SentiCommunityRLM:
"""
SentiCommunityRLM wraps the shared RLMEngine to provide deep reasoning capabilities
using a dedicated Ollama specialist model (senti-community-rlm).
"""
def __init__(self, model_name: str = "senti-community-rlm"):
import sys
import os
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if base_dir not in sys.path:
sys.path.insert(0, base_dir)
from senti.core.engines.superpacks.rlm_engine import RLMEngine
self.engine = RLMEngine(model=model_name)
async def predict_deep(self, text: str, tier: str = "C") -> dict:
import time
context = {
"tier": tier,
"domain": "senticommunity",
"timestamp": time.time(),
}
system_suffix = (
"Focus on SACCO dividend planning, public budget expenditure explainers, financial literacy teaching, and Sheng/Swahili cognitive behavioral spend nudges."
)
rlm_response = await self.engine.reason(
query=text,
context=context,
system_suffix=system_suffix
)
res = rlm_response.to_dict()
# Map RLM decision to legacy SML fields for backward compatibility
decision = res.get("decision", "stable").lower()
health_status = "Stable / Liquid"
nudge = "Weka akiba leo kwa maisha bora ya baadaye."
if any(w in decision for w in ["risk", "poor", "insolvent", "alert"]):
health_status = "At Risk / High NPLs"
nudge = "Chunga mfuko wako! Punguza madeni na ongeza hisa zako katika SACCO."
elif any(w in decision for w in ["caution", "review", "moderate"]):
health_status = "Caution / Review dividend payouts"
nudge = "Tenga bajeti vizuri ili uweze kulipa mkopo wako bila shida."
res["sacco_health_status"] = health_status
res["nudge_message"] = nudge if "swahili" in res.get("justification", "").lower() or "sheng" in res.get("justification", "").lower() else res.get("justification", nudge)
res["confidence"] = res.get("confidence", 0.5)
res["framework"] = "SASRA Sacco Regulations & Financial Literacy Guidelines"
return res
|