Kolyadual commited on
Commit
c24cf02
·
verified ·
1 Parent(s): 2b10277

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -73
app.py CHANGED
@@ -2,13 +2,14 @@
2
  import os
3
  import json
4
  import re
5
- import torch
6
  import random
 
7
  from difflib import get_close_matches
8
- from transformers import AutoTokenizer, AutoModelForCausalLM
9
  from ddgs import DDGS
10
  import gradio as gr
11
 
 
12
  PATTERNS = {}
13
  HAS_PATTERNS = False
14
  try:
@@ -28,55 +29,28 @@ KEYWORDS = {
28
  def preprocess(text):
29
  return re.sub(r'[^а-яё\s]', ' ', text.lower()).strip()
30
 
31
- print("Инициализация...")
32
- MODEL_ID = "TinyLlama/TinyLlama-1.1B-Chat-v1.0"
33
- tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, trust_remote_code=False)
34
- model = AutoModelForCausalLM.from_pretrained(
35
- MODEL_ID,
36
- torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
37
- device_map="auto",
38
- low_cpu_mem_usage=True
39
- )
40
- print("✅ готово!")
41
 
42
- # === Веб-поиск ===
43
- def web_search(query, max_results=3):
44
  try:
45
  with DDGS() as ddgs:
46
- results = ddgs.text(query, region="ru-ru", max_results=max_results)
47
- return "\n".join([f"{r['title']}: {r['body']}" for r in results])
48
- except Exception as e:
49
- return f"Ошибка поиска: {str(e)[:100]}"
50
-
51
- # === Генерация через TinyLlama ===
52
- def generate_with_tinyllama(prompt_text, max_tokens=256):
53
- try:
54
- inputs = tokenizer(prompt_text, return_tensors="pt").to(model.device)
55
- outputs = model.generate(
56
- **inputs,
57
- max_new_tokens=max_tokens,
58
- do_sample=True,
59
- temperature=0.6,
60
- top_p=0.92,
61
- pad_token_id=tokenizer.eos_token_id,
62
- repetition_penalty=1.1
63
- )
64
- full = tokenizer.decode(outputs[0], skip_special_tokens=True)
65
- if "<|assistant|>" in full:
66
- return full.split("<|assistant|>")[-1].strip()
67
- else:
68
- return full[len(prompt_text):].strip()
69
- except Exception as e:
70
- return f"Ошибка генерации: {str(e)[:100]}"
71
 
72
- # === Fallback через patterns.json ===
73
  def get_fallback_response(user_input):
74
  if not HAS_PATTERNS:
75
  return None
76
  clean = preprocess(user_input)
77
  if not clean:
78
  return None
79
- if any(w in clean for w in ["пока", "выход", "стоп", "до свидания"]):
80
  return random.choice(PATTERNS["пока"])
81
  knowledge = PATTERNS.get("knowledge", {})
82
  if clean in knowledge:
@@ -85,59 +59,70 @@ def get_fallback_response(user_input):
85
  if matches:
86
  return knowledge[matches[0]]
87
  for intent, words in KEYWORDS.items():
88
- if any(get_close_matches(token, words, n=1, cutoff=0.6) for token in clean.split()):
89
- return random.choice(PATTERNS[intent])
 
90
  return None
91
 
92
- # === Основная логика ===
93
  def respond(message, history):
94
  user_input = message.strip()
95
- user_lower = user_input.lower()
 
96
 
97
- # === Системные команды (заглушка) ===
98
- if user_lower.startswith("система:"):
99
  return "🔒 Управление ОС недоступно в демо."
100
 
101
- # === Перевод ===
102
- if user_lower.startswith("перевод:"):
103
  text = user_input[8:].strip()
104
  if not text:
105
  return "🔤 Пример: `перевод: Hello, how are you?`"
106
- prompt = f"<|user|>\nПереведи на русский язык: {text}\n<|assistant|>\n"
107
- return generate_with_tinyllama(prompt, max_tokens=128)
108
-
109
- # === Веб-поиск ===
110
- if user_lower.startswith("поиск:"):
111
  query = user_input[6:].strip()
112
  if not query:
113
  return "🔍 Пример: `поиск: погода в Москве`"
 
114
  context = web_search(query)
115
- prompt = (
116
- f"<|user|>\nИнформация из интернета:\n{context}\n\n"
117
- f"Кратко ответь на русском: {query}\n"
118
- f"<|assistant|>\n"
119
- )
120
- return generate_with_tinyllama(prompt, max_tokens=256)
 
 
121
 
122
- # === Fallback через patterns.json ===
123
- fallback = get_fallback_response(user_input)
124
- if fallback:
125
- return fallback
126
 
127
- # === Обычный режим ===
128
- prompt = f"<|user|>\n{user_input}\nОтветь кратко на русском.\n<|assistant|>\n"
129
- return generate_with_tinyllama(prompt, max_tokens=256)
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
  # === Gradio интерфейс ===
132
  chatbot = gr.ChatInterface(
133
  respond,
134
- title="🚀 Newton MAX - максимальная версия Newton! (BETA)",
135
- description="Поддержка команд: `поиск: ...`, `перевод: ...`, `система: ...`",
136
  examples=[
137
- "Привет!",
138
- "Что такое квантовый компьютер?",
139
- "поиск: курс доллара",
140
- "перевод: How are you doing today?"
141
  ],
142
  theme="soft"
143
  )
 
2
  import os
3
  import json
4
  import re
 
5
  import random
6
+ import torch
7
  from difflib import get_close_matches
8
+ from huggingface_hub import InferenceClient
9
  from ddgs import DDGS
10
  import gradio as gr
11
 
12
+ # === Загрузка patterns.json ===
13
  PATTERNS = {}
14
  HAS_PATTERNS = False
15
  try:
 
29
  def preprocess(text):
30
  return re.sub(r'[^а-яё\s]', ' ', text.lower()).strip()
31
 
32
+ # === Inference Client для Saiga Llama3 ===
33
+ MODEL_ID = "IlyaGusev/saiga_llama3_8b"
34
+ client = InferenceClient() # без токена — модель публичная
 
 
 
 
 
 
 
35
 
36
+ def web_search(query, max_results=2):
 
37
  try:
38
  with DDGS() as ddgs:
39
+ results = ddgs.text(query, region="ru-ru", max_results=max_results, timeout=10)
40
+ if results:
41
+ return "\n".join([f"{r['title']}: {r['body']}"[:180] for r in results])
42
+ else:
43
+ return "Ничего не найдено."
44
+ except Exception:
45
+ return "Поиск временно недоступен."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
 
47
  def get_fallback_response(user_input):
48
  if not HAS_PATTERNS:
49
  return None
50
  clean = preprocess(user_input)
51
  if not clean:
52
  return None
53
+ if any(w in clean for w in ["пока", "выход", "стоп"]):
54
  return random.choice(PATTERNS["пока"])
55
  knowledge = PATTERNS.get("knowledge", {})
56
  if clean in knowledge:
 
59
  if matches:
60
  return knowledge[matches[0]]
61
  for intent, words in KEYWORDS.items():
62
+ for token in clean.split():
63
+ if get_close_matches(token, words, n=1, cutoff=0.6):
64
+ return random.choice(PATTERNS[intent])
65
  return None
66
 
 
67
  def respond(message, history):
68
  user_input = message.strip()
69
+ if not user_input:
70
+ return "Пожалуйста, введите запрос."
71
 
72
+ # Система
73
+ if user_input.lower().startswith("система:"):
74
  return "🔒 Управление ОС недоступно в демо."
75
 
76
+ # Перевод
77
+ if user_input.lower().startswith("перевод:"):
78
  text = user_input[8:].strip()
79
  if not text:
80
  return "🔤 Пример: `перевод: Hello, how are you?`"
81
+ prompt = f"Переведи на русский: {text}"
82
+ # Поиск
83
+ elif user_input.lower().startswith("поиск:"):
 
 
84
  query = user_input[6:].strip()
85
  if not query:
86
  return "🔍 Пример: `поиск: погода в Москве`"
87
+ yield "🔍 Ищу...\n"
88
  context = web_search(query)
89
+ prompt = f"ИНФОРМАЦИЯ ИЗ ИНТЕРНЕТА:\n{context}\n\nОтветь кратко на русском: {query}"
90
+ # Обычный режим
91
+ else:
92
+ fallback = get_fallback_response(user_input)
93
+ if fallback:
94
+ yield fallback
95
+ return
96
+ prompt = f"Ответь кратко и чётко на русском: {user_input}"
97
 
98
+ messages = [{"role": "user", "content": prompt}]
 
 
 
99
 
100
+ response = ""
101
+ try:
102
+ for chunk in client.chat_completion(
103
+ messages,
104
+ model=MODEL_ID,
105
+ max_tokens=512,
106
+ temperature=0.6,
107
+ top_p=0.92,
108
+ stream=True
109
+ ):
110
+ token = chunk.choices[0].delta.content or ""
111
+ response += token
112
+ yield response
113
+ except Exception as e:
114
+ yield f"⚠️ Ошибка: {str(e)}"
115
 
116
  # === Gradio интерфейс ===
117
  chatbot = gr.ChatInterface(
118
  respond,
119
+ title="🚀 Newton MAX - полноценная версия Newton! [BETA]",
120
+ description="Поддержка команд: `поиск: ...`, `перевод: ...`",
121
  examples=[
122
+ ["Привет!", None],
123
+ ["Что такое квантовый компьютер?", None],
124
+ ["поиск: курс доллара", None],
125
+ ["перевод: How are you doing?", None]
126
  ],
127
  theme="soft"
128
  )