Модули
Что такое модуль и как платформа с ним обходится: папка и версии, режимы жизни и выгрузка, окружение Python, рабочая папка, память узла, параметры, нейросети.
Введение
Документ описывает модуль, его встраивание в рабочий процесс, размещение зависимостей и назначение OGAS SDK. Хозяин модулей — функция modules. Формат манифеста — Форматы файлов, раздел 4, сообщения модуля и методы функции — Методы модулей.
1 Назначение модуля
Модуль — отдельная программа, выполняющая одну задачу: получает пакет на вход и отдаёт результат на выход. Назначение модуля не ограничено. Модуль человек пишет сам или получает готовым от другого человека.
- Модуль не знает о платформе и других модулях. Всё, что нужно для встраивания, он объявляет в манифесте: входы, выходы, параметры (раздел 10), допустимость повтора его шагов, предел времени.
- Модуль запускается отдельным OS-процессом: его отказ не останавливает платформу.
- Модуль работает в рабочей папке прогона, а не рядом со своим кодом (раздел 6).
- Модуль — доверенный код и работает с правами пользователя. Модуль, полученный от другого человека, равнозначен любой загруженной программе: платформа не проверяет, что он делает (Защита, 3.1).
2 Папка модуля
modules/<module_id>/
manifest.json манифест ogas.module/1
main.py точка входа
requirements.txt зависимости Python, если есть
uv.lock | pylock.toml точные версии зависимостей, если автор их положил; платформа их не читает (раздел 5)
requirements.freeze.txt что поставил pip, для диагностики
locales/{ru,en}.json название модуля, тексты его параметров и портов (раздел 10)
test_<module_id>.py проверки модуля без платформы, если автор их написал
Готовый модуль добавляют одним из двух способов: кладут его папку в modules/ или добавляют вместе с процессом из экспорта (process.inspect, затем process.import, Сборка, установка и обслуживание, 5.6). Список модулей перечитывается из папки при каждом запросе, перезапуск не требуется. Тексты нового модуля тоже видны сразу: функция модулей при знакомстве объявляет ядру папку словарей modules/*/locales, и ядро находит словари модулей заново при каждом вопросе (Обмен с ядром, раздел 4). Далее выполняются проверка манифеста, установка зависимостей, тестовый вызов и добавление узла в граф (С чего начать, 6). Все эти действия выполняются в мастерской без ручного копирования. Создают и удаляют модуль, решают, предлагает ли его колонка графа, в библиотеке мастерской, а окружение программы ставят в окне «Модули» этой программы (Мастерская, 5.6).
3 Версии
В одной установке у каждого module_id одна версия. Версия модуля в процессе записана в одном месте — в modules.lock.json; узел графа её не хранит. Записывает её функция модулей, когда процесс сохраняют: берёт версию и отпечаток из установленного модуля. Неустановленный модуль в modules.lock.json не записывается. Перед прогоном функция графа сверяет записанную версию с установленной и передаёт её в module.execute; при несовпадении запуск отклоняется (module_version_mismatch).
Отпечаток содержимого. Файлы модуля можно изменить без изменения версии. Чтобы такое изменение было обнаружено, процесс вместе с версией запоминает отпечаток модуля — sha256 по содержимому файлов, без окружения, кэшей, диагностики и символьных ссылок (ссылка не является частью модуля и экспортом не переносится). Перед прогоном отпечаток сверяется с установленным модулем:
- при расхождении отпечатков запуск отклоняется с
module_changedи подсказкой сохранить процесс, если изменение намеренное; - сохранение процесса переписывает
modules.lock.jsonвместе с отпечатком. Сохранение является принятием изменений: отдельного режима «черновик» нет, так как режимы в платформе отсутствуют; - при отсутствии отпечатка в
modules.lock.jsonзапуск проверяет только версию.
Отпечаток показывает изменение файлов, но не указывает автора изменения: он не является подписью, и модуль остаётся доверенным кодом (Защита, раздел 1).
4 Режимы, выгрузка и параллельность
Время существования OS-процесса модуля объявляет поле process манифеста:
step— OS-процесс модуля существует в течение одного вызова.long— OS-процесс держит состояние между вызовами одного прогона. При отказе модуля состояние теряется; восстановить его может только сам модуль — по входам или по файлам результатов. Долгий модуль принадлежит одному прогону: после прогона выгружаются его долгие модули командойmodule.releaseсrun_id, а модули других прогонов, даже того же модуля, остаются (Программа: граф и запуски, раздел 13).service— служба: OS-процесс запускается при включении программы и работает до её выключения, обслуживая шаги всех её прогонов. Так работает, например, языковая модель, загрузка которой на каждое сообщение неприемлема по времени. Служба может также самостоятельно выдавать пакеты на свои выходы (уведомлениеemit, раздел 7) — в этом случае она является источником событий: такой пакет начинает новый прогон (Программа: граф и запуски, раздел 5). Что служба обслуживает — какую папку смотреть, какой порт слушать, — она узнаёт до первого шага: при каждом поднятии ей приходят узлы её модуля с их параметрами (configure, раздел 7); служба нескольких узлов называет вemitузел, для которого пакет. Правило наложения пакетов службы — полеoverlapеё узла (Программа: граф и запуски, раздел 5).
Выгрузка по ресурсам. Функция модулей учитывает запущенные модули всех включённых программ и знает, сколько видеопамяти занимает каждый: поле resources.gpu_mb манифеста. Пока сумма укладывается в настройку modules.gpu_budget_mb, модули работают одновременно; при 0 видеокартой одновременно пользуется один модуль с gpu_mb > 0. Когда для очередного модуля не хватает места, функция модулей выгружает тот, что дольше всех не работал, — долгий или службу любой включённой программы. Модуль во время шага не выгружается: шаг, которому нужна видеокарта, ожидает освобождения места не дольше своего срока (timeout_ms), а не дождавшись, завершается отказом module_gpu_full.
Память узла. Модуль — инструмент, узел — его применение: «писатель» и «судья» на одной модели — два узла и две памяти. Модуль в запуске один на все свои узлы, и веса загружаются один раз, а память у каждого узла своя — папка data/processes/<process_id>/state/<node_id>/; как узлы называют общую память и сколько она живёт — Программа: граф и запуски, раздел 13. Со стороны модуля:
- папка памяти приходит с каждым шагом узла в поле
state_dirвместе с признакомresumed(раздел 7); - модуль с
suspend: trueперед выгрузкой получаетsuspendи сохраняет память каждого узла, который обслужил, в папку этого узла; модуль безsuspendзавершается, и его узлы в следующий раз начинают сначала; - сохранение функция модулей подтверждает отметкой рядом с папкой каждого узла; перед тем как попросить модуль сохраниться, она убирает прежние отметки, так что память, запись которой оборвалась, отметки не имеет (Форматы файлов, 5.3);
resumed: trueприходит, если отметка папки есть и названы в ней те же модуль, версия и отпечаток, — в любом запуске и после перезапуска платформы: чат-бот освобождает видеокарту для модуля изображений и потом продолжает разговор;- что сохранять и как, решает модуль; платформа папку не читает;
- выгруженная служба запускается снова, когда приходит шаг; пока она выгружена, сама пакетов не выдаёт.
Части результата. Модуль может передавать результат шага частями во время работы (уведомление partial, раздел 7): текст ответа по мере генерации, готовые элементы списка. Части передаются по рёбрам выхода и сразу отображаются на пульте через переменную (Программа: граф и запуски, разделы 7, 13). Ответ на execute остаётся окончательным результатом шага.
По умолчанию вызовы одного модуля выполняются по очереди — в том числе из разных прогонов одной программы. Одновременные вызовы возможны, только если манифест объявляет parallelism > 1: это разрешение модуля, а не обещание платформы.
Ресурсы для всех модулей человек задаёт в настройках модулей (раздел «Ресурсы для модулей»):
modules.parallel_max— сколько модулей на всём компьютере выполняют шаг одновременно. Шаг сверх этого ждёт очереди, пока его модуль ещё не поднят, и снимается остановкой прогона, пока ждёт;modules.memory_max_mbиmodules.cpu_max— память и ядра процессора, которые модули занимают все вместе. Пределы держит Linux: функция модулей запускает каждый модуль в одной группе с этими пределами (limitsвcore.process.spawn, Обмен с ядром, 5.4). Модуль, который вывел группу за предел памяти, Linux останавливает, и шаг отказывает сmodule_memory_limit; что модуль успел сделать, неизвестно, как и при потере модуля. Без systemd пределы не держатся, и модуль с пределами не запускается: отказ говорит, что сделать.
Срок шага задаёт автор модуля полем timeout_ms манифеста — целое число миллисекунд, не меньше 1. Этот срок единственный: платформа не сокращает его своим пределом и не устанавливает собственных сроков. Соблюдение срока контролирует функция модулей: если модуль не ответил в срок, она останавливает его (core.process.stop, затем core.process.kill) и отвечает module_timeout. Функция графа и мастерская ожидают ответа на шаг без собственного срока: ответ поступает с результатом, с module_timeout или с function_lost при отказе самой функции модулей.
5 Окружение Python
Для рабочего процесса используется одно окружение Python, общее для всех его модулей. Процесс является законченным целым: одна установка зависимостей, один набор версий. Модули при этом остаются отдельными OS-процессами.
Окружение делает uv, и одинаковые файлы лежат на диске один раз. Окружения процессов — жёсткие ссылки на файлы пакетов в общем кэше data/cache/uv/: у каждого процесса своё окружение и свой набор версий, а пакет, одинаковый в двух процессах, занимает место один раз. Кэш лежит в папке данных, чтобы быть на одном диске с окружениями: между дисками жёсткой ссылки не бывает. uv — программа, которую называет настройка modules.uv (по умолчанию uv, ищется в PATH); если её нет, установка завершается отказом module_uv_not_found. Свой Python uv не скачивает: окружение создаётся интерпретатором, который нашёлся по modules.python_candidates.
Размещение окружения и поведение при конфликте версий:
- Размещение.
data/processes/<process_id>/.venv. Рядом лежат общийrequirements.txtпроцесса, собранный из требований модулей, иrequirements.freeze.txtдля диагностики. Эти файлы получаются из модулей, поэтому в экспорт процесса не входят. - Установка. Команда
module.installсprocess_idсобирает требования всех Python-модулей процесса в один список, создаёт.venv(uv venv) и ставит туда пакеты (uv pip install --link-mode hardlink). Какие модули у процесса, функция модулей берёт из своегоmodules.lock.json(раздел 3), а документ процесса — графа — не читает. При запуске установка не выполняется. - Конфликт версий — отказ. Если два модуля просят разные версии одного пакета, установка отклоняется с
module_environment_conflictи перечнем: какой модуль что просит. Отдельного окружения в обход конфликта нет: такое исключение означало бы несколько окружений у одного процесса, а окружение у процесса одно. Человек сам выбирает: изменить версию модуля или разделить процессы. - Требования, а не закреплённые версии. Источник —
requirements.txtмодулей.uv.lockиpylock.tomlописывают окружение одного модуля и в сведение не идут: локи разных модулей в одном окружении конфликтовали бы, а автор, которому нужны точные версии, закрепляет их вrequirements.txt. - Интерпретатор — первый найденный в системе из списка
modules.python_candidates, который подходит подruntime_pythonманифеста; если манифест версию не указал — любой Python 3.11 или новее. Модуль запускается интерпретатором окружения процесса, если окружение есть. Если не запускается ни одна программа из списка, установка и шаг модуля на Python завершаются отказомmodule_python_not_found. Требованиеruntime_python— условия через запятую (>=,>,<=,<,==,!=и версия), версия сравнивается по названным в условии частям:==3.11подходит любой 3.11. Окружение процесса создаётся интерпретатором, который подходит под требования всех его модулей; требование, которое не читается, — ошибка манифеста (module_invalid). Отказmodule_python_not_foundназывает, какие версии найдены и чего просили. - Требования без окружения. При наличии требований и отсутствии окружения выдаётся отказ
module_needs_environmentс именем процесса, чьего окружения нет, а не выполняется установка во время запуска. - Модуль вызываемого процесса работает в окружении того процесса, откуда он пришёл, — и шаг, и служба (Программа: граф и запуски, раздел 18). Вызываемый процесс отвечает за свои модули целиком: версии записаны в его
modules.lock.json, зависимости стоят в его окружении, и устанавливают их командойmodule.installдля него. Окружение вызывающего модулей вызываемого не содержит, и конфликта их версий с его модулями не возникает.
6 Рабочая папка и файлы результатов
OS-процесс модуля запускается в рабочей папке прогона в папке его процесса: data/processes/<process_id>/runs/<run_id>/work. Тестовый вызов без процесса получает свою папку data/module-tests/<module_id>/work. Служба работает дольше прогона, поэтому запускается в папке памяти процесса state/, а рабочую папку прогона получает в каждом execute полем work_dir и помещает файлы результатов туда.
- Свои файлы модуль находит по пути к своей папке. Полный путь к ней приходит в переменной
OGAS_MODULE_DIR, путь к папке прогона — вOGAS_RUN_DIR; пути к нейросетям, которые выбрали его параметры, приходят с каждым шагом полемmodels(раздел 11). В SDK для этого естьmodule_path(): относительный путь в параметрах узла считается от папки модуля, а не от рабочей папки. - Файл результата модуль называет в поле
artifacts— путём внутри рабочей папки. Функция модулей переносит файл в результаты прогонаdata/processes/<process_id>/results/<run_id>/под именем, которое дал модуль:sheet-1.svg, а не служебная ссылка. Папка в пути становится частью имени (out/a.png→out-a.png), имя, уже занятое в этом прогоне, получает номер (sheet-1-2.svg). Имя файла и есть ссылка на него: функция возвращает{ artifact_handle, kind, size, media_type, name }, гдеartifact_handle— это имя (Методы модулей, раздел 1). - Файл, названный в
artifactsдважды, — один файл: он переносится один раз, и ссылки на него называют его одинаково (две одинаковые фотографии делят одну миниатюру). Тип содержимого, если модуль его не назвал, функция модулей берёт по окончанию имени — у картинки, звука, видео, текста и документа; иначеapplication/octet-stream, и окно показывает файл файлом, а не картинкой или проигрывателем. - Файл в выходе модуль называет ссылкой с тем же путём —
{ "file": "out/a.png" }вoutputиout/a.pngвartifacts. Перенеся файл, функция модулей ставит в ссылку его имя среди результатов и дописываетname,media_typeиsize: выход несёт ссылку на файл, как любые данные (Форматы файлов, 16.2), и модуль не знает, под каким именем файл лёг. Ссылка на путь, которого нет вartifacts, остаётся как есть. - Предел размера — настройка
modules.artifact_max_bytes, по умолчанию 64 МиБ; при необходимости значение настройки увеличивают. Файл больше предела не принимается: шаг завершается ошибкойartifact_too_large. - Файл результата другого модуля и файл из данных модуль читает по пути из
artifact_filesвexecute: функция графа называет модулю артефакты пакета и файлы ссылок в данных шага — картинку из переменной, ответ на вопрос, а функция модулей даёт путь к тем из них, что лежат среди результатов этого прогона или в файлах процессаfiles/(Методы модулей, 1.2). - Файл результата после появления не изменяется: модуль, которому нужен изменённый файл, создаёт новый (Программа: граф и запуски, 24.4).
- Файл в папке человека артефактом не считается. Модуль, который по заданию раскладывает файлы в папку человека, отдаёт их путь в выходе, а
artifactsоставляет пустым: артефакт — это файл прогона, который платформа хранит и убирает вместе с прогоном.
7 Протокол модуля
Модуль обменивается с функцией модулей сообщениями JSON-RPC 2.0, по одному на строку, через stdin и stdout (таблица 1).
Таблица 1 — Протокол модуля
| Метод | Смысл |
|---|---|
init |
язык интерфейса; модуль отвечает ready, версией протокола и возможностями. До ответа execute не отправляется |
execute |
сведения о прогоне, входные данные, параметры узла (раздел 10), файлы результатов, папка памяти узла state_dir и признак resumed — память в ней сохранена целиком этим же модулем (раздел 4); ответ — выходные данные и порт |
configure |
только службе: узлы её модуля в этом процессе с их параметрами — [{ node_id, parameters }], параметры такие, какими их получил бы шаг (раздел 10), — при каждом поднятии службы: при включении программы и снова после выгрузки, до первого шага. Модуль, не знающий метода, отвечает method_not_found и работает без него; другой отказ — служба не поднимается |
cancel |
отмена конкретного execution_id |
ping |
проверка работоспособности долгого модуля и службы: функция модулей спрашивает каждый поднятый раз в modules.ping_interval_ms; не ответивший за modules.ping_timeout_ms останавливается как потерянный — идущий шаг завершается module_process_lost, служба поднимается снова к следующему шагу, — и функция говорит об этом событием function.work_failed. Отвечать на ping модуль должен и посреди шага |
suspend |
модуль с suspend: true сохраняет память каждого узла, который обслужил, в папку state_dir этого узла и отвечает, когда сохранил; после ответа функция модулей его завершает (раздел 4) |
Модуль может присылать уведомления progress (доля готовности), log, partial — часть результата шага (execution_id, port, данные; раздел 4), signal — сигнал своей программе (name, необязательные key и данные): ветка, которая ждёт его на узле signal, идёт дальше (Программа: граф и запуски, раздел 22), — и, если он служба, emit — пакет на выход вне шага, начало нового прогона (port, данные и необязательный node_id: служба нескольких узлов называет, для какого из них пакет; без имени пакет уходит всем узлам модуля, у которых есть ребро с этого выхода). stdout отдан протоколу: вывод отладочного текста в него не допускается и считается повреждением протокола; диагностика идёт в stderr.
Ответ на execute и уведомления partial и emit называют один из выходов манифеста; модуль без выходов выхода не называет. Отказ несёт код: код договора модуля или причину самого модуля, текст которой лежит в словарях модуля (таблица 2). От имени платформы модуль не отказывает: названный им код платформы становится причиной модуля. Ответ не по этим правилам успехом не считается — шаг завершается module_process_lost; уведомление не по ним дальше не передаётся, и об этом сообщается. Поля ответа и отказа — Методы модулей, 1.2.
Поток stdout ограничен так же, как шина: строка длиннее 4 МиБ или больше 256 непрочитанных ответов завершают шаг ошибкой transport_overflow. Так модуль не может незаметно занять всю память платформы.
Модуль объявляет допустимость повтора своих шагов: idempotent, non_idempotent или unknown. От этого зависит допустимость повтора и продолжения прогона (Программа: граф и запуски, раздел 14). Платформа обещает, что execute с одним operation_id дойдёт не меньше одного раза, но не «ровно один раз». Защищать внешнее действие от повторного выполнения должен сам модуль.
8 Модули на других языках
Модуль на любом языке — исполняемый файл с тем же протоколом через stdin / stdout (runtime: "native"): платформа запускает его напрямую. Протокол от языка не зависит; готовые библиотеки есть для Python и для Rust (раздел 9), на другом языке протокол пишут по Методы модулей.
9 OGAS SDK
OGAS SDK — набор средств для авторов модулей, обеспечивающий совместимость модулей разных авторов. Есть SDK для Python и для Rust.
- SDK выполняет договор модуля — манифест и протокол — и не подменяет его: модуль без SDK, работающий по тому же протоколу, равноценен модулю с SDK.
- SDK распространяется под Apache License 2.0, а заготовка нового модуля — без условий (0BSD), хотя платформа — под AGPL: модуль, который берёт SDK или сделан из заготовки, его автор лицензирует как хочет, в том числе закрыто и платно.
- SDK для Python —
sdk/python/ogas_runtime.py: обмен по протоколу для шагового (run_step) и долгого (run_long) модуля, чтение шага, ответ, отказ, слова для человека, память узла; он стоит на одном Python.ogas_models.py— общее модулей с нейросетями и картинками; его библиотеки — зависимости самого модуля. SDK для Rust — пакетogas-moduleвsdk/rust: те же имена и то же поведение. Справочник и порядок работы — OGAS SDK. - Манифест — единственный источник договора: его пишут файлом, а SDK его выполняет и из кода не порождает — два источника одной правды расходятся. Виды данных на портах — в договоре, один перечень на всю платформу (Программа: граф и запуски, 24.1). Модуль без платформы проверяют
sdk/python/ogas_check.py: по файлам — договор (раздел 10, таблица 2) и правила платформы, которые держит любой модуль, видные по файлам: сеть заявлена, пакеты не ставятся самим модулем, секрет не параметр, сбой не пропущен молча, документов платформы модуль не называет, вstdoutрядом с SDK не пишет, внутрь платформы не обращается, значения, которое влияет на результат, голым числом не прячет, а все его тексты есть в обоих словарях (OGAS SDK, раздел 10); то же спрашиваетmake ci; запуском — протокол. Проверка только называет нарушение. Упаковка модуля — его папка. - Секреты — ключи сервисов, токены — модуль держит в файле
.envсвоей папки и читаетsecret(name)SDK. Файл не входит ни в отпечаток модуля, ни в его передачу: ключ одного человека не уезжает к другому, а замена ключа не меняет модуль. Подписи модуля сверх отпечатка нет: доверие к модулю — вопрос мастерской перед первым кодом без песочницы (Защита, 3.1).
10 Параметры узла
Всё, что человек задаёт для модуля, выражается одним понятием — параметрами узла. Отдельных «настроек модуля» нет.
- Схему объявляет модуль — поле
parametersманифеста: имя, тип, умолчание, пределы или закрытый набор (Форматы файлов, раздел 4). Типы и проверка значений те же, что у настроек (Настройки, раздел 2); сверх них у параметра модуля есть типmodel— нейросеть одного вида, которую выбирает узел (раздел 11). - Значения хранит узел — поле
parametersузла вprocess.json. Два узла одного модуля в процессе задают параметры независимо. Узел хранит только то, что человек задал: копии схемы, портов и версии в нём нет. - Умолчание подставляет функция модулей. Перед
executeона дополняет параметры узла умолчаниями манифеста; параметр безdefaultнеобязательный и не передаётся, если узел его не задал. Поэтому в коде модуля второго умолчания нет: параметр читают по имени, а0и пустая строка, заданные человеком, остаются его значением. Модуль без SDK получает то же самое. - В значении можно сослаться на настройку процесса —
${имя}(Программа: граф и запуски, раздел 15). - Тексты — в словарях модуля, и именуются по тому же правилу, что тексты настроек; имена текстов в манифесте не записываются (таблица 2).
Таблица 2 — Тексты модуля в словарях
| Текст | Ключ словаря | Обязателен |
|---|---|---|
| название параметра | module.<id>.param.<имя>.title |
да |
| пояснение параметра: назначение, допустимые значения, поведение без него | module.<id>.param.<имя>.help |
да |
| название значения из закрытого набора | module.<id>.param.<имя>.choice.<значение> |
да, если есть choices |
| название входа | module.<id>.input.<порт>.title |
да |
| название выхода | module.<id>.output.<порт>.title |
да |
| подсказка входа | module.<id>.input.<порт>.help |
да |
| подсказка выхода | module.<id>.output.<порт>.help |
да |
| текст отказа по причине самого модуля | module.<id>.error.<код> |
нет; без него отказ называется общим текстом module_failed |
Эти подсказки показывает знак «?» в окне графа (Мастерская, раздел 5). Название порта стоит на узле строкой (Мастерская, 5.3), поэтому оно обязательно; подсказкой порта мастерская говорит, что даст связь с ним, поэтому обязательна и она. Проверка в make ci не проходит, если у параметра или порта модуля нет обязательного текста на русском или английском или в манифесте записан текст.
Панель свойств узла в мастерской строит поля по этой схеме: у каждого параметра — поле его типа, пустое поле значит «действует умолчание манифеста» (Мастерская, раздел 5). У параметра нейросети поле — выбор среди нейросетей её вида в библиотеке; выбранная нейросеть, которой уже нет, остаётся в выборе с пометкой, что её нет в папке нейросетей. Параметр, взятый из переменной, называет её в пустом поле и остаётся взятым, когда сохраняют другие параметры узла, — пока в его поле не набрали или не выбрали значение.
11 Нейросети
Нейросеть — нейросеть или другие большие данные, которыми пользуются модули разных программ: веса, словари, голоса. Она лежит в библиотеке одним экземпляром, а не копией у каждого модуля или в окружении каждой программы (Мастерская, 5.6). Какую нейросеть берёт модуль и что к ней ещё — дополнение, словарь, голос, — выбирает узел, в мастерской и на пульте.
- Папка нейросетей — по умолчанию
models/рядом сmodules/, в папке установки. Настройкаmodules.models_dirназывает другую — путём от папки установки или полным путём так, как его пишет WSL или Windows (D:\AI\models): нейросети берут оттуда, где они уже лежат. - Вид нейросети — подпапка папки нейросетей:
checkpoints/,loras/,voices/— как их называют модули: строчные латинские буквы, цифры,_и-, как у модуля. Своего перечня видов у платформы нет: что такое контрольная точка или дополнение, знают модули. Подпапку вида, который берёт установленный модуль, функция модулей заводит сама, когда читает папку нейросетей, — так человек видит, куда класть; саму папку нейросетей она заводит, только если это папка по умолчанию. - Нейросеть — файл или папка в подпапке своего вида или ссылка на файл или папку в другом месте — тогда её не копируют вовсе. Её имя — имя файла или папки как есть, без
/и\и не с точки: скрытый файл — недокачанное или служебное, а не нейросеть. Своего файла описания у нейросети нет: что внутри, знает модуль, а платформа считает только размер — файла или файлов папки без ссылок внутри. - Модуль берёт нейросеть параметром типа
modelс её видомkindи, если хочет, нейросетью по умолчаниюdefault(Форматы файлов, раздел 4). Сколько нейросетей — столько параметров: основная, дополнение, словарь — каждая своим параметром со своим видом. Списка нейросетей, которые модуль берёт всегда, в манифесте нет: он выбирал бы за узел. - Узел выбирает нейросеть среди нейросетей её вида, как любой параметр (Мастерская, 5.1); пустой выбор оставляет нейросеть по умолчанию. Параметр, как любой, берут из переменной, и тогда выбор делает человек на пульте: элемент «Выбор» с видом нейросетей предлагает нейросети этого вида из библиотеки (Мастерская, 6.2).
- С шагом приходит путь. Функция модулей находит выбранную нейросеть перед шагом и даёт модулю её полный путь в поле
models— «имя параметра → путь», — а службе — в каждом узлеconfigure(Методы модулей, раздел 1); в SDK путь даётchosen_model(params, имя). Нейросеть, которую не выбрали ни узел, ни манифест, модулю не даётся. - Без выбранной нейросети шаг не идёт. Если выбранной нейросети нет, шаг, служба и тестовый вызов отказывают
module_model_missingдо того, как модуль о них узнает, и называют недостающие видом и именем — а не падает модуль на чужом пути. - Удаляют нейросеть в библиотеке. Нейросеть, которую установленный модуль берёт по умолчанию, не удаляется: отказ
model_in_useназывает модули. Нейросеть, выбранную на узле, удалить можно: шаг этого узла откажет и назовёт её. Ссылка удаляется без того, на что она указывает. - Положить нейросеть — скопировать её файл или папку или поставить ссылку в подпапку её вида; библиотека показывает папку нейросетей так, как её видит Windows, и перечитывает её по кнопке.
- Скачать нейросеть — из источника в библиотеке (Мастерская, 5.6). Функция источников скачивает файлы в свою папку загрузок
downloads/, а в папку нейросетей их ставит хозяин папки, функция модулей (module.model.take): в подпапку вида, который выбрал человек, под именем, которое он назвал, — только новую, существующую она не заменяет (model_exists). - Откуда взять нейросеть по умолчанию, модуль может назвать в манифесте полем
sourcesпараметра типаmodel: источник и что в нём взять (Форматы файлов, раздел 4). По нему библиотека у программы показывает, каких нейросетей её модулям не хватает, и скачивает недостающую под именем по умолчанию (module.model.needs); модуль безsourcesпросто говорит, какой нейросети нет. - Сколько нужно видеопамяти, говорит
resources.gpu_mbманифеста — сколько видеопамяти занимает поднятый модуль с его нейросетью. По нему функция модулей делит видеокарту (раздел 4), а библиотека говорит, запустится ли модуль и программа с ним на этом компьютере (Мастерская, 5.6). Что есть у компьютера — видеокарты с их памятью, память, ядра, свободное место — функция модулей узнаёт у системы:nvidia-smi, если он есть,/proc/meminfo, место на диске (module.hardware).