Spaces:
Sleeping
Sleeping
geekyrakshit
commited on
Commit
·
d197e7f
1
Parent(s):
abd20d0
add: MultiModalRetriever.predict
Browse files
docs/retreival/multi_modal_retrieval.md
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
# Multi-Modal Retrieval
|
2 |
+
|
3 |
+
::: medrag_multi_modal.retrieval.multi_modal_retrieval
|
medrag_multi_modal/document_loader/load_image.py
CHANGED
@@ -3,11 +3,11 @@ import os
|
|
3 |
from typing import Optional
|
4 |
|
5 |
import rich
|
6 |
-
import wandb
|
7 |
import weave
|
8 |
from pdf2image.pdf2image import convert_from_path
|
9 |
from PIL import Image
|
10 |
|
|
|
11 |
from medrag_multi_modal.document_loader.load_text import TextLoader
|
12 |
|
13 |
|
|
|
3 |
from typing import Optional
|
4 |
|
5 |
import rich
|
|
|
6 |
import weave
|
7 |
from pdf2image.pdf2image import convert_from_path
|
8 |
from PIL import Image
|
9 |
|
10 |
+
import wandb
|
11 |
from medrag_multi_modal.document_loader.load_text import TextLoader
|
12 |
|
13 |
|
medrag_multi_modal/retrieval/multi_modal_retrieval.py
CHANGED
@@ -1,28 +1,104 @@
|
|
1 |
import os
|
|
|
2 |
|
3 |
-
import wandb
|
4 |
import weave
|
5 |
from byaldi import RAGMultiModalModel
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
|
8 |
class MultiModalRetriever(weave.Model):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
model_name: str
|
10 |
-
_docs_retrieval_model: RAGMultiModalModel
|
|
|
|
|
11 |
|
12 |
-
def __init__(
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
super().__init__(model_name=model_name)
|
14 |
-
self._docs_retrieval_model =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
def index(self, data_artifact_name: str, weave_dataset_name: str, index_name: str):
|
17 |
-
|
18 |
-
artifact = wandb.use_artifact(data_artifact_name, type="dataset")
|
19 |
-
artifact_dir = artifact.download()
|
20 |
-
else:
|
21 |
-
api = wandb.Api()
|
22 |
-
artifact = api.artifact(data_artifact_name)
|
23 |
-
artifact_dir = artifact.download()
|
24 |
self._docs_retrieval_model.index(
|
25 |
-
input_path=
|
26 |
index_name=index_name,
|
27 |
store_collection_with_index=False,
|
28 |
overwrite=True,
|
@@ -37,3 +113,37 @@ class MultiModalRetriever(weave.Model):
|
|
37 |
local_path=os.path.join(".byaldi", index_name), name="index"
|
38 |
)
|
39 |
artifact.save()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import os
|
2 |
+
from typing import Any, Optional
|
3 |
|
|
|
4 |
import weave
|
5 |
from byaldi import RAGMultiModalModel
|
6 |
+
from PIL import Image
|
7 |
+
|
8 |
+
import wandb
|
9 |
+
|
10 |
+
from ..utils import get_wandb_artifact
|
11 |
|
12 |
|
13 |
class MultiModalRetriever(weave.Model):
|
14 |
+
"""
|
15 |
+
MultiModalRetriever is a class that facilitates the retrieval of page images using ColPali.
|
16 |
+
|
17 |
+
This class leverages the `byaldi.RAGMultiModalModel` to perform document retrieval tasks.
|
18 |
+
It can be initialized with a pre-trained model or from a specified W&B artifact. The class
|
19 |
+
also provides methods to index new data and to predict/retrieve documents based on a query.
|
20 |
+
|
21 |
+
!!! example "Indexing Data"
|
22 |
+
```python
|
23 |
+
import wandb
|
24 |
+
from medrag_multi_modal.retrieval import MultiModalRetriever
|
25 |
+
|
26 |
+
wandb.init(project="medrag-multi-modal", entity="ml-colabs", job_type="index")
|
27 |
+
retriever = MultiModalRetriever()
|
28 |
+
retriever.index(
|
29 |
+
data_artifact_name="ml-colabs/medrag-multi-modal/grays-anatomy-images:v1",
|
30 |
+
weave_dataset_name="grays-anatomy-images:v0",
|
31 |
+
index_name="grays-anatomy",
|
32 |
+
)
|
33 |
+
```
|
34 |
+
|
35 |
+
!!! example "Retrieving Documents"
|
36 |
+
```python
|
37 |
+
import weave
|
38 |
+
|
39 |
+
import wandb
|
40 |
+
from medrag_multi_modal.retrieval import MultiModalRetriever
|
41 |
+
|
42 |
+
weave.init(project_name="ml-colabs/medrag-multi-modal")
|
43 |
+
retriever = MultiModalRetriever.from_artifact(
|
44 |
+
index_artifact_name="ml-colabs/medrag-multi-modal/grays-anatomy:v0",
|
45 |
+
metadata_dataset_name="grays-anatomy-images:v0",
|
46 |
+
data_artifact_name="ml-colabs/medrag-multi-modal/grays-anatomy-images:v1",
|
47 |
+
)
|
48 |
+
retriever.predict(
|
49 |
+
query="which neurotransmitters convey information between Merkel cells and sensory afferents?",
|
50 |
+
top_k=3,
|
51 |
+
)
|
52 |
+
```
|
53 |
+
|
54 |
+
Attributes:
|
55 |
+
model_name (str): The name of the model to be used for retrieval.
|
56 |
+
"""
|
57 |
model_name: str
|
58 |
+
_docs_retrieval_model: Optional[RAGMultiModalModel] = None
|
59 |
+
_metadata: Optional[dict] = None
|
60 |
+
_data_artifact_dir: Optional[str] = None
|
61 |
|
62 |
+
def __init__(
|
63 |
+
self,
|
64 |
+
model_name: str = "vidore/colpali-v1.2",
|
65 |
+
docs_retrieval_model: Optional[RAGMultiModalModel] = None,
|
66 |
+
data_artifact_dir: Optional[str] = None,
|
67 |
+
metadata_dataset_name: Optional[str] = None,
|
68 |
+
):
|
69 |
super().__init__(model_name=model_name)
|
70 |
+
self._docs_retrieval_model = (
|
71 |
+
docs_retrieval_model or RAGMultiModalModel.from_pretrained(self.model_name)
|
72 |
+
)
|
73 |
+
self._data_artifact_dir = data_artifact_dir
|
74 |
+
self._metadata = (
|
75 |
+
[dict(row) for row in weave.ref(metadata_dataset_name).get().rows]
|
76 |
+
if metadata_dataset_name
|
77 |
+
else None
|
78 |
+
)
|
79 |
+
|
80 |
+
@classmethod
|
81 |
+
def from_artifact(
|
82 |
+
cls,
|
83 |
+
index_artifact_name: str,
|
84 |
+
metadata_dataset_name: str,
|
85 |
+
data_artifact_name: str,
|
86 |
+
):
|
87 |
+
index_artifact_dir = get_wandb_artifact(index_artifact_name, "colpali-index")
|
88 |
+
data_artifact_dir = get_wandb_artifact(data_artifact_name, "dataset")
|
89 |
+
docs_retrieval_model = RAGMultiModalModel.from_index(
|
90 |
+
index_path=os.path.join(index_artifact_dir, "index")
|
91 |
+
)
|
92 |
+
return cls(
|
93 |
+
docs_retrieval_model=docs_retrieval_model,
|
94 |
+
metadata_dataset_name=metadata_dataset_name,
|
95 |
+
data_artifact_dir=data_artifact_dir,
|
96 |
+
)
|
97 |
|
98 |
def index(self, data_artifact_name: str, weave_dataset_name: str, index_name: str):
|
99 |
+
data_artifact_dir = get_wandb_artifact(data_artifact_name, "dataset")
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
self._docs_retrieval_model.index(
|
101 |
+
input_path=data_artifact_dir,
|
102 |
index_name=index_name,
|
103 |
store_collection_with_index=False,
|
104 |
overwrite=True,
|
|
|
113 |
local_path=os.path.join(".byaldi", index_name), name="index"
|
114 |
)
|
115 |
artifact.save()
|
116 |
+
|
117 |
+
@weave.op()
|
118 |
+
def predict(self, query: str, top_k: int = 3) -> list[dict[str, Any]]:
|
119 |
+
"""
|
120 |
+
Predicts and retrieves the top-k most relevant documents/images for a given query
|
121 |
+
using ColPali.
|
122 |
+
|
123 |
+
This function uses the document retrieval model to search for the most relevant
|
124 |
+
documents based on the provided query. It returns a list of dictionaries, each
|
125 |
+
containing the document image, document ID, and the relevance score.
|
126 |
+
|
127 |
+
Args:
|
128 |
+
query (str): The search query string.
|
129 |
+
top_k (int, optional): The number of top results to retrieve. Defaults to 10.
|
130 |
+
|
131 |
+
Returns:
|
132 |
+
list[dict[str, Any]]: A list of dictionaries where each dictionary contains:
|
133 |
+
- "doc_image" (PIL.Image.Image): The image of the document.
|
134 |
+
- "doc_id" (str): The ID of the document.
|
135 |
+
- "score" (float): The relevance score of the document.
|
136 |
+
"""
|
137 |
+
results = self._docs_retrieval_model.search(query=query, k=top_k)
|
138 |
+
retrieved_results = []
|
139 |
+
for result in results:
|
140 |
+
retrieved_results.append(
|
141 |
+
{
|
142 |
+
"doc_image": Image.open(
|
143 |
+
os.path.join(self._data_artifact_dir, f"{result['doc_id']}.png")
|
144 |
+
),
|
145 |
+
"doc_id": result["doc_id"],
|
146 |
+
"score": result["score"],
|
147 |
+
}
|
148 |
+
)
|
149 |
+
return retrieved_results
|
medrag_multi_modal/utils.py
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import wandb
|
2 |
+
|
3 |
+
|
4 |
+
def get_wandb_artifact(artifact_name: str, artifact_type: str) -> str:
|
5 |
+
if wandb.run:
|
6 |
+
artifact = wandb.use_artifact(artifact_name, type=artifact_type)
|
7 |
+
artifact_dir = artifact.download()
|
8 |
+
else:
|
9 |
+
api = wandb.Api()
|
10 |
+
artifact = api.artifact(artifact_name)
|
11 |
+
artifact_dir = artifact.download()
|
12 |
+
return artifact_dir
|
mkdocs.yml
CHANGED
@@ -66,5 +66,7 @@ nav:
|
|
66 |
- Text Loader: 'document_loader/load_text.md'
|
67 |
- Text and Image Loader: 'document_loader/load_text_image.md'
|
68 |
- Image Loader: 'document_loader/load_image.md'
|
|
|
|
|
69 |
|
70 |
-
repo_url: https://github.com/soumik12345/medrag-multi-modal
|
|
|
66 |
- Text Loader: 'document_loader/load_text.md'
|
67 |
- Text and Image Loader: 'document_loader/load_text_image.md'
|
68 |
- Image Loader: 'document_loader/load_image.md'
|
69 |
+
- Retrieval:
|
70 |
+
- Multi-Modal Retrieval: 'retreival/multi_modal_retrieval.md'
|
71 |
|
72 |
+
repo_url: https://github.com/soumik12345/medrag-multi-modal
|