diff --git a/.gitignore b/.gitignore index f7ad2b1..b78df82 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ /app/.gradio /app/core -/app/shop_chroma_db -/app/amvera_data/chroma_db -/app/amvera_data/parsed_json/ +/app/data/chroma_db +/app/data/parsed_json/ +/app/data/docs/ /app/__pycache__ /models /cache diff --git a/app/config.py b/app/config.py index 4469d56..da70882 100644 --- a/app/config.py +++ b/app/config.py @@ -6,14 +6,14 @@ from pydantic_settings import BaseSettings, SettingsConfigDict class Config(BaseSettings): BASE_DIR: str = os.path.abspath(os.path.join(os.path.dirname(__file__))) - DOCS_AMVERA_PATH: str = os.path.join(BASE_DIR, "amvera_data", "docs_amvera") - PARSED_JSON_PATH: str = os.path.join(BASE_DIR, "amvera_data", "parsed_json") - AMVERA_CHROMA_PATH: str = os.path.join(BASE_DIR, "amvera_data", "chroma_db") - AMVERA_COLLECTION_NAME: str = "amvera_docs" + DOCS_PATH: str = os.path.join(BASE_DIR, "data", "docs") + PARSED_JSON_PATH: str = os.path.join(BASE_DIR, "data", "parsed_json") + DOCS_CHROMA_PATH: str = os.path.join(BASE_DIR, "data", "chroma_db") + DOCS_COLLECTION_NAME: str = "docs" MAX_CHUNK_SIZE: int = 512 CHUNK_OVERLAP: int = 50 LM_MODEL_NAME: str = "/models/paraphrase-multilingual-MiniLM-L12-v2" - LOCAL_LLM_NAME: str = "/models/Qwen3-4B-Base" + LOCAL_LLM_NAME: str = "/models/Qwen3-4B" QWEN_MODEL_NAME: str = "qwen3-chat" diff --git a/app/amvera_data/generate_json_files.py b/app/data/generate_json_files.py similarity index 98% rename from app/amvera_data/generate_json_files.py rename to app/data/generate_json_files.py index df586f1..47a9e70 100644 --- a/app/amvera_data/generate_json_files.py +++ b/app/data/generate_json_files.py @@ -112,7 +112,7 @@ def process_all_markdown(input_folder: str, output_folder: str) -> None: if __name__ == "__main__": try: process_all_markdown( - input_folder=settings.DOCS_AMVERA_PATH, + input_folder=settings.DOCS_PATH, output_folder=settings.PARSED_JSON_PATH, ) except Exception as e: diff --git a/app/amvera_data/generated_amvera_db.py b/app/data/generated_docs_db.py similarity index 95% rename from app/amvera_data/generated_amvera_db.py rename to app/data/generated_docs_db.py index fa1706c..00aed5d 100644 --- a/app/amvera_data/generated_amvera_db.py +++ b/app/data/generated_docs_db.py @@ -60,7 +60,7 @@ def generate_chroma_db() -> Optional[Chroma]: """Инициализация ChromaDB с данными из JSON файлов.""" try: # Создаем директорию для хранения базы данных, если она не существует - os.makedirs(settings.AMVERA_CHROMA_PATH, exist_ok=True) + os.makedirs(settings.DOCS_CHROMA_PATH, exist_ok=True) # Загружаем JSON файлы documents = load_json_files(settings.PARSED_JSON_PATH) @@ -95,8 +95,8 @@ def generate_chroma_db() -> Optional[Chroma]: embedding=embeddings, ids=ids, metadatas=metadatas, - persist_directory=settings.AMVERA_CHROMA_PATH, - collection_name=settings.AMVERA_COLLECTION_NAME, + persist_directory=settings.DOCS_CHROMA_PATH, + collection_name=settings.DOCS_COLLECTION_NAME, collection_metadata={ "hnsw:space": "cosine", }, diff --git a/app/main.py b/app/main.py index 5185220..3128dc4 100644 --- a/app/main.py +++ b/app/main.py @@ -4,7 +4,7 @@ import torch import threading # Пути к модели -model_name = "/models/Qwen3-4B-Base" +model_name = "/models/Qwen3-8B" # Загрузка токенизатора и модели (один раз при старте) tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True) diff --git a/app/test.py b/app/test.py index 8f63db8..aeaffb2 100644 --- a/app/test.py +++ b/app/test.py @@ -18,17 +18,17 @@ class ChatWithAI: ) if provider == "qwen3": - model_name = getattr(settings, "LOCAL_LLM_NAME", "/models/Qwen3-4B-Base") + model_name = getattr(settings, "LOCAL_LLM_NAME", "/models/Qwen3-4B") logger.info(f"Загрузка локальной модели: {model_name}") tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForCausalLM.from_pretrained( model_name, - torch_dtype=torch.float16, + torch_dtype=torch.float32, device_map="cuda", ) - # Создаём text-generation pipeline + #Создаём text-generation pipeline self.llm = pipeline( "text-generation", model=model, @@ -43,9 +43,9 @@ class ChatWithAI: raise ValueError(f"Неподдерживаемый провайдер: {provider}") self.chroma_db = Chroma( - persist_directory=settings.AMVERA_CHROMA_PATH, + persist_directory=settings.DOCS_CHROMA_PATH, embedding_function=self.embeddings, - collection_name=settings.AMVERA_COLLECTION_NAME, + collection_name=settings.DOCS_COLLECTION_NAME, ) def get_relevant_context(self, query: str, k: int = 3) -> List[Dict[str, Any]]: @@ -89,13 +89,13 @@ class ChatWithAI: Правила: 1. Сразу переходи к сути, без фраз типа "На основе контекста" -2. Используй только факты. Если точных данных нет — отвечай общими фразами об Amvera Cloud, но не придумывай конкретику +2. Используй только факты. Если точных данных нет — отвечай общими фразами об Marzban, но не придумывай конкретику 3. Используй обычный текст без форматирования 4. Включай ссылки только если они есть в контексте 5. Говори от первого лица множественного числа: "Мы предоставляем", "У нас есть" 6. При упоминании файлов делай это естественно, например: "Я прикреплю инструкцию, где подробно описаны шаги" 7. На приветствия отвечай доброжелательно, на негатив — с легким юмором -8. Можешь при ответах использовать общую информацию из открытых источников по Amvera Cloud, но опирайся на контекст +8. Можешь при ответах использовать общую информацию из открытых источников по Marzban, но опирайся на контекст 9. Если пользователь спрашивает о ценах, планах или технических характеристиках — давай конкретные ответы из контекста 10. При технических вопросах предлагай практические решения @@ -114,7 +114,7 @@ class ChatWithAI: # Применяем chat template (поддерживается в современных моделях: Zephyr, Llama3, Qwen и т.д.) prompt = tokenizer.apply_chat_template( - messages, tokenize=False, add_generation_prompt=True + messages, tokenize=False, add_generation_prompt=True, enable_thinking=False ) # Генерация diff --git a/offline_packages/requirements.txt b/offline_packages/requirements.txt index 5b9d9ce..9f11a23 100644 --- a/offline_packages/requirements.txt +++ b/offline_packages/requirements.txt @@ -2,7 +2,8 @@ transformers>=4.50.0 gradio>=4.29.0 safetensors>=0.4.3 -accelerate>=1.9.0 +accelerate==1.9.0 +psutil==7.0.0 langchain-huggingface==0.1.2 torch>=2.7.1 loguru==0.7.3 diff --git a/offline_packages/test.txt b/offline_packages/test.txt deleted file mode 100644 index e53f808..0000000 --- a/offline_packages/test.txt +++ /dev/null @@ -1,10 +0,0 @@ -langchain-huggingface==0.1.2 -torch>=2.7.1 -loguru==0.7.3 -chromadb==0.6.3 -sentence-transformers==3.4.1 -langchain-chroma==0.2.2 -pydantic-settings==2.8.1 -langchain-text-splitters==0.3.7 -langchain-qwen3==0.1.0 -langchain-openai==0.3.11 \ No newline at end of file