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"
|