Spaces:
Running
Running
| """ | |
| prepare_data.py — скачивает датасет и готовит .txt файлы для обучения. | |
| Использует датасет текстов песен с HuggingFace (не требует токена). | |
| """ | |
| import os | |
| from pathlib import Path | |
| TRAIN_DIR = Path("data/train") | |
| VAL_DIR = Path("data/val") | |
| TRAIN_DIR.mkdir(parents=True, exist_ok=True) | |
| VAL_DIR.mkdir(parents=True, exist_ok=True) | |
| # Если данные уже есть — пропускаем | |
| train_files = list(TRAIN_DIR.glob("*.txt")) | |
| if train_files: | |
| print(f"[Data] Данные уже есть ({len(train_files)} файлов). Пропускаем скачивание.") | |
| exit(0) | |
| print("[Data] Скачиваем датасет...") | |
| try: | |
| from datasets import load_dataset | |
| # Датасет текстов песен — английский, публичный, без авторизации | |
| # ~400k песен, каждая со словами | |
| ds = load_dataset( | |
| "MB24/genius-lyrics", # публичный датасет текстов песен | |
| split="train", | |
| trust_remote_code=True, | |
| ) | |
| print(f"[Data] Загружено {len(ds)} записей") | |
| # Берём первые 50k для обучения, 5k для валидации | |
| train_texts = [] | |
| val_texts = [] | |
| for i, item in enumerate(ds): | |
| # Поле с текстом песни | |
| lyrics = item.get("lyrics") or item.get("text") or item.get("content") or "" | |
| if not lyrics or len(lyrics) < 50: | |
| continue | |
| # Чистим текст | |
| text = lyrics.strip() + "\n\n" | |
| if i % 10 == 0: | |
| val_texts.append(text) | |
| else: | |
| train_texts.append(text) | |
| if len(train_texts) >= 50000: | |
| break | |
| print(f"[Data] Train: {len(train_texts)}, Val: {len(val_texts)}") | |
| # Сохраняем чанками по 5000 записей в файл | |
| chunk_size = 5000 | |
| for chunk_i, start in enumerate(range(0, len(train_texts), chunk_size)): | |
| chunk = train_texts[start:start + chunk_size] | |
| out_path = TRAIN_DIR / f"genius_train_{chunk_i:03d}.txt" | |
| out_path.write_text("".join(chunk), encoding="utf-8") | |
| print(f"[Data] Записан {out_path} ({len(chunk)} текстов)") | |
| val_path = VAL_DIR / "genius_val.txt" | |
| val_path.write_text("".join(val_texts[:1000]), encoding="utf-8") | |
| print(f"[Data] Записан {val_path}") | |
| except Exception as e: | |
| print(f"[Data] Ошибка загрузки датасета: {e}") | |
| print("[Data] Пробуем альтернативный датасет...") | |
| try: | |
| from datasets import load_dataset | |
| # Запасной вариант — WikiText на русском/английском | |
| ds = load_dataset("wikimedia/wikipedia", "20231101.ru", split="train", streaming=True, trust_remote_code=True) | |
| train_texts = [] | |
| val_texts = [] | |
| for i, item in enumerate(ds): | |
| text = item.get("text", "").strip() | |
| if len(text) < 100: | |
| continue | |
| text = text[:2000] + "\n\n" # берём первые 2000 символов статьи | |
| if i % 10 == 0: | |
| val_texts.append(text) | |
| else: | |
| train_texts.append(text) | |
| if len(train_texts) >= 20000: | |
| break | |
| chunk_size = 5000 | |
| for chunk_i, start in enumerate(range(0, len(train_texts), chunk_size)): | |
| chunk = train_texts[start:start + chunk_size] | |
| out_path = TRAIN_DIR / f"wiki_train_{chunk_i:03d}.txt" | |
| out_path.write_text("".join(chunk), encoding="utf-8") | |
| val_path = VAL_DIR / "wiki_val.txt" | |
| val_path.write_text("".join(val_texts[:500]), encoding="utf-8") | |
| print(f"[Data] Wikipedia датасет загружен успешно") | |
| except Exception as e2: | |
| print(f"[Data] Ошибка запасного датасета: {e2}") | |
| print("[Data] Создаём минимальные демо-данные...") | |
| demo = ( | |
| "Языковая модель обучается на текстах.\n" | |
| "Нейронные сети — основа современного ИИ.\n" | |
| "Трансформеры используют механизм внимания.\n" | |
| "Python — язык для машинного обучения.\n" | |
| ) * 500 | |
| (TRAIN_DIR / "demo.txt").write_text(demo, encoding="utf-8") | |
| (VAL_DIR / "demo_val.txt").write_text(demo[:5000], encoding="utf-8") | |
| print("[Data] Демо-данные созданы.") | |
| print("[Data] Подготовка данных завершена.") | |