Пилот П-2, нейросеть в игре и упрощённый ветер как в 0.8.0

Второй пилот нейросети ветра посчитан за ночь и день: на горах, которых сеть не видела, она в 4 раза точнее профиля притока и не даёт систематического смещения, но в 10 % точек ошибается сильно — на крутом рельефе. Параллельно сеть встроена в игру (ONNX на процессоре), и первый полёт на ней в Аскарово — «летабельно». По отзыву пилота вышли 1.0.3 (выбор модели ветра) и 1.0.4 (упрощённый ветер как в 0.8.0).

Пилот П-2: 360 реальных рельефов

Ночью ответы пользователя на вопросы шлюза: добавить крутую отложенную систему — Южные Альпы Новой Зеландии (15 мест); цель несошедшихся решений — среднее поздних состояний (решатель на слабом ветре колеблется, и честная цель — среднее); места с дном квадрата выше 3000 м не брать (решатель не учитывает высоту и широту: плотность, θ0 и Кориолис постоянны — это в риски следующей волны). Итог: 360 мест — пул 300 и 4 отложенные горные системы (Аппалачи, Кавказ, Пиренеи, Южные Альпы НЗ) по 15.

Счёт набора — 4320 случаев за ~8 ч на одной видеокарте (оценка была 10 ч). Не сошлось около 20 % — почти все на слабом ветре. Обучение один раз упало: подсчёт масштаба каналов копировал весь набор целей во float32 и не влез в 31 ГБ памяти; исправлено подсчётом кусками.

Итог на отложенных горных системах (60 м над рельефом, сошедшиеся решения):

сеть П-2профиль притока
ошибка ветра, медиана / p900,62 / 1,84 м/с2,46 / 7,86 м/с
доля «ок» по ветру (≤ max(0,3 м/с; 10 %))35 %10 %
подъём < 0,1 м/с (без / с нагревом)78 % / 72 %70 % / 62 %
среднее смещение скорости на 60 м+0,008 м/с+2,32 м/с

Вердикт правилом из чисел — «правим подход». Что видно:

  • смещения нет ни по высотам, ни по силе ветра; завышение ветра на Онгудае из первого пилота (+14 %) ушло;
  • на несошедшихся сеть ошибается на уровне собственного разброса решателя (медиана отношения 0,91);
  • даже на обучающих местах «ок» лишь 49 % — дело не только в данных, а в том, что сеть учит с нуля;
  • кривая по числу мест: 25 → 300 мест — 0,83 → 0,62 м/с, примерно −7 % на удвоение, полки нет, но данные дороги;
  • сеть — 13 МБ, 21 мс на процессоре в 4 потока.

Решения о направлении

Решения пользователя за день:

  • в игре решатель заменяется сетью, решатель остаётся офлайн как источник данных; скорость и стабильность важнее точности — «лучше чуть врать, но не тормозить игру, это всё-таки игра, а не метеорологический предсказатель погоды»; ошибка 10–15 % ветра на месте допустима — пилот примет её за порыв;
  • главный вопрос пилота — заменимость: воспроизводит ли сеть решатель в пределах погрешности самого решателя (по Askervein решатель занижает разгон на вершине на 15–20 %, то есть сам ошибается на ±10–20 %);
  • на слабом ветре стационарного поля может не быть вовсе (течение от плавучести нестационарно — как неустойчивость Рэлея — Бенара); сеть выдаёт гладкое среднее — и это правильно: изменчивость дают термики и болтанка.

Отдельная сеть для термиков не нужна: термики уже считаются формулами из литературы (Дирдорф, Аллен, Холтслаг — Бовилль) поверх поля, а нужные им величины сеть поля выдаёт.

Сеть в игре

Новая ветка: расширение Godot с ONNX Runtime (только процессор, сборки Linux и Windows), подготовка входа сети в GDScript (совпадает с Python до 7·10⁻¹²), поле ветра от сети, пункт настроек «Нейросеть (экспериментально)» и страж области применимости входа. Этап «Рассчитываем ветер» на сети П-2 — около 4 с, из них сама сеть — 56 мс, остальное — сборка поля в GDScript (ускорять позже).

Первый полёт на сети П-2, Аскарово: «в целом даже „летабельно“, совсем чего-то необычного нет».

Пилот П-3: физическая кодировка

Обсуждение с пользователем — как кодировать вход и выход, чтобы сети было что учить меньше. Сложился план следующего пилота на тех же данных, без пересчёта решателя:

  • база — линейная теория обтекания (потенциальное течение через FFT), сеть учит только нелинейную поправку (отрыв, устойчивость, нагрев);
  • выход — разгон и поворот относительно базы вместо u и v; вертикаль — отклонение от течения вдоль склона (у земли поток не может идти сквозь склон — граничное условие);
  • вход — уклоны рельефа на нескольких масштабах (на высоте z поток чувствует рельеф масштаба ~z), подсеточный рельеф из тайлов 25 м (обрыв внутри клетки 400 м), маска отрыва за подветренным склоном круче ~0,3 и её след по ветру;
  • упаковка профиля по высоте несколькими главными формами.

Отложено в уме: тройная плоскость признаков с вертикальным разрезом вдоль ветра, функция тока, безразмерные числа (Фруд, Ричардсон), гидравлика мелкой воды для седловин (Бернулли с неразрывностью), каскад окон 50/25 м вокруг пилота, батч случаев в решателе (на счёте видеокарта занята мелкими ядрами, а не вычислениями).

Выпуски по отзыву пилота

Пилот: игра иногда вылетает, и тогда спасает откат на 0.8.0 — «на 0.8.0 физика не такая правдоподобная, но терпимо ради полёта». Потом отзыв жёстче: «Не мучай 1.0. Стало хуже. Сейчас 0.8 лучше всех, практически идеальная».

  • 1.0.3: в настройках «Ветер над рельефом» — «Расчёт по рельефу» или «Упрощённый» (решатель на видеокарте не запускается) (1680475); «Апогей» по настоящим размерам. Автоотключения после вылета нет — решение пользователя, достаточно пункта в настройках.
  • Разбор «что изменилось с 0.8.0»: склон, подветренные зоны, термики и болтанка в упрощённом режиме — те же; изменился профиль ветра по высоте — в 1.x он зависел от времени дня и облачности (вечером и в пасмурную погоду на высоте заметно сильнее, в ясный полдень — слабее, чем в 0.8.0).
  • 1.0.4: в упрощённом режиме профиль как в 0.8.0 — степенной, α = 0,14, не больше ×1,8 от ветра на 10 м, не зависит от часа и неба (13449e5).
  • В главном меню — версия и короткий коммит сборки (2d7b6e9): по скриншоту сразу видно, на какой версии пилот.

Проверено: вес пилота и выбор полёта сохраняются между запусками; при переключении между 0.8.0 и 1.x сбивается только выбор новых крыльев, которых нет в 0.8.0.

dp: версии 7–10

Утилита процесса агентов за день прошла версии 7–10: фоновые запуски и общие замки GPU/CPU, правка карточки уже выданной задачи, терпимая сверка ключей отчёта, прогресс приёмки. Урок дня: dp gc удалил ветку и рабочую копию модуля, который уже влили в main, но задачи которого ещё шли, — вместе с окружением Python пилота. Теперь gc не трогает модуль с незакрытыми задачами и копии, на которые ссылаются другие (a0e21b3). Обсуждали и будущее: dp вырос в небольшой таск-трекер для ИИ-агентов; переписывать на Go пока незачем (скорость не узкое место, правки идут каждый час), MCP — тонким слоем для частых команд, если понадобится.