File size: 17,903 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 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 |
# 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'
# # Phát hiện thuộc ngôn ngữ dựa trên các mẫu ký tự và từ phổ biến
# 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' # Default to Vietnamese
# text_lower = text.lower()
# scores = {}
# for lang, patterns in self.language_patterns.items():
# score = 0
# # Score based on special characters
# char_score = sum(1 for char in text if char in patterns['chars'])
# score += char_score * 2
# # Score based on common words
# word_score = sum(1 for word in patterns['common_words'] if word in text_lower)
# score += word_score
# scores[lang] = score
# # Return language with highest score
# detected_lang = max(scores.items(), key=lambda x: x[1])[0]
# # If no strong detection, use character-based fallback
# 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' # Default to English for other cases
# 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(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']
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() |