| |
| """ |
| Advanced Model Manager |
| مدیریت پیشرفته مدلهای AI با قابلیت filtering، ranking، و recommendation |
| """ |
|
|
| from typing import Dict, List, Optional, Any, Tuple |
| from dataclasses import dataclass, asdict |
| from enum import Enum |
| import json |
| import logging |
|
|
| logger = logging.getLogger(__name__) |
|
|
|
|
| class ModelCategory(Enum): |
| """دستهبندی مدلها""" |
| SENTIMENT = "sentiment" |
| GENERATION = "generation" |
| TRADING = "trading" |
| SUMMARIZATION = "summarization" |
| NER = "ner" |
| QA = "question_answering" |
| CLASSIFICATION = "classification" |
| EMBEDDING = "embedding" |
| TRANSLATION = "translation" |
| PRICE_PREDICTION = "price_prediction" |
|
|
|
|
| class ModelSize(Enum): |
| """اندازه مدلها""" |
| TINY = "tiny" |
| SMALL = "small" |
| MEDIUM = "medium" |
| LARGE = "large" |
| XLARGE = "xlarge" |
|
|
|
|
| @dataclass |
| class ModelInfo: |
| """اطلاعات کامل یک مدل AI""" |
| id: str |
| hf_id: str |
| name: str |
| category: str |
| size: str |
| size_mb: int |
| description: str |
| use_cases: List[str] |
| languages: List[str] |
| free: bool |
| requires_auth: bool |
| performance_score: float |
| popularity_score: float |
| tags: List[str] |
| api_compatible: bool = True |
| downloadable: bool = True |
| |
| def to_dict(self) -> Dict[str, Any]: |
| """تبدیل به dict""" |
| return asdict(self) |
|
|
|
|
| class AdvancedModelManager: |
| """ |
| مدیر پیشرفته مدلهای AI |
| |
| قابلیتها: |
| - Filtering بر اساس category, size, language |
| - Ranking بر اساس performance |
| - Recommendation بر اساس use case |
| - Search در تمام فیلدها |
| - Stats و Analytics |
| """ |
| |
| def __init__(self): |
| self.models = self._load_model_catalog() |
| logger.info(f"Loaded {len(self.models)} models into catalog") |
| |
| def _load_model_catalog(self) -> Dict[str, ModelInfo]: |
| """بارگذاری کاتالوگ کامل مدلها""" |
| return { |
| |
| |
| "cryptobert": ModelInfo( |
| id="cryptobert", |
| hf_id="kk08/CryptoBERT", |
| name="CryptoBERT", |
| category=ModelCategory.SENTIMENT.value, |
| size=ModelSize.SMALL.value, |
| size_mb=420, |
| description="Binary sentiment analysis optimized for crypto texts", |
| use_cases=["social_media", "news", "tweets", "reddit"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.85, |
| popularity_score=0.90, |
| tags=["crypto", "sentiment", "bert", "binary"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "elkulako_cryptobert": ModelInfo( |
| id="elkulako_cryptobert", |
| hf_id="ElKulako/cryptobert", |
| name="ElKulako CryptoBERT", |
| category=ModelCategory.SENTIMENT.value, |
| size=ModelSize.SMALL.value, |
| size_mb=450, |
| description="3-class crypto sentiment (bullish/neutral/bearish)", |
| use_cases=["twitter", "reddit", "social", "forums"], |
| languages=["en"], |
| free=True, |
| requires_auth=True, |
| performance_score=0.88, |
| popularity_score=0.85, |
| tags=["crypto", "social", "sentiment", "3-class"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "finbert": ModelInfo( |
| id="finbert", |
| hf_id="ProsusAI/finbert", |
| name="FinBERT", |
| category=ModelCategory.SENTIMENT.value, |
| size=ModelSize.SMALL.value, |
| size_mb=440, |
| description="Financial sentiment analysis (positive/negative/neutral)", |
| use_cases=["news", "articles", "reports", "earnings"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.90, |
| popularity_score=0.95, |
| tags=["finance", "sentiment", "bert", "financial"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "finbert_tone": ModelInfo( |
| id="finbert_tone", |
| hf_id="yiyanghkust/finbert-tone", |
| name="FinBERT Tone", |
| category=ModelCategory.SENTIMENT.value, |
| size=ModelSize.SMALL.value, |
| size_mb=440, |
| description="Financial tone analysis for earnings calls and reports", |
| use_cases=["earnings_calls", "reports", "financial_documents"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.87, |
| popularity_score=0.80, |
| tags=["finance", "tone", "bert"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "distilroberta_financial": ModelInfo( |
| id="distilroberta_financial", |
| hf_id="mrm8488/distilroberta-finetuned-financial-news-sentiment-analysis", |
| name="DistilRoBERTa Financial", |
| category=ModelCategory.SENTIMENT.value, |
| size=ModelSize.SMALL.value, |
| size_mb=330, |
| description="Fast financial sentiment analysis with DistilRoBERTa", |
| use_cases=["news", "real_time", "streaming"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.83, |
| popularity_score=0.75, |
| tags=["finance", "sentiment", "distil", "fast"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "fintwit_bert": ModelInfo( |
| id="fintwit_bert", |
| hf_id="StephanAkkerman/FinTwitBERT-sentiment", |
| name="FinTwitBERT", |
| category=ModelCategory.SENTIMENT.value, |
| size=ModelSize.SMALL.value, |
| size_mb=440, |
| description="Financial Twitter sentiment analysis", |
| use_cases=["twitter", "social", "fintwit"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.86, |
| popularity_score=0.82, |
| tags=["finance", "twitter", "sentiment"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "twitter_roberta": ModelInfo( |
| id="twitter_roberta", |
| hf_id="cardiffnlp/twitter-roberta-base-sentiment-latest", |
| name="Twitter RoBERTa", |
| category=ModelCategory.SENTIMENT.value, |
| size=ModelSize.MEDIUM.value, |
| size_mb=500, |
| description="State-of-the-art Twitter sentiment analysis", |
| use_cases=["twitter", "social_media", "tweets"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.89, |
| popularity_score=0.92, |
| tags=["twitter", "sentiment", "roberta", "social"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "xlm_roberta_sentiment": ModelInfo( |
| id="xlm_roberta_sentiment", |
| hf_id="cardiffnlp/twitter-xlm-roberta-base-sentiment", |
| name="XLM-RoBERTa Sentiment", |
| category=ModelCategory.SENTIMENT.value, |
| size=ModelSize.MEDIUM.value, |
| size_mb=1100, |
| description="Multilingual sentiment (100+ languages)", |
| use_cases=["global", "multilingual", "international"], |
| languages=["multi"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.87, |
| popularity_score=0.88, |
| tags=["multilingual", "sentiment", "roberta", "global"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "bertweet_sentiment": ModelInfo( |
| id="bertweet_sentiment", |
| hf_id="finiteautomata/bertweet-base-sentiment-analysis", |
| name="BERTweet Sentiment", |
| category=ModelCategory.SENTIMENT.value, |
| size=ModelSize.MEDIUM.value, |
| size_mb=540, |
| description="BERT trained specifically on tweets", |
| use_cases=["twitter", "social", "monitoring"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.85, |
| popularity_score=0.80, |
| tags=["twitter", "bert", "sentiment"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "crypto_news_bert": ModelInfo( |
| id="crypto_news_bert", |
| hf_id="mathugo/crypto_news_bert", |
| name="Crypto News BERT", |
| category=ModelCategory.SENTIMENT.value, |
| size=ModelSize.SMALL.value, |
| size_mb=420, |
| description="BERT fine-tuned on crypto news articles", |
| use_cases=["news", "articles", "crypto_media"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.84, |
| popularity_score=0.70, |
| tags=["crypto", "news", "bert"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| |
| |
| "crypto_gpt_o3": ModelInfo( |
| id="crypto_gpt_o3", |
| hf_id="OpenC/crypto-gpt-o3-mini", |
| name="Crypto GPT-O3 Mini", |
| category=ModelCategory.GENERATION.value, |
| size=ModelSize.MEDIUM.value, |
| size_mb=850, |
| description="Crypto/DeFi text generation model", |
| use_cases=["analysis", "reports", "content", "explanation"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.80, |
| popularity_score=0.70, |
| tags=["crypto", "generation", "gpt", "defi"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "fingpt": ModelInfo( |
| id="fingpt", |
| hf_id="oliverwang15/FinGPT", |
| name="FinGPT", |
| category=ModelCategory.GENERATION.value, |
| size=ModelSize.LARGE.value, |
| size_mb=1500, |
| description="Financial text generation and analysis", |
| use_cases=["reports", "analysis", "financial_content"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.82, |
| popularity_score=0.75, |
| tags=["finance", "generation", "gpt"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| |
| |
| "crypto_trader_lm": ModelInfo( |
| id="crypto_trader_lm", |
| hf_id="agarkovv/CryptoTrader-LM", |
| name="CryptoTrader LM", |
| category=ModelCategory.TRADING.value, |
| size=ModelSize.SMALL.value, |
| size_mb=450, |
| description="BTC/ETH trading signals (buy/sell/hold)", |
| use_cases=["trading", "signals", "predictions", "analysis"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.75, |
| popularity_score=0.65, |
| tags=["trading", "signals", "crypto", "predictions"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "crypto_price_predictor": ModelInfo( |
| id="crypto_price_predictor", |
| hf_id="mrm8488/bert-mini-finetuned-crypto-price-prediction", |
| name="Crypto Price Predictor", |
| category=ModelCategory.PRICE_PREDICTION.value, |
| size=ModelSize.TINY.value, |
| size_mb=60, |
| description="Price trend prediction for cryptocurrencies", |
| use_cases=["prediction", "forecasting", "trends"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.70, |
| popularity_score=0.60, |
| tags=["prediction", "price", "trends"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| |
| |
| "crypto_news_summarizer": ModelInfo( |
| id="crypto_news_summarizer", |
| hf_id="FurkanGozukara/Crypto-Financial-News-Summarizer", |
| name="Crypto News Summarizer", |
| category=ModelCategory.SUMMARIZATION.value, |
| size=ModelSize.MEDIUM.value, |
| size_mb=1200, |
| description="Summarize crypto and financial news articles", |
| use_cases=["news", "digest", "reports", "articles"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.82, |
| popularity_score=0.75, |
| tags=["summarization", "news", "crypto"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "financial_summarizer_pegasus": ModelInfo( |
| id="financial_summarizer_pegasus", |
| hf_id="human-centered-summarization/financial-summarization-pegasus", |
| name="Financial Summarizer (PEGASUS)", |
| category=ModelCategory.SUMMARIZATION.value, |
| size=ModelSize.LARGE.value, |
| size_mb=2300, |
| description="High-quality financial document summarization", |
| use_cases=["reports", "documents", "earnings", "filings"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.88, |
| popularity_score=0.80, |
| tags=["summarization", "finance", "pegasus"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "bart_large_cnn": ModelInfo( |
| id="bart_large_cnn", |
| hf_id="facebook/bart-large-cnn", |
| name="BART Large CNN", |
| category=ModelCategory.SUMMARIZATION.value, |
| size=ModelSize.LARGE.value, |
| size_mb=1600, |
| description="General-purpose news summarization", |
| use_cases=["news", "articles", "blogs", "content"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.90, |
| popularity_score=0.95, |
| tags=["summarization", "bart", "news"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "t5_base_summarization": ModelInfo( |
| id="t5_base_summarization", |
| hf_id="t5-base", |
| name="T5 Base", |
| category=ModelCategory.SUMMARIZATION.value, |
| size=ModelSize.MEDIUM.value, |
| size_mb=850, |
| description="Flexible text-to-text model for summarization", |
| use_cases=["general", "flexible", "any_text"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.85, |
| popularity_score=0.90, |
| tags=["summarization", "t5", "flexible"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| |
| |
| "bert_base_ner": ModelInfo( |
| id="bert_base_ner", |
| hf_id="dslim/bert-base-NER", |
| name="BERT Base NER", |
| category=ModelCategory.NER.value, |
| size=ModelSize.SMALL.value, |
| size_mb=420, |
| description="Named Entity Recognition for financial entities", |
| use_cases=["entities", "extraction", "companies", "tickers"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.88, |
| popularity_score=0.85, |
| tags=["ner", "entities", "bert"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| |
| |
| "roberta_squad2": ModelInfo( |
| id="roberta_squad2", |
| hf_id="deepset/roberta-base-squad2", |
| name="RoBERTa SQuAD2", |
| category=ModelCategory.QA.value, |
| size=ModelSize.MEDIUM.value, |
| size_mb=500, |
| description="Question answering for any text", |
| use_cases=["qa", "chatbot", "faq", "retrieval"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.90, |
| popularity_score=0.92, |
| tags=["qa", "roberta", "squad"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "bert_squad2": ModelInfo( |
| id="bert_squad2", |
| hf_id="deepset/bert-base-cased-squad2", |
| name="BERT SQuAD2", |
| category=ModelCategory.QA.value, |
| size=ModelSize.SMALL.value, |
| size_mb=420, |
| description="Financial FAQ and Q&A", |
| use_cases=["faq", "support", "chatbot"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.87, |
| popularity_score=0.88, |
| tags=["qa", "bert", "squad"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| |
| |
| "sentence_bert_mpnet": ModelInfo( |
| id="sentence_bert_mpnet", |
| hf_id="sentence-transformers/all-mpnet-base-v2", |
| name="Sentence-BERT MPNet", |
| category=ModelCategory.EMBEDDING.value, |
| size=ModelSize.SMALL.value, |
| size_mb=420, |
| description="High-quality sentence embeddings", |
| use_cases=["search", "similarity", "clustering", "retrieval"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.92, |
| popularity_score=0.95, |
| tags=["embeddings", "sentence", "bert"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| "e5_large_v2": ModelInfo( |
| id="e5_large_v2", |
| hf_id="intfloat/e5-large-v2", |
| name="E5 Large V2", |
| category=ModelCategory.EMBEDDING.value, |
| size=ModelSize.MEDIUM.value, |
| size_mb=1300, |
| description="State-of-the-art embeddings", |
| use_cases=["search", "retrieval", "rag", "semantic"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.94, |
| popularity_score=0.90, |
| tags=["embeddings", "e5", "search"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| |
| |
| |
| "bart_mnli": ModelInfo( |
| id="bart_mnli", |
| hf_id="facebook/bart-large-mnli", |
| name="BART MNLI", |
| category=ModelCategory.CLASSIFICATION.value, |
| size=ModelSize.LARGE.value, |
| size_mb=1600, |
| description="Zero-shot topic classification", |
| use_cases=["classification", "topics", "zero_shot"], |
| languages=["en"], |
| free=True, |
| requires_auth=False, |
| performance_score=0.89, |
| popularity_score=0.92, |
| tags=["classification", "bart", "zero_shot"], |
| api_compatible=True, |
| downloadable=True |
| ), |
| } |
| |
| |
| |
| def get_all_models(self) -> List[ModelInfo]: |
| """دریافت تمام مدلها""" |
| return list(self.models.values()) |
| |
| def get_model_by_id(self, model_id: str) -> Optional[ModelInfo]: |
| """دریافت مدل بر اساس ID""" |
| return self.models.get(model_id) |
| |
| def filter_models( |
| self, |
| category: Optional[str] = None, |
| size: Optional[str] = None, |
| max_size_mb: Optional[int] = None, |
| language: Optional[str] = None, |
| free_only: bool = True, |
| no_auth: bool = True, |
| min_performance: float = 0.0, |
| api_compatible: Optional[bool] = None, |
| tags: Optional[List[str]] = None |
| ) -> List[ModelInfo]: |
| """ |
| فیلتر کردن مدلها بر اساس معیارهای مختلف |
| """ |
| filtered = self.get_all_models() |
| |
| if category: |
| filtered = [m for m in filtered if m.category == category] |
| |
| if size: |
| filtered = [m for m in filtered if m.size == size] |
| |
| if max_size_mb: |
| filtered = [m for m in filtered if m.size_mb <= max_size_mb] |
| |
| if language: |
| filtered = [ |
| m for m in filtered |
| if language in m.languages or "multi" in m.languages |
| ] |
| |
| if free_only: |
| filtered = [m for m in filtered if m.free] |
| |
| if no_auth: |
| filtered = [m for m in filtered if not m.requires_auth] |
| |
| if min_performance > 0: |
| filtered = [m for m in filtered if m.performance_score >= min_performance] |
| |
| if api_compatible is not None: |
| filtered = [m for m in filtered if m.api_compatible == api_compatible] |
| |
| if tags: |
| filtered = [ |
| m for m in filtered |
| if any(tag in m.tags for tag in tags) |
| ] |
| |
| return filtered |
| |
| def get_best_models( |
| self, |
| category: str, |
| top_n: int = 3, |
| max_size_mb: Optional[int] = None |
| ) -> List[ModelInfo]: |
| """ |
| دریافت بهترین مدلها بر اساس performance |
| """ |
| filtered = self.filter_models( |
| category=category, |
| max_size_mb=max_size_mb |
| ) |
| |
| |
| sorted_models = sorted( |
| filtered, |
| key=lambda m: (m.performance_score, m.popularity_score), |
| reverse=True |
| ) |
| |
| return sorted_models[:top_n] |
| |
| def recommend_models( |
| self, |
| use_case: str, |
| max_models: int = 5, |
| max_size_mb: Optional[int] = None |
| ) -> List[ModelInfo]: |
| """ |
| پیشنهاد مدلها بر اساس use case |
| """ |
| all_models = self.get_all_models() |
| |
| |
| relevant = [ |
| m for m in all_models |
| if use_case in m.use_cases or any(use_case in uc for uc in m.use_cases) |
| ] |
| |
| |
| if max_size_mb: |
| relevant = [m for m in relevant if m.size_mb <= max_size_mb] |
| |
| |
| sorted_models = sorted( |
| relevant, |
| key=lambda m: (m.performance_score * m.popularity_score), |
| reverse=True |
| ) |
| |
| return sorted_models[:max_models] |
| |
| def search_models(self, query: str) -> List[ModelInfo]: |
| """ |
| جستجو در تمام فیلدهای مدلها |
| """ |
| query_lower = query.lower() |
| all_models = self.get_all_models() |
| |
| results = [] |
| for model in all_models: |
| |
| if ( |
| query_lower in model.name.lower() |
| or query_lower in model.description.lower() |
| or any(query_lower in tag for tag in model.tags) |
| or any(query_lower in uc for uc in model.use_cases) |
| or query_lower in model.hf_id.lower() |
| ): |
| results.append(model) |
| |
| |
| return sorted( |
| results, |
| key=lambda m: (m.performance_score, m.popularity_score), |
| reverse=True |
| ) |
| |
| def get_model_stats(self) -> Dict[str, Any]: |
| """آمار کامل مدلها""" |
| all_models = self.get_all_models() |
| |
| |
| by_category = {} |
| for cat in ModelCategory: |
| count = len([m for m in all_models if m.category == cat.value]) |
| by_category[cat.value] = count |
| |
| |
| by_size = {} |
| for size in ModelSize: |
| count = len([m for m in all_models if m.size == size.value]) |
| by_size[size.value] = count |
| |
| |
| all_tags = {} |
| for model in all_models: |
| for tag in model.tags: |
| all_tags[tag] = all_tags.get(tag, 0) + 1 |
| |
| |
| top_tags = sorted(all_tags.items(), key=lambda x: x[1], reverse=True)[:10] |
| |
| return { |
| "total_models": len(all_models), |
| "by_category": by_category, |
| "by_size": by_size, |
| "free_models": len([m for m in all_models if m.free]), |
| "no_auth_models": len([m for m in all_models if not m.requires_auth]), |
| "api_compatible": len([m for m in all_models if m.api_compatible]), |
| "downloadable": len([m for m in all_models if m.downloadable]), |
| "avg_performance": round( |
| sum(m.performance_score for m in all_models) / len(all_models), 2 |
| ), |
| "avg_popularity": round( |
| sum(m.popularity_score for m in all_models) / len(all_models), 2 |
| ), |
| "total_size_gb": round(sum(m.size_mb for m in all_models) / 1024, 2), |
| "top_tags": [{"tag": tag, "count": count} for tag, count in top_tags], |
| "languages_supported": list(set( |
| lang for m in all_models for lang in m.languages |
| )) |
| } |
| |
| def get_categories(self) -> List[Dict[str, Any]]: |
| """لیست categories با آمار""" |
| all_models = self.get_all_models() |
| |
| categories = [] |
| for cat in ModelCategory: |
| models_in_cat = [m for m in all_models if m.category == cat.value] |
| if models_in_cat: |
| categories.append({ |
| "id": cat.value, |
| "name": cat.name, |
| "count": len(models_in_cat), |
| "avg_performance": round( |
| sum(m.performance_score for m in models_in_cat) / len(models_in_cat), |
| 2 |
| ), |
| "models": [m.id for m in models_in_cat[:5]] |
| }) |
| |
| return sorted(categories, key=lambda x: x["count"], reverse=True) |
| |
| def export_catalog_json(self, filepath: str): |
| """Export کردن کاتالوگ به JSON""" |
| catalog = { |
| "models": [m.to_dict() for m in self.get_all_models()], |
| "stats": self.get_model_stats(), |
| "categories": self.get_categories() |
| } |
| |
| with open(filepath, 'w', encoding='utf-8') as f: |
| json.dump(catalog, f, indent=2, ensure_ascii=False) |
| |
| logger.info(f"Exported catalog to {filepath}") |
|
|
|
|
| |
| _model_manager = None |
|
|
| def get_model_manager() -> AdvancedModelManager: |
| """دریافت instance سراسری model manager""" |
| global _model_manager |
| if _model_manager is None: |
| _model_manager = AdvancedModelManager() |
| return _model_manager |
|
|
|
|
| |
| if __name__ == "__main__": |
| |
| manager = AdvancedModelManager() |
| |
| print("=== Model Manager Test ===\n") |
| |
| |
| stats = manager.get_model_stats() |
| print(f"📊 Total Models: {stats['total_models']}") |
| print(f"📊 Free Models: {stats['free_models']}") |
| print(f"📊 API Compatible: {stats['api_compatible']}") |
| print(f"📊 Avg Performance: {stats['avg_performance']}") |
| print(f"📊 Total Size: {stats['total_size_gb']} GB\n") |
| |
| |
| print("🏆 Best Sentiment Models:") |
| best_sentiment = manager.get_best_models("sentiment", top_n=3, max_size_mb=500) |
| for i, model in enumerate(best_sentiment, 1): |
| print(f" {i}. {model.name} - {model.performance_score:.2f}") |
| |
| |
| print("\n💡 Recommended for 'twitter':") |
| recommended = manager.recommend_models("twitter", max_models=3) |
| for i, model in enumerate(recommended, 1): |
| print(f" {i}. {model.name} - {model.description[:50]}...") |
| |
| |
| print("\n🔍 Search for 'crypto':") |
| search_results = manager.search_models("crypto")[:3] |
| for i, model in enumerate(search_results, 1): |
| print(f" {i}. {model.name} - {model.category}") |
| |
| |
| |
| print("\n✅ Test complete!") |
|
|