| import gradio as gr |
| from datasets import Dataset, load_from_disk |
| import random |
| import json |
| import os |
| import time |
| from threading import Thread |
|
|
| |
|
|
| dialog_templates = [ |
| { |
| "dialog": [ |
| ("Привет!", "Здравствуйте! Как я могу вам помочь?"), |
| ("Привет!", "Приветствую! Чем могу быть полезен?"), |
| ("Доброе утро!", "Доброе утро! Отличный день, не правда ли?"), |
| ("Добрый день!", "Добрый день! Чем могу помочь?"), |
| ("Здравствуйте!", "Здравствуйте! Рад вас видеть."), |
| ("Привет!", "Привет! Как у тебя дела?"), |
| ("Хай!", "Хай! Что нового?"), |
| ] |
| }, |
| { |
| "dialog": [ |
| ("Как дела?", "Всё отлично! А у вас?"), |
| ("Что нового?", "Много интересного! А у вас?"), |
| ("Как жизнь?", "Жизнь прекрасна! Спасибо, что спросили."), |
| ("Как настроение?", "Настроение отличное! А у вас?"), |
| ("Как успехи?", "Успехи есть! Работаю над новыми проектами."), |
| ] |
| }, |
| { |
| "dialog": [ |
| ("Кто ты?", "Я искусственный интеллект, созданный чтобы помогать людям."), |
| ("Что ты умеешь?", "Я умею отвечать на вопросы, писать тексты, помогать с задачами."), |
| ("Где ты живёшь?", "Я живу в облаке! Всегда рядом с вами."), |
| ("Сколько тебе лет?", "Мне несколько лет, но я постоянно учусь."), |
| ("Зачем ты здесь?", "Я здесь, чтобы помогать людям в их повседневных задачах."), |
| ("У тебя есть имя?", "Меня зовут AI-ассистент. А вас?"), |
| ("Ты человек?", "Нет, я компьютерная программа, но стараюсь быть полезной."), |
| ] |
| }, |
| { |
| "dialog": [ |
| ("Почему небо голубое?", "Небо голубое из-за рассеяния Рэлея."), |
| ("Как работает интернет?", "Интернет работает через сеть серверов и маршрутизаторов."), |
| ("Что такое искусственный интеллект?", "ИИ — это технология, позволяющая машинам имитировать человеческий разум."), |
| ("Что такое нейросети?", "Нейросети — это алгоритмы, вдохновлённые структурой мозга."), |
| ("Почему трава зелёная?", "Трава зелёная из-за хлорофилла."), |
| ("Когда появилась жизнь на Земле?", "Жизнь появилась около 3,5 миллиардов лет назад."), |
| ("Сколько планет в солнечной системе?", "В солнечной системе 8 планет."), |
| ("Что такое чёрная дыра?", "Чёрная дыра — область пространства с огромной гравитацией."), |
| ] |
| }, |
| { |
| "dialog": [ |
| ("Кто написал Войну и мир?", "Войну и мир написал Лев Толстой."), |
| ("Что такое роман?", "Роман — это литературный жанр с развёрнутым сюжетом."), |
| ("Кто такой Шекспир?", "Шекспир — великий английский драматург и поэт."), |
| ("Что такое живопись?", "Живопись — искусство создания изображений красками."), |
| ("Кто нарисовал Мону Лизу?", "Мону Лизу нарисовал Леонардо да Винчи."), |
| ("Что такое театр?", "Театр — это искусство драматических представлений."), |
| ("Кто такой Пушкин?", "Александр Пушкин — великий русский поэт."), |
| ] |
| }, |
| { |
| "dialog": [ |
| ("Где можно купить хлеб?", "Хлеб можно купить в ближайшем супермаркете."), |
| ("Как приготовить яичницу?", "Разбейте яйца на сковороду, обжарьте до готовности."), |
| ("Сколько времени?", "Сейчас 12:00, если точнее."), |
| ("Как пройти в библиотеку?", "Пройдите прямо, затем поверните налево."), |
| ("Что посмотреть вечером?", "Рекомендую хороший фильм или книгу."), |
| ("Как выучить язык?", "Нужна регулярная практика и мотивация."), |
| ] |
| }, |
| { |
| "dialog": [ |
| ("Как выучить Python?", "Начните с основ: переменные, циклы, функции."), |
| ("Что такое API?", "API — это интерфейс для взаимодействия программ."), |
| ("Как создать сайт?", "Нужно знать HTML, CSS, JavaScript и серверный язык."), |
| ("Что такое Git?", "Git — система контроля версий для кода."), |
| ("Как стать разработчиком?", "Много практикуйтесь, изучайте алгоритмы."), |
| ("Что такое Docker?", "Docker — платформа для контейнеризации приложений."), |
| ] |
| }, |
| { |
| "dialog": [ |
| ("Как справиться со стрессом?", "Помогают медитация, отдых и спорт."), |
| ("Что делать при тревоге?", "Подышите глубоко, сосредоточьтесь на моменте."), |
| ("Как найти смысл жизни?", "Смысл в том, что вы делаете и кого любите."), |
| ("Почему люди счастливы?", "Счастье в простых вещах: любви, здоровье, увлечениях."), |
| ] |
| }, |
| { |
| "dialog": [ |
| ("Где лучше отдыхать?", "Всё зависит от ваших предпочтений: море, горы, город."), |
| ("Что посмотреть в Европе?", "Рекомендую Париж, Рим, Лондон."), |
| ("Как добраться до Парижа?", "Можно на поезде или самолёте."), |
| ("Где находится Эйфелева башня?", "В Париже, Франция."), |
| ] |
| }, |
| { |
| "dialog": [ |
| ("Что такое любовь?", "Любовь — глубокое чувство привязанности и заботы."), |
| ("Что такое дружба?", "Дружба — доверительные отношения между людьми."), |
| ("Что такое справедливость?", "Справедливость — принцип равенства и честности."), |
| ("Что такое свобода?", "Свобода — возможность действовать по своей воле."), |
| ] |
| }, |
| ] |
|
|
| |
|
|
| def generate_dialog(): |
| template = random.choice(dialog_templates) |
| q, a = random.choice(template["dialog"]) |
| |
| variations = [ |
| a, |
| f"{a} А что вы думаете?", |
| f"{a} Это интересный вопрос!", |
| f"{a} Я надеюсь, это поможет.", |
| f"{a} Есть ещё вопросы?", |
| ] |
| answer = random.choice(variations) |
| |
| prefixes = ["Скажите, ", "А можно узнать, ", "Подскажите, ", "Интересно, ", ""] |
| prefix = random.choice(prefixes) |
| |
| dialog = f"Человек: {prefix}{q.lower()}\nАссистент: {answer}" |
| return dialog |
|
|
| def generate_long_dialog(): |
| turns = random.randint(5, 12) |
| lines = [] |
| |
| topics = ["работа", "учёба", "хобби", "путешествия", "наука", "искусство", "технологии", "здоровье"] |
| topic = random.choice(topics) |
| lines.append(f"Тема: {topic.capitalize()}") |
| |
| for i in range(turns): |
| if i % 2 == 0: |
| template = random.choice(dialog_templates) |
| q, _ = random.choice(template["dialog"]) |
| prefixes = ["Скажите, ", "А можно узнать, ", "Подскажите, ", "Интересно, ", ""] |
| prefix = random.choice(prefixes) |
| lines.append(f"Человек: {prefix}{q.lower()}") |
| else: |
| template = random.choice(dialog_templates) |
| _, a = random.choice(template["dialog"]) |
| responses = [ |
| a, |
| f"О, {a}", |
| f"Хорошо, {a}", |
| f"Да, {a}", |
| f"Верно, {a}", |
| f"Конечно же, {a}", |
| f"Без сомнения, {a}", |
| ] |
| lines.append(f"Ассистент: {random.choice(responses)}") |
| |
| return "\n".join(lines) |
|
|
| def generate_dialog_batch(): |
| count = random.randint(2, 5) |
| dialogs = [] |
| for _ in range(count): |
| if random.random() > 0.5: |
| dialogs.append(generate_long_dialog()) |
| else: |
| dialogs.append(generate_dialog()) |
| return "\n\n---\n\n".join(dialogs) |
|
|
| |
|
|
| class DatasetGenerator: |
| def __init__(self): |
| self.data = {"text": [], "dialog": [], "turns": []} |
| self.target_size = 100 * 1024 * 1024 |
| self.current_size = 0 |
| self.is_running = False |
| self.count = 0 |
| |
| self.load_existing() |
| |
| def load_existing(self): |
| if os.path.exists("/data/dialog_dataset"): |
| try: |
| dataset = load_from_disk("/data/dialog_dataset") |
| self.data["text"] = list(dataset["text"]) |
| self.data["dialog"] = list(dataset["dialog"]) |
| self.data["turns"] = list(dataset["turns"]) |
| self.count = len(self.data["text"]) |
| self.current_size = len(json.dumps(self.data, ensure_ascii=False).encode('utf-8')) |
| print(f"✅ Загружено {self.count} диалогов, {self.current_size // 1024 // 1024} МБ") |
| except Exception as e: |
| print(f"❌ Ошибка загрузки: {e}") |
| |
| def generate_batch(self, batch_size=100): |
| new_texts = [] |
| new_dialogs = [] |
| new_turns = [] |
| |
| for _ in range(batch_size): |
| if random.random() < 0.3: |
| dialog = generate_dialog_batch() |
| turns = random.randint(5, 15) |
| elif random.random() < 0.6: |
| dialog = generate_long_dialog() |
| turns = random.randint(5, 12) |
| else: |
| dialog = generate_dialog() |
| turns = random.randint(2, 4) |
| |
| new_texts.append(dialog) |
| new_dialogs.append(dialog) |
| new_turns.append(turns) |
| |
| return new_texts, new_dialogs, new_turns |
| |
| def generate_loop(self): |
| self.is_running = True |
| |
| while self.is_running and self.current_size < self.target_size: |
| texts, dialogs, turns = self.generate_batch(100) |
| |
| self.data["text"].extend(texts) |
| self.data["dialog"].extend(dialogs) |
| self.data["turns"].extend(turns) |
| |
| self.count += len(texts) |
| self.current_size = len(json.dumps(self.data, ensure_ascii=False).encode('utf-8')) |
| |
| if self.count % 1000 == 0: |
| self.save_dataset() |
| print(f"💾 Сохранено {self.count} диалогов, {self.current_size // 1024 // 1024} МБ") |
| |
| time.sleep(0.1) |
| |
| self.is_running = False |
| self.save_dataset() |
| print("✅ Генерация завершена!") |
| |
| def save_dataset(self): |
| os.makedirs("/data", exist_ok=True) |
| dataset = Dataset.from_dict(self.data) |
| dataset.save_to_disk("/data/dialog_dataset") |
| |
| with open("/data/dialog_dataset.jsonl", "w", encoding="utf-8") as f: |
| for i in range(len(self.data["text"])): |
| entry = { |
| "text": self.data["text"][i], |
| "dialog": self.data["dialog"][i], |
| "turns": self.data["turns"][i] |
| } |
| f.write(json.dumps(entry, ensure_ascii=False) + "\n") |
| |
| def get_status(self): |
| percent = (self.current_size / self.target_size) * 100 if self.target_size > 0 else 0 |
| return { |
| "count": self.count, |
| "size_mb": self.current_size // 1024 // 1024, |
| "target_mb": self.target_size // 1024 // 1024, |
| "percent": min(percent, 100), |
| "is_running": self.is_running |
| } |
|
|
| |
|
|
| generator = DatasetGenerator() |
|
|
| def start_generation(): |
| if generator.is_running: |
| return "⏳ Генерация уже запущена!" |
| |
| thread = Thread(target=generator.generate_loop) |
| thread.daemon = True |
| thread.start() |
| return "🚀 Генерация Minset запущена!" |
|
|
| def stop_generation(): |
| generator.is_running = False |
| return "⏹️ Генерация остановлена" |
|
|
| def get_status(): |
| status = generator.get_status() |
| progress_bar = "█" * int(status['percent'] // 2) + "░" * (50 - int(status['percent'] // 2)) |
| return f""" |
| 📊 **Minset - Статус генерации** |
| |
| 📝 Диалогов: **{status['count']}** |
| 💾 Размер: **{status['size_mb']} МБ / {status['target_mb']} МБ** |
| 📈 Прогресс: **{status['percent']:.1f}%** |
| 🔄 Состояние: **{'✅ Работает' if status['is_running'] else '⏸️ Остановлен'}** |
| |
| `{progress_bar}` |
| """ |
|
|
| def get_sample(): |
| if generator.count == 0: |
| return "Нет сгенерированных диалогов" |
| |
| idx = random.randint(0, generator.count - 1) |
| return f"**Пример диалога Minset #{idx}**\n\n{generator.data['text'][idx]}" |
|
|
| |
|
|
| with gr.Blocks(title="Minset Dataset Generator") as demo: |
| gr.Markdown(""" |
| # 🤖 Minset - Генератор датасета диалогов |
| |
| **Minset** — это датасет русских диалогов для обучения моделей. |
| |
| ⚠️ **Важно:** Модели **ОБУЧАЮТСЯ НА ЭТОМ ДАТАСЕТЕ**, а не являются им самим. |
| """) |
| |
| with gr.Row(): |
| with gr.Column(scale=1): |
| start_btn = gr.Button("▶️ Запустить генерацию Minset", variant="primary", size="lg") |
| stop_btn = gr.Button("⏹️ Остановить", variant="stop", size="lg") |
| |
| refresh_btn = gr.Button("🔄 Обновить статус", variant="secondary") |
| sample_btn = gr.Button("📝 Показать пример диалога", variant="secondary") |
| |
| status_output = gr.Markdown(get_status()) |
| sample_output = gr.Markdown("") |
| |
| start_btn.click(start_generation, outputs=[status_output]) |
| start_btn.click(get_status, outputs=[status_output]) |
| |
| stop_btn.click(stop_generation, outputs=[status_output]) |
| stop_btn.click(get_status, outputs=[status_output]) |
| |
| refresh_btn.click(get_status, outputs=[status_output]) |
| sample_btn.click(get_sample, outputs=[sample_output]) |
|
|
| if __name__ == "__main__": |
| demo.launch(share=True) |