air-nn — журнал хода работ
Журнал продолжается в
tools/dp:docs/plan/air-nn/(tools/dp status air-nn,tools/dp log air-nn). Ниже — история до 02.10 23:00.
План — docs/plan/air_nn.md; контракты — docs/contracts/air-nn.md. Ветка feature/air-nn (от main 9360397),
копия ~/deltaplan-air-nn. Координатор — dp-coordinator.
Текущая цель (02.10.2026, от главной сессии)
Подготовить этап П к запуску: окружение, данные, один скрипт run_pilot.sh (досчёт → обучение → оценка → отчёт,
с продолжением после прерывания), проверка мини-прогоном и прерываниями. Сам пилот запускает пользователь.
Решения
- 02.10:
AIR_NN_DATA=~/air_nn_data(корневой диск, ~48 ГБ свободно; диск 1–2 ТБ — открытый вопрос §10.0). - 02.10: решения air-lite (49/688) не сохранились —
fields/*.npzбыли вне git в удалённой копии; в ветке есть толькоout/runs.jsonl(метаданные и время). Пересчитываются генератором пилота с нуля (дёшево, см. ниже). - 02.10: время случая по
runs.jsonl(сумма t_init + t_solve всех решений случая): встроенные места — 21,8 с (область 13,7 с), синтетика — 9,9 с (область 7,9 с); 8 из 49 случаев —max(предел итераций). Оценка плана 688 случаев ≈ 3–4 ч GPU; +40 процедурных рельефов × ~30 условий ≈ 4 ч — меньше одной ночи. - 02.10: окружение пилота — свой
.venv(uv, Python 3.12), версии —requirements.lock(torch cu126, cupy-cuda12x, onnx, onnxruntime),setup_env.sh; системный python не трогаем. - 02.10: контракты пилота П1 (образец набора), П2 (вход/выход сети), П3 (отчёт) —
docs/contracts/air-nn.md. - 02.10: формат образца — раскладка air-lite (
npz, fp16) без изменений; Zarr и полныйstate.sqliteволны 0 — не в пилоте (кроме статусов случаев в SQLite и атомарной записи — §4.6).
Задачи
| Задача | Статус | Исполнитель | Копия / ветка | Коммиты | Числа, решения |
|---|---|---|---|---|---|
| NN-P1 — генератор набора пилота (досчёт air-lite + процедурные рельефы, SQLite, продолжение) | принята (02.10) | dp-researcher | влита, копия удалена | a02ec7c, f071978, 514422e, ad1fcf1; слияние f015853 | dataset.py plan/run/status/export/path; main = 690 air-lite (не 688 — опечатка плана) + 40 p_* × 30 = 1890 случаев; план air-lite воспроизведён побитно (тест); тест прерывания: 4×kill -9 + SIGINT → 8/8 файлов побитно равны непрерванному; замер: встроенные ~23 с/случай, синтетика ~10 с, процедурные ~4–12 с; оценка ~7,5 ч GPU, ~3,8 ГБ; версия решателя s0-3acd749 |
NN-P2 — обучение, оценка (а)/(б)/(в), отчёт, ORT, run_pilot.sh | принята (02.10) | dp-researcher | влита (b40931c), копия удалена | 4135bcc, 7082e50, 01f4d08, 9415419, 34c062a, 9efabd0, 8374401, 875a5cc, bb5eedc | U-Net+FiLM 3,22 млн парам.; эпоха 1220 образцов 10,6 с (детерм.); оценка полного прогона без досчёта ≈ 1,25 ч (150 эпох, верхняя граница); тест прерываний smoke: 913 чисел metrics.json побитно равны непрерванному; ORT↔PyTorch 1,55e-6; ONNX 13 МБ fp32, ORT Xeon 4 потока 18–20 мс, 1 поток 45–49 мс; dev (48 случаев): ветер на 60 м медиана 0,67 против 1,18 м/с у профиля притока; контракт П2 → v2 (координатные карты x′, y′) ; smoke = ongudai, s_hill, p_000…p_002 × 3 (15 случаев) — все разделы отчёта (а)/(б)/(в 2 точки) заполнены; тест прерываний на новом smoke: 1712 чисел, отличалось только gpu_lock_wait_s (не метрика, исключено); test_prep зелёный (перепроверено) |
| NN-P3 — независимая проверка: мини-прогон по README, прерывания, оценка времени | отменена (02.10, решение пользователя) | dp-mechanic (Sonnet) | — | — | ждала конца досчёта main; ничего не запускала; пилот пользователь запускает сам |
- 02.10 (пользователь, через главную сессию):
run_pilot.shв tmux показывает «этап n из N: название» + одну обновляемую строку «сделано/всего, %, ETA» в единицах этапа; после продолжения счётчики учитывают сделанное; подробный лог — в файл. Передано NN-P2 (владелец скрипта) и NN-P1 (выводrunв файл, прогрессstatus --json). - 02.10: полный досчёт main запущен координатором фоном:
dp job start airnn_gen_main 57600 … dataset.py run --dataset main --log ~/air_nn_data/pilot/logs/dataset_main_precompute.log(PID 79562, 14:16); первые ETA 4–6 ч. Прерывание безопасно —run_pilot.shпродолжит. - 02.10 (пользователь, через главную сессию): параллельно с пилотом — NN-2а (таблица параметров поверхности по литературе, Sonnet) и NN-7а (пробник ORT ↔ Godot GDExtension, Linux + выяснить Windows/macOS); без GPU, пилот приоритетнее. Контракты П4, П5.
| Задача | Статус | Исполнитель | Копия / ветка | Коммиты | Числа, решения |
|---|---|---|---|---|---|
| NN-2а — таблица α, β, z0, G/Rn по WorldCover (литература) | принята (02.10) | dp-researcher (Sonnet) | влита, копия удалена | 778c2ab | docs/research/surface_params.{md,csv}, 11 классов + snow_fresh/snow_old, CSV по П4 (столбцы и диапазоны проверены); прямо прочитаны Oke 1987 и Wilson 2002, остальное — вторично (помечено); 6+ оценок EST (β кустарника, мхов, мангров, влажного грунта; G/Rn мангров; α скал и кода 70); для NN-2: H по формуле Боуэна для тающего снега неприменим — ограничивать H снега; замыкание баланса FLUXNET ≈ 80 %; вопрос: делить ли класс 10 на хвойный/лиственный |
| NN-7а — пробник ORT ↔ Godot (GDExtension), Windows-сборка | принята (02.10) | dp-engineer | влита, копия удалена | 5c1b5f7 | native/air_nn_probe/ (build.sh all с нуля 3 мин 31 с), тест tests/air_nn/test_air_nn_probe.gd (без сборки — пропуск); перепроверено: max|Δ| = 0 против ORT Python, run 1,5 мс (1 поток) / 0,9 мс (4 потока) на пустышке [1,4,96,96]; ORT 1.30.0, godot-cpp 10.0.0 (API 4.7); Linux .so 0,64 МБ + ORT 28,9 МБ; Windows DLL собрана llvm-mingw, запуск не проверен (нет wine), нужны VC++ DLL; macOS — только способ (CI macos-14, ORT только arm64); находка: libdd3d (debug_draw_3d) экспортирует символы libstdc++ как GNU_UNIQUE → ORT падал → ORT грузится через dlmopen; контракт П5 → v2 |
- 02.10: открытые вопросы NN-7а для NN-7/N5 (не решаются сейчас): штатный путь на Linux — dlmopen или пересборка libdd3d со скрытыми символами; проверка на экспортированной сборке; размер ORT (+29 МБ Linux / +16,5 МБ Windows, minimal build — своя сборка ORT); проверка запуска на Windows (CI или машина пилота); Intel-Mac без готового ORT.
- 02.10 (пользователь, через главную сессию):
addons/debug_draw_3dудаляем полностью вместе с Debug Menu (F2); остаётся FPS по F1, стрелки ветра F5 — свой меш. В плане — задача NN-7б (предусловие NN-7,dp-engineer, 0,5 д), сейчас не исполняется (пилот приоритетнее). Контракт П5: после NN-7б — обычныйdlopen. - 02.10 (пользователь подтвердил): F5 (стрелки ветра) остаётся, перерисовать своим мешем — решение пользователя, не вариант по умолчанию.
- 02.10 18:08: досчёт main мягко остановлен координатором (SIGTERM, код 2) на 1263/1890 (max 147, failed 0):
GpuLockNN-P1 ждёт опросом LOCK_NB и голодает, покаrun mainперезахватывает замок сразу после пачки (нашёл NN-P2 — smoke 40+ мин не мог взять замок). Правка (пауза после пачки + блокирующий flock с прерыванием сигналом) — в ветке NN-P2; досчёт перезапускается с исправленным кодом. - 02.10: правка замка GPU в
dataset.py(NN-P2) отклонена системой прав — не обходим, вопрос пользователю в отчёте; досчёт main перезапущен на прежнем коде (шаги обучения/оценки ждут блокирующим flock и проходят между пачками; голодает только второйdataset.py runпри идущем main). - 02.10 (решение пользователя): правка замка GPU в
tools/research/air_nn_pilot/dataset.py(GpuLock) одобрена — блокирующийflockс прерыванием сигналом вместо опроса LOCK_NB + пауза ~2 с после пачки; только скрипт пилота, чужие скрипты и путь замка не меняются. Задача NN-P1б (dp-researcher, Sonnet),~/deltaplan-air-nn-lockfix,air-nn/lockfix. Идущий досчёт main не прерывается — новый код подхватится при следующем запуске. - 02.10: NN-P1б принята (
dp-researcherSonnet, b28d6a0, слияние в feature/air-nn):GpuLock— блокирующий flock +stop.in_lock→Abandonпо сигналу; пауза 2 с после пачки. Тест прерывания NN-P1 зелёный (8/8 файлов побитно, дублей 0) при идущем main: ожидание замка 297/313/304 с — голодания нет; SIGINT во время ожидания замка → код 2, замок не взят. Идущий досчёт main — на старом коде (не прерывался), новый код — со следующего запуска. - 02.10 (решение пользователя): NN-P3 не проводить; пилот пользователь запускает сам сразу после досчёта main.
Команда:
cd ~/deltaplan-air-nn/tools/research/air_nn_pilot && ./setup_env.sh && tmux new -s pilot './run_pilot.sh; exec bash'; оценка ≈ 1,25 ч (верхняя граница) + остаток досчёта. Этап П подготовлен; дальше — шлюз ШП по отчёту~/air_nn_data/pilot/reports/<дата>_pilot/report.md.
Этап П-2 (повторный пилот на реальных рельефах)
- 02.10: итог ШП (прогон
2026-10-02_pilot,pilot/reports/2026-10-02_pilot/report.md): правилом — «правим подход и повторяем пилот». Сеть лучше базовых линий (ветер на 60 м в ~2,5 раза точнее профиля притока на знакомом и отложенных процедурных; подъём 89–92 % < 0,1 м/с; ORT 19 мс / 4 потока); переобучение (проверка на полке ≈ 0,42 с ~30-й эпохи; 1188 случаев, 44 рельефа); Онгудай — завышение ветра при сильном ветре (ongudai_007 +1,7 м/с, +14 %), вход вне диапазона: медианный уклон 400 м Онгудая 0,22 (p95 0,39, размах 1964 м) против процедурных 0,016 (p95 0,12, ~720 м); кривая (в) по ветру падает (ongudai 1,16 → 0,82), подъём — полка; решенияmax(238/1890) ошибку не меняют. - 02.10 (решения пользователя — в плане «02.10.2026, итог первого пилота»): П-2 на 300 реальных рельефах (+ готовые
1890); рельеф путём рантайма игры (Terrarium как
terrarium_loader.gd, без сглаживания, клетки 400 м); 300 квадратов 38,4 км стратифицированно по уклону/размаху, отложенные горные системы — главная оценка, Онгудай вне обучения; вход —- карты уклона вдоль/поперёк точного ветра, TPI ~2 и ~8 км, затенённость на ветер; только область 400 м, 10–12 условий на место; критерий ШП-2 — ветер ≤ max(0,3; 10 %) и подъём < 0,1 в ≥ 90 % точек + нет смещения; стадии пачкой, параллельно CPU/GPU, прерываемо; массовый счёт — по согласованию.
- 02.10: контракты — П1 v2 (набор
terrain: только область, местаt_*, несколько наборов), П2 v3 (9 карт: + уклон вдоль/поперёк, TPI 2/8 км, Sx Winstral; деление с отложенными системами, кривая 25…300, точка 300 = основная сеть), П3 v2 (точки — вся область на 60 м и гребни; ок ветра ≤ max(0,3; 10 %); смещение по высотам/U10/гребням), П6 v1 (вырезка места: путь рантайма → сетка 25 м → клетки 400 м,index.csv,cut/<id>.npz; контрактный тестtests/test_contract_terrain.py). Расхождение с игрой записано:AirPlace.block_meanна слое рантайма берёт f = round(400/s) узлов (клетка f·s ≠ 400 м) — исправлять в NN-4/N1. - 02.10: решения координатора (в пределах плана): вода у мест
t_*— нет (озёра как суша, граница пилота); дата —reference_context(как игра для выбранной точки; в южном полушарии — зима); отложенные системы — сверх 300 мест пула (кривая до 300); точка кривой 300 = основная сеть (экономия обучения); порог смещения — предложение (max(0,1 м/с; 2 %)), подтверждает пользователь.
| Задача | Статус | Исполнитель | Копия / ветка | Коммиты | Числа, решения |
|---|---|---|---|---|---|
| NN-P4 — рельефы: выбор, скачивание, нарезка (П6) | остановлена (02.10, СТОП) | dp-researcher | ~/deltaplan-air-nn-terrain / air-nn/terrain (на 4d9d663) | — (кода нет) | разбор: Terrarium ~1 с/тайл, 50–100 КБ, 16 потоков ≈ 15 тайлов/с; над океаном — отрицательные глубины (правило «≤ 0,5 м — море» работает; Каспийская низменность отсеется); для побитного R.grid_domain = hc400 — h в float64 в places.location; requests не нужен (urllib). План: screen z5 (маска гор) → z8 (все кандидаты) → z10 (~2–3 тыс. + отложенные), сетка кандидатов без перекрытия; select — слои уклона p50 0/0,06/0,12/0,2/0,3/0,4/∞ по 50 мест, предел доли системы; отложенные Кавказ/Пиренеи/Аппалачи по 15; оценка ≈ 19 тыс. тайлов z12, ~1,7 ГБ сырья + ~2,8 ГБ вырезок, ~25 мин загрузки (+ экран ~1–1,5 ГБ) — не проверено пробой |
| NN-P5 — вход П2 v3, деление, оценка и отчёт П3 v2 | остановлена (02.10, СТОП), часть сделана | dp-researcher | ~/deltaplan-air-nn-inputs / air-nn/inputs | 28b0ac5 (не влит) | готово: 9 карт П2 v3 в prep.py (константы — как в контракте), test_prep.py (плоскость при любом угле — ±1e-9, гора: TPI/Sx/уклон, поворот ×4, MAP_NAMES) зелёный на smoke; не сделано: split.py v3, data.py (несколько наборов), кеш подготовки по набору (prep_dirs), pilot.py, evaluate.py/report.py П3 v2, подставной П6 (tests/make_mock_p6.py: t_0000…t_0009 из случаев main), удаление профиля dev, README, замер времени обучения; кривая/оценка/test_interrupt_train с 9 картами не перепроверены |
| NN-P6 — генератор П-2: только область, воркеры GPU, замер | остановлена (02.10, СТОП) | dp-researcher | ~/deltaplan-air-nn-gen2 / air-nn/gen2 (на 4d9d663) | — (кода нет) | разбор по main (только область, сумма двух решений): встроенные ср. 10,1 с (мед. 2,3; max 16 %), процедурные 7,5 (1,7; 12 %), синтетика 5,5 (1,3; 9 %); случай max ~55–60 с ≈ 90 % времени GPU; ~100 итер/с на 96×96×~40 — похоже на упор в задержки (воркеры должны помочь — проверить). План: окна = пустой список в solve_case; terrain/probe (probe — подмножество плана terrain); lru_cache мест чистить (345 × ~10 МБ); подстановка П6 AIRNN_TILES_SHIM=1 до NN-P4; воркеры: родитель держит runner.lock и замок GPU, N spawn-воркеров с «шлюзом» на пачку, PDEATHSIG, workers.lock, SIGUSR1 — бросить случай; замер N=1…4 на 12 случаях main (4 max + 8 ok) с проверкой побитности |
NN-P7 — сборка П-2 в run_pilot.sh, smoke, прерывания | не начата | — | — | — | ждёт NN-P4…P6 |
- 02.10: СТОП по решению пользователя (меняется способ ведения журналов и заданий — утилита
dp; продолжим позже). Исполнители остановлены, фоновых прогонов и процессов модуля нет; вmainничего не вливалось, не пушилось. Копии задач оставлены (в каждой незакоммиченный симлинкtools/research/air_nn_pilot/.venv→ venv копии модуля — не коммитить):~/deltaplan-air-nn-terrain,~/deltaplan-air-nn-inputs(28b0ac5),~/deltaplan-air-nn-gen2. - 02.10: контракт П6 v1 уточнён (вопрос NN-P4): неперекрытие квадратов пула — |Δx| ≥ 38,4 км или |Δy| ≥ 38,4 км.
- Открытые вопросы (пользователю при продолжении): верхний предел размаха квадрата (NN-P4 предлагает ~3000 м — в Гималаях 4–5 км, число уровней решателя растёт с размахом); порог смещения ШП-2 max(0,1 м/с; 2 %); выбор отложенных систем (Кавказ, Пиренеи, Аппалачи).
- Следующий шаг: перезапустить NN-P4, NN-P5, NN-P6 свежими исполнителями в тех же копиях/ветках с прежними заданиями + планы из строк выше (NN-P5 — с пункта «split.py v3», поверх 28b0ac5); затем NN-P7; затем пробный замер времени и готовая команда массового счёта — на согласование пользователю.