Вход: ExperimentConfig cfg
Инициализация: set_seed(cfg.seed), configure_gpu()
Загрузка данных: val_loader ← build_val_loader(cfg)
Кэш GPU: gpu_cache ← GPUValCache(val_loader) если cfg.cache_val_on_gpu
Screen (tiered): screen_cache ← GPUValCache(screen_loader) если cfg.fitness_tiered_enabled
Screen RAM: store ← ScreenCacheStore(cfg) если tiered + cache enabled
Контроллер батча: vram_ctrl ← VRAMBatchController(cfg)
Популяция: neat ← CnnNeat(cfg.population_size, ...)
neat.initialize_random_unique_population()
write_run_meta(cfg, neat)
для gen = 0, 1, ..., cfg.num_generations - 1:
# --- Оценка ---
batch_size ← vram_ctrl.current_batch_size
если cfg.fitness_tiered_enabled:
result ← evaluate_population_fitness_tiered(
pop, lineage, screen_cache, gpu_cache, cfg, store)
fitness ← result.scores # combined: full val для survivors, screen для остальных
иначе:
fitness ← evaluate_population_fitness(pop, gpu_cache, cfg)
neat.set_fitness_scores(fitness)
# --- Логирование и сохранение ---
log_top_k_metrics(neat, gen)
save_current_generation(neat, gen)
build_generation_summary(neat, gen) → generation_summary.json
update_live_dashboard(neat)
# --- Опциональный Periodic GD ---
если cfg.periodic_gd_enabled и gen % cfg.periodic_gd_every == 0:
run_periodic_gd_on_population(neat.population, train_loader, cfg)
# --- Адаптация VRAM ---
vram_ctrl.after_generation(neat.population)
# --- Screen-cache элит (post-GD веса) ---
если tiered и cache enabled:
elite_idx ← neat.select_elite(cfg.elite_percent)
refresh_elite_screen_cache(elites, elite_idx, gen, screen_cache, store)
# --- Отбор и размножение ---
если cfg.elite_refinement_enabled:
elites ← run_elite_refinement(neat, val_loader, train_loader, test_loader, cfg)
neat.evolve_from_elites(elites)
иначе:
elites ← neat.select_elite()
neat.evolve(elites)
gc.collect(); torch.cuda.empty_cache()
# --- Финальный отчёт ---
save_final_run_report(neat, cfg)
save_experiment_index(cfg)