Spaces:
Sleeping
Sleeping
Commit
·
2df0370
1
Parent(s):
497bfbe
new table document + image document processing functions + added more comprehensive loggings
Browse files- config.py +0 -2
- documents_prep.py +46 -29
- utils.py +23 -8
config.py
CHANGED
|
@@ -13,8 +13,6 @@ TABLE_DATA_DIR = "Табличные данные_JSON"
|
|
| 13 |
IMAGE_DATA_DIR = "Изображения"
|
| 14 |
DOWNLOAD_DIR = "rag_files"
|
| 15 |
JSON_FILES_DIR ="JSON"
|
| 16 |
-
HF_TOKEN = os.getenv('HF_TOKEN')
|
| 17 |
-
|
| 18 |
|
| 19 |
GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY')
|
| 20 |
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
|
|
|
|
| 13 |
IMAGE_DATA_DIR = "Изображения"
|
| 14 |
DOWNLOAD_DIR = "rag_files"
|
| 15 |
JSON_FILES_DIR ="JSON"
|
|
|
|
|
|
|
| 16 |
|
| 17 |
GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY')
|
| 18 |
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
|
documents_prep.py
CHANGED
|
@@ -286,36 +286,55 @@ def extract_zip_and_process_json(zip_path):
|
|
| 286 |
return documents
|
| 287 |
|
| 288 |
def table_to_document(table_data, document_id=None):
|
| 289 |
-
|
|
|
|
| 290 |
if isinstance(table_data, dict):
|
| 291 |
doc_id = document_id or table_data.get('document_id', table_data.get('document', 'Неизвестно'))
|
| 292 |
-
|
| 293 |
table_num = table_data.get('table_number', 'Неизвестно')
|
| 294 |
table_title = table_data.get('table_title', 'Неизвестно')
|
| 295 |
section = table_data.get('section', 'Неизвестно')
|
| 296 |
|
| 297 |
-
|
| 298 |
-
|
| 299 |
-
content += f"Документ: {doc_id}\n"
|
| 300 |
-
content += f"Раздел: {section}\n"
|
| 301 |
|
| 302 |
if 'data' in table_data and isinstance(table_data['data'], list):
|
| 303 |
-
|
|
|
|
| 304 |
if isinstance(row, dict):
|
| 305 |
row_text = " | ".join([f"{k}: {v}" for k, v in row.items()])
|
| 306 |
-
content
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 307 |
|
| 308 |
-
return
|
| 309 |
-
text=content,
|
| 310 |
-
metadata={
|
| 311 |
-
"type": "table",
|
| 312 |
-
"table_number": table_data.get('table_number', 'unknown'),
|
| 313 |
-
"table_title": table_data.get('table_title', 'unknown'),
|
| 314 |
-
"document_id": doc_id or table_data.get('document_id', table_data.get('document', 'unknown')),
|
| 315 |
-
"section": table_data.get('section', 'unknown'),
|
| 316 |
-
"section_id": table_data.get('section', 'unknown')
|
| 317 |
-
}
|
| 318 |
-
)
|
| 319 |
|
| 320 |
def load_table_data(repo_id, hf_token, table_data_dir):
|
| 321 |
log_message("Начинаю загрузку табличных данных")
|
|
@@ -381,12 +400,9 @@ def load_image_data(repo_id, hf_token, image_data_dir):
|
|
| 381 |
if file.startswith(image_data_dir) and file.endswith('.csv'):
|
| 382 |
image_files.append(file)
|
| 383 |
|
| 384 |
-
log_message(f"Найдено {len(image_files)} CSV файлов с изображениями")
|
| 385 |
-
|
| 386 |
image_documents = []
|
| 387 |
for file_path in image_files:
|
| 388 |
try:
|
| 389 |
-
log_message(f"Обрабатываю файл изображений: {file_path}")
|
| 390 |
local_path = hf_hub_download(
|
| 391 |
repo_id=repo_id,
|
| 392 |
filename=file_path,
|
|
@@ -396,9 +412,9 @@ def load_image_data(repo_id, hf_token, image_data_dir):
|
|
| 396 |
)
|
| 397 |
|
| 398 |
df = pd.read_csv(local_path)
|
| 399 |
-
log_message(f"Загружено {len(df)} записей изображений из файла {file_path}")
|
| 400 |
|
| 401 |
for _, row in df.iterrows():
|
|
|
|
| 402 |
section_value = row.get('Раздел документа', row.get('section', 'Неизвестно'))
|
| 403 |
|
| 404 |
content = f"Изображение: {row.get('№ Изображения', 'Неизвестно')}\n"
|
|
@@ -412,11 +428,13 @@ def load_image_data(repo_id, hf_token, image_data_dir):
|
|
| 412 |
text=content,
|
| 413 |
metadata={
|
| 414 |
"type": "image",
|
| 415 |
-
"image_number": row.get('№ Изображения', 'unknown'),
|
| 416 |
-
"
|
| 417 |
-
"
|
| 418 |
-
"
|
| 419 |
-
"
|
|
|
|
|
|
|
| 420 |
}
|
| 421 |
)
|
| 422 |
image_documents.append(doc)
|
|
@@ -425,7 +443,6 @@ def load_image_data(repo_id, hf_token, image_data_dir):
|
|
| 425 |
log_message(f"Ошибка обработки файла {file_path}: {str(e)}")
|
| 426 |
continue
|
| 427 |
|
| 428 |
-
log_message(f"Создано {len(image_documents)} документов из изображений")
|
| 429 |
return image_documents
|
| 430 |
|
| 431 |
except Exception as e:
|
|
|
|
| 286 |
return documents
|
| 287 |
|
| 288 |
def table_to_document(table_data, document_id=None):
|
| 289 |
+
documents = []
|
| 290 |
+
|
| 291 |
if isinstance(table_data, dict):
|
| 292 |
doc_id = document_id or table_data.get('document_id', table_data.get('document', 'Неизвестно'))
|
|
|
|
| 293 |
table_num = table_data.get('table_number', 'Неизвестно')
|
| 294 |
table_title = table_data.get('table_title', 'Неизвестно')
|
| 295 |
section = table_data.get('section', 'Неизвестно')
|
| 296 |
|
| 297 |
+
# Создаем заголовочный документ
|
| 298 |
+
header_content = f"Таблица: {table_num}\nНазвание: {table_title}\nДокумент: {doc_id}\nРаздел: {section}\n"
|
|
|
|
|
|
|
| 299 |
|
| 300 |
if 'data' in table_data and isinstance(table_data['data'], list):
|
| 301 |
+
# Каждая строка таблицы - отдельный документ
|
| 302 |
+
for row_idx, row in enumerate(table_data['data']):
|
| 303 |
if isinstance(row, dict):
|
| 304 |
row_text = " | ".join([f"{k}: {v}" for k, v in row.items()])
|
| 305 |
+
content = header_content + f"Строка {row_idx + 1}: {row_text}"
|
| 306 |
+
|
| 307 |
+
doc = Document(
|
| 308 |
+
text=content,
|
| 309 |
+
metadata={
|
| 310 |
+
"type": "table_row",
|
| 311 |
+
"table_number": table_num,
|
| 312 |
+
"table_title": table_title,
|
| 313 |
+
"document_id": doc_id,
|
| 314 |
+
"section": section,
|
| 315 |
+
"section_id": section,
|
| 316 |
+
"row_number": row_idx + 1,
|
| 317 |
+
"total_rows": len(table_data['data'])
|
| 318 |
+
}
|
| 319 |
+
)
|
| 320 |
+
documents.append(doc)
|
| 321 |
+
|
| 322 |
+
# Если нет строк, создаем общий документ
|
| 323 |
+
if not documents:
|
| 324 |
+
doc = Document(
|
| 325 |
+
text=header_content,
|
| 326 |
+
metadata={
|
| 327 |
+
"type": "table",
|
| 328 |
+
"table_number": table_num,
|
| 329 |
+
"table_title": table_title,
|
| 330 |
+
"document_id": doc_id,
|
| 331 |
+
"section": section,
|
| 332 |
+
"section_id": section
|
| 333 |
+
}
|
| 334 |
+
)
|
| 335 |
+
documents.append(doc)
|
| 336 |
|
| 337 |
+
return documents
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 338 |
|
| 339 |
def load_table_data(repo_id, hf_token, table_data_dir):
|
| 340 |
log_message("Начинаю загрузку табличных данных")
|
|
|
|
| 400 |
if file.startswith(image_data_dir) and file.endswith('.csv'):
|
| 401 |
image_files.append(file)
|
| 402 |
|
|
|
|
|
|
|
| 403 |
image_documents = []
|
| 404 |
for file_path in image_files:
|
| 405 |
try:
|
|
|
|
| 406 |
local_path = hf_hub_download(
|
| 407 |
repo_id=repo_id,
|
| 408 |
filename=file_path,
|
|
|
|
| 412 |
)
|
| 413 |
|
| 414 |
df = pd.read_csv(local_path)
|
|
|
|
| 415 |
|
| 416 |
for _, row in df.iterrows():
|
| 417 |
+
# Создаем отдельный документ для каждого изображения
|
| 418 |
section_value = row.get('Раздел документа', row.get('section', 'Неизвестно'))
|
| 419 |
|
| 420 |
content = f"Изображение: {row.get('№ Изображения', 'Неизвестно')}\n"
|
|
|
|
| 428 |
text=content,
|
| 429 |
metadata={
|
| 430 |
"type": "image",
|
| 431 |
+
"image_number": str(row.get('№ Изображения', 'unknown')),
|
| 432 |
+
"image_title": str(row.get('Название изображения', 'unknown')),
|
| 433 |
+
"image_description": str(row.get('Описание изображение', 'unknown')),
|
| 434 |
+
"document_id": str(row.get('Обозначение документа', 'unknown')),
|
| 435 |
+
"file_path": str(row.get('Файл изображения', 'unknown')),
|
| 436 |
+
"section": str(section_value),
|
| 437 |
+
"section_id": str(section_value)
|
| 438 |
}
|
| 439 |
)
|
| 440 |
image_documents.append(doc)
|
|
|
|
| 443 |
log_message(f"Ошибка обработки файла {file_path}: {str(e)}")
|
| 444 |
continue
|
| 445 |
|
|
|
|
| 446 |
return image_documents
|
| 447 |
|
| 448 |
except Exception as e:
|
utils.py
CHANGED
|
@@ -146,20 +146,35 @@ def answer_question(question, query_engine, reranker, current_model, chunks_df=N
|
|
| 146 |
|
| 147 |
try:
|
| 148 |
log_message(f"Получен вопрос: {question}")
|
| 149 |
-
log_message(f"Используется модель: {current_model}")
|
| 150 |
start_time = time.time()
|
| 151 |
|
| 152 |
-
|
| 153 |
retrieved_nodes = query_engine.retriever.retrieve(question)
|
| 154 |
log_message(f"Извлечено {len(retrieved_nodes)} узлов")
|
| 155 |
-
for i in range(min(3, len(retrieved_nodes))):
|
| 156 |
-
log_message(f"Пример узла {i+1}: {retrieved_nodes[i].text[:200]}...")
|
| 157 |
|
| 158 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
reranked_nodes = rerank_nodes(question, retrieved_nodes, reranker, top_k=10)
|
| 160 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
formatted_context = format_context_for_llm(reranked_nodes)
|
| 162 |
-
log_message(f"
|
| 163 |
|
| 164 |
enhanced_question = f"""
|
| 165 |
Контекст из базы данных:
|
|
@@ -167,10 +182,10 @@ def answer_question(question, query_engine, reranker, current_model, chunks_df=N
|
|
| 167 |
|
| 168 |
Вопрос пользователя: {question}"""
|
| 169 |
|
| 170 |
-
log_message(f"Отправляю запрос в LLM с {len(reranked_nodes)} узлами")
|
| 171 |
-
log_message(f"Вопрос для LLM:\n{enhanced_question}...")
|
| 172 |
response = query_engine.query(enhanced_question)
|
| 173 |
|
|
|
|
|
|
|
| 174 |
end_time = time.time()
|
| 175 |
processing_time = end_time - start_time
|
| 176 |
|
|
|
|
| 146 |
|
| 147 |
try:
|
| 148 |
log_message(f"Получен вопрос: {question}")
|
|
|
|
| 149 |
start_time = time.time()
|
| 150 |
|
| 151 |
+
# Извлечение узлов
|
| 152 |
retrieved_nodes = query_engine.retriever.retrieve(question)
|
| 153 |
log_message(f"Извлечено {len(retrieved_nodes)} узлов")
|
|
|
|
|
|
|
| 154 |
|
| 155 |
+
# ДЕТАЛЬНОЕ ЛОГИРОВАНИЕ ИСТОЧНИКОВ
|
| 156 |
+
log_message("=== ДЕТАЛЬНАЯ ИНФОРМАЦИЯ О НАЙДЕННЫХ УЗЛАХ ===")
|
| 157 |
+
for i, node in enumerate(retrieved_nodes):
|
| 158 |
+
log_message(f"Узел {i+1}:")
|
| 159 |
+
log_message(f" Документ: {node.metadata.get('document_id', 'unknown')}")
|
| 160 |
+
log_message(f" Тип: {node.metadata.get('type', 'unknown')}")
|
| 161 |
+
log_message(f" Раздел: {node.metadata.get('section_id', 'unknown')}")
|
| 162 |
+
log_message(f" Текст (первые 200 символов): {node.text[:200]}...")
|
| 163 |
+
log_message(f" Метаданные: {node.metadata}")
|
| 164 |
+
|
| 165 |
+
# Переранжировка
|
| 166 |
reranked_nodes = rerank_nodes(question, retrieved_nodes, reranker, top_k=10)
|
| 167 |
|
| 168 |
+
log_message("=== УЗЛЫ ПОСЛЕ ПЕРЕРАНЖИРОВКИ ===")
|
| 169 |
+
for i, node in enumerate(reranked_nodes):
|
| 170 |
+
log_message(f"Переранжированный узел {i+1}:")
|
| 171 |
+
log_message(f" Документ: {node.metadata.get('document_id', 'unknown')}")
|
| 172 |
+
log_message(f" Тип: {node.metadata.get('type', 'unknown')}")
|
| 173 |
+
log_message(f" Раздел: {node.metadata.get('section_id', 'unknown')}")
|
| 174 |
+
log_message(f" Полный текст: {node.text}")
|
| 175 |
+
|
| 176 |
formatted_context = format_context_for_llm(reranked_nodes)
|
| 177 |
+
log_message(f"ПОЛНЫЙ КОНТЕКСТ ДЛЯ LLM:\n{formatted_context}")
|
| 178 |
|
| 179 |
enhanced_question = f"""
|
| 180 |
Контекст из базы данных:
|
|
|
|
| 182 |
|
| 183 |
Вопрос пользователя: {question}"""
|
| 184 |
|
|
|
|
|
|
|
| 185 |
response = query_engine.query(enhanced_question)
|
| 186 |
|
| 187 |
+
log_message(f"ОТВЕТ LLM: {response.response}")
|
| 188 |
+
|
| 189 |
end_time = time.time()
|
| 190 |
processing_time = end_time - start_time
|
| 191 |
|