Spaces:
Runtime error
Runtime error
Commit
·
5760f5e
1
Parent(s):
77eeb1b
update api
Browse files- config.py +3 -1
- dependencies.py +21 -7
- rag_components.py +58 -2
- schemas/chat.py +1 -1
config.py
CHANGED
|
@@ -56,4 +56,6 @@ APP_ENVIRONMENT = os.environ.get("APP_ENVIRONMENT")
|
|
| 56 |
# CHECKPOINT_FILE = "processed_files.log"
|
| 57 |
|
| 58 |
MONGODB_CLOUD_URI= os.environ.get("MONGODB_CLOUD_URI")
|
| 59 |
-
DB_NAME= os.environ.get("DB_NAME")
|
|
|
|
|
|
|
|
|
| 56 |
# CHECKPOINT_FILE = "processed_files.log"
|
| 57 |
|
| 58 |
MONGODB_CLOUD_URI= os.environ.get("MONGODB_CLOUD_URI")
|
| 59 |
+
DB_NAME= os.environ.get("DB_NAME")
|
| 60 |
+
|
| 61 |
+
GOOGLE_API_KEYS=os.environ.get("GOOGLE_API_KEYS", "")
|
dependencies.py
CHANGED
|
@@ -58,10 +58,10 @@ async def initialize_api_components(app_state: AppState):
|
|
| 58 |
logger.error("🔸Lỗi kết nối tới MongoDB hoặc Weaviate.", mongo_db.users)
|
| 59 |
raise HTTPException(status_code=500, detail="Lỗi kết nối tới database.")
|
| 60 |
|
| 61 |
-
app_state.google_api_key = os.environ.get("GOOGLE_API_KEY")
|
| 62 |
-
if not app_state.google_api_key:
|
| 63 |
-
|
| 64 |
-
|
| 65 |
|
| 66 |
app_state.device = 'cuda' if torch.cuda.is_available() else 'cpu'
|
| 67 |
logger.info(f"🔸Sử dụng thiết bị: {app_state.device}")
|
|
@@ -90,9 +90,23 @@ async def initialize_api_components(app_state: AppState):
|
|
| 90 |
# 3. Tải LLM
|
| 91 |
logger.info(f"🔸Đang tải LLM...")
|
| 92 |
|
| 93 |
-
llm = rag_components.get_google_llm(app_state.google_api_key)
|
| 94 |
-
app_state.llm = llm
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
if not app_state.llm:
|
| 98 |
raise HTTPException(status_code=500, detail="Failed to load LLM")
|
|
|
|
| 58 |
logger.error("🔸Lỗi kết nối tới MongoDB hoặc Weaviate.", mongo_db.users)
|
| 59 |
raise HTTPException(status_code=500, detail="Lỗi kết nối tới database.")
|
| 60 |
|
| 61 |
+
# app_state.google_api_key = os.environ.get("GOOGLE_API_KEY")
|
| 62 |
+
# if not app_state.google_api_key:
|
| 63 |
+
# logger.error("🔸GG API Key không được cung cấp.")
|
| 64 |
+
# raise HTTPException(status_code=500, detail="Missing GG API Key")
|
| 65 |
|
| 66 |
app_state.device = 'cuda' if torch.cuda.is_available() else 'cpu'
|
| 67 |
logger.info(f"🔸Sử dụng thiết bị: {app_state.device}")
|
|
|
|
| 90 |
# 3. Tải LLM
|
| 91 |
logger.info(f"🔸Đang tải LLM...")
|
| 92 |
|
| 93 |
+
# llm = rag_components.get_google_llm(app_state.google_api_key)
|
| 94 |
+
# app_state.llm = llm
|
| 95 |
+
if not config.GOOGLE_API_KEYS:
|
| 96 |
+
logger.error("🚨 BIẾN MÔI TRƯỜNG 'GOOGLE_API_KEYS' CHƯA ĐƯỢC THIẾT LẬP TRÊN HUGGING FACE SPACES!")
|
| 97 |
+
# Tại đây, bạn có thể dừng chương trình hoặc xử lý lỗi
|
| 98 |
+
google_api_keys_list = []
|
| 99 |
+
else:
|
| 100 |
+
google_api_keys_list = [key.strip() for key in config.GOOGLE_API_KEYS.split(',') if key.strip()]
|
| 101 |
+
logger.info(f"✅ Đã tìm thấy và tải {len(google_api_keys_list)} API key từ secrets.")
|
| 102 |
+
|
| 103 |
+
if not google_api_keys_list:
|
| 104 |
+
logger.error("🚨 KHÔNG CÓ GOOGLE API KEYS NÀO ĐƯỢC CẤP PHÁT!")
|
| 105 |
+
raise HTTPException(status_code=500, detail="No Google API keys found")
|
| 106 |
+
|
| 107 |
+
app_state.llm = rag_components.create_llm_from_google_key_list(google_api_keys=google_api_keys_list)
|
| 108 |
+
|
| 109 |
+
|
| 110 |
|
| 111 |
if not app_state.llm:
|
| 112 |
raise HTTPException(status_code=500, detail="Failed to load LLM")
|
rag_components.py
CHANGED
|
@@ -5,7 +5,7 @@ from langchain_core.prompts import ChatPromptTemplate
|
|
| 5 |
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
|
| 6 |
from langchain_core.documents import Document
|
| 7 |
import logging
|
| 8 |
-
from langchain_core.output_parsers import StrOutputParser
|
| 9 |
from typing import List,Any,Dict
|
| 10 |
from langchain_weaviate.vectorstores import WeaviateVectorStore
|
| 11 |
from langchain_google_genai import ChatGoogleGenerativeAI
|
|
@@ -13,6 +13,7 @@ from utils.process_data import filter_and_serialize_complex_metadata
|
|
| 13 |
import weaviate
|
| 14 |
import weaviate.classes.config as wvc_config
|
| 15 |
from weaviate.exceptions import WeaviateQueryException
|
|
|
|
| 16 |
import time
|
| 17 |
import json
|
| 18 |
import re
|
|
@@ -310,7 +311,7 @@ def get_google_llm(google_api_key):
|
|
| 310 |
model="gemini-2.5-flash-preview-05-20",
|
| 311 |
google_api_key=google_api_key,
|
| 312 |
temperature=0.0, # Điều chỉnh nhiệt độ nếu cần, 0.1-0.3 thường tốt cho RAG
|
| 313 |
-
safety_settings={
|
| 314 |
)
|
| 315 |
|
| 316 |
llm = create_chat_google()
|
|
@@ -321,6 +322,61 @@ def get_google_llm(google_api_key):
|
|
| 321 |
logger.error(f"🔸Lỗi khi khởi tạo Google Generative AI LLM: {e}")
|
| 322 |
return None
|
| 323 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 324 |
|
| 325 |
# def create_qa_chain(
|
| 326 |
# llm: Any,
|
|
|
|
| 5 |
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
|
| 6 |
from langchain_core.documents import Document
|
| 7 |
import logging
|
| 8 |
+
from langchain_core.output_parsers import StrOutputParser
|
| 9 |
from typing import List,Any,Dict
|
| 10 |
from langchain_weaviate.vectorstores import WeaviateVectorStore
|
| 11 |
from langchain_google_genai import ChatGoogleGenerativeAI
|
|
|
|
| 13 |
import weaviate
|
| 14 |
import weaviate.classes.config as wvc_config
|
| 15 |
from weaviate.exceptions import WeaviateQueryException
|
| 16 |
+
from google.api_core.exceptions import ResourceExhausted, PermissionDenied
|
| 17 |
import time
|
| 18 |
import json
|
| 19 |
import re
|
|
|
|
| 311 |
model="gemini-2.5-flash-preview-05-20",
|
| 312 |
google_api_key=google_api_key,
|
| 313 |
temperature=0.0, # Điều chỉnh nhiệt độ nếu cần, 0.1-0.3 thường tốt cho RAG
|
| 314 |
+
safety_settings={},
|
| 315 |
)
|
| 316 |
|
| 317 |
llm = create_chat_google()
|
|
|
|
| 322 |
logger.error(f"🔸Lỗi khi khởi tạo Google Generative AI LLM: {e}")
|
| 323 |
return None
|
| 324 |
|
| 325 |
+
def create_llm_from_google_key_list(google_api_keys: List[str]):
|
| 326 |
+
"""
|
| 327 |
+
Khởi tạo một LLM duy nhất có khả năng tự động fallback qua một danh sách
|
| 328 |
+
các API key của Google.
|
| 329 |
+
|
| 330 |
+
Khi một key hết hạn mức (lỗi ResourceExhausted), nó sẽ tự động thử key tiếp theo.
|
| 331 |
+
|
| 332 |
+
:param google_api_keys: Một list chứa các chuỗi API key của Google.
|
| 333 |
+
:return: Một đối tượng LLM của LangChain, hoặc None nếu có lỗi.
|
| 334 |
+
"""
|
| 335 |
+
if not google_api_keys or not isinstance(google_api_keys, list):
|
| 336 |
+
logger.error("❌ Danh sách API key không hợp lệ hoặc bị rỗng.")
|
| 337 |
+
return None
|
| 338 |
+
|
| 339 |
+
logger.info(f"🔸 Đang khởi tạo chuỗi LLM từ {len(google_api_keys)} API key của Google...")
|
| 340 |
+
|
| 341 |
+
try:
|
| 342 |
+
# --- 1. Tạo một danh sách các instance LLM, mỗi cái với một key khác nhau ---
|
| 343 |
+
llm_instances = [
|
| 344 |
+
ChatGoogleGenerativeAI(
|
| 345 |
+
model="gemini-2.5-flash-preview-05-20",
|
| 346 |
+
google_api_key=key,
|
| 347 |
+
temperature=0.0, # Điều chỉnh nhiệt độ nếu cần, 0.1-0.3 thường tốt cho RAG
|
| 348 |
+
safety_settings={},
|
| 349 |
+
)
|
| 350 |
+
for key in google_api_keys
|
| 351 |
+
]
|
| 352 |
+
|
| 353 |
+
# --- 2. Nếu chỉ có một key, không cần fallback ---
|
| 354 |
+
if len(llm_instances) == 1:
|
| 355 |
+
logger.info("✅ Chỉ có một API key được cung cấp. Không cấu hình fallback.")
|
| 356 |
+
return llm_instances[0]
|
| 357 |
+
|
| 358 |
+
# --- 3. Dùng LLM đầu tiên làm LLM chính, phần còn lại làm fallback ---
|
| 359 |
+
primary_llm = llm_instances[0]
|
| 360 |
+
fallback_llms = llm_instances[1:]
|
| 361 |
+
|
| 362 |
+
logger.info(f"▶️ LLM chính sẽ dùng key: '...{google_api_keys[0][-4:]}'")
|
| 363 |
+
for i, llm in enumerate(fallback_llms):
|
| 364 |
+
logger.info(f"↪️ Fallback {i+1} sẽ dùng key: '...{google_api_keys[i+1][-4:]}'")
|
| 365 |
+
|
| 366 |
+
# --- 4. Kết hợp chúng lại ---
|
| 367 |
+
llm_with_fallbacks = primary_llm.with_fallbacks(
|
| 368 |
+
fallbacks=fallback_llms,
|
| 369 |
+
exceptions_to_handle=(ResourceExhausted, PermissionDenied)
|
| 370 |
+
)
|
| 371 |
+
|
| 372 |
+
logger.info("✅ Đã tạo thành công chuỗi LLM với cơ chế fallback giữa các key Google!")
|
| 373 |
+
return llm_with_fallbacks
|
| 374 |
+
|
| 375 |
+
except Exception as e:
|
| 376 |
+
logger.error(f"❌ Lỗi nghiêm trọng khi tạo chuỗi LLM từ danh sách key: {e}", exc_info=True)
|
| 377 |
+
return None
|
| 378 |
+
|
| 379 |
+
|
| 380 |
|
| 381 |
# def create_qa_chain(
|
| 382 |
# llm: Any,
|
schemas/chat.py
CHANGED
|
@@ -5,7 +5,7 @@ from datetime import datetime
|
|
| 5 |
class AppState(BaseModel):
|
| 6 |
embeddings: Optional[Any] = None
|
| 7 |
vectorstore: Optional[Any] = None
|
| 8 |
-
llm: Optional[Any] = None
|
| 9 |
process_input_llm: Optional[Any] = None
|
| 10 |
qa_chain: Optional[Any] = None
|
| 11 |
device: str = "cpu"
|
|
|
|
| 5 |
class AppState(BaseModel):
|
| 6 |
embeddings: Optional[Any] = None
|
| 7 |
vectorstore: Optional[Any] = None
|
| 8 |
+
# llm: Optional[Any] = None
|
| 9 |
process_input_llm: Optional[Any] = None
|
| 10 |
qa_chain: Optional[Any] = None
|
| 11 |
device: str = "cpu"
|