EgorDan commited on
Commit
777cb96
1 Parent(s): 598c750

copy from git

Browse files
__pycache__/faiss_file.cpython-39.pyc ADDED
Binary file (1.62 kB). View file
 
embeddings_dataset.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b540e2ca547809af2ea03ae7d7c81131dcbeadba37f0c56d69c0d9f81c600fb8
3
+ size 22647057
faiss_file.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from joblib import load
2
+
3
+ ### pip install faiss-cpu
4
+ import faiss
5
+
6
+ ### pip install datasets
7
+ from datasets import Dataset
8
+
9
+ import torch
10
+ import pandas as pd
11
+
12
+ import streamlit as st
13
+
14
+ device = 'cpu'
15
+
16
+ ### подгрузка всех компонентов - модель, токенайзер и датасет с эмбеддингами
17
+ embeddings_dataset = load('./embeddings_dataset.joblib')
18
+ tokenizer = load('./tokenizer.joblib')
19
+ model = load('./model.joblib')
20
+
21
+ ### функция возвращающая от БЕРТа только [CLS] опиывающий общий смысл всего предложения
22
+ def embed_bert_cls(text, model, tokenizer):
23
+ t = tokenizer(text, padding=True, truncation=True, return_tensors='pt')
24
+ with torch.no_grad():
25
+ model_output = model(**{k: v.to(device) for k, v in t.items()})
26
+ embeddings = model_output.last_hidden_state[:, 0, :]
27
+ embeddings = torch.nn.functional.normalize(embeddings)
28
+ return embeddings[0].cpu().numpy()
29
+
30
+ ### функция ниже отдает готовый датасет с рекомендациями книг
31
+ def recommend(input_string,n_neighbors=5):
32
+
33
+ ### input_string - то, что вводит пользователь в аннотации, эмбеддинг пользовательского текста
34
+ question_embedding = embed_bert_cls([input_string], model, tokenizer)
35
+
36
+ ### n_neighbors - число предлагаемых системой книг, вводит пользователь,
37
+ ### поиск похожих книг по запросу
38
+ scores, samples = embeddings_dataset.get_nearest_examples(
39
+ "embeddings", question_embedding, k=n_neighbors
40
+ )
41
+
42
+ ### для корректной работы требуется формат таблиц huggingface, поэтому в конце
43
+ ### происходит перевод в пандас для удобства
44
+ samples_df = pd.DataFrame.from_dict(samples)
45
+ samples_df["scores"] = scores
46
+ samples_df.sort_values("scores", ascending=False, inplace=True)
47
+
48
+ return samples_df
49
+
50
+ ### конечный датасет: samples_df
51
+
52
+
53
+ user_input = st.text_input('Your text here:', )
54
+ number = st.number_input('Insert a number', min_value = 1, max_value = 5, value = 3)
55
+
56
+ if len(user_input) > 1:
57
+ st.write(recommend(user_input, number))
final_emb.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a7fc2b732b8562b706b1411abb47325d2fe39463e5bea17c319f322deefed4e6
3
+ size 19199575
kmeans.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bce848639b7c9372fe451e995b57a033008601eb0f14d295c054113061e6ecef
3
+ size 48779
main.py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ st.set_page_config(page_title="FindMyBook", page_icon="📚", menu_items=None, initial_sidebar_state="auto")
3
+
4
+ import matplotlib.pyplot as plt
5
+ import pandas as pd
6
+ import numpy as np
7
+ import csv
8
+ from joblib import load
9
+ from transformers import AutoTokenizer, AutoModel
10
+ from faiss_file import model, tokenizer, embeddings_dataset, embed_bert_cls, recommend
11
+
12
+
13
+ # Модель, токенайзер, датасет, kmeans, функция рекомендаций
14
+
15
+ device = 'cpu'
16
+
17
+ tokenizer_k = AutoTokenizer.from_pretrained("cointegrated/rubert-tiny")
18
+ model_k = AutoModel.from_pretrained("cointegrated/rubert-tiny")
19
+ kmeans = load('kmeans.joblib')
20
+ emb = load('final_emb.joblib')
21
+
22
+ def recomendation(input):
23
+
24
+ user_input = embed_bert_cls(input, model_k, tokenizer_k)
25
+ label = kmeans.predict(user_input.reshape(1, -1))[0]
26
+ sample_df = emb[emb['labels'] == label].copy()
27
+ sample_df['cosine'] = sample_df['embeddings'].apply(lambda x: np.dot(x, user_input) / (np.linalg.norm(x) * np.linalg.norm(user_input)))
28
+
29
+ return sample_df.sort_values('cosine', ascending=False)
30
+
31
+
32
+
33
+ st.title('Умный поиск книг')
34
+
35
+ with st.sidebar:
36
+ st.markdown('Добро пожаловать в мир **FindMyBook** - самого умного поисковика книг! Это как твой личный библиотекарь, который знает все о тебе и твоих предпочтениях в литературе! Это не просто обычный поисковик, который ищет книги по авторам или названиям, это настоящий литературный детектив, который проникает в глубь содержания книг и помогает найти именно те, которые оставят неизгладимое впечатление.')
37
+ st.markdown('**FindMyBook** работает на основе передовых алгоритмов искусственного интеллекта, которые позволяют ему анализировать содержание книг и находить связи между ними. Этот поисковик сможет найти книгу, которая понравится именно тебе, учитывая твои предпочтения и интересы.')
38
+ st.markdown('Не нужно тратить время на бесконечный поиск книг в огромных онлайн-библиотеках. Просто введи тему, которая тебя интересует, и **FindMyBook** уже начнет искать книги, которые подходят именно тебе!')
39
+
40
+ user_prompt = st.text_area(label='Введите запрос:', placeholder="Хочу прочитать о...", height=200)
41
+
42
+ books_per_page = st.number_input('Количество рекомендаций:', min_value=1, max_value=5, value=3)
43
+
44
+ button = st.button("Найти")
45
+
46
+ tab1, tab2 = st.tabs(["Faiss Search", "K-Mean"])
47
+
48
+ with tab1:
49
+
50
+ if button and len(user_prompt) > 1:
51
+ book_recs = recommend(user_prompt, books_per_page)
52
+ for i in range(books_per_page):
53
+
54
+ col1, col2 = st.columns([2,7])
55
+ with col1:
56
+ image = book_recs['image_url'].iloc[i]
57
+ st.image(image)
58
+
59
+ with col2:
60
+ title = book_recs['title'].iloc[i]
61
+ try:
62
+ author = book_recs['author'].iloc[i].rstrip()
63
+ except:
64
+ author = book_recs['author'].iloc[i]
65
+ annotation = book_recs['annotation'].iloc[i]
66
+ st.subheader(title)
67
+ st.markdown(f'_{author}_')
68
+ st.caption(annotation)
69
+ st.markdown(f"[Подробнее...]({book_recs['page_url'].iloc[i]})")
70
+ st.divider()
71
+
72
+ with tab2:
73
+
74
+ book_recs = recommend(user_prompt, books_per_page)
75
+ if button and len(user_prompt) > 1:
76
+
77
+ book_recs = recomendation(user_prompt)
78
+ for i in range(books_per_page):
79
+
80
+ col1, col2 = st.columns([2,7])
81
+ with col1:
82
+ image = book_recs['image_url'].iloc[i]
83
+ st.image(image)
84
+
85
+ with col2:
86
+ title = book_recs['title'].iloc[i]
87
+ try:
88
+ author = book_recs['author'].iloc[i].rstrip()
89
+ except:
90
+ author = book_recs['author'].iloc[i]
91
+ annotation = book_recs['annotation'].iloc[i]
92
+ st.subheader(title)
93
+ st.markdown(f'_{author}_')
94
+ st.caption(annotation)
95
+ st.markdown(f"[Подробнее...]({book_recs['page_url'].iloc[i]})")
96
+ st.divider()
model.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cbf65abc66debfb76486401c470d9170d80d49d07aa73e13f45a35bd47eccd6c
3
+ size 116837561
pages/.gitattributes ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ *.joblib filter=lfs diff=lfs merge=lfs -text
2
+ *.pt filter=lfs diff=lfs merge=lfs -text
pages/annotation_generator.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from joblib import load
3
+ import textwrap
4
+ import streamlit as st
5
+
6
+ device = 'cpu'
7
+
8
+ tokenizer = load('./pages/tokenizer.joblib')
9
+ model = load('./pages/model.joblib')
10
+ weights = model.load_state_dict(torch.load('./pages/model_weights.pt', map_location=device))
11
+
12
+ temperature = st.slider('Градус дичи:', min_value = 1., max_value = 20., value = 3.)
13
+ num_beams = st.slider('Число веток для поиска:', min_value = 1, max_value = 15, value = 7)
14
+ max_length = st.slider('Максимальная длина генерации:', min_value = 50, max_value = 150, value = 70)
15
+
16
+ prompt = st.text_input('Дайте волю фантазии!',)
17
+ if len(prompt) > 1:
18
+ with torch.inference_mode():
19
+ prompt = tokenizer.encode(prompt, return_tensors='pt').to(device)
20
+ out = model.generate(
21
+ input_ids=prompt,
22
+ max_length=max_length,
23
+ num_beams=num_beams,
24
+ do_sample=True,
25
+ temperature=temperature,
26
+ top_k=50,
27
+ top_p=0.6,
28
+ no_repeat_ngram_size=3,
29
+ num_return_sequences=3,
30
+ ).cpu().numpy()
31
+ for out_ in out:
32
+ st.write(textwrap.fill(tokenizer.decode(out_), 40), end='\n------------------\n')
pages/model.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5bdfe86f85eed4d288ef6a0e9c950c509c0e727c967511928aa0e21c50ec48cb
3
+ size 551335281
pages/model_weights.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8da23517b808864217db05ff78cf20d4fec1887e6e2612d74ec63248b949d936
3
+ size 551321853
pages/tokenizer.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a7505a6d5173cf65c4ee11a834912ab6024525ce1417c9c0a513f4ef9dea3105
3
+ size 10247307
requirements.txt ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiohttp==3.8.4
2
+ aiosignal==1.3.1
3
+ altair==4.2.2
4
+ async-timeout==4.0.2
5
+ attrs==23.1.0
6
+ blinker==1.6.2
7
+ cachetools==5.3.0
8
+ certifi==2022.12.7
9
+ charset-normalizer==3.1.0
10
+ click==8.1.3
11
+ cmake==3.26.3
12
+ contourpy==1.0.7
13
+ cycler==0.11.0
14
+ datasets==2.12.0
15
+ decorator==5.1.1
16
+ dill==0.3.6
17
+ entrypoints==0.4
18
+ faiss-cpu==1.7.4
19
+ filelock==3.12.0
20
+ fonttools==4.39.3
21
+ frozenlist==1.3.3
22
+ fsspec==2023.4.0
23
+ gitdb==4.0.10
24
+ GitPython==3.1.31
25
+ huggingface-hub==0.14.1
26
+ idna==3.4
27
+ importlib-metadata==6.6.0
28
+ importlib-resources==5.12.0
29
+ Jinja2==3.1.2
30
+ joblib==1.2.0
31
+ jsonschema==4.17.3
32
+ kiwisolver==1.4.4
33
+ lit==16.0.2
34
+ markdown-it-py==2.2.0
35
+ MarkupSafe==2.1.2
36
+ matplotlib==3.7.1
37
+ mdurl==0.1.2
38
+ mpmath==1.3.0
39
+ multidict==6.0.4
40
+ multiprocess==0.70.14
41
+ networkx==3.1
42
+ numpy==1.24.3
43
+ nvidia-cublas-cu11==11.10.3.66
44
+ nvidia-cuda-cupti-cu11==11.7.101
45
+ nvidia-cuda-nvrtc-cu11==11.7.99
46
+ nvidia-cuda-runtime-cu11==11.7.99
47
+ nvidia-cudnn-cu11==8.5.0.96
48
+ nvidia-cufft-cu11==10.9.0.58
49
+ nvidia-curand-cu11==10.2.10.91
50
+ nvidia-cusolver-cu11==11.4.0.1
51
+ nvidia-cusparse-cu11==11.7.4.91
52
+ nvidia-nccl-cu11==2.14.3
53
+ nvidia-nvtx-cu11==11.7.91
54
+ packaging==23.1
55
+ pandas==2.0.1
56
+ Pillow==9.5.0
57
+ protobuf==3.20.3
58
+ pyarrow==12.0.0
59
+ pydeck==0.8.1b0
60
+ Pygments==2.15.1
61
+ Pympler==1.0.1
62
+ pyparsing==3.0.9
63
+ pyrsistent==0.19.3
64
+ python-dateutil==2.8.2
65
+ pytz==2023.3
66
+ pytz-deprecation-shim==0.1.0.post0
67
+ PyYAML==6.0
68
+ regex==2023.5.5
69
+ requests==2.29.0
70
+ responses==0.18.0
71
+ rich==13.3.5
72
+ scikit-learn==1.2.2
73
+ scipy==1.10.1
74
+ six==1.16.0
75
+ smmap==5.0.0
76
+ streamlit==1.22.0
77
+ sympy==1.11.1
78
+ tenacity==8.2.2
79
+ threadpoolctl==3.1.0
80
+ tokenizers==0.13.3
81
+ toml==0.10.2
82
+ toolz==0.12.0
83
+ torch==2.0.0
84
+ tornado==6.3.1
85
+ tqdm==4.65.0
86
+ transformers==4.28.1
87
+ triton==2.0.0
88
+ typing_extensions==4.5.0
89
+ tzdata==2023.3
90
+ tzlocal==4.3
91
+ urllib3==1.26.15
92
+ validators==0.20.0
93
+ watchdog==3.0.0
94
+ xxhash==3.2.0
95
+ yarl==1.9.2
96
+ zipp==3.15.0
tokenizer.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f1ebec50c02e9b3861bbd8127234b1e373b7885669d50df99b19cf48a223f7ce
3
+ size 1743035