Bjg6742635 commited on
Commit
a67e9f5
·
1 Parent(s): b7302da

Optimize app.py for cached loading

Browse files
Files changed (1) hide show
  1. app.py +57 -17
app.py CHANGED
@@ -19,39 +19,74 @@ from bs4 import BeautifulSoup
19
  @st.cache_resource
20
  def load_data():
21
  # Загрузка датасета
22
- data = load_dataset('Romyx/ru_QA_school_history', split='train')
23
- df = pd.DataFrame(data)
 
 
 
 
 
 
 
 
24
  df['Pt_question'] = df['question'].apply(preprocess_text)
25
  df['Pt_answer'] = df['answer'].apply(preprocess_text)
26
  return df
27
 
28
  @st.cache_resource
29
  def load_model_and_tokenizer():
30
- # Загрузка предобученной модели вопрос-ответа (например, SberQuad)
31
- model_name = "AlexKay/xlm-roberta-large-qa-multilingual-finedtuned-ru" # замените на нужную модель, например, "bert-base-uncased"
32
- tokenizer = AutoTokenizer.from_pretrained(model_name)
33
- model = AutoModelForQuestionAnswering.from_pretrained(model_name)
 
 
 
 
 
 
34
  return tokenizer, model
35
 
36
  @st.cache_resource
37
  def build_vectorizer(_df):
38
- combined_texts = _df['Pt_question'].tolist() + _df['Pt_answer'].tolist()
39
- vectorizer = TfidfVectorizer()
40
- tfidf_matrix = vectorizer.fit_transform(combined_texts)
 
 
 
 
 
 
41
  return vectorizer, tfidf_matrix
42
 
43
  # === Предобработка текста ===
44
 
45
- # Загрузка Spacy модели
46
- nlp = spacy.load('ru_core_news_lg')
47
- stop_words = set(stopwords.words('russian'))
48
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  cache_dict = {}
50
 
51
- def get_norm_form(word):
52
  if word in cache_dict:
53
  return cache_dict[word]
54
- norm_form = nlp(word)[0].lemma_
 
55
  cache_dict[word] = norm_form
56
  return norm_form
57
 
@@ -75,14 +110,19 @@ def preprocess_text(text):
75
  text = re.sub(r'[^\w\s]', '', text)
76
 
77
  tokens = word_tokenize(text)
78
- tokens = [token for token in tokens if token not in stop_words]
79
- tokens = [get_norm_form(token) for token in tokens]
 
 
 
 
80
 
81
  words_to_remove = {"ответ", "new"}
82
  tokens = [token for token in tokens if token not in words_to_remove]
83
 
84
  return ' '.join(tokens)
85
 
 
86
  # === Основная функция получения ответа ===
87
  def get_answer_from_qa_model(user_question, df, vectorizer, tfidf_matrix, model, tokenizer):
88
  processed = preprocess_text(user_question)
 
19
  @st.cache_resource
20
  def load_data():
21
  # Загрузка датасета
22
+ st.info("Загрузка датасета...")
23
+ try:
24
+ data = load_dataset('Romyx/ru_QA_school_history', split='train')
25
+ df = pd.DataFrame(data)
26
+ st.success("Датасет загружен.")
27
+ except Exception as e:
28
+ st.error(f"Ошибка загрузки датасета: {e}")
29
+ raise e # Прерывает выполнение, если датасет не загрузился
30
+
31
+ # Предобработка сразу после загрузки
32
  df['Pt_question'] = df['question'].apply(preprocess_text)
33
  df['Pt_answer'] = df['answer'].apply(preprocess_text)
34
  return df
35
 
36
  @st.cache_resource
37
  def load_model_and_tokenizer():
38
+ st.info("Загрузка модели вопрос-ответа...")
39
+ try:
40
+ # Убедитесь, что это имя совпадает с именем модели, загруженной в Dockerfile
41
+ model_name = "AlexKay/xlm-roberta-large-qa-multilingual-finedtuned-ru"
42
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
43
+ model = AutoModelForQuestionAnswering.from_pretrained(model_name)
44
+ st.success("Модель вопрос-ответа загружена.")
45
+ except Exception as e:
46
+ st.error(f"Ошибка загрузки модели вопрос-ответа: {e}")
47
+ raise e
48
  return tokenizer, model
49
 
50
  @st.cache_resource
51
  def build_vectorizer(_df):
52
+ st.info("Обучение TF-IDF векторайзера...")
53
+ try:
54
+ combined_texts = _df['Pt_question'].tolist() + _df['Pt_answer'].tolist()
55
+ vectorizer = TfidfVectorizer()
56
+ tfidf_matrix = vectorizer.fit_transform(combined_texts)
57
+ st.success("TF-IDF векторайзер обучен.")
58
+ except Exception as e:
59
+ st.error(f"Ошибка обучения TF-IDF: {e}")
60
+ raise e
61
  return vectorizer, tfidf_matrix
62
 
63
  # === Предобработка текста ===
64
 
65
+ # Загрузка Spacy модели при запуске скрипта (не внутри @st.cache_resource, если она в образе)
66
+ # Используем @st.cache_resource для загрузки nlp модели, чтобы она кэшировалась
67
+ @st.cache_resource
68
+ def load_spacy_model():
69
+ st.info("Загрузка SpaCy модели...")
70
+ try:
71
+ # Убедитесь, что это имя совпадает с моделью, загруженной в Dockerfile
72
+ nlp = spacy.load('ru_core_news_lg')
73
+ st.success("SpaCy модель загружена.")
74
+ except OSError as e:
75
+ st.error(f"SpaCy модель 'ru_core_news_lg' не найдена. Проверьте Dockerfile: {e}")
76
+ raise e
77
+ return nlp
78
+
79
+ # Функция для получения нормальной формы слова
80
+ # Используем кэш внутри функции для избежания повторных вызовов spaCy
81
+ # Но для кэширования результатов между вызовами функции можно использовать кэш Streamlit или обычный словарь
82
+ # Для простоты, кэшируем в обычном словаре, но помните, что это не персистентный кэш между перезапусками
83
  cache_dict = {}
84
 
85
+ def get_norm_form(nlp_model, word): # Передаём nlp_model как аргумент
86
  if word in cache_dict:
87
  return cache_dict[word]
88
+ # Используем переданную модель
89
+ norm_form = nlp_model(word)[0].lemma_
90
  cache_dict[word] = norm_form
91
  return norm_form
92
 
 
110
  text = re.sub(r'[^\w\s]', '', text)
111
 
112
  tokens = word_tokenize(text)
113
+ # stop_words загружается при старте
114
+ stop_words_set = set(stopwords.words('russian'))
115
+ tokens = [token for token in tokens if token not in stop_words_set]
116
+ # Загружаем nlp модель из кэша Streamlit
117
+ nlp_model = load_spacy_model()
118
+ tokens = [get_norm_form(nlp_model, token) for token in tokens]
119
 
120
  words_to_remove = {"ответ", "new"}
121
  tokens = [token for token in tokens if token not in words_to_remove]
122
 
123
  return ' '.join(tokens)
124
 
125
+
126
  # === Основная функция получения ответа ===
127
  def get_answer_from_qa_model(user_question, df, vectorizer, tfidf_matrix, model, tokenizer):
128
  processed = preprocess_text(user_question)