Nord-AI / download_data.py
zerdovzad's picture
Upload 4 files
d831a32 verified
"""
╔══════════════════════════════════════════════════════════════════════════╗
║ PROJECT NORD — Крок 1: Завантаження датасету ║
║ ║
║ Просто запусти: ║
║ python download_data.py ║
║ ║
║ Воно запитає куди зберегти і почне качати. ║
║ Датасет: FineWeb-Edu (високоякісні освітні тексти англійською) ║
║ Розмір: ~40 GB тексту (JSONL формат) ║
╚══════════════════════════════════════════════════════════════════════════╝
Потрібно встановити один раз:
pip install datasets tqdm
"""
import json
import os
import sys
import time
def format_size(bytes_val: int) -> str:
"""Форматувати байти в людський вигляд."""
for unit in ["B", "KB", "MB", "GB", "TB"]:
if bytes_val < 1024:
return f"{bytes_val:.1f} {unit}"
bytes_val /= 1024
return f"{bytes_val:.1f} PB"
def download():
print("=" * 60)
print(" PROJECT NORD — Завантаження датасету")
print("=" * 60)
print()
# ── Запитати куди зберегти ──
default_path = os.path.join("D:", os.sep, "nord_dataset", "train_data.jsonl")
print(f" Куди зберегти датасет?")
print(f" (Enter = {default_path})")
user_path = input(" Шлях: ").strip()
save_path = user_path if user_path else default_path
# ── Запитати розмір ──
print()
print(" Скільки гігабайт завантажити?")
print(" Рекомендовано: 10 GB — швидкий тест")
print(" 40 GB — повне навчання")
print(f" (Enter = 40)")
size_input = input(" Розмір (GB): ").strip()
target_gb = float(size_input) if size_input else 40.0
target_bytes = int(target_gb * (1024 ** 3))
# Створити папку
os.makedirs(os.path.dirname(save_path) or ".", exist_ok=True)
print()
print(f" 📁 Зберігаємо в: {save_path}")
print(f" 📦 Цільовий розмір: {target_gb:.0f} GB")
print()
# ── Перевірити чи вже є частина файлу (для продовження) ──
bytes_written = 0
samples_written = 0
mode = "w"
if os.path.exists(save_path):
existing_size = os.path.getsize(save_path)
if existing_size > 0:
print(f" [!] Файл вже існує ({format_size(existing_size)})")
print(f" Продовжити дозавантаження? (y/n, Enter = y)")
choice = input(" > ").strip().lower()
if choice in ("", "y", "yes", "так", "д"):
bytes_written = existing_size
# Count existing lines
print(" Підраховуємо існуючі рядки...")
with open(save_path, "r", encoding="utf-8") as f:
samples_written = sum(1 for _ in f)
mode = "a"
print(f" Продовжуємо з {samples_written:,} зразків ({format_size(bytes_written)})")
else:
print(" Починаємо з нуля...")
if bytes_written >= target_bytes:
print(f"\n [✓] Датасет вже повний! ({format_size(bytes_written)})")
print(f" Тепер запускай: python train_nord.py")
return save_path
# ── Завантаження ──
print()
print(" [*] Підключаємося до HuggingFace...")
print(" [*] Датасет: HuggingFaceFW/fineweb-edu (sample-10BT)")
print(" Це високоякісні освітні тексти — найкраще для навчання LLM")
print()
try:
from datasets import load_dataset
except ImportError:
print(" [✗] Бібліотека 'datasets' не встановлена!")
print(" Виконай: pip install datasets")
sys.exit(1)
# Stream dataset — НІКОЛИ не вантажить все в RAM
dataset = load_dataset(
"HuggingFaceFW/fineweb-edu",
name="sample-10BT",
split="train",
streaming=True,
)
# Якщо продовжуємо — пропустити вже завантажені зразки
data_iter = iter(dataset)
if samples_written > 0:
print(f" [*] Пропускаємо {samples_written:,} вже завантажених зразків...")
for _ in range(samples_written):
try:
next(data_iter)
except StopIteration:
break
print(f" [*] Починаємо запис... (Ctrl+C щоб зупинити, можна продовжити пізніше)")
print()
t_start = time.time()
last_print = t_start
try:
with open(save_path, mode, encoding="utf-8") as f:
for sample in data_iter:
text = sample.get("text", "")
if not text or len(text) < 50:
continue
line = json.dumps({"text": text}, ensure_ascii=False) + "\n"
line_bytes = len(line.encode("utf-8"))
f.write(line)
bytes_written += line_bytes
samples_written += 1
# Прогрес кожні 2 секунди
now = time.time()
if now - last_print >= 2.0:
elapsed = now - t_start
speed = (bytes_written - (0 if mode == "w" else bytes_written)) / elapsed if elapsed > 0 else 0
pct = bytes_written / target_bytes * 100
bar_len = 30
filled = int(bar_len * min(pct, 100) / 100)
bar = "█" * filled + "░" * (bar_len - filled)
print(
f"\r [{bar}] {pct:.1f}% "
f"{format_size(bytes_written)}/{format_size(target_bytes)} "
f"{samples_written:,} зразків "
f"{format_size(int(speed))}/s ",
end="", flush=True,
)
last_print = now
# Flush periodically
if samples_written % 10000 == 0:
f.flush()
# Досягли цільового розміру
if bytes_written >= target_bytes:
break
except KeyboardInterrupt:
print(f"\n\n [⏸] Зупинено! Збережено {format_size(bytes_written)} ({samples_written:,} зразків)")
print(f" Щоб продовжити пізніше — просто запусти цей скрипт знову.")
return save_path
elapsed = time.time() - t_start
print(f"\n\n {'═' * 50}")
print(f" [✓] ГОТОВО!")
print(f" 📁 Файл: {save_path}")
print(f" 📦 Розмір: {format_size(bytes_written)}")
print(f" 📝 Зразків: {samples_written:,}")
print(f" ⏱ Час: {elapsed/60:.0f} хвилин")
print(f" {'═' * 50}")
print()
print(f" Наступний крок:")
print(f" python train_nord.py")
print()
return save_path
if __name__ == "__main__":
download()