aiagents4pharma 0.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aiagents4pharma/__init__.py +11 -0
- aiagents4pharma/talk2aiagents4pharma/.dockerignore +13 -0
- aiagents4pharma/talk2aiagents4pharma/Dockerfile +133 -0
- aiagents4pharma/talk2aiagents4pharma/README.md +1 -0
- aiagents4pharma/talk2aiagents4pharma/__init__.py +5 -0
- aiagents4pharma/talk2aiagents4pharma/agents/__init__.py +6 -0
- aiagents4pharma/talk2aiagents4pharma/agents/main_agent.py +70 -0
- aiagents4pharma/talk2aiagents4pharma/configs/__init__.py +5 -0
- aiagents4pharma/talk2aiagents4pharma/configs/agents/__init__.py +5 -0
- aiagents4pharma/talk2aiagents4pharma/configs/agents/main_agent/default.yaml +29 -0
- aiagents4pharma/talk2aiagents4pharma/configs/app/__init__.py +0 -0
- aiagents4pharma/talk2aiagents4pharma/configs/app/frontend/__init__.py +0 -0
- aiagents4pharma/talk2aiagents4pharma/configs/app/frontend/default.yaml +102 -0
- aiagents4pharma/talk2aiagents4pharma/configs/config.yaml +4 -0
- aiagents4pharma/talk2aiagents4pharma/docker-compose/cpu/.env.example +23 -0
- aiagents4pharma/talk2aiagents4pharma/docker-compose/cpu/docker-compose.yml +93 -0
- aiagents4pharma/talk2aiagents4pharma/docker-compose/gpu/.env.example +23 -0
- aiagents4pharma/talk2aiagents4pharma/docker-compose/gpu/docker-compose.yml +108 -0
- aiagents4pharma/talk2aiagents4pharma/install.md +154 -0
- aiagents4pharma/talk2aiagents4pharma/states/__init__.py +5 -0
- aiagents4pharma/talk2aiagents4pharma/states/state_talk2aiagents4pharma.py +18 -0
- aiagents4pharma/talk2aiagents4pharma/tests/__init__.py +3 -0
- aiagents4pharma/talk2aiagents4pharma/tests/test_main_agent.py +312 -0
- aiagents4pharma/talk2biomodels/.dockerignore +13 -0
- aiagents4pharma/talk2biomodels/Dockerfile +104 -0
- aiagents4pharma/talk2biomodels/README.md +1 -0
- aiagents4pharma/talk2biomodels/__init__.py +5 -0
- aiagents4pharma/talk2biomodels/agents/__init__.py +6 -0
- aiagents4pharma/talk2biomodels/agents/t2b_agent.py +104 -0
- aiagents4pharma/talk2biomodels/api/__init__.py +5 -0
- aiagents4pharma/talk2biomodels/api/ols.py +75 -0
- aiagents4pharma/talk2biomodels/api/uniprot.py +36 -0
- aiagents4pharma/talk2biomodels/configs/__init__.py +5 -0
- aiagents4pharma/talk2biomodels/configs/agents/__init__.py +5 -0
- aiagents4pharma/talk2biomodels/configs/agents/t2b_agent/__init__.py +3 -0
- aiagents4pharma/talk2biomodels/configs/agents/t2b_agent/default.yaml +14 -0
- aiagents4pharma/talk2biomodels/configs/app/__init__.py +0 -0
- aiagents4pharma/talk2biomodels/configs/app/frontend/__init__.py +0 -0
- aiagents4pharma/talk2biomodels/configs/app/frontend/default.yaml +72 -0
- aiagents4pharma/talk2biomodels/configs/config.yaml +7 -0
- aiagents4pharma/talk2biomodels/configs/tools/__init__.py +5 -0
- aiagents4pharma/talk2biomodels/configs/tools/ask_question/__init__.py +3 -0
- aiagents4pharma/talk2biomodels/configs/tools/ask_question/default.yaml +30 -0
- aiagents4pharma/talk2biomodels/configs/tools/custom_plotter/__init__.py +3 -0
- aiagents4pharma/talk2biomodels/configs/tools/custom_plotter/default.yaml +8 -0
- aiagents4pharma/talk2biomodels/configs/tools/get_annotation/__init__.py +3 -0
- aiagents4pharma/talk2biomodels/configs/tools/get_annotation/default.yaml +8 -0
- aiagents4pharma/talk2biomodels/install.md +63 -0
- aiagents4pharma/talk2biomodels/models/__init__.py +5 -0
- aiagents4pharma/talk2biomodels/models/basico_model.py +125 -0
- aiagents4pharma/talk2biomodels/models/sys_bio_model.py +60 -0
- aiagents4pharma/talk2biomodels/states/__init__.py +6 -0
- aiagents4pharma/talk2biomodels/states/state_talk2biomodels.py +49 -0
- aiagents4pharma/talk2biomodels/tests/BIOMD0000000449_url.xml +1585 -0
- aiagents4pharma/talk2biomodels/tests/__init__.py +3 -0
- aiagents4pharma/talk2biomodels/tests/article_on_model_537.pdf +0 -0
- aiagents4pharma/talk2biomodels/tests/test_api.py +31 -0
- aiagents4pharma/talk2biomodels/tests/test_ask_question.py +42 -0
- aiagents4pharma/talk2biomodels/tests/test_basico_model.py +67 -0
- aiagents4pharma/talk2biomodels/tests/test_get_annotation.py +190 -0
- aiagents4pharma/talk2biomodels/tests/test_getmodelinfo.py +92 -0
- aiagents4pharma/talk2biomodels/tests/test_integration.py +116 -0
- aiagents4pharma/talk2biomodels/tests/test_load_biomodel.py +35 -0
- aiagents4pharma/talk2biomodels/tests/test_param_scan.py +71 -0
- aiagents4pharma/talk2biomodels/tests/test_query_article.py +184 -0
- aiagents4pharma/talk2biomodels/tests/test_save_model.py +47 -0
- aiagents4pharma/talk2biomodels/tests/test_search_models.py +35 -0
- aiagents4pharma/talk2biomodels/tests/test_simulate_model.py +44 -0
- aiagents4pharma/talk2biomodels/tests/test_steady_state.py +86 -0
- aiagents4pharma/talk2biomodels/tests/test_sys_bio_model.py +67 -0
- aiagents4pharma/talk2biomodels/tools/__init__.py +17 -0
- aiagents4pharma/talk2biomodels/tools/ask_question.py +125 -0
- aiagents4pharma/talk2biomodels/tools/custom_plotter.py +165 -0
- aiagents4pharma/talk2biomodels/tools/get_annotation.py +342 -0
- aiagents4pharma/talk2biomodels/tools/get_modelinfo.py +159 -0
- aiagents4pharma/talk2biomodels/tools/load_arguments.py +134 -0
- aiagents4pharma/talk2biomodels/tools/load_biomodel.py +44 -0
- aiagents4pharma/talk2biomodels/tools/parameter_scan.py +310 -0
- aiagents4pharma/talk2biomodels/tools/query_article.py +64 -0
- aiagents4pharma/talk2biomodels/tools/save_model.py +98 -0
- aiagents4pharma/talk2biomodels/tools/search_models.py +96 -0
- aiagents4pharma/talk2biomodels/tools/simulate_model.py +137 -0
- aiagents4pharma/talk2biomodels/tools/steady_state.py +187 -0
- aiagents4pharma/talk2biomodels/tools/utils.py +23 -0
- aiagents4pharma/talk2cells/README.md +1 -0
- aiagents4pharma/talk2cells/__init__.py +5 -0
- aiagents4pharma/talk2cells/agents/__init__.py +6 -0
- aiagents4pharma/talk2cells/agents/scp_agent.py +87 -0
- aiagents4pharma/talk2cells/states/__init__.py +6 -0
- aiagents4pharma/talk2cells/states/state_talk2cells.py +15 -0
- aiagents4pharma/talk2cells/tests/scp_agent/test_scp_agent.py +22 -0
- aiagents4pharma/talk2cells/tools/__init__.py +6 -0
- aiagents4pharma/talk2cells/tools/scp_agent/__init__.py +6 -0
- aiagents4pharma/talk2cells/tools/scp_agent/display_studies.py +27 -0
- aiagents4pharma/talk2cells/tools/scp_agent/search_studies.py +78 -0
- aiagents4pharma/talk2knowledgegraphs/.dockerignore +13 -0
- aiagents4pharma/talk2knowledgegraphs/Dockerfile +131 -0
- aiagents4pharma/talk2knowledgegraphs/README.md +1 -0
- aiagents4pharma/talk2knowledgegraphs/__init__.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/agents/__init__.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/agents/t2kg_agent.py +99 -0
- aiagents4pharma/talk2knowledgegraphs/configs/__init__.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/configs/agents/t2kg_agent/__init__.py +3 -0
- aiagents4pharma/talk2knowledgegraphs/configs/agents/t2kg_agent/default.yaml +62 -0
- aiagents4pharma/talk2knowledgegraphs/configs/app/__init__.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/configs/app/frontend/__init__.py +3 -0
- aiagents4pharma/talk2knowledgegraphs/configs/app/frontend/default.yaml +79 -0
- aiagents4pharma/talk2knowledgegraphs/configs/config.yaml +13 -0
- aiagents4pharma/talk2knowledgegraphs/configs/tools/__init__.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/configs/tools/graphrag_reasoning/__init__.py +3 -0
- aiagents4pharma/talk2knowledgegraphs/configs/tools/graphrag_reasoning/default.yaml +24 -0
- aiagents4pharma/talk2knowledgegraphs/configs/tools/multimodal_subgraph_extraction/__init__.py +0 -0
- aiagents4pharma/talk2knowledgegraphs/configs/tools/multimodal_subgraph_extraction/default.yaml +33 -0
- aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_extraction/__init__.py +3 -0
- aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_extraction/default.yaml +43 -0
- aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_summarization/__init__.py +3 -0
- aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_summarization/default.yaml +9 -0
- aiagents4pharma/talk2knowledgegraphs/configs/utils/database/milvus/__init__.py +3 -0
- aiagents4pharma/talk2knowledgegraphs/configs/utils/database/milvus/default.yaml +61 -0
- aiagents4pharma/talk2knowledgegraphs/configs/utils/enrichments/ols_terms/default.yaml +3 -0
- aiagents4pharma/talk2knowledgegraphs/configs/utils/enrichments/reactome_pathways/default.yaml +3 -0
- aiagents4pharma/talk2knowledgegraphs/configs/utils/enrichments/uniprot_proteins/default.yaml +6 -0
- aiagents4pharma/talk2knowledgegraphs/configs/utils/pubchem_utils/default.yaml +5 -0
- aiagents4pharma/talk2knowledgegraphs/datasets/__init__.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/datasets/biobridge_primekg.py +607 -0
- aiagents4pharma/talk2knowledgegraphs/datasets/dataset.py +25 -0
- aiagents4pharma/talk2knowledgegraphs/datasets/primekg.py +212 -0
- aiagents4pharma/talk2knowledgegraphs/datasets/starkqa_primekg.py +210 -0
- aiagents4pharma/talk2knowledgegraphs/docker-compose/cpu/.env.example +23 -0
- aiagents4pharma/talk2knowledgegraphs/docker-compose/cpu/docker-compose.yml +93 -0
- aiagents4pharma/talk2knowledgegraphs/docker-compose/gpu/.env.example +23 -0
- aiagents4pharma/talk2knowledgegraphs/docker-compose/gpu/docker-compose.yml +108 -0
- aiagents4pharma/talk2knowledgegraphs/entrypoint.sh +180 -0
- aiagents4pharma/talk2knowledgegraphs/install.md +165 -0
- aiagents4pharma/talk2knowledgegraphs/milvus_data_dump.py +886 -0
- aiagents4pharma/talk2knowledgegraphs/states/__init__.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/states/state_talk2knowledgegraphs.py +40 -0
- aiagents4pharma/talk2knowledgegraphs/tests/__init__.py +0 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_agents_t2kg_agent.py +318 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_biobridge_primekg.py +248 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_dataset.py +33 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_primekg.py +86 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_starkqa_primekg.py +125 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_tools_graphrag_reasoning.py +257 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_tools_milvus_multimodal_subgraph_extraction.py +1444 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_tools_multimodal_subgraph_extraction.py +159 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_tools_subgraph_extraction.py +152 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_tools_subgraph_summarization.py +201 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_database_milvus_connection_manager.py +812 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_embeddings.py +51 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_huggingface.py +49 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_nim_molmim.py +59 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_ollama.py +63 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_sentencetransformer.py +47 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_enrichments.py +40 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_ollama.py +94 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_ols.py +70 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_pubchem.py +45 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_reactome.py +44 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_uniprot.py +48 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_extractions_milvus_multimodal_pcst.py +759 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_kg_utils.py +78 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_pubchem_utils.py +123 -0
- aiagents4pharma/talk2knowledgegraphs/tools/__init__.py +11 -0
- aiagents4pharma/talk2knowledgegraphs/tools/graphrag_reasoning.py +138 -0
- aiagents4pharma/talk2knowledgegraphs/tools/load_arguments.py +22 -0
- aiagents4pharma/talk2knowledgegraphs/tools/milvus_multimodal_subgraph_extraction.py +965 -0
- aiagents4pharma/talk2knowledgegraphs/tools/multimodal_subgraph_extraction.py +374 -0
- aiagents4pharma/talk2knowledgegraphs/tools/subgraph_extraction.py +291 -0
- aiagents4pharma/talk2knowledgegraphs/tools/subgraph_summarization.py +123 -0
- aiagents4pharma/talk2knowledgegraphs/utils/__init__.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/utils/database/__init__.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/utils/database/milvus_connection_manager.py +586 -0
- aiagents4pharma/talk2knowledgegraphs/utils/embeddings/__init__.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/utils/embeddings/embeddings.py +81 -0
- aiagents4pharma/talk2knowledgegraphs/utils/embeddings/huggingface.py +111 -0
- aiagents4pharma/talk2knowledgegraphs/utils/embeddings/nim_molmim.py +54 -0
- aiagents4pharma/talk2knowledgegraphs/utils/embeddings/ollama.py +87 -0
- aiagents4pharma/talk2knowledgegraphs/utils/embeddings/sentence_transformer.py +73 -0
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/__init__.py +12 -0
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/enrichments.py +37 -0
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ollama.py +129 -0
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ols_terms.py +89 -0
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/pubchem_strings.py +78 -0
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/reactome_pathways.py +71 -0
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/uniprot_proteins.py +98 -0
- aiagents4pharma/talk2knowledgegraphs/utils/extractions/__init__.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/utils/extractions/milvus_multimodal_pcst.py +762 -0
- aiagents4pharma/talk2knowledgegraphs/utils/extractions/multimodal_pcst.py +298 -0
- aiagents4pharma/talk2knowledgegraphs/utils/extractions/pcst.py +229 -0
- aiagents4pharma/talk2knowledgegraphs/utils/kg_utils.py +67 -0
- aiagents4pharma/talk2knowledgegraphs/utils/pubchem_utils.py +104 -0
- aiagents4pharma/talk2scholars/.dockerignore +13 -0
- aiagents4pharma/talk2scholars/Dockerfile +104 -0
- aiagents4pharma/talk2scholars/README.md +1 -0
- aiagents4pharma/talk2scholars/__init__.py +7 -0
- aiagents4pharma/talk2scholars/agents/__init__.py +13 -0
- aiagents4pharma/talk2scholars/agents/main_agent.py +89 -0
- aiagents4pharma/talk2scholars/agents/paper_download_agent.py +96 -0
- aiagents4pharma/talk2scholars/agents/pdf_agent.py +101 -0
- aiagents4pharma/talk2scholars/agents/s2_agent.py +135 -0
- aiagents4pharma/talk2scholars/agents/zotero_agent.py +127 -0
- aiagents4pharma/talk2scholars/configs/__init__.py +7 -0
- aiagents4pharma/talk2scholars/configs/agents/__init__.py +7 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/__init__.py +7 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/default.yaml +52 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/paper_download_agent/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/paper_download_agent/default.yaml +19 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/pdf_agent/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/pdf_agent/default.yaml +19 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/default.yaml +44 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/zotero_agent/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/zotero_agent/default.yaml +19 -0
- aiagents4pharma/talk2scholars/configs/app/__init__.py +7 -0
- aiagents4pharma/talk2scholars/configs/app/frontend/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/app/frontend/default.yaml +72 -0
- aiagents4pharma/talk2scholars/configs/config.yaml +16 -0
- aiagents4pharma/talk2scholars/configs/tools/__init__.py +21 -0
- aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/default.yaml +26 -0
- aiagents4pharma/talk2scholars/configs/tools/paper_download/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/tools/paper_download/default.yaml +124 -0
- aiagents4pharma/talk2scholars/configs/tools/question_and_answer/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/tools/question_and_answer/default.yaml +62 -0
- aiagents4pharma/talk2scholars/configs/tools/retrieve_semantic_scholar_paper_id/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/tools/retrieve_semantic_scholar_paper_id/default.yaml +12 -0
- aiagents4pharma/talk2scholars/configs/tools/search/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/tools/search/default.yaml +26 -0
- aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/default.yaml +26 -0
- aiagents4pharma/talk2scholars/configs/tools/zotero_read/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/tools/zotero_read/default.yaml +57 -0
- aiagents4pharma/talk2scholars/configs/tools/zotero_write/__inti__.py +3 -0
- aiagents4pharma/talk2scholars/configs/tools/zotero_write/default.yaml +55 -0
- aiagents4pharma/talk2scholars/docker-compose/cpu/.env.example +21 -0
- aiagents4pharma/talk2scholars/docker-compose/cpu/docker-compose.yml +90 -0
- aiagents4pharma/talk2scholars/docker-compose/gpu/.env.example +21 -0
- aiagents4pharma/talk2scholars/docker-compose/gpu/docker-compose.yml +105 -0
- aiagents4pharma/talk2scholars/install.md +122 -0
- aiagents4pharma/talk2scholars/state/__init__.py +7 -0
- aiagents4pharma/talk2scholars/state/state_talk2scholars.py +98 -0
- aiagents4pharma/talk2scholars/tests/__init__.py +3 -0
- aiagents4pharma/talk2scholars/tests/test_agents_main_agent.py +256 -0
- aiagents4pharma/talk2scholars/tests/test_agents_paper_agents_download_agent.py +139 -0
- aiagents4pharma/talk2scholars/tests/test_agents_pdf_agent.py +114 -0
- aiagents4pharma/talk2scholars/tests/test_agents_s2_agent.py +198 -0
- aiagents4pharma/talk2scholars/tests/test_agents_zotero_agent.py +160 -0
- aiagents4pharma/talk2scholars/tests/test_s2_tools_display_dataframe.py +91 -0
- aiagents4pharma/talk2scholars/tests/test_s2_tools_query_dataframe.py +191 -0
- aiagents4pharma/talk2scholars/tests/test_states_state.py +38 -0
- aiagents4pharma/talk2scholars/tests/test_tools_paper_downloader.py +507 -0
- aiagents4pharma/talk2scholars/tests/test_tools_question_and_answer_tool.py +105 -0
- aiagents4pharma/talk2scholars/tests/test_tools_s2_multi.py +307 -0
- aiagents4pharma/talk2scholars/tests/test_tools_s2_retrieve.py +67 -0
- aiagents4pharma/talk2scholars/tests/test_tools_s2_search.py +286 -0
- aiagents4pharma/talk2scholars/tests/test_tools_s2_single.py +298 -0
- aiagents4pharma/talk2scholars/tests/test_utils_arxiv_downloader.py +469 -0
- aiagents4pharma/talk2scholars/tests/test_utils_base_paper_downloader.py +598 -0
- aiagents4pharma/talk2scholars/tests/test_utils_biorxiv_downloader.py +669 -0
- aiagents4pharma/talk2scholars/tests/test_utils_medrxiv_downloader.py +500 -0
- aiagents4pharma/talk2scholars/tests/test_utils_nvidia_nim_reranker.py +117 -0
- aiagents4pharma/talk2scholars/tests/test_utils_pdf_answer_formatter.py +67 -0
- aiagents4pharma/talk2scholars/tests/test_utils_pdf_batch_processor.py +92 -0
- aiagents4pharma/talk2scholars/tests/test_utils_pdf_collection_manager.py +173 -0
- aiagents4pharma/talk2scholars/tests/test_utils_pdf_document_processor.py +68 -0
- aiagents4pharma/talk2scholars/tests/test_utils_pdf_generate_answer.py +72 -0
- aiagents4pharma/talk2scholars/tests/test_utils_pdf_gpu_detection.py +129 -0
- aiagents4pharma/talk2scholars/tests/test_utils_pdf_paper_loader.py +116 -0
- aiagents4pharma/talk2scholars/tests/test_utils_pdf_rag_pipeline.py +88 -0
- aiagents4pharma/talk2scholars/tests/test_utils_pdf_retrieve_chunks.py +190 -0
- aiagents4pharma/talk2scholars/tests/test_utils_pdf_singleton_manager.py +159 -0
- aiagents4pharma/talk2scholars/tests/test_utils_pdf_vector_normalization.py +121 -0
- aiagents4pharma/talk2scholars/tests/test_utils_pdf_vector_store.py +406 -0
- aiagents4pharma/talk2scholars/tests/test_utils_pubmed_downloader.py +1007 -0
- aiagents4pharma/talk2scholars/tests/test_utils_read_helper_utils.py +106 -0
- aiagents4pharma/talk2scholars/tests/test_utils_s2_utils_ext_ids.py +403 -0
- aiagents4pharma/talk2scholars/tests/test_utils_tool_helper_utils.py +85 -0
- aiagents4pharma/talk2scholars/tests/test_utils_zotero_human_in_the_loop.py +266 -0
- aiagents4pharma/talk2scholars/tests/test_utils_zotero_path.py +496 -0
- aiagents4pharma/talk2scholars/tests/test_utils_zotero_pdf_downloader_utils.py +46 -0
- aiagents4pharma/talk2scholars/tests/test_utils_zotero_read.py +743 -0
- aiagents4pharma/talk2scholars/tests/test_utils_zotero_write.py +151 -0
- aiagents4pharma/talk2scholars/tools/__init__.py +9 -0
- aiagents4pharma/talk2scholars/tools/paper_download/__init__.py +12 -0
- aiagents4pharma/talk2scholars/tools/paper_download/paper_downloader.py +442 -0
- aiagents4pharma/talk2scholars/tools/paper_download/utils/__init__.py +22 -0
- aiagents4pharma/talk2scholars/tools/paper_download/utils/arxiv_downloader.py +207 -0
- aiagents4pharma/talk2scholars/tools/paper_download/utils/base_paper_downloader.py +336 -0
- aiagents4pharma/talk2scholars/tools/paper_download/utils/biorxiv_downloader.py +313 -0
- aiagents4pharma/talk2scholars/tools/paper_download/utils/medrxiv_downloader.py +196 -0
- aiagents4pharma/talk2scholars/tools/paper_download/utils/pubmed_downloader.py +323 -0
- aiagents4pharma/talk2scholars/tools/pdf/__init__.py +7 -0
- aiagents4pharma/talk2scholars/tools/pdf/question_and_answer.py +170 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/__init__.py +37 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/answer_formatter.py +62 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/batch_processor.py +198 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/collection_manager.py +172 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/document_processor.py +76 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/generate_answer.py +97 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/get_vectorstore.py +59 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/gpu_detection.py +150 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/nvidia_nim_reranker.py +97 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/paper_loader.py +123 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/rag_pipeline.py +113 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/retrieve_chunks.py +197 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/singleton_manager.py +140 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/tool_helper.py +86 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/vector_normalization.py +150 -0
- aiagents4pharma/talk2scholars/tools/pdf/utils/vector_store.py +327 -0
- aiagents4pharma/talk2scholars/tools/s2/__init__.py +21 -0
- aiagents4pharma/talk2scholars/tools/s2/display_dataframe.py +110 -0
- aiagents4pharma/talk2scholars/tools/s2/multi_paper_rec.py +111 -0
- aiagents4pharma/talk2scholars/tools/s2/query_dataframe.py +233 -0
- aiagents4pharma/talk2scholars/tools/s2/retrieve_semantic_scholar_paper_id.py +128 -0
- aiagents4pharma/talk2scholars/tools/s2/search.py +101 -0
- aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py +102 -0
- aiagents4pharma/talk2scholars/tools/s2/utils/__init__.py +5 -0
- aiagents4pharma/talk2scholars/tools/s2/utils/multi_helper.py +223 -0
- aiagents4pharma/talk2scholars/tools/s2/utils/search_helper.py +205 -0
- aiagents4pharma/talk2scholars/tools/s2/utils/single_helper.py +216 -0
- aiagents4pharma/talk2scholars/tools/zotero/__init__.py +7 -0
- aiagents4pharma/talk2scholars/tools/zotero/utils/__init__.py +7 -0
- aiagents4pharma/talk2scholars/tools/zotero/utils/read_helper.py +270 -0
- aiagents4pharma/talk2scholars/tools/zotero/utils/review_helper.py +74 -0
- aiagents4pharma/talk2scholars/tools/zotero/utils/write_helper.py +194 -0
- aiagents4pharma/talk2scholars/tools/zotero/utils/zotero_path.py +180 -0
- aiagents4pharma/talk2scholars/tools/zotero/utils/zotero_pdf_downloader.py +133 -0
- aiagents4pharma/talk2scholars/tools/zotero/zotero_read.py +105 -0
- aiagents4pharma/talk2scholars/tools/zotero/zotero_review.py +162 -0
- aiagents4pharma/talk2scholars/tools/zotero/zotero_write.py +91 -0
- aiagents4pharma-0.0.0.dist-info/METADATA +335 -0
- aiagents4pharma-0.0.0.dist-info/RECORD +336 -0
- aiagents4pharma-0.0.0.dist-info/WHEEL +4 -0
- aiagents4pharma-0.0.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""
|
|
2
|
+
GPU Detection Utility for Milvus Index Selection
|
|
3
|
+
Handle COSINE -> IP conversion for GPU indexes
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
import subprocess
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def detect_nvidia_gpu(config=None) -> bool:
|
|
14
|
+
"""
|
|
15
|
+
Detect if NVIDIA GPU is available and should be used.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
config: Hydra config object that may contain force_cpu_mode flag
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
bool: True if GPU should be used, False if CPU should be used
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
# Check for force CPU mode in config
|
|
25
|
+
if config and hasattr(config, "gpu_detection"):
|
|
26
|
+
force_cpu = getattr(config.gpu_detection, "force_cpu_mode", False)
|
|
27
|
+
if force_cpu:
|
|
28
|
+
logger.info(
|
|
29
|
+
"Force CPU mode enabled in config - using CPU even though GPU may be available"
|
|
30
|
+
)
|
|
31
|
+
return False
|
|
32
|
+
|
|
33
|
+
# Normal GPU detection logic
|
|
34
|
+
try:
|
|
35
|
+
result = subprocess.run(
|
|
36
|
+
["nvidia-smi", "--query-gpu=name", "--format=csv,noheader"],
|
|
37
|
+
capture_output=True,
|
|
38
|
+
text=True,
|
|
39
|
+
timeout=10,
|
|
40
|
+
check=False,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
if result.returncode == 0 and result.stdout.strip():
|
|
44
|
+
gpu_names = result.stdout.strip().split("\n")
|
|
45
|
+
logger.info("Detected NVIDIA GPU(s): %s", gpu_names)
|
|
46
|
+
logger.info("To force CPU mode, set 'force_cpu_mode: true' in config")
|
|
47
|
+
return True
|
|
48
|
+
|
|
49
|
+
logger.info("nvidia-smi command failed or no GPUs detected")
|
|
50
|
+
return False
|
|
51
|
+
|
|
52
|
+
except (subprocess.TimeoutExpired, FileNotFoundError) as e:
|
|
53
|
+
logger.info("NVIDIA GPU detection failed: %s", e)
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_optimal_index_config(
|
|
58
|
+
has_gpu: bool, embedding_dim: int = 768, use_cosine: bool = True
|
|
59
|
+
) -> tuple[dict[str, Any], dict[str, Any]]:
|
|
60
|
+
"""
|
|
61
|
+
Get optimal index and search parameters based on GPU availability.
|
|
62
|
+
|
|
63
|
+
IMPORTANT: GPU indexes don't support COSINE distance. When using GPU with COSINE,
|
|
64
|
+
vectors must be normalized and IP distance used instead.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
has_gpu (bool): Whether NVIDIA GPU is available
|
|
68
|
+
embedding_dim (int): Dimension of embeddings
|
|
69
|
+
use_cosine (bool): Whether to use cosine similarity (will be converted to IP for GPU)
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
Tuple[Dict[str, Any], Dict[str, Any]]: (index_params, search_params)
|
|
73
|
+
"""
|
|
74
|
+
if has_gpu:
|
|
75
|
+
logger.info("Configuring GPU_CAGRA index for NVIDIA GPU")
|
|
76
|
+
|
|
77
|
+
# For GPU: COSINE is not supported, must use IP with normalized vectors
|
|
78
|
+
if use_cosine:
|
|
79
|
+
logger.warning(
|
|
80
|
+
"GPU indexes don't support COSINE distance. "
|
|
81
|
+
"Vectors will be normalized and IP distance will be used instead."
|
|
82
|
+
)
|
|
83
|
+
metric_type = "IP" # Inner Product for normalized vectors = cosine similarity
|
|
84
|
+
else:
|
|
85
|
+
metric_type = "IP" # Default to IP for GPU
|
|
86
|
+
|
|
87
|
+
# GPU_CAGRA index parameters - optimized for performance
|
|
88
|
+
index_params = {
|
|
89
|
+
"index_type": "GPU_CAGRA",
|
|
90
|
+
"metric_type": metric_type,
|
|
91
|
+
"params": {
|
|
92
|
+
"intermediate_graph_degree": 64, # Higher for better recall
|
|
93
|
+
"graph_degree": 32, # Balanced performance/recall
|
|
94
|
+
"build_algo": "IVF_PQ", # Higher quality build
|
|
95
|
+
"cache_dataset_on_device": "true", # Cache for better recall
|
|
96
|
+
"adapt_for_cpu": "false", # Pure GPU mode
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# GPU_CAGRA search parameters
|
|
101
|
+
search_params = {
|
|
102
|
+
"metric_type": metric_type,
|
|
103
|
+
"params": {
|
|
104
|
+
"itopk_size": 128, # Power of 2, good for intermediate results
|
|
105
|
+
"search_width": 16, # Balanced entry points
|
|
106
|
+
"team_size": 16, # Optimize for typical vector dimensions
|
|
107
|
+
},
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
else:
|
|
111
|
+
logger.info("Configuring CPU index (IVF_FLAT) - no NVIDIA GPU detected")
|
|
112
|
+
|
|
113
|
+
# CPU supports COSINE directly
|
|
114
|
+
metric_type = "COSINE" if use_cosine else "IP"
|
|
115
|
+
|
|
116
|
+
# CPU IVF_FLAT index parameters
|
|
117
|
+
index_params = {
|
|
118
|
+
"index_type": "IVF_FLAT",
|
|
119
|
+
"metric_type": metric_type,
|
|
120
|
+
"params": {
|
|
121
|
+
"nlist": min(1024, max(64, embedding_dim // 8)) # Dynamic nlist based on dimension
|
|
122
|
+
},
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
# CPU search parameters
|
|
126
|
+
search_params = {
|
|
127
|
+
"metric_type": metric_type,
|
|
128
|
+
"params": {"nprobe": 16}, # Slightly higher than original for better recall
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return index_params, search_params
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def log_index_configuration(
|
|
135
|
+
index_params: dict[str, Any], search_params: dict[str, Any], use_cosine: bool = True
|
|
136
|
+
) -> None:
|
|
137
|
+
"""Log the selected index configuration for debugging."""
|
|
138
|
+
index_type = index_params.get("index_type", "Unknown")
|
|
139
|
+
metric_type = index_params.get("metric_type", "Unknown")
|
|
140
|
+
|
|
141
|
+
logger.info("=== Milvus Index Configuration ===")
|
|
142
|
+
logger.info("Index Type: %s", index_type)
|
|
143
|
+
logger.info("Metric Type: %s", metric_type)
|
|
144
|
+
|
|
145
|
+
if index_type == "GPU_CAGRA" and use_cosine and metric_type == "IP":
|
|
146
|
+
logger.info("NOTE: Using IP with normalized vectors to simulate COSINE for GPU")
|
|
147
|
+
|
|
148
|
+
logger.info("Index Params: %s", index_params.get("params", {}))
|
|
149
|
+
logger.info("Search Params: %s", search_params.get("params", {}))
|
|
150
|
+
logger.info("===================================")
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""
|
|
2
|
+
NVIDIA NIM Reranker Utility for Milvus Integration
|
|
3
|
+
Rerank chunks instead of papers following traditional RAG pipeline
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
import os
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from langchain_core.documents import Document
|
|
11
|
+
from langchain_nvidia_ai_endpoints import NVIDIARerank
|
|
12
|
+
|
|
13
|
+
# Set up logging with configurable level
|
|
14
|
+
log_level = os.environ.get("LOG_LEVEL", "INFO")
|
|
15
|
+
logging.basicConfig(level=getattr(logging, log_level))
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
logger.setLevel(getattr(logging, log_level))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def rerank_chunks(
|
|
21
|
+
chunks: list[Document], query: str, config: Any, top_k: int = 25
|
|
22
|
+
) -> list[Document]:
|
|
23
|
+
"""
|
|
24
|
+
Rerank chunks by relevance to the query using NVIDIA's reranker.
|
|
25
|
+
|
|
26
|
+
This follows the traditional RAG pipeline: first retrieve chunks, then rerank them.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
chunks (List[Document]): List of chunks to rerank
|
|
30
|
+
query (str): The query string
|
|
31
|
+
config (Any): Configuration containing reranker settings
|
|
32
|
+
top_k (int): Number of top chunks to return after reranking
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
List[Document]: Reranked chunks (top_k most relevant)
|
|
36
|
+
"""
|
|
37
|
+
logger.info(
|
|
38
|
+
"Starting NVIDIA chunk reranker for query: '%s' with %d chunks, top_k=%d",
|
|
39
|
+
query[:50] + "..." if len(query) > 50 else query,
|
|
40
|
+
len(chunks),
|
|
41
|
+
top_k,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# If we have fewer chunks than top_k, just return all
|
|
45
|
+
if len(chunks) <= top_k:
|
|
46
|
+
logger.info(
|
|
47
|
+
"Number of chunks (%d) <= top_k (%d), returning all chunks without reranking",
|
|
48
|
+
len(chunks),
|
|
49
|
+
top_k,
|
|
50
|
+
)
|
|
51
|
+
return chunks
|
|
52
|
+
|
|
53
|
+
# Get API key from config
|
|
54
|
+
api_key = config.reranker.api_key
|
|
55
|
+
if not api_key:
|
|
56
|
+
logger.error("No NVIDIA API key found in configuration for reranking")
|
|
57
|
+
raise ValueError("Configuration 'reranker.api_key' must be set for reranking")
|
|
58
|
+
|
|
59
|
+
logger.info("Using NVIDIA reranker model: %s", config.reranker.model)
|
|
60
|
+
|
|
61
|
+
# Initialize reranker with truncation to handle long chunks
|
|
62
|
+
reranker = NVIDIARerank(
|
|
63
|
+
model=config.reranker.model,
|
|
64
|
+
api_key=api_key,
|
|
65
|
+
truncate="END", # Truncate at the end if too long
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
# Log chunk metadata for debugging
|
|
69
|
+
logger.debug(
|
|
70
|
+
"Reranking chunks from papers: %s",
|
|
71
|
+
list({chunk.metadata.get("paper_id", "unknown") for chunk in chunks})[:5],
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Rerank the chunks
|
|
75
|
+
logger.info("Calling NVIDIA reranker API with %d chunks...", len(chunks))
|
|
76
|
+
reranked_chunks = reranker.compress_documents(query=query, documents=chunks)
|
|
77
|
+
|
|
78
|
+
for i, doc in enumerate(reranked_chunks[:top_k]):
|
|
79
|
+
score = doc.metadata.get("relevance_score", "N/A")
|
|
80
|
+
source = doc.metadata.get("paper_id", "unknown")
|
|
81
|
+
logger.info("Rank %d | Score: %.4f | Source: %s", i + 1, score, source)
|
|
82
|
+
|
|
83
|
+
logger.info(
|
|
84
|
+
"Successfully reranked chunks. Returning top %d chunks",
|
|
85
|
+
min(top_k, len(reranked_chunks)),
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# Log which papers the top chunks come from
|
|
89
|
+
if reranked_chunks and logger.isEnabledFor(logging.DEBUG):
|
|
90
|
+
top_papers = {}
|
|
91
|
+
for chunk in reranked_chunks[:top_k]:
|
|
92
|
+
paper_id = chunk.metadata.get("paper_id", "unknown")
|
|
93
|
+
top_papers[paper_id] = top_papers.get(paper_id, 0) + 1
|
|
94
|
+
logger.debug("Top %d chunks distribution by paper: %s", top_k, top_papers)
|
|
95
|
+
|
|
96
|
+
# Return only top_k chunks (convert to list to match return type)
|
|
97
|
+
return list(reranked_chunks[:top_k])
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Paper loading utilities for managing PDF documents in vector store.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from .batch_processor import add_papers_batch
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def load_all_papers(
|
|
14
|
+
vector_store: Any, # The Vectorstore instance
|
|
15
|
+
articles: dict[str, Any],
|
|
16
|
+
call_id: str,
|
|
17
|
+
config: Any,
|
|
18
|
+
has_gpu: bool,
|
|
19
|
+
) -> None:
|
|
20
|
+
"""
|
|
21
|
+
Ensure all papers from article_data are loaded into the Milvus vector store.
|
|
22
|
+
Optimized for GPU/CPU processing.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
vector_store: The Vectorstore instance
|
|
26
|
+
articles: Dictionary of article data
|
|
27
|
+
call_id: Call identifier for logging
|
|
28
|
+
config: Configuration object
|
|
29
|
+
has_gpu: Whether GPU is available
|
|
30
|
+
"""
|
|
31
|
+
papers_to_load = []
|
|
32
|
+
skipped_papers = []
|
|
33
|
+
already_loaded = []
|
|
34
|
+
|
|
35
|
+
# Check which papers need to be loaded
|
|
36
|
+
for pid, article_info in articles.items():
|
|
37
|
+
if pid not in vector_store.loaded_papers:
|
|
38
|
+
pdf_url = article_info.get("pdf_url")
|
|
39
|
+
if pdf_url:
|
|
40
|
+
# Prepare tuple for batch loading
|
|
41
|
+
papers_to_load.append((pid, pdf_url, article_info))
|
|
42
|
+
else:
|
|
43
|
+
skipped_papers.append(pid)
|
|
44
|
+
else:
|
|
45
|
+
already_loaded.append(pid)
|
|
46
|
+
|
|
47
|
+
# Log summary of papers status with hardware info
|
|
48
|
+
hardware_info = f" (GPU acceleration: {'enabled' if has_gpu else 'disabled'})"
|
|
49
|
+
logger.info(
|
|
50
|
+
"%s: Paper loading summary%s - Total: %d, Already loaded: %d, To load: %d, No PDF: %d",
|
|
51
|
+
call_id,
|
|
52
|
+
hardware_info,
|
|
53
|
+
len(articles),
|
|
54
|
+
len(already_loaded),
|
|
55
|
+
len(papers_to_load),
|
|
56
|
+
len(skipped_papers),
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
if skipped_papers:
|
|
60
|
+
logger.warning(
|
|
61
|
+
"%s: Skipping %d papers without PDF URLs: %s%s",
|
|
62
|
+
call_id,
|
|
63
|
+
len(skipped_papers),
|
|
64
|
+
skipped_papers[:5], # Show first 5
|
|
65
|
+
"..." if len(skipped_papers) > 5 else "",
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
if not papers_to_load:
|
|
69
|
+
logger.info("%s: All papers with PDFs are already loaded in Milvus", call_id)
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
# Use batch loading with parallel processing for ALL papers at once
|
|
73
|
+
# Adjust parameters based on hardware capabilities
|
|
74
|
+
if has_gpu:
|
|
75
|
+
# GPU can handle more parallel processing
|
|
76
|
+
max_workers = min(12, max(4, len(papers_to_load))) # More workers for GPU
|
|
77
|
+
batch_size = config.get("embedding_batch_size", 2000) # Larger batches for GPU
|
|
78
|
+
logger.info(
|
|
79
|
+
"%s: Using GPU-optimized loading parameters: %d workers, batch size %d",
|
|
80
|
+
call_id,
|
|
81
|
+
max_workers,
|
|
82
|
+
batch_size,
|
|
83
|
+
)
|
|
84
|
+
else:
|
|
85
|
+
# CPU - more conservative parameters
|
|
86
|
+
max_workers = min(8, max(3, len(papers_to_load))) # Conservative for CPU
|
|
87
|
+
batch_size = config.get("embedding_batch_size", 1000) # Smaller batches for CPU
|
|
88
|
+
logger.info(
|
|
89
|
+
"%s: Using CPU-optimized loading parameters: %d workers, batch size %d",
|
|
90
|
+
call_id,
|
|
91
|
+
max_workers,
|
|
92
|
+
batch_size,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
logger.info(
|
|
96
|
+
"%s: Loading %d papers in ONE BATCH using %d parallel workers (batch size: %d, %s)",
|
|
97
|
+
call_id,
|
|
98
|
+
len(papers_to_load),
|
|
99
|
+
max_workers,
|
|
100
|
+
batch_size,
|
|
101
|
+
"GPU accelerated" if has_gpu else "CPU processing",
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# This should process ALL papers at once with hardware optimization
|
|
105
|
+
add_papers_batch(
|
|
106
|
+
papers_to_add=papers_to_load,
|
|
107
|
+
vector_store=vector_store.vector_store, # Pass the LangChain vector store
|
|
108
|
+
loaded_papers=vector_store.loaded_papers,
|
|
109
|
+
paper_metadata=vector_store.paper_metadata,
|
|
110
|
+
documents=vector_store.documents,
|
|
111
|
+
config=vector_store.config,
|
|
112
|
+
metadata_fields=vector_store.metadata_fields,
|
|
113
|
+
has_gpu=vector_store.has_gpu,
|
|
114
|
+
max_workers=max_workers,
|
|
115
|
+
batch_size=batch_size,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
logger.info(
|
|
119
|
+
"%s: Successfully completed batch loading of all %d papers with %s",
|
|
120
|
+
call_id,
|
|
121
|
+
len(papers_to_load),
|
|
122
|
+
"GPU acceleration" if has_gpu else "CPU processing",
|
|
123
|
+
)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""
|
|
2
|
+
RAG pipeline for retrieving and reranking chunks from a vector store.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
# Import our GPU detection utility
|
|
9
|
+
from .nvidia_nim_reranker import rerank_chunks
|
|
10
|
+
from .retrieve_chunks import retrieve_relevant_chunks
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def retrieve_and_rerank_chunks(
|
|
16
|
+
vector_store: Any, query: str, config: Any, call_id: str, has_gpu: bool
|
|
17
|
+
) -> list[Any]:
|
|
18
|
+
"""
|
|
19
|
+
Traditional RAG pipeline: retrieve chunks from all papers, then rerank.
|
|
20
|
+
Optimized for GPU/CPU hardware.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
vs: Vector store instance
|
|
24
|
+
query: User query
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
List of reranked chunks
|
|
28
|
+
"""
|
|
29
|
+
hardware_mode = "GPU-accelerated" if has_gpu else "CPU-optimized"
|
|
30
|
+
logger.info(
|
|
31
|
+
"%s: Starting traditional RAG pipeline - retrieve then rerank (%s)",
|
|
32
|
+
call_id,
|
|
33
|
+
hardware_mode,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
# Step 1: Retrieve chunks from ALL papers (cast wide net)
|
|
37
|
+
# Adjust initial retrieval count based on hardware
|
|
38
|
+
if has_gpu:
|
|
39
|
+
# GPU can handle larger initial retrieval efficiently
|
|
40
|
+
initial_chunks_count = config.get("initial_retrieval_k", 150) # Increased for GPU
|
|
41
|
+
mmr_diversity = config.get("mmr_diversity", 0.75) # Slightly more diverse for larger sets
|
|
42
|
+
else:
|
|
43
|
+
# CPU - use conservative settings
|
|
44
|
+
initial_chunks_count = config.get("initial_retrieval_k", 100) # Original
|
|
45
|
+
mmr_diversity = config.get("mmr_diversity", 0.8) # Original
|
|
46
|
+
|
|
47
|
+
logger.info(
|
|
48
|
+
"%s: Step 1 - Retrieving top %d chunks from ALL papers (%s mode)",
|
|
49
|
+
call_id,
|
|
50
|
+
initial_chunks_count,
|
|
51
|
+
hardware_mode,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
retrieved_chunks = retrieve_relevant_chunks(
|
|
55
|
+
vector_store,
|
|
56
|
+
query=query,
|
|
57
|
+
paper_ids=None, # No filter - retrieve from all papers
|
|
58
|
+
top_k=initial_chunks_count,
|
|
59
|
+
mmr_diversity=mmr_diversity,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
if not retrieved_chunks:
|
|
63
|
+
logger.warning("%s: No chunks retrieved from vector store", call_id)
|
|
64
|
+
return []
|
|
65
|
+
|
|
66
|
+
logger.info(
|
|
67
|
+
"%s: Retrieved %d chunks from %d unique papers using %s",
|
|
68
|
+
call_id,
|
|
69
|
+
len(retrieved_chunks),
|
|
70
|
+
len({chunk.metadata.get("paper_id", "unknown") for chunk in retrieved_chunks}),
|
|
71
|
+
hardware_mode,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Step 2: Rerank the retrieved chunks
|
|
75
|
+
final_chunk_count = config.top_k_chunks
|
|
76
|
+
logger.info(
|
|
77
|
+
"%s: Step 2 - Reranking %d chunks to get top %d",
|
|
78
|
+
call_id,
|
|
79
|
+
len(retrieved_chunks),
|
|
80
|
+
final_chunk_count,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
reranked_chunks = rerank_chunks(
|
|
84
|
+
chunks=retrieved_chunks,
|
|
85
|
+
query=query,
|
|
86
|
+
config=config,
|
|
87
|
+
top_k=final_chunk_count,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# Log final results with hardware info
|
|
91
|
+
final_papers = len({chunk.metadata.get("paper_id", "unknown") for chunk in reranked_chunks})
|
|
92
|
+
|
|
93
|
+
logger.info(
|
|
94
|
+
"%s: Reranking complete using %s. Final %d chunks from %d unique papers",
|
|
95
|
+
call_id,
|
|
96
|
+
hardware_mode,
|
|
97
|
+
len(reranked_chunks),
|
|
98
|
+
final_papers,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Log performance insights
|
|
102
|
+
if len(retrieved_chunks) > 0:
|
|
103
|
+
efficiency = len(reranked_chunks) / len(retrieved_chunks) * 100
|
|
104
|
+
logger.debug(
|
|
105
|
+
"%s: Pipeline efficiency: %.1f%% (%d final / %d initial chunks) - %s",
|
|
106
|
+
call_id,
|
|
107
|
+
efficiency,
|
|
108
|
+
len(reranked_chunks),
|
|
109
|
+
len(retrieved_chunks),
|
|
110
|
+
hardware_mode,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
return reranked_chunks
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Retrieve relevant chunks from a Milvus vector store using MMR (Maximal Marginal Relevance).
|
|
3
|
+
Follows traditional RAG pipeline - retrieve first, then rerank.
|
|
4
|
+
With automatic GPU/CPU search parameter optimization.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
import os
|
|
9
|
+
|
|
10
|
+
from langchain_core.documents import Document
|
|
11
|
+
|
|
12
|
+
# Set up logging with configurable level
|
|
13
|
+
log_level = os.environ.get("LOG_LEVEL", "INFO")
|
|
14
|
+
logging.basicConfig(level=getattr(logging, log_level))
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
logger.setLevel(getattr(logging, log_level))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def retrieve_relevant_chunks(
|
|
20
|
+
vector_store,
|
|
21
|
+
query: str,
|
|
22
|
+
paper_ids: list[str] | None = None,
|
|
23
|
+
top_k: int = 100, # Increased default to cast wider net before reranking
|
|
24
|
+
mmr_diversity: float = 0.8, # Slightly reduced for better diversity
|
|
25
|
+
) -> list[Document]:
|
|
26
|
+
"""
|
|
27
|
+
Retrieve the most relevant chunks for a query using maximal marginal relevance.
|
|
28
|
+
Automatically uses GPU-optimized search parameters if GPU is available.
|
|
29
|
+
|
|
30
|
+
In the traditional RAG pipeline, this should retrieve chunks from ALL available papers,
|
|
31
|
+
not just pre-selected ones. The reranker will then select the best chunks.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
vector_store: The Milvus vector store instance
|
|
35
|
+
query: Query string
|
|
36
|
+
paper_ids: Optional list of paper IDs to filter by (default: None - search all papers)
|
|
37
|
+
top_k: Number of chunks to retrieve (default: 100 for reranking pipeline)
|
|
38
|
+
mmr_diversity: Diversity parameter for MMR (0=max diversity, 1=max relevance)
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
List of document chunks
|
|
42
|
+
"""
|
|
43
|
+
if not vector_store:
|
|
44
|
+
logger.error("Vector store is not initialized")
|
|
45
|
+
return []
|
|
46
|
+
|
|
47
|
+
# Check if vector store has GPU capabilities
|
|
48
|
+
has_gpu = getattr(vector_store, "has_gpu", False)
|
|
49
|
+
search_mode = "GPU-accelerated" if has_gpu else "CPU"
|
|
50
|
+
|
|
51
|
+
# Prepare filter for paper_ids if provided
|
|
52
|
+
filter_dict = None
|
|
53
|
+
if paper_ids:
|
|
54
|
+
logger.warning(
|
|
55
|
+
"Paper IDs filter provided. Traditional RAG pipeline typically"
|
|
56
|
+
"retrieves from ALL papers first. "
|
|
57
|
+
"Consider removing paper_ids filter for better results."
|
|
58
|
+
)
|
|
59
|
+
logger.info("Filtering retrieval to papers: %s", paper_ids)
|
|
60
|
+
filter_dict = {"paper_id": paper_ids}
|
|
61
|
+
else:
|
|
62
|
+
logger.info(
|
|
63
|
+
"Retrieving chunks from ALL papers (traditional RAG approach) using %s search",
|
|
64
|
+
search_mode,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Use Milvus's built-in MMR search with optimized parameters
|
|
68
|
+
logger.info(
|
|
69
|
+
"Performing %s MMR search with query: '%s', k=%d, diversity=%.2f",
|
|
70
|
+
search_mode,
|
|
71
|
+
query[:50] + "..." if len(query) > 50 else query,
|
|
72
|
+
top_k,
|
|
73
|
+
mmr_diversity,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Fetch more candidates for better MMR results
|
|
77
|
+
# Adjust fetch_k based on available hardware
|
|
78
|
+
if has_gpu:
|
|
79
|
+
# GPU can handle larger candidate sets efficiently
|
|
80
|
+
fetch_k = min(top_k * 6, 800) # Increased for GPU
|
|
81
|
+
logger.debug("Using GPU-optimized fetch_k: %d", fetch_k)
|
|
82
|
+
else:
|
|
83
|
+
# CPU - more conservative to avoid performance issues
|
|
84
|
+
fetch_k = min(top_k * 4, 500) # Original conservative approach
|
|
85
|
+
logger.debug("Using CPU-optimized fetch_k: %d", fetch_k)
|
|
86
|
+
|
|
87
|
+
# Get search parameters from vector store if available
|
|
88
|
+
search_params = getattr(vector_store, "search_params", None)
|
|
89
|
+
|
|
90
|
+
if search_params:
|
|
91
|
+
logger.debug("Using hardware-optimized search parameters: %s", search_params)
|
|
92
|
+
else:
|
|
93
|
+
logger.debug("Using default search parameters (no hardware optimization)")
|
|
94
|
+
|
|
95
|
+
# Perform MMR search - let the vector store handle search_params internally
|
|
96
|
+
# Don't pass search_params explicitly to avoid conflicts
|
|
97
|
+
results = vector_store.max_marginal_relevance_search(
|
|
98
|
+
query=query,
|
|
99
|
+
k=top_k,
|
|
100
|
+
fetch_k=fetch_k,
|
|
101
|
+
lambda_mult=mmr_diversity,
|
|
102
|
+
filter=filter_dict,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
logger.info("Retrieved %d chunks using %s MMR from Milvus", len(results), search_mode)
|
|
106
|
+
|
|
107
|
+
# Log some details about retrieved chunks for debugging
|
|
108
|
+
if results and logger.isEnabledFor(logging.DEBUG):
|
|
109
|
+
paper_counts = {}
|
|
110
|
+
for doc in results:
|
|
111
|
+
paper_id = doc.metadata.get("paper_id", "unknown")
|
|
112
|
+
paper_counts[paper_id] = paper_counts.get(paper_id, 0) + 1
|
|
113
|
+
|
|
114
|
+
logger.debug(
|
|
115
|
+
"%s retrieval - chunks per paper: %s",
|
|
116
|
+
search_mode,
|
|
117
|
+
dict(sorted(paper_counts.items(), key=lambda x: x[1], reverse=True)[:10]),
|
|
118
|
+
)
|
|
119
|
+
logger.debug(
|
|
120
|
+
"%s retrieval - total papers represented: %d",
|
|
121
|
+
search_mode,
|
|
122
|
+
len(paper_counts),
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
return results
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def retrieve_relevant_chunks_with_scores(
|
|
129
|
+
vector_store,
|
|
130
|
+
query: str,
|
|
131
|
+
paper_ids: list[str] | None = None,
|
|
132
|
+
top_k: int = 100,
|
|
133
|
+
score_threshold: float = 0.0,
|
|
134
|
+
) -> list[tuple[Document, float]]:
|
|
135
|
+
"""
|
|
136
|
+
Retrieve chunks with similarity scores, optimized for GPU/CPU.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
vector_store: The Milvus vector store instance
|
|
140
|
+
query: Query string
|
|
141
|
+
paper_ids: Optional list of paper IDs to filter by
|
|
142
|
+
top_k: Number of chunks to retrieve
|
|
143
|
+
score_threshold: Minimum similarity score threshold
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
List of (document, score) tuples
|
|
147
|
+
"""
|
|
148
|
+
if not vector_store:
|
|
149
|
+
logger.error("Vector store is not initialized")
|
|
150
|
+
return []
|
|
151
|
+
|
|
152
|
+
has_gpu = getattr(vector_store, "has_gpu", False)
|
|
153
|
+
search_mode = "GPU-accelerated" if has_gpu else "CPU"
|
|
154
|
+
|
|
155
|
+
# Prepare filter
|
|
156
|
+
filter_dict = None
|
|
157
|
+
if paper_ids:
|
|
158
|
+
filter_dict = {"paper_id": paper_ids}
|
|
159
|
+
|
|
160
|
+
logger.info(
|
|
161
|
+
"Performing %s similarity search with scores: query='%s', k=%d, threshold=%.3f",
|
|
162
|
+
search_mode,
|
|
163
|
+
query[:50] + "..." if len(query) > 50 else query,
|
|
164
|
+
top_k,
|
|
165
|
+
score_threshold,
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
# Check hardware optimization status instead of unused search_params
|
|
169
|
+
has_optimization = hasattr(vector_store, "has_gpu") and vector_store.has_gpu
|
|
170
|
+
|
|
171
|
+
if has_optimization:
|
|
172
|
+
logger.debug("GPU-accelerated similarity search enabled")
|
|
173
|
+
else:
|
|
174
|
+
logger.debug("Standard CPU similarity search")
|
|
175
|
+
|
|
176
|
+
if hasattr(vector_store, "similarity_search_with_score"):
|
|
177
|
+
# Don't pass search_params to avoid conflicts
|
|
178
|
+
results = vector_store.similarity_search_with_score(
|
|
179
|
+
query=query,
|
|
180
|
+
k=top_k,
|
|
181
|
+
filter=filter_dict,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# Filter by score threshold
|
|
185
|
+
filtered_results = [(doc, score) for doc, score in results if score >= score_threshold]
|
|
186
|
+
|
|
187
|
+
logger.info(
|
|
188
|
+
"%s search with scores retrieved %d/%d chunks above threshold %.3f",
|
|
189
|
+
search_mode,
|
|
190
|
+
len(filtered_results),
|
|
191
|
+
len(results),
|
|
192
|
+
score_threshold,
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
return filtered_results
|
|
196
|
+
|
|
197
|
+
raise NotImplementedError("Vector store does not support similarity_search_with_score")
|