Adityapande403 commited on
Commit
4d0bdb1
·
verified ·
1 Parent(s): 8c1ee89

feat: upload VisDoc-AI model card, projection weights, and benchmark reports

Browse files
README.md CHANGED
@@ -1,3 +1,87 @@
1
- ---
2
- license: mit
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language:
3
+ - en
4
+ license: mit
5
+ library_name: colpali-engine
6
+ tags:
7
+ - colpali
8
+ - colqwen
9
+ - multi-vector
10
+ - late-interaction
11
+ - visual-document-retrieval
12
+ - document-ai
13
+ - quantization
14
+ - maxsim
15
+ base_model: vidore/colqwen2.5-v0.2
16
+ pipeline_tag: feature-extraction
17
+ ---
18
+
19
+ # VisDoc AI: Multimodal Visual Document Retrieval with Late Interaction & Quantization
20
+
21
+ **VisDoc AI** is a visual document retrieval engine built on Vision-Language Models (`ColQwen2.5` / `ColPali`) and multi-vector late-interaction MaxSim scoring.
22
+
23
+ It indexes and searches complex visual documents—**engineering datasheets, electrical schematics, PCB diagrams, financial balance sheets, commercial invoices, and stamped inspection certificates**—without OCR-based text chunking.
24
+
25
+ - **GitHub Repository**: [https://github.com/adityapande403/VisDoc-AI](https://github.com/adityapande403/VisDoc-AI)
26
+ - **Base Architecture**: `vidore/colqwen2.5-v0.2` (`Qwen/Qwen2.5-VL-3B-Instruct` backbone)
27
+ - **Output Representation**: Multi-vector token embeddings with dimension $D = 128$ and unit L2-normalization.
28
+ - **Scoring Function**: MaxSim Late Interaction:
29
+ $$S(Q, D) = \sum_{i=1}^{N_q} M_{q, i} \max_{j \in D} (q_i \cdot d_j)$$
30
+
31
+ ---
32
+
33
+ ## Benchmark Results (Empirically Measured)
34
+
35
+ ### 1. Retrieval Quality & Compression Retention (Held-Out Test Set)
36
+
37
+ | Representation | NDCG@5 | MRR@10 | Recall@5 | Relative NDCG@5 Retention | Embedding Payload | Compression vs FP16 |
38
+ | :--- | :---: | :---: | :---: | :---: | :---: | :---: |
39
+ | **FP16 Baseline** | 0.5132 | 0.4361 | 0.8333 | **100.0%** (Baseline) | 0.09 MB | 1.0x |
40
+ | **INT8 Scalar** | 0.5132 | 0.4361 | 0.8333 | **100.0%** | 0.05 MB | **2.0x** |
41
+ | **1-Bit Binary** | 0.3747 | 0.2556 | 0.8333 | **73.0%** | 0.01 MB | **16.0x** (32x vs FP32) |
42
+
43
+ ### 2. 10,000-Page Scale Benchmark (5,000,000 Multi-Vectors)
44
+
45
+ | Index Format | Total Indexed Pages | Embedding Memory (MB) | Compression vs FP16 | Mean Latency (ms) | P95 Latency (ms) | Throughput (QPS) |
46
+ | :--- | :---: | :---: | :---: | :---: | :---: | :---: |
47
+ | **FP16** | 10,000 | 1,220.7 MB | 1.0x | 2,028.90 ms | 2,135.90 ms | 0.5 |
48
+ | **INT8** | 10,000 | 610.4 MB | **2.0x** | 3,013.15 ms | 3,083.47 ms | 0.3 |
49
+ | **BINARY** | 10,000 | **76.3 MB** | **16.0x** | 2,770.02 ms | 2,890.07 ms | 0.4 |
50
+
51
+ *Two-stage candidate filtering reduces 1,000-page latency from 253.26 ms to **10.69 ms** (23.7x acceleration).*
52
+
53
+ ---
54
+
55
+ ## Quickstart
56
+
57
+ ```python
58
+ from visdoc import VisualDocumentRetriever
59
+
60
+ # Initialize with INT8 compressed index (100% NDCG@5 retention, 2x memory reduction)
61
+ retriever = VisualDocumentRetriever(index_format="int8")
62
+
63
+ # Ingest and index PDF document pages
64
+ retriever.index_documents(paths=["./datasheet.pdf"])
65
+
66
+ # Run late-interaction visual search
67
+ results = retriever.search(
68
+ query="Which pin provides the 5.0 V analog sensor supply on the TX-4000?",
69
+ top_k=5,
70
+ )
71
+
72
+ for result in results:
73
+ print(f"Document: {result.document_id} | Page: {result.page_number} | Score: {result.score:.4f}")
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Citation & Reference
79
+
80
+ ```bibtex
81
+ @software{visdoc_ai_2026,
82
+ author = {Aditya Pande},
83
+ title = {VisDoc AI: Multimodal Visual Document Retrieval with ColPali, ColQwen and Late Interaction},
84
+ url = {https://github.com/adityapande403/VisDoc-AI},
85
+ year = {2026}
86
+ }
87
+ ```
config.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "ColQwen2_5"
4
+ ],
5
+ "model_type": "colqwen2_5",
6
+ "base_model": "vidore/colqwen2.5-v0.2",
7
+ "embedding_dim": 128,
8
+ "projection_dim": 128,
9
+ "torch_dtype": "bfloat16",
10
+ "similarity_metric": "maxsim",
11
+ "quantization_schemes": [
12
+ "fp16",
13
+ "int8",
14
+ "binary"
15
+ ],
16
+ "version": "0.1.0"
17
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4df5e9412d8d8f9207cb79a2e82904c183ec8b5d1013e36f66a097424de509a4
3
+ size 1049264
retrieval_benchmark.json ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fp16": {
3
+ "format": "fp16",
4
+ "metrics": {
5
+ "ndcg@5": 0.5132314787418083,
6
+ "mrr@10": 0.4361111111111111,
7
+ "recall@1": 0.16666666666666666,
8
+ "recall@5": 0.8333333333333334,
9
+ "recall@10": 1.0,
10
+ "recall@20": 1.0,
11
+ "evaluated_queries": 6
12
+ },
13
+ "retention": 1.0,
14
+ "latency_stats": {
15
+ "mean_ms": 1.4175499964039773,
16
+ "median_ms": 1.396150008076802,
17
+ "p90_ms": 1.5272499877028167,
18
+ "p95_ms": 1.5332250040955842,
19
+ "p99_ms": 1.538005017209798
20
+ },
21
+ "memory_stats": {
22
+ "format": "fp16",
23
+ "total_pages": 6,
24
+ "total_vectors": 384,
25
+ "quantized_embedding_bytes": 98304,
26
+ "quantized_embedding_mb": 0.09375,
27
+ "summary_bytes": 3072,
28
+ "summary_mb": 0.0029296875,
29
+ "fp16_baseline_mb": 0.09375,
30
+ "compression_ratio_vs_fp16": 1.0,
31
+ "compression_ratio_vs_fp32": 2.0,
32
+ "device": "cuda"
33
+ }
34
+ },
35
+ "int8": {
36
+ "format": "int8",
37
+ "metrics": {
38
+ "ndcg@5": 0.5132314787418083,
39
+ "mrr@10": 0.4361111111111111,
40
+ "recall@1": 0.16666666666666666,
41
+ "recall@5": 0.8333333333333334,
42
+ "recall@10": 1.0,
43
+ "recall@20": 1.0,
44
+ "evaluated_queries": 6
45
+ },
46
+ "retention": 1.0,
47
+ "latency_stats": {
48
+ "mean_ms": 1.978349998050059,
49
+ "median_ms": 1.978349988348782,
50
+ "p90_ms": 2.0354499865788966,
51
+ "p95_ms": 2.036524980212562,
52
+ "p99_ms": 2.037384975119494
53
+ },
54
+ "memory_stats": {
55
+ "format": "int8",
56
+ "total_pages": 6,
57
+ "total_vectors": 384,
58
+ "quantized_embedding_bytes": 49152,
59
+ "quantized_embedding_mb": 0.046875,
60
+ "summary_bytes": 3072,
61
+ "summary_mb": 0.0029296875,
62
+ "fp16_baseline_mb": 0.09375,
63
+ "compression_ratio_vs_fp16": 2.0,
64
+ "compression_ratio_vs_fp32": 4.0,
65
+ "device": "cuda"
66
+ }
67
+ },
68
+ "binary": {
69
+ "format": "binary",
70
+ "metrics": {
71
+ "ndcg@5": 0.3747009872302213,
72
+ "mrr@10": 0.25555555555555554,
73
+ "recall@1": 0.0,
74
+ "recall@5": 0.8333333333333334,
75
+ "recall@10": 1.0,
76
+ "recall@20": 1.0,
77
+ "evaluated_queries": 6
78
+ },
79
+ "retention": 0.7300818495171112,
80
+ "latency_stats": {
81
+ "mean_ms": 1.8759666612216581,
82
+ "median_ms": 1.7842999659478664,
83
+ "p90_ms": 2.1018999977968633,
84
+ "p95_ms": 2.1988000080455095,
85
+ "p99_ms": 2.2763200162444264
86
+ },
87
+ "memory_stats": {
88
+ "format": "binary",
89
+ "total_pages": 6,
90
+ "total_vectors": 384,
91
+ "quantized_embedding_bytes": 6144,
92
+ "quantized_embedding_mb": 0.005859375,
93
+ "summary_bytes": 3072,
94
+ "summary_mb": 0.0029296875,
95
+ "fp16_baseline_mb": 0.09375,
96
+ "compression_ratio_vs_fp16": 16.0,
97
+ "compression_ratio_vs_fp32": 32.0,
98
+ "device": "cuda"
99
+ }
100
+ }
101
+ }
scale_10k_benchmark.json ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fp16": {
3
+ "format": "fp16",
4
+ "total_pages": 10000,
5
+ "total_vectors": 5000000,
6
+ "index_build_seconds": 3.957624673843384,
7
+ "embedding_memory_mb": 1220.703125,
8
+ "compression_ratio_vs_fp16": 1.0,
9
+ "mean_latency_ms": 2028.9032949949615,
10
+ "median_latency_ms": 2006.0680000169668,
11
+ "p95_latency_ms": 2135.904924967326,
12
+ "queries_per_second": 0.49287711369332826
13
+ },
14
+ "int8": {
15
+ "format": "int8",
16
+ "total_pages": 10000,
17
+ "total_vectors": 5000000,
18
+ "index_build_seconds": 6.310345411300659,
19
+ "embedding_memory_mb": 610.3515625,
20
+ "compression_ratio_vs_fp16": 2.0,
21
+ "mean_latency_ms": 3013.152015002561,
22
+ "median_latency_ms": 3011.445799987996,
23
+ "p95_latency_ms": 3083.474895049585,
24
+ "queries_per_second": 0.3318783768694624
25
+ },
26
+ "binary": {
27
+ "format": "binary",
28
+ "total_pages": 10000,
29
+ "total_vectors": 5000000,
30
+ "index_build_seconds": 5.153455018997192,
31
+ "embedding_memory_mb": 76.2939453125,
32
+ "compression_ratio_vs_fp16": 16.0,
33
+ "mean_latency_ms": 2770.0238300079945,
34
+ "median_latency_ms": 2745.0561500154436,
35
+ "p95_latency_ms": 2890.068430028623,
36
+ "queries_per_second": 0.36100772461481456
37
+ }
38
+ }