Spaces:
Runtime error
Runtime error
# app.py | |
import gradio as gr | |
from transformers import pipeline, set_seed | |
import random | |
import re # Для регулярных выражений (очистка текста) | |
# --- Загрузка моделей (как в прошлый раз, выберите нужные) --- | |
try: | |
# generator = pipeline('text-generation', model='distilgpt2', max_length=100, num_return_sequences=1, truncation=True, pad_token_id=50256) | |
generator = pipeline('text-generation', model='sberbank-ai/rugpt3small_based_on_gpt2', max_length=100, num_return_sequences=1, truncation=True, pad_token_id=50256) | |
print("Генератор текста загружен.") | |
GENERATOR_LOADED = True | |
except Exception as e: | |
print(f"ОШИБКА: Не удалось загрузить генератор текста! {e}") | |
generator = None | |
GENERATOR_LOADED = False | |
try: | |
# qa_pipeline = pipeline('question-answering', model='bert-large-uncased-whole-word-masking-finetuned-squad') | |
qa_pipeline = pipeline('question-answering', model='timpal0l/mdeberta-v3-base-squad2') # Мультиязычная | |
print("QA модель загружена.") | |
QA_LOADED = True | |
except Exception as e: | |
print(f"ОШИБКА: Не удалось загрузить QA модель! {e}") | |
qa_pipeline = None | |
QA_LOADED = False | |
# --- Встроенные знания и команды (РАСШИРЕНО для КОДИНГА) --- | |
knowledge_base = { | |
# Мета-информация | |
"кто ты": "Я Nova, модель Alpha 0.95, работающая на платформе Hugging Face Spaces. Я использую нейросетевые модели для генерации ответов и ответов на вопросы.", | |
"что ты умеешь": "Я могу пытаться поддерживать диалог, отвечать на вопросы по контексту, генерировать текст и давать базовую информацию по некоторым темам, включая программирование. Мои знания ограничены, и я не выполняю код.", | |
"как дела": "Как у программы, у меня все по плану! Готова обрабатывать ваши запросы.", | |
"помощь": "Спросите меня о чем-нибудь, например, 'что такое переменная в программировании?' или 'какие есть циклы?'. Я постараюсь ответить. Также знаю команды: 'кто ты', 'что ты умеешь'.", | |
# Основы Программирования | |
"что такое программирование": "Программирование - это процесс написания инструкций (кода) для компьютера, чтобы он выполнял определенные задачи. Это как составление очень точного рецепта для машины.", | |
"зачем нужно программирование": "Программирование позволяет создавать программы, веб-сайты, игры, автоматизировать задачи, анализировать данные и многое другое. Оно лежит в основе почти всех современных технологий.", | |
"что такое алгоритм": "Алгоритм - это пошаговая инструкция или набор правил для решения определенной задачи. Например, рецепт приготовления блюда - это алгоритм.", | |
"основные концепции программирования": "Ключевые идеи включают: переменные (хранение данных), типы данных (числа, строки), условные операторы (if/else - если/иначе), циклы (for, while - для повторения действий), функции (для организации кода).", | |
"что такое переменная": "Переменная в программировании - это как именованный контейнер или ячейка памяти, где можно хранить данные (число, текст, и т.д.), чтобы использовать их позже в программе. Например, `age = 30`.", | |
"что такое типы данных": "Типы данных определяют, какого рода информацию может хранить переменная и какие операции с ней можно выполнять. Распространенные типы: целые числа (integer), числа с плавающей точкой (float), строки (string - текст), булевы (boolean - истина/ложь).", | |
"что такое строка": "Строка (string) - это последовательность символов, обычно используемая для представления текста. В большинстве языков строки заключаются в кавычки (одинарные или двойные). Например, \"Привет, мир!\".", | |
"условный оператор if": "Оператор `if` (если) позволяет выполнить блок кода только в том случае, если определенное условие истинно. Часто используется вместе с `else` (иначе) для выполнения другого блока кода, если условие ложно.", | |
"что такое цикл": "Цикл - это конструкция, которая позволяет повторять выполнение блока кода несколько раз. Основные виды: `for` (для), который обычно используется для перебора элементов (например, в списке) или выполнения заданное число раз, и `while` (пока), который выполняется, пока истинно определенное условие.", | |
"цикл for": "Цикл `for` удобен, когда вы знаете, сколько раз нужно повторить действие, или когда нужно пройти по всем элементам коллекции (списка, строки).", | |
"цикл while": "Цикл `while` повторяет блок кода до тех пор, пока заданное условие остается истинным. Важно убедиться, что условие когда-нибудь станет ложным, иначе цикл будет бесконечным.", | |
"что такое функция": "Функция - это именованный блок кода, который выполняет определенную задачу. Функции помогают разбивать сложную программу на мелкие, управляемые части, избегать повторения кода и делать его более читаемым.", | |
"язык программирования": "Язык программирования - это формальный язык, предназначенный для записи компьютерных программ. Популярные языки: Python (хорош для новичков, науки о данных, веб-бэкенда), JavaScript (для веб-фронтенда и бэкенда), Java (для энтерпрайза, Android), C++ (для игр, системного программирования), C# (для Windows, игр на Unity).", | |
"python": "Python - популярный, высокоуровневый язык программирования с простым синтаксисом, подходящий для широкого круга задач: веб-разработка, наука о данных, машинное обучение, автоматизация.", | |
"javascript": "JavaScript (JS) - основной язык для создания интерактивных веб-страниц (фронтенд). Также используется на бэкенде (Node.js) и для мобильных приложений.", | |
"html": "HTML (HyperText Markup Language) - это не язык программирования, а язык разметки. Он используется для определения структуры и содержимого веб-страницы (заголовки, параграфы, картинки, ссылки).", | |
"css": "CSS (Cascading Style Sheets) - язык стилей, используемый для описания внешнего вида документа, написанного на языке разметки (обычно HTML). Определяет цвета, шрифты, отступы, расположение элементов.", | |
"что такое api": "API (Application Programming Interface) - это набор правил и протоколов, который позволяет разным программам 'общаться' друг с другом. Это как меню в ресторане: вы выбираете блюдо (функцию API), и кухня (другая программа) его готовит и отдает вам.", | |
"что такое git": "Git - это распределенная система контроля версий. Она помогает разработчикам отслеживать изменения в коде, возвращаться к предыдущим версиям, работать над проектом совместно и не терять изменения.", | |
"где учиться программировать": "Существует множество ресурсов: интерактивные онлайн-курсы (Codecademy, Coursera, Stepik, Яндекс.Практикум), документация языков, книги, видеоуроки на YouTube, форумы (Stack Overflow), сообщества разработчиков." | |
# Добавьте сюда больше вопросов и ответов по кодингу! | |
} | |
# --- Функция обработки запроса (логика остается той же) --- | |
def respond(message, chat_history): | |
print(f"Получено сообщение: {message}") | |
user_message_lower = message.lower().strip().replace("?","").replace(".","").replace("!","") # Очищенный ввод для команд | |
# 1. Проверка на встроенные команды/знания | |
if user_message_lower in knowledge_base: | |
bot_response = knowledge_base[user_message_lower] | |
print(f"Ответ из базы знаний: {bot_response}") | |
chat_history.append((message, bot_response)) | |
return "", chat_history | |
# 2. Попытка ответа на вопрос с помощью QA модели (упрощенная логика) | |
if "?" in message and QA_LOADED and qa_pipeline: | |
context = "" | |
if chat_history: | |
context_parts = [] | |
for user_msg, bot_msg in chat_history[-2:]: # Последние 2 обмена | |
context_parts.append(f"Пользователь: {user_msg}") | |
context_parts.append(f"Бот: {bot_msg}") | |
context = "\n".join(context_parts) | |
if len(context) > 50: # Нужен минимальный контекст | |
print("Попытка ответа на вопрос через QA модель...") | |
print(f"Контекст: {context[:200]}...") | |
print(f"Вопрос: {message}") | |
try: | |
qa_result = qa_pipeline(question=message, context=context) | |
print(f"Результат QA: {qa_result}") | |
if qa_result and qa_result['score'] > 0.15: # Немного повысим порог | |
bot_response = qa_result['answer'] | |
chat_history.append((message, bot_response)) | |
print(f"Ответ от QA модели: {bot_response}") | |
return "", chat_history | |
else: | |
print("QA модель не уверена в ответе.") | |
except Exception as e: | |
print(f"Ошибка при использовании QA модели: {e}") | |
# 3. Генерация ответа с помощью основной модели | |
if GENERATOR_LOADED and generator: | |
print("Генерация ответа с помощью основной модели...") | |
prompt_history = [] | |
for user_msg, bot_msg in chat_history[-3:]: # Последние 3 обмена | |
prompt_history.append(f"Пользователь: {user_msg}") | |
prompt_history.append(f"Бот: {bot_msg}") | |
prompt_history.append(f"Пользователь: {message}") | |
prompt_history.append("Бот:") | |
full_prompt = "\n".join(prompt_history) | |
print(f"Промпт для генератора: {full_prompt[-500:]}") | |
try: | |
generated_output = generator(full_prompt)[0]['generated_text'] | |
bot_response = generated_output | |
# Очистка | |
if generated_output.startswith(full_prompt): | |
bot_response = generated_output[len(full_prompt):].strip() | |
else: | |
last_user_line = f"Пользователь: {message}\nБот:" | |
if bot_response.strip().startswith(last_user_line.strip()): | |
bot_response = bot_response.strip()[len(last_user_line.strip()):].strip() | |
elif len(bot_response) > len(message) and message.lower() in bot_response[:len(message)*2].lower(): | |
parts = bot_response.split('\n') | |
if len(parts)>1: bot_response = '\n'.join(parts[1:]).strip() | |
bot_response = re.sub(r'^\s*(пользователь|user|бот|bot)\s*[:\-]?\s*', '', bot_response, flags=re.IGNORECASE).strip() | |
if not bot_response or len(bot_response) < 3: | |
bot_response = knowledge_base.get("не найдено", "Хм, не знаю, что на это ответить...") # Используем "не найдено" из базы | |
print("Сгенерирован слишком короткий ответ, используется заглушка.") | |
except Exception as e: | |
print(f"Ошибка при генерации: {e}") | |
bot_response = knowledge_base.get("ошибка генерации", f"Упс, произошла ошибка при генерации: {e}") # Используем текст ошибки из базы | |
else: | |
bot_response = "К сожалению, мои основные модули сейчас недоступны." | |
print("Ошибка: Генератор текста не загружен.") | |
chat_history.append((message, bot_response)) | |
print(f"Финальный ответ: {bot_response}") | |
return "", chat_history | |
# --- Создание интерфейса Gradio с УЛУЧШЕННЫМ CSS --- | |
# Определяем CSS стили | |
custom_css = """ | |
/* Общий фон */ | |
.gradio-container { | |
background: linear-gradient(to bottom right, #e0f7fa, #f1f8e9); /* Приятный градиент */ | |
border-radius: 15px; | |
padding: 25px; | |
} | |
/* Заголовок */ | |
h1 { | |
color: #004d40; /* Темно-бирюзовый */ | |
text-align: center; | |
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; | |
margin-bottom: 15px; | |
} | |
/* Контейнер чата */ | |
#chatbot { | |
background-color: #ffffff; /* Белый фон для сообщений */ | |
border-radius: 10px; | |
box-shadow: 0 2px 5px rgba(0,0,0,0.1); /* Легкая тень */ | |
border: 1px solid #e0e0e0; | |
} | |
/* Сообщения пользователя */ | |
#chatbot .user { | |
background-color: #e3f2fd; /* Голубоватый фон */ | |
color: #0d47a1; /* Темно-синий текст */ | |
border-radius: 15px 15px 0 15px; /* Скругление углов */ | |
padding: 10px 15px; | |
margin: 5px; | |
align-self: flex-end; /* Выравнивание справа */ | |
max-width: 85%; | |
} | |
/* Сообщения бота */ | |
#chatbot .bot { | |
background-color: #f1f8e9; /* Светло-зеленоватый фон */ | |
color: #33691e; /* Темно-зеленый текст */ | |
border-radius: 15px 15px 15px 0; /* Скругление углов */ | |
padding: 10px 15px; | |
margin: 5px; | |
align-self: flex-start; /* Выравнивание слева */ | |
max-width: 85%; | |
} | |
/* Поле ввода текста */ | |
textarea { | |
border: 1px solid #b0bec5; /* Сероватая рамка */ | |
border-radius: 8px !important; /* !important нужен для переопределения стандартных стилей gradio */ | |
padding: 12px !important; | |
background-color: #ffffff; | |
transition: border-color 0.3s ease; | |
} | |
textarea:focus { | |
border-color: #0277bd !important; /* Синяя рамка при фокусе */ | |
box-shadow: 0 0 5px rgba(2, 119, 189, 0.3); | |
} | |
/* Кнопки */ | |
button { | |
border-radius: 8px !important; | |
transition: background-color 0.3s ease, box-shadow 0.3s ease !important; | |
font-weight: 500 !important; | |
} | |
button.primary { /* Основная кнопка Отправить */ | |
background: linear-gradient(to right, #007991, #78ffd6) !important; /* Бирюзовый градиент */ | |
color: white !important; | |
border: none !important; | |
} | |
button.primary:hover { | |
box-shadow: 0 4px 8px rgba(0, 121, 145, 0.3); | |
background: linear-gradient(to right, #006073, #5fddb8) !important; /* Чуть темнее при наведении */ | |
} | |
button.secondary { /* Кнопка Очистить */ | |
background-color: #cfd8dc !important; /* Светло-серый */ | |
color: #37474f !important; | |
border: 1px solid #b0bec5 !important; | |
} | |
button.secondary:hover { | |
background-color: #b0bec5 !important; /* Темнее при наведении */ | |
} | |
""" | |
with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo: # Применяем CSS и мягкую тему | |
gr.Markdown( | |
""" | |
# 🤖 Nova Alpha 0.95 🎨 | |
Улучшенный интерфейс! Задавайте вопросы или команды. | |
""", elem_id="title-markdown" # Можно задать ID для CSS | |
) | |
chatbot = gr.Chatbot(label="Диалог", height=500, elem_id="chatbot") | |
with gr.Row(): | |
msg = gr.Textbox( | |
label="Ваше сообщение", | |
placeholder="Спросите о Python или скажите 'привет'...", | |
scale=4 | |
) | |
submit_btn = gr.Button("Отправить", variant="primary", scale=1) | |
clear_btn = gr.Button("Очистить", variant="secondary", scale=1) # Добавили класс для CSS | |
msg.submit(respond, [msg, chatbot], [msg, chatbot]) | |
submit_btn.click(respond, [msg, chatbot], [msg, chatbot]) | |
clear_btn.click(lambda: (None, []), None, [msg, chatbot], queue=False) | |
demo.queue() | |
demo.launch(debug=True) |