По требованию пользователя «не сохранять всё подряд, а только то, что нужно для эволюции»: рядовые геномы поколения больше НЕ пишутся строками в runs — писатель получает лёгкие StatsOnly-инкременты (счётчики, гистограмма, причины отказов на дашборде остаются честными по ВСЕМ оценкам), а полная строка пишется только когда лучший геном острова улучшился (+ полировка). Вставка миллионов строк в HDD-базу с 6 индексами была узким местом конвейера: GPU считал цикл ~23 мин, дозапись хвоста очереди шла часами (~150 строк/с), реальная скорость была ~165 оценок/с вместо ~1300/с. gpu_record_worker стал не нужен — удалён. Выборка эволюции уменьшена до 10000 на поколение (8 островов x 1250, было 8x4000=32000) — по просьбе пользователя, чтобы поколения сменялись быстрее; поколений за цикл теперь 120 (было 60) — при освобождённом писателе цикл углубляется вдвое дальше за то же время.
38 lines
2.4 KiB
Bash
Executable File
38 lines
2.4 KiB
Bash
Executable File
#!/bin/bash
|
||
# Вечная эволюция на GPU: бесконечный конвейер циклов. Каждый цикл — свежая
|
||
# случайная популяция («революция» против застревания в локальном оптимуме),
|
||
# всё пишется в одну базу, дашборд показывает лучший за всё время.
|
||
# Развёртывание: см. deploy/README.md; systemd-юнит: gausse-evolve.service.
|
||
cd /home/user/gausse
|
||
source .venv/bin/activate
|
||
LOG=results/gausse.sqlite3.log
|
||
cycle=1
|
||
while true; do
|
||
best=$(python3 - <<'PY'
|
||
import sqlite3
|
||
try:
|
||
c = sqlite3.connect("results/gausse.sqlite3")
|
||
# НЕ max(): он сканирует всю базу (гигабайты); частичный индекс отдаёт мгновенно
|
||
row = c.execute("select efficiency from runs indexed by idx_runs_feas_eff "
|
||
"where feasible=1 order by efficiency desc limit 1").fetchone()
|
||
print(f"{row[0]*100:.2f}%" if row and row[0] is not None else "пока нет")
|
||
except Exception:
|
||
print("пока нет")
|
||
PY
|
||
)
|
||
echo "$(date -Is) ═════ ЦИКЛ #$cycle стартует (конвейер бесконечный; лучший КПД за всё время: $best) ═════" >> "$LOG"
|
||
# выборка 10000 на поколение (8 островов x 1250) — по просьбе пользователя:
|
||
# меньше популяция + больше поколений за цикл = быстрее углубляется.
|
||
# Рядовые оценки в базу не пишутся (только счётчики) — писатель больше
|
||
# не душит конвейер, GPU занят почти всё время цикла.
|
||
python3 -c "from pathlib import Path
|
||
from gausse.optim.evolutionary import run_evolution
|
||
try:
|
||
run_evolution(Path('results/gausse.sqlite3'), n_generations=120, population_size=1250, seed=None, polish=True, use_gpu=True, islands=8)
|
||
except KeyboardInterrupt:
|
||
pass # штатная остановка сервиса: база уже дописана в finally"
|
||
echo "$(date -Is) ═════ ЦИКЛ #$cycle завершён — это НЕ остановка: через 3с стартует цикл #$((cycle+1)) со свежей случайной популяцией ═════" >> "$LOG"
|
||
cycle=$((cycle+1))
|
||
sleep 3
|
||
done
|