visual-rag-toolkit 0.1.2__py3-none-any.whl → 0.1.3__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.
- demo/app.py +20 -8
- demo/evaluation.py +5 -45
- demo/indexing.py +180 -221
- demo/qdrant_utils.py +12 -5
- demo/ui/playground.py +1 -1
- demo/ui/sidebar.py +4 -3
- demo/ui/upload.py +5 -4
- visual_rag/__init__.py +43 -1
- visual_rag/config.py +4 -7
- visual_rag/indexing/__init__.py +21 -4
- visual_rag/indexing/qdrant_indexer.py +92 -42
- visual_rag/retrieval/multi_vector.py +63 -65
- visual_rag/retrieval/single_stage.py +7 -0
- visual_rag/retrieval/two_stage.py +8 -10
- {visual_rag_toolkit-0.1.2.dist-info → visual_rag_toolkit-0.1.3.dist-info}/METADATA +24 -15
- {visual_rag_toolkit-0.1.2.dist-info → visual_rag_toolkit-0.1.3.dist-info}/RECORD +19 -19
- {visual_rag_toolkit-0.1.2.dist-info → visual_rag_toolkit-0.1.3.dist-info}/WHEEL +0 -0
- {visual_rag_toolkit-0.1.2.dist-info → visual_rag_toolkit-0.1.3.dist-info}/entry_points.txt +0 -0
- {visual_rag_toolkit-0.1.2.dist-info → visual_rag_toolkit-0.1.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -17,11 +17,17 @@ Research Context:
|
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
19
|
import logging
|
|
20
|
+
import time
|
|
20
21
|
from typing import Any, Dict, List, Optional, Union
|
|
21
22
|
|
|
22
23
|
import numpy as np
|
|
23
24
|
import torch
|
|
24
25
|
|
|
26
|
+
from qdrant_client.http import models as qdrant_models
|
|
27
|
+
from qdrant_client.models import FieldCondition, Filter, MatchAny, MatchValue
|
|
28
|
+
|
|
29
|
+
from visual_rag.embedding.pooling import compute_maxsim_score
|
|
30
|
+
|
|
25
31
|
logger = logging.getLogger(__name__)
|
|
26
32
|
|
|
27
33
|
|
|
@@ -82,8 +88,6 @@ class TwoStageRetriever:
|
|
|
82
88
|
self.retry_sleep = float(retry_sleep)
|
|
83
89
|
|
|
84
90
|
def _retry_call(self, fn):
|
|
85
|
-
import time
|
|
86
|
-
|
|
87
91
|
last_err = None
|
|
88
92
|
for attempt in range(self.max_retries):
|
|
89
93
|
try:
|
|
@@ -120,8 +124,6 @@ class TwoStageRetriever:
|
|
|
120
124
|
Returns:
|
|
121
125
|
List of results with scores
|
|
122
126
|
"""
|
|
123
|
-
from qdrant_client.http import models
|
|
124
|
-
|
|
125
127
|
query_np = self._to_numpy(query_embedding)
|
|
126
128
|
|
|
127
129
|
if prefetch_k is None:
|
|
@@ -155,9 +157,9 @@ class TwoStageRetriever:
|
|
|
155
157
|
limit=top_k,
|
|
156
158
|
query_filter=filter_obj,
|
|
157
159
|
with_payload=True,
|
|
158
|
-
search_params=
|
|
160
|
+
search_params=qdrant_models.SearchParams(exact=True),
|
|
159
161
|
prefetch=[
|
|
160
|
-
|
|
162
|
+
qdrant_models.Prefetch(
|
|
161
163
|
query=prefetch_query,
|
|
162
164
|
using=prefetch_using,
|
|
163
165
|
limit=prefetch_k,
|
|
@@ -363,8 +365,6 @@ class TwoStageRetriever:
|
|
|
363
365
|
return_embeddings: bool = False,
|
|
364
366
|
) -> List[Dict[str, Any]]:
|
|
365
367
|
"""Stage 2: Rerank with full multi-vector MaxSim scoring."""
|
|
366
|
-
from visual_rag.embedding.pooling import compute_maxsim_score
|
|
367
|
-
|
|
368
368
|
# Fetch full embeddings for candidates
|
|
369
369
|
candidate_ids = [c["id"] for c in candidates]
|
|
370
370
|
|
|
@@ -435,8 +435,6 @@ class TwoStageRetriever:
|
|
|
435
435
|
|
|
436
436
|
Supports single values or lists (using MatchAny).
|
|
437
437
|
"""
|
|
438
|
-
from qdrant_client.models import FieldCondition, Filter, MatchAny, MatchValue
|
|
439
|
-
|
|
440
438
|
conditions = []
|
|
441
439
|
|
|
442
440
|
if year is not None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: visual-rag-toolkit
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: End-to-end visual document retrieval with ColPali, featuring two-stage pooling for scalable search
|
|
5
5
|
Project-URL: Homepage, https://github.com/Ara-Yeroyan/visual-rag-toolkit
|
|
6
6
|
Project-URL: Documentation, https://github.com/Ara-Yeroyan/visual-rag-toolkit#readme
|
|
@@ -88,11 +88,6 @@ Description-Content-Type: text/markdown
|
|
|
88
88
|
[](https://pypi.org/project/visual-rag-toolkit/)
|
|
89
89
|
[](https://pypi.org/project/visual-rag-toolkit/)
|
|
90
90
|
[](LICENSE)
|
|
91
|
-
[](https://github.com/Ara-Yeroyan/visual-rag-toolkit/actions/workflows/ci.yaml)
|
|
92
|
-
|
|
93
|
-
Note:
|
|
94
|
-
- The **PyPI badge** shows “not found” until the first release is published.
|
|
95
|
-
- The **CI badge** requires the GitHub repo to be **public** (GitHub does not serve Actions badges for private repos).
|
|
96
91
|
|
|
97
92
|
End-to-end visual document retrieval toolkit featuring **fast multi-stage retrieval** (prefetch with pooled vectors + exact MaxSim reranking).
|
|
98
93
|
|
|
@@ -162,7 +157,7 @@ for r in results[:3]:
|
|
|
162
157
|
|
|
163
158
|
### End-to-end: ingest PDFs (with cropping) → index in Qdrant
|
|
164
159
|
|
|
165
|
-
This is the
|
|
160
|
+
This is the "SDK-style" pipeline: PDF → images → optional crop → embed → store vectors + payload in Qdrant.
|
|
166
161
|
|
|
167
162
|
```python
|
|
168
163
|
import os
|
|
@@ -174,8 +169,8 @@ import torch
|
|
|
174
169
|
from visual_rag import VisualEmbedder
|
|
175
170
|
from visual_rag.indexing import ProcessingPipeline, QdrantIndexer
|
|
176
171
|
|
|
177
|
-
QDRANT_URL = os.environ["
|
|
178
|
-
QDRANT_KEY = os.getenv("
|
|
172
|
+
QDRANT_URL = os.environ["QDRANT_URL"]
|
|
173
|
+
QDRANT_KEY = os.getenv("QDRANT_API_KEY", "")
|
|
179
174
|
|
|
180
175
|
collection = "my_visual_docs"
|
|
181
176
|
|
|
@@ -193,6 +188,8 @@ indexer = QdrantIndexer(
|
|
|
193
188
|
prefer_grpc=True,
|
|
194
189
|
vector_datatype="float16",
|
|
195
190
|
)
|
|
191
|
+
|
|
192
|
+
# Creates collection + required payload indexes (e.g., "filename" for skip_existing)
|
|
196
193
|
indexer.create_collection(force_recreate=False)
|
|
197
194
|
|
|
198
195
|
pipeline = ProcessingPipeline(
|
|
@@ -208,19 +205,32 @@ pipeline = ProcessingPipeline(
|
|
|
208
205
|
|
|
209
206
|
pdfs = [Path("docs/a.pdf"), Path("docs/b.pdf")]
|
|
210
207
|
for pdf_path in pdfs:
|
|
211
|
-
pipeline.process_pdf(
|
|
208
|
+
result = pipeline.process_pdf(
|
|
212
209
|
pdf_path,
|
|
213
|
-
skip_existing=True,
|
|
210
|
+
skip_existing=True, # Skip pages already in Qdrant (uses filename index)
|
|
214
211
|
upload_to_cloudinary=False,
|
|
215
212
|
upload_to_qdrant=True,
|
|
216
213
|
)
|
|
214
|
+
# Logs automatically shown:
|
|
215
|
+
# [10:23:45] 📚 Processing PDF: a.pdf
|
|
216
|
+
# [10:23:45] 🖼️ Converting PDF to images...
|
|
217
|
+
# [10:23:46] ✅ Converted 12 pages
|
|
218
|
+
# [10:23:46] 📦 Processing pages 1-8/12
|
|
219
|
+
# [10:23:46] 🤖 Generating embeddings for 8 pages...
|
|
220
|
+
# [10:23:48] 📤 Uploading batch of 8 pages...
|
|
221
|
+
# [10:23:48] ✅ Uploaded 8 points to Qdrant
|
|
222
|
+
# [10:23:48] 📦 Processing pages 9-12/12
|
|
223
|
+
# [10:23:48] 🤖 Generating embeddings for 4 pages...
|
|
224
|
+
# [10:23:50] 📤 Uploading batch of 4 pages...
|
|
225
|
+
# [10:23:50] ✅ Uploaded 4 points to Qdrant
|
|
226
|
+
# [10:23:50] ✅ Completed a.pdf: 12 uploaded, 0 skipped, 0 failed
|
|
217
227
|
```
|
|
218
228
|
|
|
219
229
|
CLI equivalent:
|
|
220
230
|
|
|
221
231
|
```bash
|
|
222
|
-
export
|
|
223
|
-
export
|
|
232
|
+
export QDRANT_URL="https://YOUR_QDRANT"
|
|
233
|
+
export QDRANT_API_KEY="YOUR_KEY"
|
|
224
234
|
|
|
225
235
|
visual-rag process \
|
|
226
236
|
--reports-dir ./docs \
|
|
@@ -263,7 +273,7 @@ Stage 2: Exact MaxSim reranking on candidates
|
|
|
263
273
|
└── Return top-k results (e.g., 10)
|
|
264
274
|
```
|
|
265
275
|
|
|
266
|
-
Three-stage extends this with an additional
|
|
276
|
+
Three-stage extends this with an additional "cheap prefetch" stage before stage 2.
|
|
267
277
|
|
|
268
278
|
## 📁 Package Structure
|
|
269
279
|
|
|
@@ -374,4 +384,3 @@ MIT License - see [LICENSE](LICENSE) for details.
|
|
|
374
384
|
- [Qdrant](https://qdrant.tech/) - Vector database with multi-vector support
|
|
375
385
|
- [ColPali](https://github.com/illuin-tech/colpali) - Visual document retrieval models
|
|
376
386
|
- [ViDoRe](https://huggingface.co/spaces/vidore/vidore-leaderboard) - Benchmark dataset
|
|
377
|
-
|
|
@@ -12,24 +12,24 @@ benchmarks/vidore_tatdqa_test/metrics.py,sha256=cLdYbRt5VcxInO1cN79ve6ZLP3kaSxRk
|
|
|
12
12
|
benchmarks/vidore_tatdqa_test/run_qdrant.py,sha256=_PikeqIYpWPim-KEQOwvT-aqwYoAWASjqJVisi8PfQg,28681
|
|
13
13
|
benchmarks/vidore_tatdqa_test/sweep_eval.py,sha256=d_kbyNTJ1LoFfIVnsZyiRO1nKyMqmRB5jEweZL6kYd4,12688
|
|
14
14
|
demo/__init__.py,sha256=jVzjsVKZl5ZZuFxawA8Pxj3yuIKL7llkao3rBpde-aQ,204
|
|
15
|
-
demo/app.py,sha256=
|
|
15
|
+
demo/app.py,sha256=nZbCz1mpRK-GZTgOHyz4m4AfgKFgsH-09JwXeL3d3ng,1405
|
|
16
16
|
demo/commands.py,sha256=qxRE2x610yZvcjwEfSKiR9CyFonX-vRxFqQNJCUKfyA,13690
|
|
17
17
|
demo/config.py,sha256=BNkV4NSEEMIV9e6Z-cxds2v247uVmTPCgL-M5ItPzMg,757
|
|
18
18
|
demo/download_models.py,sha256=J10qQt2TpEshVOxvCX_ZSbV7YozIBqDATZnt8fUKFHs,2868
|
|
19
|
-
demo/evaluation.py,sha256=
|
|
19
|
+
demo/evaluation.py,sha256=4ixJGg50KAVNiZ_mr5FMVv-QKCrZRooJ80LbrjKXM1s,27467
|
|
20
20
|
demo/example_metadata_mapping_sigir.json,sha256=UCgqZtr6Wnq_vS7zxPxpvuokk9gxOVgKydC7f1lauw8,824
|
|
21
|
-
demo/indexing.py,sha256=
|
|
22
|
-
demo/qdrant_utils.py,sha256=
|
|
21
|
+
demo/indexing.py,sha256=qUVEB3QrIolS53Ggxurccbh-QyeLLbzcY5TLyVBVKME,10620
|
|
22
|
+
demo/qdrant_utils.py,sha256=Xh-thLIrACrYkFCrqazYNH0p3vS8_yMCaTbvt4HAy98,7778
|
|
23
23
|
demo/results.py,sha256=dprvxnyHwxJvkAQuh4deaCsiEG1wm0n9svPyxI37vJg,1050
|
|
24
24
|
demo/test_qdrant_connection.py,sha256=hkbyl3zGsw_GdBBp5MkW_3SBKTHXbwH3Sr_pUE54_po,3866
|
|
25
25
|
demo/ui/__init__.py,sha256=EyBCvnXYfPbdyxJzyp9TjQBeJJUgmOY1yRHkUeC6JFQ,412
|
|
26
26
|
demo/ui/benchmark.py,sha256=HiGCN4HrqeOC7L6t2kuzIiyWdcVE_cP2JTxoewrmPSo,14218
|
|
27
27
|
demo/ui/header.py,sha256=J2hXr_nNyg1H9rmrd-EGx3WUl7lYo-Ca30ptgzBCfBs,806
|
|
28
|
-
demo/ui/playground.py,sha256=
|
|
29
|
-
demo/ui/sidebar.py,sha256=
|
|
30
|
-
demo/ui/upload.py,sha256=
|
|
31
|
-
visual_rag/__init__.py,sha256=
|
|
32
|
-
visual_rag/config.py,sha256=
|
|
28
|
+
demo/ui/playground.py,sha256=yRlWWzJgsc596vALn5f0PHhmhtJCMmfv61nYakW75GQ,13672
|
|
29
|
+
demo/ui/sidebar.py,sha256=DLVhEj-8xAJCXUwOhndNv8ZFT4K3u8iE6FVOoH-jRuA,7699
|
|
30
|
+
demo/ui/upload.py,sha256=6iv4xDsacMtUF1FrquRBE_xNb92HevgxCMS0LBK4Ay0,20455
|
|
31
|
+
visual_rag/__init__.py,sha256=4NksVCaN_p32ezMF1N-oxpPFKeOm8xRo70VC4OSa2a0,3911
|
|
32
|
+
visual_rag/config.py,sha256=qqSQk2lM5MiRji-6xQNGS2gSiXA4NgyJnCbgGx7uGJQ,7395
|
|
33
33
|
visual_rag/demo_runner.py,sha256=wi0Wz3gZ39l4aovMd6zURq_CKUSgma4kGjF6hpQHwGY,2793
|
|
34
34
|
visual_rag/qdrant_admin.py,sha256=NNczko2S5-K3qATNUxgYn51hNWgWb6boheL7vlCQGpM,7055
|
|
35
35
|
visual_rag/cli/__init__.py,sha256=WgBRXm0VACfLltvVlLcSs3FTM1uQ7Uuw3CVD4-zWZwc,46
|
|
@@ -37,22 +37,22 @@ visual_rag/cli/main.py,sha256=QmpnQ0lbC6Q9lwxaSCDh6paEEzI78IPY1jwc3_9y7VI,21083
|
|
|
37
37
|
visual_rag/embedding/__init__.py,sha256=7QIENmxwRnwnUzsYKRY3VQTyF3HJkRiL1D7Au9XHF0w,682
|
|
38
38
|
visual_rag/embedding/pooling.py,sha256=x8uY4VHbxEnsJRM2JeOkzPHDiwOkbi5NK4XW21U1hAc,11401
|
|
39
39
|
visual_rag/embedding/visual_embedder.py,sha256=he9JpVHmo_szOiXCwtJdrCseGmf2y5Gi0UEFjwazzVY,23198
|
|
40
|
-
visual_rag/indexing/__init__.py,sha256=
|
|
40
|
+
visual_rag/indexing/__init__.py,sha256=rloBEBt3x8BQut1Tj1n8fuaQ3iXMS3pm64o8n-NlSAw,985
|
|
41
41
|
visual_rag/indexing/cloudinary_uploader.py,sha256=e-G5du4D7z6mWWl2lahMidG-Wdc-baImFFILTojebpA,8826
|
|
42
42
|
visual_rag/indexing/pdf_processor.py,sha256=V3RAKpwgIFicqUaXzaaljePxh_oP4UV5W0aiJyfv0BY,10247
|
|
43
43
|
visual_rag/indexing/pipeline.py,sha256=1ScpVRlLCq2FWi3IPvlQcIfDCQQ2F64IlRd9ZZHiTaA,25037
|
|
44
|
-
visual_rag/indexing/qdrant_indexer.py,sha256=
|
|
44
|
+
visual_rag/indexing/qdrant_indexer.py,sha256=Q0e8JCr9B1OxgOMW7BWeg7MlWiLPaBUmjoFof4gZFYo,19519
|
|
45
45
|
visual_rag/preprocessing/__init__.py,sha256=rCzfBO0jaVKp6MpPRRused_4gasHfobAbG-139Y806E,121
|
|
46
46
|
visual_rag/preprocessing/crop_empty.py,sha256=iHXITFkRlF40VPJ4k9d432RUAi_89BhAEvK4wOEn96Q,5211
|
|
47
47
|
visual_rag/retrieval/__init__.py,sha256=J9pnbeB83Fqs9n4g3GcIp1VR9dnuyAlcsIDVsf0lSb8,601
|
|
48
|
-
visual_rag/retrieval/multi_vector.py,sha256=
|
|
49
|
-
visual_rag/retrieval/single_stage.py,sha256=
|
|
48
|
+
visual_rag/retrieval/multi_vector.py,sha256=ZZ_O4x7MZbhF--kRp8T4UJG5GuenfjJ91FKicklhK3Q,7006
|
|
49
|
+
visual_rag/retrieval/single_stage.py,sha256=Ba06V-KRSFSZm0xzbjFR3EBEWaQkDo7U_pWNx25W8H0,4425
|
|
50
50
|
visual_rag/retrieval/three_stage.py,sha256=YC0CVEohxTT5zhilcQHI7nYAk08E5jC3zkQ3-rNdLMw,5951
|
|
51
|
-
visual_rag/retrieval/two_stage.py,sha256=
|
|
51
|
+
visual_rag/retrieval/two_stage.py,sha256=JJ6rXv_3_3WLIjAcxOY7NuhSyuPzIMyHf3ooiGFTp9k,16776
|
|
52
52
|
visual_rag/visualization/__init__.py,sha256=SITKNvBEseDp7F3K6UzLPA-6OQFqYfY5azS5nlDdihQ,447
|
|
53
53
|
visual_rag/visualization/saliency.py,sha256=F3Plc18Sf3tzWcyncuaruTmENm1IfW5j9NFGEQR93cY,11248
|
|
54
|
-
visual_rag_toolkit-0.1.
|
|
55
|
-
visual_rag_toolkit-0.1.
|
|
56
|
-
visual_rag_toolkit-0.1.
|
|
57
|
-
visual_rag_toolkit-0.1.
|
|
58
|
-
visual_rag_toolkit-0.1.
|
|
54
|
+
visual_rag_toolkit-0.1.3.dist-info/METADATA,sha256=IQaXJV0GkBuRZG5JTkFA-Zv6pboaAeoWoQIeWzu7-Z4,13180
|
|
55
|
+
visual_rag_toolkit-0.1.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
56
|
+
visual_rag_toolkit-0.1.3.dist-info/entry_points.txt,sha256=6Tob1GPg_ILGELjYTPsAnNMZ1W0NS939nfI7xyW2DIY,102
|
|
57
|
+
visual_rag_toolkit-0.1.3.dist-info/licenses/LICENSE,sha256=hEg_weKnHXJakQRR3sw2ygcZ101zCI00zMhBOPb3yfA,1069
|
|
58
|
+
visual_rag_toolkit-0.1.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|