SirinootKK commited on
Commit
5f7b796
1 Parent(s): 4b72dd5
Files changed (2) hide show
  1. app.py +224 -0
  2. requirements.txt +311 -0
app.py ADDED
@@ -0,0 +1,224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """gradio_wangchanberta
3
+
4
+ Automatically generated by Colaboratory.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/1Kw2k1oymhq4ZAcy4oBYOlIg4bBU-HlVr
8
+ """
9
+
10
+ #@title scirpts
11
+ import time
12
+ import numpy as np
13
+ import pandas as pd
14
+ import torch
15
+ import faiss
16
+ from sklearn.preprocessing import normalize
17
+ from transformers import AutoTokenizer, AutoModelForQuestionAnswering
18
+ from sentence_transformers import SentenceTransformer,util
19
+ from pythainlp import Tokenizer
20
+ import pickle
21
+ import evaluate
22
+ from sklearn.metrics.pairwise import cosine_similarity,euclidean_distances
23
+
24
+ print(torch.cuda.is_available())
25
+
26
+ __all__ = [
27
+ "mdeberta",
28
+ "wangchanberta-hyp", # Best model
29
+ ]
30
+
31
+ predict_method = [
32
+ "faiss",
33
+ "faissWithModel",
34
+ "cosineWithModel",
35
+ "semanticSearchWithModel",
36
+ ]
37
+
38
+ DEFAULT_MODEL='wangchanberta-hyp'
39
+ DEFAULT_SENTENCE_EMBEDDING_MODEL='intfloat/multilingual-e5-base'
40
+
41
+ MODEL_DICT = {
42
+ 'wangchanberta': 'Chananchida/wangchanberta-th-wiki-qa_ref-params',
43
+ 'wangchanberta-hyp': 'Chananchida/wangchanberta-th-wiki-qa_hyp-params',
44
+ 'mdeberta': 'Chananchida/mdeberta-v3-th-wiki-qa_ref-params',
45
+ 'mdeberta-hyp': 'Chananchida/mdeberta-v3-th-wiki-qa_hyp-params',
46
+ }
47
+
48
+ DATA_PATH='models/dataset.xlsx'
49
+ EMBEDDINGS_PATH='models/embeddings.pkl'
50
+
51
+
52
+ class ChatbotModel:
53
+ def __init__(self, model=DEFAULT_MODEL):
54
+ self._chatbot = Chatbot()
55
+ self._chatbot.load_data()
56
+ self._chatbot.load_model(model)
57
+ self._chatbot.load_embedding_model(DEFAULT_SENTENCE_EMBEDDING_MODEL)
58
+ self._chatbot.set_vectors()
59
+ self._chatbot.set_index()
60
+
61
+
62
+ def chat(self, question):
63
+ return self._chatbot.answer_question(question)
64
+
65
+ def eval(self,model,predict_method):
66
+ return self._chatbot.eval(model_name=model,predict_method=predict_method)
67
+
68
+ class Chatbot:
69
+ def __init__(self):
70
+ # Initialize variables
71
+ self.df = None
72
+ self.test_df = None
73
+ self.model = None
74
+ self.model_name = None
75
+ self.tokenizer = None
76
+ self.embedding_model = None
77
+ self.vectors = None
78
+ self.index = None
79
+ self.k = 1 # top k most similar
80
+
81
+ def load_data(self, path: str = DATA_PATH):
82
+ self.df = pd.read_excel(path, sheet_name='Default')
83
+ self.df['Context'] = pd.read_excel(path, sheet_name='mdeberta')['Context']
84
+ print('Load data done')
85
+
86
+ def load_model(self, model_name: str = DEFAULT_MODEL):
87
+ self.model = AutoModelForQuestionAnswering.from_pretrained(MODEL_DICT[model_name])
88
+ self.tokenizer = AutoTokenizer.from_pretrained(MODEL_DICT[model_name])
89
+ self.model_name = model_name
90
+ print('Load model done')
91
+
92
+ def load_embedding_model(self, model_name: str = DEFAULT_SENTENCE_EMBEDDING_MODEL):
93
+ if torch.cuda.is_available(): # Check if GPU is available
94
+ self.embedding_model = SentenceTransformer(model_name, device='cpu')
95
+ else: self.embedding_model = SentenceTransformer(model_name)
96
+ print('Load sentence embedding model done')
97
+
98
+ def set_vectors(self):
99
+ self.vectors = self.prepare_sentences_vector(self.load_embeddings(EMBEDDINGS_PATH))
100
+
101
+ def set_index(self):
102
+ if torch.cuda.is_available(): # Check if GPU is available
103
+ res = faiss.StandardGpuResources()
104
+ self.index = faiss.IndexFlatL2(self.vectors.shape[1])
105
+ gpu_index_flat = faiss.index_cpu_to_gpu(res, 0, self.index)
106
+ gpu_index_flat.add(self.vectors)
107
+ self.index = gpu_index_flat
108
+ else: # If GPU is not available, use CPU-based Faiss index
109
+ self.index = faiss.IndexFlatL2(self.vectors.shape[1])
110
+ self.index.add(self.vectors)
111
+
112
+ def get_embeddings(self, text_list):
113
+ return self.embedding_model.encode(text_list)
114
+
115
+ def prepare_sentences_vector(self, encoded_list):
116
+ encoded_list = [i.reshape(1, -1) for i in encoded_list]
117
+ encoded_list = np.vstack(encoded_list).astype('float32')
118
+ encoded_list = normalize(encoded_list)
119
+ return encoded_list
120
+
121
+
122
+ def store_embeddings(self, embeddings):
123
+ with open('models/embeddings.pkl', "wb") as fOut:
124
+ pickle.dump({'sentences': self.df['Question'], 'embeddings': embeddings}, fOut, protocol=pickle.HIGHEST_PROTOCOL)
125
+ print('Store embeddings done')
126
+
127
+ def load_embeddings(self, file_path):
128
+ with open(file_path, "rb") as fIn:
129
+ stored_data = pickle.load(fIn)
130
+ stored_sentences = stored_data['sentences']
131
+ stored_embeddings = stored_data['embeddings']
132
+ print('Load (questions) embeddings done')
133
+ return stored_embeddings
134
+
135
+ def model_pipeline(self, question, similar_context):
136
+ inputs = self.tokenizer(question, similar_context, return_tensors="pt")
137
+ with torch.no_grad():
138
+ outputs = self.model(**inputs)
139
+ answer_start_index = outputs.start_logits.argmax()
140
+ answer_end_index = outputs.end_logits.argmax()
141
+ predict_answer_tokens = inputs.input_ids[0, answer_start_index: answer_end_index + 1]
142
+ Answer = self.tokenizer.decode(predict_answer_tokens)
143
+ return Answer
144
+
145
+ def faiss_search(self, question_vector):
146
+ distances, indices = self.index.search(question_vector, self.k)
147
+ similar_questions = [self.df['Question'][indices[0][i]] for i in range(self.k)]
148
+ similar_contexts = [self.df['Context'][indices[0][i]] for i in range(self.k)]
149
+ return similar_questions, similar_contexts, distances, indices
150
+
151
+ def predict_faiss(self, message):
152
+ message = message.strip()
153
+ question_vector = self.get_embeddings(message)
154
+ question_vector = self.prepare_sentences_vector([question_vector])
155
+ similar_questions, similar_contexts, distances, indices = self.faiss_search(question_vector)
156
+ Answers = [self.df['Answer'][i] for i in indices[0]]
157
+ Answer = Answers[0]
158
+
159
+ return Answer
160
+
161
+ # Function to predict using BERT embedding
162
+ def predict_bert_embedding(self,message):
163
+ message = message.strip()
164
+ question_vector = self.get_embeddings(message)
165
+ question_vector=self.prepare_sentences_vector([question_vector])
166
+ similar_questions, similar_contexts, distances,indices = self.faiss_search(question_vector)
167
+ Answer = self.model_pipeline(similar_questions, similar_contexts)
168
+ return Answer
169
+
170
+ # def predict_semantic_search(self,message,corpus_embeddings):
171
+ # message = message.strip()
172
+ # query_embedding = self.embedding_model.encode(message, convert_to_tensor=True)
173
+ # query_embedding = query_embedding.to('cpu')
174
+ # hits = util.semantic_search(query_embedding, corpus_embeddings, top_k=1)
175
+ # hit = hits[0][0]
176
+ # context=self.df['Context'][hit['corpus_id']]
177
+ # score="{:.4f})".format(hit['score'])
178
+ # Answer = self.model_pipeline(message, context)
179
+ # return Answer
180
+ def predict_semantic_search(self, message):
181
+ message = message.strip()
182
+ query_embedding = self.embedding_model.encode([message], convert_to_tensor=True)[0] # Fix here
183
+ query_embedding = query_embedding.to('cpu')
184
+ corpus_embeddings = self.embedding_model.encode(self.df['Question'].tolist(), convert_to_tensor=True) # Fix here
185
+ hits = util.semantic_search(query_embedding, corpus_embeddings, top_k=1)
186
+ hit = hits[0][0]
187
+ context = self.df['Context'][hit['corpus_id']]
188
+ score = "{:.4f})".format(hit['score'])
189
+ Answer = self.model_pipeline(message, context)
190
+ return Answer
191
+
192
+ def predict_without_faiss(self,message):
193
+ MostSimilarContext = ""
194
+ min_distance = 1000
195
+ message = message.strip(' \t\n')
196
+ question_vector = self.get_embeddings([message])
197
+ question_vector=self.prepare_sentences_vector(question_vector)
198
+ for j, _question_vector in enumerate(self.vectors):
199
+ distance = euclidean_distances(question_vector, _question_vector.reshape(1, -1))[0][0]
200
+ if distance < min_distance:
201
+ min_distance = distance
202
+ MostSimilarContext = self.df['Context'][j]
203
+ similar_question = self.df['Question'][j]
204
+ if distance <= 0.02469331026:
205
+ break
206
+ predict_answer = self.model_pipeline(message, MostSimilarContext)
207
+ Answer = predict_answer.strip().replace("<unk>","@")
208
+ return Answer
209
+
210
+ bot = ChatbotModel()
211
+
212
+ """#Gradio"""
213
+
214
+ import gradio as gr
215
+
216
+ EXAMPLE_PATH = ["หลิน ไห่เฟิง มีชื่อเรียกอีกชื่อว่าอะไร" , "ใครเป็นผู้ตั้งสภาเศรษฐกิจโลกขึ้นในปี พ.ศ. 2514 โดยทุกปีจะมีการประชุมที่ประเทศสวิตเซอร์แลนด์", "โปรดิวเซอร์ของอัลบั้มตลอดกาล ของวงคีรีบูนคือใคร", "สกุลเดิมของหม่อมครูนุ่ม นวรัตน ณ อยุธยา คืออะไร"]
217
+
218
+ demoFaiss = gr.Interface(fn=bot._chatbot.predict_faiss, inputs="text", outputs="text", examples=EXAMPLE_PATH, title="TH wiki (just Faiss)")
219
+ demoBert = gr.Interface(fn=bot._chatbot.predict_bert_embedding, inputs="text", outputs="text",examples=EXAMPLE_PATH, title="TH wiki (Faiss & Model)")
220
+ demoSemantic = gr.Interface(fn=bot._chatbot.predict_semantic_search, inputs="text", outputs="text",examples=EXAMPLE_PATH, title="TH wiki (Semantic Search & Model)")
221
+ demoWithoutFiss = gr.Interface(fn=bot._chatbot.predict_without_faiss, inputs="text", outputs="text",examples=EXAMPLE_PATH, title="TH wiki (just Model)")
222
+
223
+ demo = gr.TabbedInterface([demoFaiss, demoWithoutFiss, demoBert, demoSemantic], ["Faiss", "Model", "Faiss & Model", "Semantic Search & Model"])
224
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,311 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ absl-py==2.1.0
2
+ accelerate==0.26.1
3
+ aiohttp==3.9.1
4
+ aiosignal==1.3.1
5
+ async-timeout==4.0.3
6
+ attrs==23.2.0
7
+ bert-score==0.3.13
8
+ certifi==2023.11.17
9
+ charset-normalizer==3.3.2
10
+ click==8.1.7
11
+ colorama==0.4.6
12
+ contourpy==1.2.0
13
+ cycler==0.12.1
14
+ datasets==2.16.1
15
+ dill==0.3.7
16
+ evaluate==0.4.1
17
+ faiss-cpu==1.7.4
18
+ filelock==3.13.1
19
+ fonttools==4.47.2
20
+ frozenlist==1.4.1
21
+ fsspec==2023.10.0
22
+ huggingface-hub==0.20.2
23
+ idna==3.6
24
+ Jinja2==3.1.3
25
+ joblib==1.3.2
26
+ kiwisolver==1.4.5
27
+ MarkupSafe==2.1.4
28
+ matplotlib==3.8.2
29
+ mpmath==1.3.0
30
+ multidict==6.0.4
31
+ multiprocess==0.70.15
32
+ networkx==3.2.1
33
+ nltk==3.8.1
34
+ numpy==1.26.3
35
+ packaging==23.2
36
+ pandas==2.2.0
37
+ pillow==10.2.0
38
+ psutil==5.9.8
39
+ pyarrow==14.0.2
40
+ pyarrow-hotfix==0.6
41
+ pyparsing==3.1.1
42
+ pythainlp==4.0.2
43
+ python-dateutil==2.8.2
44
+ pytz==2023.3.post1
45
+ PyYAML==6.0.1
46
+ regex==2023.12.25
47
+ requests==2.31.0
48
+ responses==0.18.0
49
+ rouge_score==0.1.2
50
+ safetensors==0.4.1
51
+ scikit-learn==1.4.0
52
+ scipy==1.11.4
53
+ sentence-transformers==2.2.2
54
+ sentencepiece==0.1.99
55
+ six==1.16.0
56
+ sympy==1.12
57
+ threadpoolctl==3.2.0
58
+ tokenizers==0.15.0
59
+ torch==2.1.2
60
+ torchvision==0.16.2
61
+ tqdm==4.66.1
62
+ transformers==4.36.2
63
+ typing_extensions==4.9.0
64
+ tzdata==2023.4
65
+ urllib3==2.1.0
66
+ xxhash==3.4.1
67
+ yarl==1.9.4
68
+ absl-py==2.1.0
69
+ accelerate==0.26.1
70
+ aiohttp==3.9.1
71
+ aiosignal==1.3.1
72
+ async-timeout==4.0.3
73
+ attrs==23.2.0
74
+ bert-score==0.3.13
75
+ certifi==2023.11.17
76
+ charset-normalizer==3.3.2
77
+ click==8.1.7
78
+ colorama==0.4.6
79
+ contourpy==1.2.0
80
+ cycler==0.12.1
81
+ datasets==2.16.1
82
+ dill==0.3.7
83
+ evaluate==0.4.1
84
+ faiss-cpu==1.7.4
85
+ filelock==3.13.1
86
+ fonttools==4.47.2
87
+ frozenlist==1.4.1
88
+ fsspec==2023.10.0
89
+ huggingface-cli==0.1
90
+ huggingface-hub==0.20.2
91
+ idna==3.6
92
+ Jinja2==3.1.3
93
+ joblib==1.3.2
94
+ kiwisolver==1.4.5
95
+ MarkupSafe==2.1.4
96
+ matplotlib==3.8.2
97
+ mpmath==1.3.0
98
+ multidict==6.0.4
99
+ multiprocess==0.70.15
100
+ networkx==3.2.1
101
+ nltk==3.8.1
102
+ numpy==1.26.3
103
+ packaging==23.2
104
+ pandas==2.2.0
105
+ pillow==10.2.0
106
+ psutil==5.9.8
107
+ pyarrow==14.0.2
108
+ pyarrow-hotfix==0.6
109
+ pyparsing==3.1.1
110
+ pythainlp==4.0.2
111
+ python-dateutil==2.8.2
112
+ pytz==2023.3.post1
113
+ PyYAML==6.0.1
114
+ regex==2023.12.25
115
+ requests==2.31.0
116
+ responses==0.18.0
117
+ rouge_score==0.1.2
118
+ safetensors==0.4.1
119
+ scikit-learn==1.4.0
120
+ scipy==1.11.4
121
+ sentence-transformers==2.2.2
122
+ sentencepiece==0.1.99
123
+ six==1.16.0
124
+ sympy==1.12
125
+ threadpoolctl==3.2.0
126
+ tokenizers==0.15.0
127
+ torch==2.1.2
128
+ torchvision==0.16.2
129
+ tqdm==4.66.1
130
+ transformers==4.36.2
131
+ typing_extensions==4.9.0
132
+ tzdata==2023.4
133
+ urllib3==2.1.0
134
+ xxhash==3.4.1
135
+ yarl==1.9.4
136
+ absl-py==2.1.0
137
+ accelerate==0.26.1
138
+ aiohttp==3.9.1
139
+ aiosignal==1.3.1
140
+ async-timeout==4.0.3
141
+ attrs==23.2.0
142
+ bert-score==0.3.13
143
+ certifi==2023.11.17
144
+ charset-normalizer==3.3.2
145
+ click==8.1.7
146
+ colorama==0.4.6
147
+ contourpy==1.2.0
148
+ cycler==0.12.1
149
+ datasets==2.16.1
150
+ dill==0.3.7
151
+ et-xmlfile==1.1.0
152
+ evaluate==0.4.1
153
+ faiss-cpu==1.7.4
154
+ filelock==3.13.1
155
+ fonttools==4.47.2
156
+ frozenlist==1.4.1
157
+ fsspec==2023.10.0
158
+ huggingface-cli==0.1
159
+ huggingface-hub==0.20.2
160
+ idna==3.6
161
+ Jinja2==3.1.3
162
+ joblib==1.3.2
163
+ kiwisolver==1.4.5
164
+ MarkupSafe==2.1.4
165
+ matplotlib==3.8.2
166
+ mpmath==1.3.0
167
+ multidict==6.0.4
168
+ multiprocess==0.70.15
169
+ networkx==3.2.1
170
+ nltk==3.8.1
171
+ numpy==1.26.3
172
+ openpyxl==3.1.2
173
+ packaging==23.2
174
+ pandas==2.2.0
175
+ pillow==10.2.0
176
+ psutil==5.9.8
177
+ pyarrow==14.0.2
178
+ pyarrow-hotfix==0.6
179
+ pyparsing==3.1.1
180
+ pythainlp==4.0.2
181
+ python-dateutil==2.8.2
182
+ pytz==2023.3.post1
183
+ PyYAML==6.0.1
184
+ regex==2023.12.25
185
+ requests==2.31.0
186
+ responses==0.18.0
187
+ rouge_score==0.1.2
188
+ safetensors==0.4.1
189
+ scikit-learn==1.4.0
190
+ scipy==1.11.4
191
+ sentence-transformers==2.2.2
192
+ sentencepiece==0.1.99
193
+ six==1.16.0
194
+ sympy==1.12
195
+ threadpoolctl==3.2.0
196
+ tokenizers==0.15.0
197
+ torch==2.1.2
198
+ torchvision==0.16.2
199
+ tqdm==4.66.1
200
+ transformers==4.36.2
201
+ typing_extensions==4.9.0
202
+ tzdata==2023.4
203
+ urllib3==2.1.0
204
+ xxhash==3.4.1
205
+ yarl==1.9.4
206
+ absl-py==2.1.0
207
+ accelerate==0.26.1
208
+ aiofiles==23.2.1
209
+ aiohttp==3.9.1
210
+ aiosignal==1.3.1
211
+ altair==5.2.0
212
+ annotated-types==0.6.0
213
+ anyio==4.2.0
214
+ async-timeout==4.0.3
215
+ attrs==23.2.0
216
+ bert-score==0.3.13
217
+ certifi==2023.11.17
218
+ charset-normalizer==3.3.2
219
+ click==8.1.7
220
+ colorama==0.4.6
221
+ contourpy==1.2.0
222
+ cycler==0.12.1
223
+ datasets==2.16.1
224
+ dill==0.3.7
225
+ et-xmlfile==1.1.0
226
+ evaluate==0.4.1
227
+ exceptiongroup==1.2.0
228
+ faiss-cpu==1.7.4
229
+ fastapi==0.109.0
230
+ ffmpy==0.3.1
231
+ filelock==3.13.1
232
+ fonttools==4.47.2
233
+ frozenlist==1.4.1
234
+ fsspec==2023.10.0
235
+ gradio==4.15.0
236
+ gradio_client==0.8.1
237
+ h11==0.14.0
238
+ httpcore==1.0.2
239
+ httpx==0.26.0
240
+ huggingface-cli==0.1
241
+ huggingface-hub==0.20.2
242
+ idna==3.6
243
+ importlib-resources==6.1.1
244
+ Jinja2==3.1.3
245
+ joblib==1.3.2
246
+ jsonschema==4.21.1
247
+ jsonschema-specifications==2023.12.1
248
+ kiwisolver==1.4.5
249
+ markdown-it-py==3.0.0
250
+ MarkupSafe==2.1.4
251
+ matplotlib==3.8.2
252
+ mdurl==0.1.2
253
+ mpmath==1.3.0
254
+ multidict==6.0.4
255
+ multiprocess==0.70.15
256
+ networkx==3.2.1
257
+ nltk==3.8.1
258
+ numpy==1.26.3
259
+ openpyxl==3.1.2
260
+ orjson==3.9.12
261
+ packaging==23.2
262
+ pandas==2.2.0
263
+ pillow==10.2.0
264
+ psutil==5.9.8
265
+ pyarrow==14.0.2
266
+ pyarrow-hotfix==0.6
267
+ pydantic==2.5.3
268
+ pydantic_core==2.14.6
269
+ pydub==0.25.1
270
+ Pygments==2.17.2
271
+ pyparsing==3.1.1
272
+ pythainlp==4.0.2
273
+ python-dateutil==2.8.2
274
+ python-multipart==0.0.6
275
+ pytz==2023.3.post1
276
+ PyYAML==6.0.1
277
+ referencing==0.32.1
278
+ regex==2023.12.25
279
+ requests==2.31.0
280
+ responses==0.18.0
281
+ rich==13.7.0
282
+ rouge_score==0.1.2
283
+ rpds-py==0.17.1
284
+ ruff==0.1.14
285
+ safetensors==0.4.1
286
+ scikit-learn==1.4.0
287
+ scipy==1.11.4
288
+ semantic-version==2.10.0
289
+ sentence-transformers==2.2.2
290
+ sentencepiece==0.1.99
291
+ shellingham==1.5.4
292
+ six==1.16.0
293
+ sniffio==1.3.0
294
+ starlette==0.35.1
295
+ sympy==1.12
296
+ threadpoolctl==3.2.0
297
+ tokenizers==0.15.0
298
+ tomlkit==0.12.0
299
+ toolz==0.12.0
300
+ torch==2.1.2
301
+ torchvision==0.16.2
302
+ tqdm==4.66.1
303
+ transformers==4.36.2
304
+ typer==0.9.0
305
+ typing_extensions==4.9.0
306
+ tzdata==2023.4
307
+ urllib3==2.1.0
308
+ uvicorn==0.26.0
309
+ websockets==11.0.3
310
+ xxhash==3.4.1
311
+ yarl==1.9.4