cakiki commited on
Commit
aeb12b8
1 Parent(s): a74a6e9

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -1,35 +1,2 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ index/**/* filter=lfs diff=lfs merge=lfs -text
2
+ data/data-00000-of-00001.arrow filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.md CHANGED
@@ -1,12 +1,13 @@
1
  ---
2
- title: Imdb Search Demo
3
- emoji: 💻
4
  colorFrom: blue
5
- colorTo: gray
6
  sdk: gradio
7
- sdk_version: 3.39.0
8
  app_file: app.py
9
  pinned: false
 
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: IMDB search
3
+ emoji: 🐠
4
  colorFrom: blue
5
+ colorTo: blue
6
  sdk: gradio
7
+ sdk_version: 3.29.0
8
  app_file: app.py
9
  pinned: false
10
+ license: apache-2.0
11
  ---
12
 
13
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from datasets import load_from_disk
3
+ from pyserini.search.lucene import LuceneSearcher
4
+
5
+ searcher = LuceneSearcher("index")
6
+ ds = load_from_disk("data")
7
+ NUM_PAGES = 10 # STATIC. THIS CAN'T CHANGE BECAUSE GRADIO CAN'T DYNAMICALLY CREATE COMPONENTS.
8
+ RESULTS_PER_PAGE = 5
9
+
10
+ TEXT_FIELD = "text"
11
+ METADATA_FIELD = "label"
12
+
13
+
14
+ def result_html(result, meta):
15
+ return (
16
+ f"<div style=\"color:#2a5cb3;font-weight: 500\"><u>{meta}</u></div><br>"
17
+ f"<div><details><summary>{result[:250]}...</summary><p>{result[250:]}</p></details></div><br><hr><br>"
18
+ )
19
+
20
+
21
+ def format_results(results):
22
+ return "\n".join([result_html(result, meta) for result,meta in zip(results[TEXT_FIELD], results[METADATA_FIELD])])
23
+
24
+
25
+ def page_0(query):
26
+ hits = searcher.search(query, k=NUM_PAGES*RESULTS_PER_PAGE)
27
+ ix = [int(hit.docid) for hit in hits]
28
+ results = ds.select(ix).shard(num_shards=NUM_PAGES, index=0, contiguous=True) # no need to shard. split ix in batches instead. (would make sense if results was cacheable)
29
+ results = format_results(results)
30
+ return results, [ix], gr.update(visible=True)
31
+
32
+
33
+ def page_i(i, ix):
34
+ ix = ix[0]
35
+ results = ds.select(ix).shard(num_shards=NUM_PAGES, index=i, contiguous=True)
36
+ results = format_results(results)
37
+ return results, [ix]
38
+
39
+
40
+ with gr.Blocks(css="#b {min-width:15px;background:transparent;border:white;box-shadow:none;}") as demo: #
41
+ with gr.Row():
42
+ gr.Markdown(value="""## <p style="text-align: center;"> IMDB search </p>""")
43
+ with gr.Row():
44
+ with gr.Column(scale=1):
45
+ result_list = gr.Dataframe(type="array", visible=False, col_count=1)
46
+ with gr.Column(scale=13):
47
+ query = gr.Textbox(lines=1, max_lines=1, placeholder="Search…", label="")
48
+ with gr.Column(scale=1):
49
+ with gr.Row(scale=1):
50
+ pass
51
+ with gr.Row(scale=1):
52
+ submit_btn = gr.Button("🔍", elem_id="b").style(full_width=False)
53
+ with gr.Row(scale=1):
54
+ pass
55
+
56
+ with gr.Row():
57
+ with gr.Column(scale=1):
58
+ pass
59
+ with gr.Column(scale=13):
60
+ c = gr.HTML(label="Results")
61
+ with gr.Row(visible=False) as pagination:
62
+ # left = gr.Button(value="◀", elem_id="b", visible=False).style(full_width=True)
63
+ page_1 = gr.Button(value="1", elem_id="b").style(full_width=True)
64
+ page_2 = gr.Button(value="2", elem_id="b").style(full_width=True)
65
+ page_3 = gr.Button(value="3", elem_id="b").style(full_width=True)
66
+ page_4 = gr.Button(value="4", elem_id="b").style(full_width=True)
67
+ page_5 = gr.Button(value="5", elem_id="b").style(full_width=True)
68
+ page_6 = gr.Button(value="6", elem_id="b").style(full_width=True)
69
+ page_7 = gr.Button(value="7", elem_id="b").style(full_width=True)
70
+ page_8 = gr.Button(value="8", elem_id="b").style(full_width=True)
71
+ page_9 = gr.Button(value="9", elem_id="b").style(full_width=True)
72
+ page_10 = gr.Button(value="10", elem_id="b").style(full_width=True)
73
+ # right = gr.Button(value="▶", elem_id="b", visible=False).style(full_width=True)
74
+ with gr.Column(scale=1):
75
+ pass
76
+
77
+ query.submit(fn=page_0, inputs=[query], outputs=[c, result_list, pagination])
78
+ submit_btn.click(page_0, inputs=[query], outputs=[c, result_list, pagination])
79
+
80
+ with gr.Box(visible=False):
81
+ nums = [gr.Number(i, visible=False, precision=0) for i in range(NUM_PAGES)]
82
+
83
+ page_1.click(fn=page_i, inputs=[nums[0], result_list], outputs=[c, result_list])
84
+ page_2.click(fn=page_i, inputs=[nums[1], result_list], outputs=[c, result_list])
85
+ page_3.click(fn=page_i, inputs=[nums[2], result_list], outputs=[c, result_list])
86
+ page_4.click(fn=page_i, inputs=[nums[3], result_list], outputs=[c, result_list])
87
+ page_5.click(fn=page_i, inputs=[nums[4], result_list], outputs=[c, result_list])
88
+ page_6.click(fn=page_i, inputs=[nums[5], result_list], outputs=[c, result_list])
89
+ page_7.click(fn=page_i, inputs=[nums[6], result_list], outputs=[c, result_list])
90
+ page_8.click(fn=page_i, inputs=[nums[7], result_list], outputs=[c, result_list])
91
+ page_9.click(fn=page_i, inputs=[nums[8], result_list], outputs=[c, result_list])
92
+ page_10.click(fn=page_i, inputs=[nums[9], result_list], outputs=[c, result_list])
93
+
94
+ demo.launch(enable_queue=True, debug=True)
data/.gitkeep ADDED
File without changes
data/data-00000-of-00001.arrow ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ccad9a2cace25de89d2198d210317033e23de1a8175d1be4faafec3ceb187b20
3
+ size 66094864
data/dataset_info.json ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "builder_name": "imdb",
3
+ "citation": "@InProceedings{maas-EtAl:2011:ACL-HLT2011,\n author = {Maas, Andrew L. and Daly, Raymond E. and Pham, Peter T. and Huang, Dan and Ng, Andrew Y. and Potts, Christopher},\n title = {Learning Word Vectors for Sentiment Analysis},\n booktitle = {Proceedings of the 49th Annual Meeting of the Association for Computational Linguistics: Human Language Technologies},\n month = {June},\n year = {2011},\n address = {Portland, Oregon, USA},\n publisher = {Association for Computational Linguistics},\n pages = {142--150},\n url = {http://www.aclweb.org/anthology/P11-1015}\n}\n",
4
+ "config_name": "plain_text",
5
+ "dataset_size": 133190302,
6
+ "description": "Large Movie Review Dataset.\nThis is a dataset for binary sentiment classification containing substantially more data than previous benchmark datasets. We provide a set of 25,000 highly polar movie reviews for training, and 25,000 for testing. There is additional unlabeled data for use as well.",
7
+ "download_checksums": {
8
+ "https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz": {
9
+ "num_bytes": 84125825,
10
+ "checksum": null
11
+ }
12
+ },
13
+ "download_size": 84125825,
14
+ "features": {
15
+ "text": {
16
+ "dtype": "string",
17
+ "_type": "Value"
18
+ },
19
+ "label": {
20
+ "names": [
21
+ "neg",
22
+ "pos"
23
+ ],
24
+ "_type": "ClassLabel"
25
+ }
26
+ },
27
+ "homepage": "http://ai.stanford.edu/~amaas/data/sentiment/",
28
+ "license": "",
29
+ "size_in_bytes": 217316127,
30
+ "splits": {
31
+ "train": {
32
+ "name": "train",
33
+ "num_bytes": 33432823,
34
+ "num_examples": 25000,
35
+ "dataset_name": "imdb"
36
+ },
37
+ "test": {
38
+ "name": "test",
39
+ "num_bytes": 32650685,
40
+ "num_examples": 25000,
41
+ "dataset_name": "imdb"
42
+ },
43
+ "unsupervised": {
44
+ "name": "unsupervised",
45
+ "num_bytes": 67106794,
46
+ "num_examples": 50000,
47
+ "dataset_name": "imdb"
48
+ }
49
+ },
50
+ "task_templates": [
51
+ {
52
+ "task": "text-classification",
53
+ "label_column": "label"
54
+ }
55
+ ],
56
+ "version": {
57
+ "version_str": "1.0.0",
58
+ "description": "",
59
+ "major": 1,
60
+ "minor": 0,
61
+ "patch": 0
62
+ }
63
+ }
data/state.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_data_files": [
3
+ {
4
+ "filename": "data-00000-of-00001.arrow"
5
+ }
6
+ ],
7
+ "_fingerprint": "079439276ed0dd9a",
8
+ "_format_columns": null,
9
+ "_format_kwargs": {},
10
+ "_format_type": null,
11
+ "_output_all_columns": false,
12
+ "_split": "train+test"
13
+ }
index/.gitkeep ADDED
File without changes
index/_5.fdm ADDED
Binary file (158 Bytes). View file
 
index/_5.fdt ADDED
Binary file (284 kB). View file
 
index/_5.fdx ADDED
Binary file (247 Bytes). View file
 
index/_5.fnm ADDED
Binary file (322 Bytes). View file
 
index/_5.nvd ADDED
Binary file (50.1 kB). View file
 
index/_5.nvm ADDED
Binary file (103 Bytes). View file
 
index/_5.si ADDED
Binary file (534 Bytes). View file
 
index/_5_Lucene90_0.doc ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c51f857a0b58e236592cfe90fe106dcf7a5d0834dfea20e0d26be498e696bd1d
3
+ size 7539565
index/_5_Lucene90_0.dvd ADDED
Binary file (314 kB). View file
 
index/_5_Lucene90_0.dvm ADDED
Binary file (171 Bytes). View file
 
index/_5_Lucene90_0.pos ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b9e28efcc32c72172e4e2f83cf00dddd5cbfe8f9c25289d806022c3a97f14254
3
+ size 9575136
index/_5_Lucene90_0.tim ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:94b77d8179588eba0fec5f782efd2d42466182b5988e5463683c148ea415b087
3
+ size 1043047
index/_5_Lucene90_0.tip ADDED
Binary file (26.6 kB). View file
 
index/_5_Lucene90_0.tmd ADDED
Binary file (262 Bytes). View file
 
index/segments_2 ADDED
Binary file (154 Bytes). View file
 
index/write.lock ADDED
File without changes
packages.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ default-jdk
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ pyserini
2
+ datasets
3
+ faiss-cpu
4
+ torch
spacerini_utils/__init__.py ADDED
File without changes
spacerini_utils/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (161 Bytes). View file
 
spacerini_utils/__pycache__/index.cpython-39.pyc ADDED
Binary file (769 Bytes). View file
 
spacerini_utils/__pycache__/search.cpython-39.pyc ADDED
Binary file (4.41 kB). View file
 
spacerini_utils/index.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from typing import Any
3
+ from typing import Dict
4
+
5
+ from pyserini.index.lucene import IndexReader
6
+
7
+
8
+ def fetch_index_stats(index_path: str) -> Dict[str, Any]:
9
+ """
10
+ Fetch index statistics
11
+ index_path : str
12
+ Path to index directory
13
+ Returns
14
+ -------
15
+ Dictionary of index statistics
16
+ Dictionary Keys ==> total_terms, documents, unique_terms
17
+ """
18
+ assert os.path.exists(index_path), f"Index path {index_path} does not exist"
19
+ index_reader = IndexReader(index_path)
20
+ return index_reader.stats()
spacerini_utils/search.py ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from typing import List, Literal, Protocol, Tuple, TypedDict, Union
3
+
4
+ from pyserini.analysis import get_lucene_analyzer
5
+ from pyserini.index import IndexReader
6
+ from pyserini.search import DenseSearchResult, JLuceneSearcherResult
7
+ from pyserini.search.faiss.__main__ import init_query_encoder
8
+ from pyserini.search.faiss import FaissSearcher
9
+ from pyserini.search.hybrid import HybridSearcher
10
+ from pyserini.search.lucene import LuceneSearcher
11
+
12
+ EncoderClass = Literal["dkrr", "dpr", "tct_colbert", "ance", "sentence", "contriever", "auto"]
13
+
14
+
15
+ class AnalyzerArgs(TypedDict):
16
+ language: str
17
+ stemming: bool
18
+ stemmer: str
19
+ stopwords: bool
20
+ huggingFaceTokenizer: str
21
+
22
+
23
+ class SearchResult(TypedDict):
24
+ docid: str
25
+ text: str
26
+ score: float
27
+ language: str
28
+
29
+
30
+ class Searcher(Protocol):
31
+ def search(self, query: str, **kwargs) -> List[Union[DenseSearchResult, JLuceneSearcherResult]]:
32
+ ...
33
+
34
+
35
+ def init_searcher_and_reader(
36
+ sparse_index_path: str = None,
37
+ bm25_k1: float = None,
38
+ bm25_b: float = None,
39
+ analyzer_args: AnalyzerArgs = None,
40
+ dense_index_path: str = None,
41
+ encoder_name_or_path: str = None,
42
+ encoder_class: EncoderClass = None,
43
+ tokenizer_name: str = None,
44
+ device: str = None,
45
+ prefix: str = None
46
+ ) -> Tuple[Union[FaissSearcher, HybridSearcher, LuceneSearcher], IndexReader]:
47
+ """
48
+ Initialize and return an approapriate searcher
49
+
50
+ Parameters
51
+ ----------
52
+ sparse_index_path: str
53
+ Path to sparse index
54
+ dense_index_path: str
55
+ Path to dense index
56
+ encoder_name_or_path: str
57
+ Path to query encoder checkpoint or encoder name
58
+ encoder_class: str
59
+ Query encoder class to use. If None, infer from `encoder`
60
+ tokenizer_name: str
61
+ Tokenizer name or path
62
+ device: str
63
+ Device to load Query encoder on.
64
+ prefix: str
65
+ Query prefix if exists
66
+
67
+ Returns
68
+ -------
69
+ Searcher: FaissSearcher | HybridSearcher | LuceneSearcher
70
+ A sparse, dense or hybrid searcher
71
+ """
72
+ reader = None
73
+ if sparse_index_path:
74
+ ssearcher = LuceneSearcher(sparse_index_path)
75
+ if analyzer_args:
76
+ analyzer = get_lucene_analyzer(**analyzer_args)
77
+ ssearcher.set_analyzer(analyzer)
78
+ if bm25_k1 and bm25_b:
79
+ ssearcher.set_bm25(bm25_k1, bm25_b)
80
+
81
+ if dense_index_path:
82
+ encoder = init_query_encoder(
83
+ encoder=encoder_name_or_path,
84
+ encoder_class=encoder_class,
85
+ tokenizer_name=tokenizer_name,
86
+ topics_name=None,
87
+ encoded_queries=None,
88
+ device=device,
89
+ prefix=prefix
90
+ )
91
+
92
+ reader = IndexReader(sparse_index_path)
93
+ dsearcher = FaissSearcher(dense_index_path, encoder)
94
+
95
+ if sparse_index_path:
96
+ hsearcher = HybridSearcher(dense_searcher=dsearcher, sparse_searcher=ssearcher)
97
+ return hsearcher, reader
98
+ else:
99
+ return dsearcher, reader
100
+
101
+ return ssearcher, reader
102
+
103
+
104
+ def _search(searcher: Searcher, reader: IndexReader, query: str, num_results: int = 10) -> List[SearchResult]:
105
+ """
106
+ Parameters:
107
+ -----------
108
+ searcher: FaissSearcher | HybridSearcher | LuceneSearcher
109
+ A sparse, dense or hybrid searcher
110
+ query: str
111
+ Query for which to retrieve results
112
+ num_results: int
113
+ Maximum number of results to retrieve
114
+
115
+ Returns:
116
+ --------
117
+ Dict:
118
+ """
119
+ def _get_dict(r: Union[DenseSearchResult, JLuceneSearcherResult]):
120
+ if isinstance(r, JLuceneSearcherResult):
121
+ return json.loads(r.raw)
122
+ elif isinstance(r, DenseSearchResult):
123
+ # Get document from sparse_index using index reader
124
+ return json.loads(reader.doc(r.docid).raw())
125
+
126
+ search_results = searcher.search(query, k=num_results)
127
+ all_results = [
128
+ SearchResult(
129
+ docid=result["id"],
130
+ text=result["contents"],
131
+ score=search_results[idx].score
132
+ ) for idx, result in enumerate(map(lambda r: _get_dict(r), search_results))
133
+ ]
134
+
135
+ return all_results