Leri777 commited on
Commit
19632ec
·
verified ·
1 Parent(s): 440bf4d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -176
app.py CHANGED
@@ -1,14 +1,10 @@
1
  import os
2
  import logging
 
 
3
  import gradio as gr
4
  from huggingface_hub import InferenceClient
5
  from logging.handlers import RotatingFileHandler
6
- from telegram import Update
7
- from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, filters, ContextTypes
8
- from google.oauth2 import service_account
9
- from googleapiclient.discovery import build
10
- from googleapiclient.http import MediaFileUpload
11
- import json
12
 
13
  # Настройка логирования
14
  log_file = 'app_debug.log'
@@ -19,47 +15,38 @@ file_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(mes
19
  logger.addHandler(file_handler)
20
  logger.debug("Application started")
21
 
22
- # Упрощённый системный промпт
23
- DEFAULT_SYSTEM_PROMPT = "For every question I ask I want you to think through the problem. Using Chain Of Thought and your plan think through the question or query step by step."
24
-
25
- # Настройки Google Drive
26
- SERVICE_ACCOUNT_INFO = json.loads(os.getenv("GOOGLE_DRIVE_SERVICE_ACCOUNT")) # Используйте секрет для хранения учетных данных
27
- SCOPES = ["https://www.googleapis.com/auth/drive.file"]
28
 
29
- credentials = service_account.Credentials.from_service_account_info(SERVICE_ACCOUNT_INFO, scopes=SCOPES)
30
- drive_service = build("drive", "v3", credentials=credentials)
31
-
32
- # Класс для бота Фрикадельчик
33
- class FrikadelikBot:
34
  def __init__(self):
35
- self.client = InferenceClient("mistralai/Mistral-7B-Instruct-v0.3")
36
  self.system_prompt = DEFAULT_SYSTEM_PROMPT
37
- logger.debug("Bot initialized with default system prompt")
38
 
39
  def format_prompt(self, message, history):
40
- # Создаём промпт: системный промпт + последнее сообщение пользователя и ответ бота
41
- prompt = f"<s>[INST] <<SYS>>\n{self.system_prompt}\n<</SYS>>\n\n"
42
-
43
- # Добавляем только последнее сообщение из истории (если оно есть)
 
 
 
44
  if history:
45
- user_msg, bot_msg = history[-1]
46
- prompt += f"[INST] {user_msg.strip()} [/INST] {bot_msg.strip()} </s><s>"
47
-
48
  # Добавляем текущее сообщение пользователя
49
  prompt += f"[INST] {message.strip()} [/INST]"
50
  logger.debug(f"Formatted prompt length (tokens): {len(prompt.split())}")
51
  return prompt
52
 
53
- def generate_response(self, message, history, temperature=0.7, max_new_tokens=256, top_p=0.95, repetition_penalty=1.2):
54
  try:
55
- # Ограничиваем историю до одного сообщения для предотвращения переполнения
56
- if len(history) > 1:
57
- history = history[-1:]
58
-
59
  formatted_prompt = self.format_prompt(message, history)
60
  logger.debug(f"Formatted prompt:\n{formatted_prompt}")
61
 
62
- # Параметры генерации
63
  generation_args = {
64
  "temperature": max(float(temperature), 1e-2),
65
  "max_new_tokens": int(max_new_tokens),
@@ -72,36 +59,22 @@ class FrikadelikBot:
72
  "return_full_text": False
73
  }
74
 
75
- # Генерация ответа
76
- stream = self.client.text_generation(formatted_prompt, **generation_args)
 
 
77
 
78
  response = ""
79
  for token in stream:
80
  response += token.token.text
81
-
 
82
  logger.debug(f"Generated response length: {len(response)}")
83
- return response
84
 
85
  except Exception as e:
86
  error_msg = f"Ошибка при генерации ответа: {str(e)}"
87
  logger.error(error_msg)
88
- return f"Извините, произошла ошибка: {error_msg}"
89
-
90
- def save_history_to_google_drive(self, history):
91
- try:
92
- # Сохраняем историю в локальный файл
93
- local_file = "history.json"
94
- with open(local_file, "w", encoding="utf-8") as f:
95
- json.dump(history, f, ensure_ascii=False, indent=4)
96
-
97
- # Загрузка файла на Google Drive
98
- file_metadata = {"name": "history.json", "mimeType": "application/json"}
99
- media = MediaFileUpload(local_file, mimetype="application/json")
100
- file = drive_service.files().create(body=file_metadata, media_body=media, fields="id").execute()
101
-
102
- logger.info(f"Chat history uploaded to Google Drive with ID: {file.get('id')}")
103
- except Exception as e:
104
- logger.error(f"Error saving history to Google Drive: {str(e)}")
105
 
106
  def clear_chat_history(self):
107
  try:
@@ -111,136 +84,79 @@ class FrikadelikBot:
111
  logger.error(f"Error clearing chat history: {str(e)}")
112
  return None
113
 
114
- bot = FrikadelikBot()
115
-
116
- # Функция для обновления истории после каждого сообщения
117
- def update_history_and_save_to_drive(user_message, bot_response, context):
118
- if "history" not in context.chat_data:
119
- context.chat_data["history"] = []
120
-
121
- # Обновление истории сообщений
122
- context.chat_data["history"].append((user_message, bot_response))
123
- if len(context.chat_data["history"]) > 1:
124
- context.chat_data["history"] = context.chat_data["history"][-1:] # Храним только последнее сообщение
125
-
126
- # Сохраняем историю на Google Диск
127
- bot.save_history_to_google_drive(context.chat_data["history"])
128
-
129
- # Инициализация Telegram-бота с использованием токена из переменной окружения
130
- TELEGRAM_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
131
-
132
- if TELEGRAM_TOKEN is None:
133
- raise ValueError("Telegram bot token not found. Please set the 'TELEGRAM_BOT_TOKEN' environment variable.")
134
 
135
- async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
136
- """Команда /start"""
137
- await update.message.reply_text("Привет! Я Фрикадельчик. Готов помочь вам в любом вопросе.")
138
 
139
- async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
140
- """Команда /help"""
141
- await update.message.reply_text("Напишите мне любой вопрос, и я постараюсь ответить!")
142
-
143
- async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
144
- """Обработка сообщений пользователя"""
145
- user_message = update.message.text
146
-
147
- # Используем историю сообщений (для каждого чата можно сохранять историю отдельно)
148
- if "history" not in context.chat_data:
149
- context.chat_data["history"] = []
150
-
151
- # Генерация ответа
152
- response = bot.generate_response(user_message, context.chat_data["history"])
153
-
154
- # Обновление истории сообщений и сохранение на Google Drive
155
- update_history_and_save_to_drive(user_message, response, context)
156
-
157
- # Ответ пользователю
158
- await update.message.reply_text(response)
159
-
160
- # Запуск приложения Telegram-бота
161
- app = ApplicationBuilder().token(TELEGRAM_TOKEN).build()
162
-
163
- app.add_handler(CommandHandler("start", start))
164
- app.add_handler(CommandHandler("help", help_command))
165
- app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
166
-
167
- if __name__ == "__main__":
168
- import asyncio
169
- loop = asyncio.get_event_loop()
170
- loop.create_task(app.run_polling())
171
-
172
- # Gradio интерфейс для локального тестирования
173
- with gr.Blocks() as gr_app:
174
- gr.Markdown("# Frikadelchik v0.3")
175
-
176
- # Компонент для чата
177
- chatbot = gr.Chatbot(
178
- show_label=False,
179
- show_share_button=False,
180
- show_copy_button=True,
181
- likeable=True,
182
- layout="panel"
183
  )
184
 
185
- # Текстовое пол�� для ввода сообщения
186
- msg = gr.Textbox(
187
- placeholder="Введите сообщение...",
188
- label="Input"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  )
190
 
191
- # Параметры генерации
192
- with gr.Accordion("Generation Parameters", open=False):
193
- temperature = gr.Slider(
194
- label="Temperature",
195
- value=0.7,
196
- minimum=0.0,
197
- maximum=1.0,
198
- step=0.05,
199
- interactive=True,
200
- info="Lower values make the output more focused"
201
- )
202
- max_new_tokens = gr.Slider(
203
- label="Max new tokens",
204
- value=256,
205
- minimum=1,
206
- maximum=1024,
207
- step=64,
208
- interactive=True,
209
- info="The maximum number of tokens to generate"
210
- )
211
- top_p = gr.Slider(
212
- label="Top-p (nucleus sampling)",
213
- value=0.95,
214
- minimum=0.0,
215
- maximum=1.0,
216
- step=0.05,
217
- interactive=True,
218
- info="Higher values consider more token options"
219
- )
220
- repetition_penalty = gr.Slider(
221
- label="Repetition penalty",
222
- value=1.2,
223
- minimum=1.0,
224
- maximum=2.0,
225
- step=0.05,
226
- interactive=True,
227
- info="Penalty for repeated tokens"
228
- )
229
-
230
- # Кнопка очистки чата
231
- clear = gr.Button("Очистить чат")
232
 
233
- # Обработчики событий
234
- msg.submit(
235
- bot.generate_response,
236
- inputs=[msg, chatbot, temperature, max_new_tokens, top_p, repetition_penalty],
237
- outputs=[chatbot, msg]
238
- )
239
 
240
- clear.click(
241
- bot.clear_chat_history,
242
- outputs=[chatbot]
243
- )
244
 
245
- gr_app.launch(show_api=False, debug=True)
 
246
  logger.debug("Chat interface initialized and launched")
 
1
  import os
2
  import logging
3
+ import json
4
+ from datetime import datetime
5
  import gradio as gr
6
  from huggingface_hub import InferenceClient
7
  from logging.handlers import RotatingFileHandler
 
 
 
 
 
 
8
 
9
  # Настройка логирования
10
  log_file = 'app_debug.log'
 
15
  logger.addHandler(file_handler)
16
  logger.debug("Application started")
17
 
18
+ # Системный промпт по умолчанию
19
+ DEFAULT_SYSTEM_PROMPT = "For every question I ask, I want you to think through the problem step by step using Chain Of Thought."
 
 
 
 
20
 
21
+ class FrikadelchikBot:
 
 
 
 
22
  def __init__(self):
23
+ self.client = InferenceClient(model="mistralai/Mistral-7B-Instruct-v0.3")
24
  self.system_prompt = DEFAULT_SYSTEM_PROMPT
25
+ logger.debug("Bot initialized")
26
 
27
  def format_prompt(self, message, history):
28
+ # Максимальное количество токенов контекстного окна модели
29
+ max_context_length = 2048
30
+
31
+ # Формируем системный промпт
32
+ prompt = f"<s>[INST] <<SYS>>\n{self.system_prompt.strip()}\n<</SYS>>\n\n"
33
+
34
+ # Добавляем только последнее сообщение пользователя и ответ бота для предотвращения переполнения
35
  if history:
36
+ last_user_msg, last_bot_msg = history[-1]
37
+ prompt += f"[INST] {last_user_msg.strip()} [/INST] {last_bot_msg.strip()} </s><s>"
38
+
39
  # Добавляем текущее сообщение пользователя
40
  prompt += f"[INST] {message.strip()} [/INST]"
41
  logger.debug(f"Formatted prompt length (tokens): {len(prompt.split())}")
42
  return prompt
43
 
44
+ def generate(self, message, history, temperature=0.7, max_new_tokens=256, top_p=0.95, repetition_penalty=1.2):
45
  try:
 
 
 
 
46
  formatted_prompt = self.format_prompt(message, history)
47
  logger.debug(f"Formatted prompt:\n{formatted_prompt}")
48
 
49
+ # Настройка параметров генерации
50
  generation_args = {
51
  "temperature": max(float(temperature), 1e-2),
52
  "max_new_tokens": int(max_new_tokens),
 
59
  "return_full_text": False
60
  }
61
 
62
+ stream = self.client.text_generation(
63
+ formatted_prompt,
64
+ **generation_args
65
+ )
66
 
67
  response = ""
68
  for token in stream:
69
  response += token.token.text
70
+ yield history + [[message, response]], ""
71
+
72
  logger.debug(f"Generated response length: {len(response)}")
 
73
 
74
  except Exception as e:
75
  error_msg = f"Ошибка при генерации ответа: {str(e)}"
76
  logger.error(error_msg)
77
+ yield history + [[message, f"Извините, произошла ошибка: {error_msg}"]], ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  def clear_chat_history(self):
80
  try:
 
84
  logger.error(f"Error clearing chat history: {str(e)}")
85
  return None
86
 
87
+ bot = FrikadelchikBot()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
+ with gr.Blocks() as app:
90
+ gr.Markdown("# Фрикадельчик v0.3")
 
91
 
92
+ with gr.Accordion("Системный промпт", open=False):
93
+ system_prompt = gr.TextArea(
94
+ value=DEFAULT_SYSTEM_PROMPT,
95
+ label="Системный промпт",
96
+ lines=4,
97
+ interactive=True,
98
+ info="Определите поведение и личность бота"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  )
100
 
101
+ chatbot = gr.Chatbot()
102
+
103
+ msg = gr.Textbox(
104
+ placeholder="Введите сообщение...",
105
+ label="Ввод"
106
+ )
107
+
108
+ with gr.Accordion("Параметры генерации", open=False):
109
+ temperature = gr.Slider(
110
+ label="Температура",
111
+ value=0.7,
112
+ minimum=0.0,
113
+ maximum=1.0,
114
+ step=0.05,
115
+ interactive=True,
116
+ info="Меньшие значения делают ответы более сфокусированными"
117
+ )
118
+ max_new_tokens = gr.Slider(
119
+ label="Максимальное количество новых токенов",
120
+ value=256,
121
+ minimum=0,
122
+ maximum=1024,
123
+ step=64,
124
+ interactive=True,
125
+ info="Максимальное количество генерируемых токенов"
126
+ )
127
+ top_p = gr.Slider(
128
+ label="Top-p (ядровая выборка)",
129
+ value=0.95,
130
+ minimum=0.0,
131
+ maximum=1.0,
132
+ step=0.05,
133
+ interactive=True,
134
+ info="Более высокие значения учитывают больше вероятных токенов"
135
+ )
136
+ repetition_penalty = gr.Slider(
137
+ label="Штраф за повторения",
138
+ value=1.2,
139
+ minimum=1.0,
140
+ maximum=2.0,
141
+ step=0.05,
142
+ interactive=True,
143
+ info="Штраф за повторяющиеся токены"
144
  )
145
 
146
+ clear = gr.Button("Очистить чат")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
+ # Обработчики событий
149
+ msg.submit(
150
+ bot.generate,
151
+ inputs=[msg, chatbot, temperature, max_new_tokens, top_p, repetition_penalty],
152
+ outputs=[chatbot, msg]
153
+ )
154
 
155
+ clear.click(
156
+ bot.clear_chat_history,
157
+ outputs=[chatbot]
158
+ )
159
 
160
+ if __name__ == "__main__":
161
+ app.launch(show_api=False, debug=True)
162
  logger.debug("Chat interface initialized and launched")