Fix Silero model cleanup and document runtime configuration

This commit is contained in:
evgeny committed 2026-10-21 16:29:44 +02:00
1 parent f31b34d0f0
commit 1ff02188ca
4 files changed
+33 -8

No files matched your search

+14 -4
View File
@@ -259,10 +259,20 @@
существование файла, а `wf()` создаёт его до записи. Читатель иногда получает
пустую ссылку и ошибку префикса `utun://`. Публиковать готовый файл атомарно.
[ ] **Linux ONNX Runtime: повторная регистрация схем при запуске теста** — 03.10.2026:
test_silero_vad при загрузке модели печатает серии `Schema error: ... already registered`.
Инференс, речь, тишина и reset проходят; отдельно проверить состав и загрузку Linux-библиотек ONNX.
Диагностика: `/tmp/vad-compressor-silero-tests.log`; Android-сборка таких сообщений не содержит.
[+] **Linux ONNX Runtime: повторная регистрация схем при запуске теста** — проверено 21.10.2026:
Причина в системной сборке `1.23.2+dfsg-6ubuntu1`: Runtime вручную регистрирует схемы,
затем динамическая `libonnx.so.1` повторяет регистрацию в `OpSchemaRegistry::map()`.
Подтверждено GDB (`/tmp/silero-schema-gdb.log`) и исходниками обеих библиотек.
Текущая Linux x64 CMake-сборка переключена на [официальный Runtime 1.23.2](https://github.com/microsoft/onnxruntime/releases/tag/v1.23.2).
Архив `onnxruntime-linux-x64-1.23.2.tgz` распакован в `.cache/onnxruntime/`;
SHA-256: `1fa4dcaef22f6f7d5cd81b28c2800414350c10116f5fdd46a2160082551c5f9b`.
Для существующего include `onnxruntime/onnxruntime_c_api.h` создана ссылка
`.cache/onnxruntime/include/onnxruntime` → `../onnxruntime-linux-x64-1.23.2/include`.
В CMake явно заданы абсолютные пути: `ONNXRUNTIME_INCLUDE_DIR=<repo>/.cache/onnxruntime/include`,
`ONNXRUNTIME_LIB=<repo>/.cache/onnxruntime/onnxruntime-linux-x64-1.23.2/lib/libonnxruntime.so`.
Выбор сохраняется в `tools/chatgui/build/CMakeCache.txt`; после удаления cache его нужно повторить.
`ldd` подтверждает официальный Runtime без отдельной `libonnx`; весь `test_silero_vad` проходит без `Schema error`.
Лог проверки: `/tmp/silero-runtime-test.log`, полный вывод — `tools/chatgui/build/Testing/Temporary/LastTest.log`.
[ ] **debug_parse_config: формат и индексы категорий** — parser ожидает `:`, документация
описывает `=`; преобразование битовой маски осталось после перехода enum на индексы.
+3 -2
View File
@@ -82,7 +82,8 @@ static int vad_read_file(const char* path, uint8_t** out, size_t* out_len) {
}
/* Общая инициализация детектора из байтов модели (файл или вшитая модель).
* data может указывать на внешний буфер (вшитая модель) — тогда не освобождается. */
* owned_buf передаётся детектору только при успехе; при ошибке остаётся у вызывающего.
* Для вшитой модели owned_buf == NULL, её байты не освобождаются. */
static silero_vad_t* silero_vad_create_from_bytes(const uint8_t* data, size_t len,
const uint8_t* owned_buf, const char* label) {
silero_vad_t* vad = NULL;
@@ -107,7 +108,6 @@ static silero_vad_t* silero_vad_create_from_bytes(const uint8_t* data, size_t le
return NULL;
}
vad->ort = ort;
vad->model_data = (uint8_t*)owned_buf;
vad->model_len = len;
status = ort->CreateEnv(ORT_LOGGING_LEVEL_WARNING, "utun_silero_vad", &vad->env);
@@ -127,6 +127,7 @@ static silero_vad_t* silero_vad_create_from_bytes(const uint8_t* data, size_t le
if (status) { vad_report_ort_error(ort, status, "CreateCpuMemoryInfo"); goto fail; }
ort->ReleaseSessionOptions(opts);
vad->model_data = (uint8_t*)owned_buf;
DEBUG_INFO(DEBUG_CATEGORY_VAD, "silero_vad_create(%s): ok bytes=%zu window=%d context=%d input=%d", label, len,
SILERO_VAD_WINDOW_SAMPLES, SILERO_VAD_CONTEXT_SAMPLES, SILERO_VAD_INPUT_SAMPLES);
+10 -1
View File
@@ -2,7 +2,7 @@
*
* Проверяет:
* - загрузку модели и жизненный цикл (create/destroy/reset);
* - обработку ошибок (пустой/несуществующий путь, NULL-аргументы);
* - обработку ошибок (пустой/несуществующий путь, неверная модель, NULL-аргументы);
* - что на тишине вероятность речи близка к нулю (реальный инференс, не мусор);
* - что путь pcm16 даёт тот же результат, что и float (конвертация /32768);
* - что вероятность всегда лежит в [0;1].
@@ -17,6 +17,7 @@
#include "../lib/silero_vad.h"
#include "../lib/audio_compressor.h"
#include "../lib/debug_config.h"
#include "../lib/mem.h"
#include "../src/radio/radio_auto.h"
#define PI 3.14159265358979323846
@@ -60,6 +61,14 @@ static int test_lifecycle_and_errors(const char* model_path) {
vad = silero_vad_create("/nonexistent/silero_vad.onnx");
CHECK(vad == NULL, "create(bad path) should fail");
/* Непустая PCM-фикстура читается успешно, но ONNX должен отклонить её без double-free и утечки. */
size_t allocated = u_get_allocated_count();
vad = silero_vad_create(TEST_SILERO_SPEECH_PATH);
CHECK(vad == NULL, "create(invalid model) should fail");
silero_vad_destroy(vad);
CHECK(u_get_allocated_count() == allocated, "create(invalid model) leaked allocations");
DEBUG_INFO(DEBUG_CATEGORY_VAD, "invalid model cleanup: allocations before=%zu after=%zu", allocated, u_get_allocated_count());
vad = silero_vad_create(model_path);
CHECK(vad != NULL, "create(%s) should succeed", model_path);
if (!vad) return 1;
+6 -1
View File
@@ -1,6 +1,11 @@
Vibechat
Децентрализованный чат, с поддержкой групп. По дизайну отправляет сообщения преимущественно напрямую адресату, а если прямое подключение невозможно то только через других участников этой группы.
Это децентрализованный мессенджер с упором на конфиденциальность и прямой обмен данными между узлами. Работает без каких либо серверов, напрямую между участниками. Поэтому для стабильной работы группы желательно иметь хотябы одного участника который имеет постоянный ip адрес и постоянно доступен.
После установки вы получаете мессенджер который не привязан ни к каким серерам, а использует для коммуникации только помощь других как вы участников групп которые вы добавили.
В начале вам надо либо создать свою группу и приглашать по ссылке других участников, либо присоединиться к чьей-то группе - попросите ссылку-приглашение и присоединитесь к группе.
Поддерживает групповые чаты, видеозвонки, рацию, голосовые сообщения, видеотрансляции, файлообмен. По дизайну отправляет сообщения преимущественно напрямую адресату, а если прямое подключение невозможно то только через других участников этой группы.
Участника группы можно сделать суперузлом и медиаузлом. Суперузел должен иметь прямой ip адрес. Такие узлы будут помогать маршрутизации между узлами, а медиаузлы - хранению контента группы.
Также есть личные сообщения - которые могут проходить через промежуточные узлы, но только в зашифрованном виде, включая аттачи. Если адресат недоступен, отправитель просит медиаузел сохранить собощение и передать узлу когда он станет доступен.
Контент группы хранится на узлах которые его загрузили в незашифрованном виде.