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