File size: 11,043 Bytes
6d48dc9 dbf2148 99c5f5a dbf2148 65be612 6d48dc9 65be612 6d48dc9 65be612 6d48dc9 65be612 dbf2148 65be612 6d48dc9 65be612 6d48dc9 dbf2148 6d48dc9 dbf2148 6d48dc9 dbf2148 6d48dc9 dbf2148 6d48dc9 dbf2148 99c5f5a 6d48dc9 99c5f5a 6d48dc9 dbf2148 6d48dc9 99c5f5a 6d48dc9 dbf2148 6d48dc9 dbf2148 6d48dc9 dbf2148 6d48dc9 dbf2148 6d48dc9 99c5f5a 6d48dc9 99c5f5a dbf2148 65be612 6d48dc9 65be612 6d48dc9 65be612 6d48dc9 7c433d8 65be612 6d48dc9 dbf2148 65be612 dbf2148 65be612 6d48dc9 dbf2148 65be612 6d48dc9 65be612 6d48dc9 99c5f5a |
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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
import re
from typing import Dict, Tuple, Optional
from sentence_transformers import SentenceTransformer
from langdetect import detect, detect_langs
from langdetect.lang_detect_exception import LangDetectException
from config.settings import settings
class MultilingualManager:
def __init__(self):
self.vietnamese_model = None
self.multilingual_model = None
self.current_language = 'vi'
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}")
# Fallback to multilingual model
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}")
# Fallback to default model
try:
self.multilingual_model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
print("✅ Đã tải mô hình fallback đa ngôn ngữ")
except Exception as fallback_error:
print(f"❌ Lỗi tải mô hình fallback: {fallback_error}")
self.multilingual_model = None
def detect_language(self, text: str, fallback_method: bool = True) -> str:
"""
Phát hiện ngôn ngữ với độ chính xác cao sử dụng langdetect
"""
if not text or len(text.strip()) == 0:
return 'vi' # Default to Vietnamese
# Clean text
text = self._clean_text_for_detection(text)
if len(text.strip()) < 3:
return 'vi'
try:
# Sử dụng langdetect với xác suất
languages = detect_langs(text)
# Lấy ngôn ngữ có xác suất cao nhất
best_lang = str(languages[0]).split(':')[0]
# Map langdetect codes to our codes
lang_map = {
'vi': 'vi', 'en': 'en', 'fr': 'fr', 'es': 'es',
'de': 'de', 'ja': 'ja', 'ko': 'ko', 'zh-cn': 'zh', 'zh-tw': 'zh',
'it': 'en', 'pt': 'en', 'ru': 'en', 'ar': 'en' # Fallback to English for others
}
detected_lang = lang_map.get(best_lang, 'en')
# Kiểm tra độ tin cậy
confidence = float(str(languages[0]).split(':')[1])
if confidence < 0.6 and fallback_method:
# Nếu độ tin cậy thấp, sử dụng fallback method
return self._fallback_language_detection(text)
print(f"🔍 Phát hiện ngôn ngữ: {detected_lang} (độ tin cậy: {confidence:.2f})")
return detected_lang
except LangDetectException as e:
print(f"⚠️ LangDetect lỗi, sử dụng fallback: {e}")
return self._fallback_language_detection(text) if fallback_method else 'vi'
except Exception as e:
print(f"⚠️ Lỗi phát hiện ngôn ngữ: {e}")
return self._fallback_language_detection(text) if fallback_method else 'vi'
def _fallback_language_detection(self, text: str) -> str:
"""
Fallback method sử dụng các quy tắc heuristic
"""
text_lower = text.lower()
# Vietnamese detection với các từ đặc trưng
vietnamese_indicators = [
'của', 'và', 'là', 'có', 'được', 'trong', 'cho', 'với', 'như', 'tôi',
'bạn', 'ông', 'bà', 'anh', 'chị', 'em', 'này', 'kia', 'đó', 'đây',
'không', 'có', 'phải', 'rất', 'nhất', 'các', 'những', 'một', 'hai', 'ba'
]
english_indicators = [
'the', 'and', 'is', 'are', 'for', 'with', 'this', 'that', 'you', 'they',
'what', 'where', 'when', 'why', 'how', 'which', 'who', 'their', 'have', 'has',
'from', 'your', 'will', 'would', 'could', 'should', 'about', 'into', 'through'
]
# Đếm số từ chỉ định
vi_count = sum(1 for word in vietnamese_indicators if word in text_lower)
en_count = sum(1 for word in english_indicators if word in text_lower)
# Kiểm tra ký tự đặc biệt
vietnamese_chars = set('àáâãèéêìíòóôõùúýăđĩũơưạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹ')
vi_char_count = sum(1 for char in text if char in vietnamese_chars)
# Quyết định dựa trên các chỉ số
if vi_count > en_count or vi_char_count > 2:
return 'vi'
elif en_count > vi_count:
return 'en'
else:
# Kiểm tra các ngôn ngữ khác bằng ký tự
if 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'
elif any(char in text for char in 'àâæçèéêëîïôœùûüÿ'):
return 'fr'
elif any(char in text for char in 'áéíóúñü'):
return 'es'
elif any(char in text for char in 'äöüß'):
return 'de'
else:
return 'en' # Mặc định là English
def _clean_text_for_detection(self, text: str) -> str:
"""Làm sạch văn bản để phát hiện ngôn ngữ chính xác hơn"""
# Loại bỏ URL, số, ký tự đặc biệt không cần thiết
text = re.sub(r'http\S+', '', text)
text = re.sub(r'[0-9]+', '', text)
text = re.sub(r'[^\w\s]', ' ', text)
text = re.sub(r'\s+', ' ', text)
return text.strip()
def detect_language_with_confidence(self, text: str) -> Tuple[str, float]:
"""
Phát hiện ngôn ngữ với điểm tin cậy
"""
if not text or len(text.strip()) < 3:
return 'vi', 0.0
try:
languages = detect_langs(text)
best_lang = str(languages[0])
lang_code, confidence = best_lang.split(':')
lang_map = {
'vi': 'vi', 'en': 'en', 'fr': 'fr', 'es': 'es',
'de': 'de', 'ja': 'ja', 'ko': 'ko', 'zh-cn': 'zh', 'zh-tw': 'zh'
}
detected_lang = lang_map.get(lang_code, 'en')
confidence_score = float(confidence)
return detected_lang, confidence_score
except LangDetectException as e:
print(f"⚠️ Lỗi phát hiện ngôn ngữ với confidence: {e}")
return 'vi', 0.5
except Exception as e:
print(f"⚠️ Lỗi phát hiện ngôn ngữ với confidence: {e}")
return 'vi', 0.5
def detect_language_simple(self, text: str) -> str:
"""
Phát hiện ngôn ngữ đơn giản (nhanh hơn, ít chính xác hơn)
"""
if not text or len(text.strip()) < 3:
return 'vi'
try:
# Sử dụng detect đơn giản thay vì detect_langs
lang_code = detect(text)
lang_map = {
'vi': 'vi', 'en': 'en', 'fr': 'fr', 'es': 'es',
'de': 'de', 'ja': 'ja', 'ko': 'ko', 'zh-cn': 'zh', 'zh-tw': 'zh'
}
return lang_map.get(lang_code, 'en')
except LangDetectException:
return self._fallback_language_detection(text)
except Exception:
return 'vi'
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"""
if language and language in settings.SUPPORTED_LANGUAGES:
lang = language
else:
lang = self.current_language
if lang == 'vi' and self.vietnamese_model is not None:
return self.vietnamese_model
else:
return self.multilingual_model
def get_llm_model(self, language: str = None) -> str:
"""Lấy tên mô hình LLM dựa trên ngôn ngữ đã phát hiện"""
if language and language in settings.SUPPORTED_LANGUAGES:
lang = language
else:
lang = 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 đủ"""
if language and language in settings.SUPPORTED_LANGUAGES:
lang = language
else:
lang = self.current_language
language_names = {
'vi': 'Tiếng Việt',
'en': 'English',
'fr': 'Français',
'es': 'Español',
'de': 'Deutsch',
'ja': '日本語',
'ko': '한국어',
'zh': '中文'
}
return {
'code': lang,
'name': language_names.get(lang, 'Unknown'),
'embedding_model': settings.VIETNAMESE_EMBEDDING_MODEL if lang == 'vi' else settings.MULTILINGUAL_EMBEDDING_MODEL,
'llm_model': settings.VIETNAMESE_LLM_MODEL if lang == 'vi' else settings.MULTILINGUAL_LLM_MODEL,
'embedding_status': 'active' if (self.vietnamese_model if lang == 'vi' else self.multilingual_model) else 'inactive'
}
def get_supported_languages(self) -> Dict[str, str]:
"""Lấy danh sách ngôn ngữ được hỗ trợ"""
return {
'vi': 'Tiếng Việt',
'en': 'English',
'fr': 'Français',
'es': 'Español',
'de': 'Deutsch',
'ja': '日本語',
'ko': '한국어',
'zh': '中文'
}
def is_language_supported(self, language: str) -> bool:
"""Kiểm tra xem ngôn ngữ có được hỗ trợ không"""
return language in self.get_supported_languages() |