|
|
import re |
|
|
from typing import Dict, Tuple, Optional |
|
|
from sentence_transformers import SentenceTransformer |
|
|
from config.settings import settings |
|
|
|
|
|
class MultilingualManager: |
|
|
def __init__(self): |
|
|
self.vietnamese_model = None |
|
|
self.multilingual_model = None |
|
|
self.current_language = 'vi' |
|
|
|
|
|
|
|
|
self.language_patterns = { |
|
|
'vi': { |
|
|
'chars': set('àáâãèéêìíòóôõùúýăđĩũơưạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹ'), |
|
|
'common_words': ['của', 'và', 'là', 'có', 'được', 'trong', 'cho', 'với', 'như', 'tôi'] |
|
|
}, |
|
|
'en': { |
|
|
'chars': set('abcdefghijklmnopqrstuvwxyz'), |
|
|
'common_words': ['the', 'and', 'is', 'are', 'for', 'with', 'this', 'that', 'you', 'they'] |
|
|
}, |
|
|
'fr': { |
|
|
'chars': set('àâæçèéêëîïôœùûüÿ'), |
|
|
'common_words': ['le', 'la', 'et', 'est', 'dans', 'pour', 'avec', 'vous', 'nous', 'ils'] |
|
|
}, |
|
|
'es': { |
|
|
'chars': set('áéíóúñü'), |
|
|
'common_words': ['el', 'la', 'y', 'es', 'en', 'por', 'con', 'los', 'las', 'del'] |
|
|
}, |
|
|
'de': { |
|
|
'chars': set('äöüß'), |
|
|
'common_words': ['der', 'die', 'das', 'und', 'ist', 'in', 'für', 'mit', 'sich', 'nicht'] |
|
|
}, |
|
|
'ja': { |
|
|
'chars': set('ぁ-んァ-ン一-龯'), |
|
|
'common_words': ['の', 'に', 'は', 'を', 'た', 'で', 'し', 'が', 'ます', 'です'] |
|
|
}, |
|
|
'ko': { |
|
|
'chars': set('가-힣'), |
|
|
'common_words': ['이', '그', '에', '를', '의', '에', '에서', '으로', '하다', '이다'] |
|
|
}, |
|
|
'zh': { |
|
|
'chars': set('一-鿌'), |
|
|
'common_words': ['的', '是', '在', '有', '和', '了', '人', '我', '他', '这'] |
|
|
} |
|
|
} |
|
|
self._initialize_models() |
|
|
def _initialize_models(self): |
|
|
"""Khởi tạo các mô hình đa ngôn ngữ""" |
|
|
try: |
|
|
print("🔄 Đang tải mô hình embedding tiếng Việt...") |
|
|
self.vietnamese_model = SentenceTransformer(settings.VIETNAMESE_EMBEDDING_MODEL) |
|
|
print("✅ Đã tải mô hình embedding tiếng Việt") |
|
|
except Exception as e: |
|
|
print(f"❌ Lỗi tải mô hình embedding tiếng Việt: {e}") |
|
|
self.vietnamese_model = None |
|
|
|
|
|
try: |
|
|
print("🔄 Đang tải mô hình embedding đa ngôn ngữ...") |
|
|
self.multilingual_model = SentenceTransformer(settings.MULTILINGUAL_EMBEDDING_MODEL,trust_remote_code=True ) |
|
|
print("✅ Đã tải mô hình embedding đa ngôn ngữ") |
|
|
except Exception as e: |
|
|
print(f"❌ Lỗi tải mô hình embedding đa ngôn ngữ: {e}") |
|
|
self.multilingual_model = None |
|
|
|
|
|
def detect_language(self, text: str) -> str: |
|
|
"""Phát hiện ngôn ngữ với độ chính xác cao""" |
|
|
if not text or len(text.strip()) == 0: |
|
|
return 'vi' |
|
|
|
|
|
text_lower = text.lower() |
|
|
scores = {} |
|
|
|
|
|
for lang, patterns in self.language_patterns.items(): |
|
|
score = 0 |
|
|
|
|
|
|
|
|
char_score = sum(1 for char in text if char in patterns['chars']) |
|
|
score += char_score * 2 |
|
|
|
|
|
|
|
|
word_score = sum(1 for word in patterns['common_words'] if word in text_lower) |
|
|
score += word_score |
|
|
|
|
|
scores[lang] = score |
|
|
|
|
|
|
|
|
detected_lang = max(scores.items(), key=lambda x: x[1])[0] |
|
|
|
|
|
|
|
|
if max(scores.values()) < 3: |
|
|
vietnamese_chars = set('àáâãèéêìíòóôõùúýăđĩũơưạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹ') |
|
|
if any(char in vietnamese_chars for char in text): |
|
|
return 'vi' |
|
|
elif any(char in text for char in 'あいうえおぁ-んァ-ン'): |
|
|
return 'ja' |
|
|
elif any(char in text for char in '你好'): |
|
|
return 'zh' |
|
|
elif any(char in text for char in '안녕'): |
|
|
return 'ko' |
|
|
else: |
|
|
return 'en' |
|
|
|
|
|
return detected_lang |
|
|
def get_embedding_model(self, language: str = None) -> Optional[SentenceTransformer]: |
|
|
"""Lấy mô hình embedding dựa trên ngôn ngữ đã phát hiện""" |
|
|
lang = language if language in settings.SUPPORTED_LANGUAGES else self.current_language |
|
|
|
|
|
if lang == 'vi': |
|
|
return self.vietnamese_model |
|
|
else: |
|
|
return self.multilingual_model |
|
|
|
|
|
def get_llm_model_name(self, language: str = None) -> str: |
|
|
"""Lấy tên mô hình LLM dựa trên ngôn ngữ đã phát hiện""" |
|
|
lang = language if language in settings.SUPPORTED_LANGUAGES else self.current_language |
|
|
|
|
|
if lang == 'vi': |
|
|
return settings.VIETNAMESE_LLM_MODEL |
|
|
else: |
|
|
return settings.MULTILINGUAL_LLM_MODEL |
|
|
|
|
|
def get_language_info(self, language: str = None) -> Dict: |
|
|
"""Lấy thông tin ngôn ngữ bao gồm mã và tên đầy đủ""" |
|
|
lang = language if language in settings.SUPPORTED_LANGUAGES else self.current_language |
|
|
|
|
|
model_info = { |
|
|
'vi': { |
|
|
'name': 'Tiếng Việt', |
|
|
'embedding_model': settings.VIETNAMESE_EMBEDDING_MODEL, |
|
|
'llm_model': settings.VIETNAMESE_LLM_MODEL, |
|
|
'status': 'active' if self.vietnamese_model else 'inactive' |
|
|
}, |
|
|
'other': { |
|
|
'name': 'Multilingual', |
|
|
'embedding_model': settings.MULTILINGUAL_EMBEDDING_MODEL, |
|
|
'llm_model': settings.MULTILINGUAL_LLM_MODEL, |
|
|
'status': 'active' if self.multilingual_model else 'inactive' |
|
|
} |
|
|
} |
|
|
|
|
|
if lang == 'vi': |
|
|
return model_info['vi'] |
|
|
else: |
|
|
return model_info['other'] |
|
|
|