our_knp/reports/2026-10-07/Отчёт_запуск_KNP_в_WSL.md
int 1b58551d67 Add 2026-10-07 report (KNP build in WSL)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 11:03:53 +03:00

12 KiB
Raw Permalink Blame History

Отчёт: запуск KNP в WSL

Oct 7, 2026 · @Александр Ступак

Kaspersky Neuromorphic Platform собрана из исходников и работает на CPU: полный MNIST (60 000 картинок) обучается за 11,5 минут, но на GPU запустить сеть не удалось.

Что это

KNP (Kaspersky Neuromorphic Platform) — платформа для создания, обучения и запуска импульсных (спайковых) нейросетей. Работает на C++ и Python, лицензия Apache 2.0, рассчитана на CPU, GPU (CUDA) и нейроморфный чип «Алтай».

В C:\KNP лежали:

  • knp-2.0.0-py3-none-any.whl — готовый Python-пакет, но под Python 3.11 и Boost 1.81, а в системе Python 3.14 и Boost 1.90;
  • examples/ — клон репозитория GitHub с исходниками и C++-примерами;
  • 1/ — заготовка проекта на uv с import knp.

В wheel нет библиотеки libknp-base-framework-core.so, поэтому import knp из него не работает. Прав администратора (sudo) нет, так что всё собрано из исходников в домашней папке WSL.

Что сделано

  1. Собрал минимальный OpenCV 4.10 (core, imgproc, highgui, imgcodecs) в ~/deps: CMake требовал OpenCV, а в системе его не было.
  2. Поставил mypy, build, pytest в ~/toolvenv: нужен stubgen, иначе Python-фреймворк не собирается.
  3. Собрал KNP из исходников (make -j20): CPU-бэкенды, Python-фреймворк, примеры, wheel под Python 3.14.
  4. Установил wheel в C:\KNP\1\.venv. Проверил import knp, knp.core, knp.base_framework.

Три проблемы при сборке и как я их решил:

  • CMake выбирал Boost.Python для Python 2.7 — указал -DBoost_PYTHON_VERSION=3.14.
  • GCC 15 превращал предупреждение maybe-uninitialized в ошибку — отключил его флагами.
  • Сборка wheel падала без модуля build — доустановил.

Результаты на CPU

Однопоточный бэкенд быстрее многопоточного: полный MNIST на нём занял 11,5 минут, а многопоточный за 30 минут прошёл лишь часть пути.

Запуск Бэкенд Время Результат
simple-network (20 шагов) CPU, 1 поток мгновенно спайки на шагах 1 6 7 11 12 13 16 17 18 19
MNIST, 1000 обучение / 300 проверка CPU, 1 поток 5 с работает
MNIST, 3000 / 1000 CPU, 1 поток 15 с precision по классам 93–97%
MNIST, 60 000 / 10 000 CPU, 1 поток 690 с (11,5 мин) 3086 из 10 000 верно (30,9%)
MNIST, 60 000 / 10 000 CPU, многопоточный прерван на 30 мин дошёл до шага ≈155 тыс. из ≈ 1,05 млн

Полный MNIST на однопоточном бэкенде: сеть почти всегда права, когда отвечает (precision по классам 92–100%), но на большую часть картинок ответа нет (recall 20–51%). Столбец ACCURACY в таблице примера (92–95%) считается по каждому классу отдельно и вводит в заблуждение; честный итог — около 31%. Почему так, не выяснял.

MNIST 60 000 / 10 000: результаты по цифрам

Модель blifat, однопоточный бэкенд, 900 000 шагов обучения и 150 000 шагов проверки. Столбец «верно» — TRUE_POSITIVES из лога прогона.

Цифра Картинок Верно Ложные срабатывания Precision Recall
0 980 310 0 1,000 0,316
1 1135 576 5 0,991 0,510
2 1032 204 8 0,962 0,199
3 1010 233 4 0,983 0,232
4 982 234 20 0,921 0,243
5 892 258 8 0,970 0,292
6 958 228 5 0,979 0,239
7 1028 360 18 0,952 0,356
8 974 192 6 0,970 0,198
9 1009 491 3 0,994 0,488
Итого 10 000 3086 (30,9%) 77
  • Самые хорошие цифры: 1 (recall 0,51) и 9 (0,49). Самые слабые: 8 (0,20) и 2 (0,20).
  • Ложных срабатываний по таблице всего 77 на 10 000 картинок (0,8%). То есть сеть в основном молчит, а не ошибается: остальные 6914 картинок не получили верного ответа. Это моё чтение таблицы: точный смысл столбцов примера я не верифицировал по исходникам.

Сравнение малого и полного прогонов

Прогон Обучение Проверка Время Верно Ложные срабатывания
Малый 3000 1000 15 с 471 (47,1%) 36
Полный 60 000 10 000 690 с 3086 (30,9%) 77

Неожиданный результат: после обучения на 3000 картинках доля верных ответов выше, чем после 60 000. Наборы для проверки разного размера (1000 и 10 000), поэтому сравнение приблизительное. Причину я не выяснял; возможно, при длинном обучении веса «забывают» ранние образы, это только гипотеза.

Однопоточный и многопоточный бэкенд

Однопоточный Многопоточный
Загрузка CPU ≈ 97% (1 ядро) ≈ 196% (2 ядра из 24)
Время полного прогона 690 с не завершён, остановлен на 30 мин
Пройдено шагов из 1 050 000 все ≈ 156 000 (≈ 15%)

По темпу многопоточный был примерно в 7 раз медленнее (оценка по доле пройденных шагов за 30 минут до остановки и время однопоточного). Почему, не выяснял; вероятно, накладные расходы на синхронизацию потоков на сети такого размера.

GPU

На видеокарте (RTX 4070 Ti SUPER, 16 ГБ, драйвер CUDA 13.3) нейросеть не запустилась: GPU-бэкенд собран и загружается, но вычисления падают.

Что получилось

  • GPU виден из WSL, простое тестовое ядро CUDA работает.
  • Тулкит CUDA 12.9 поставлен в ~/cuda-12.9 вручную: штатный установщик требует libxml2.so.2, которой нет, поэтому я распаковал компоненты из .run-файла.
  • nvcc 12.9 не работает с GCC 15, поэтому поставил GCC 14 через micromamba.
  • GPU-бэкенд libknp-gpu-cuda-backend.so собран (пришлось подавить предупреждения Boost и поправить команду линковки).

Что не получилось

  • MNIST на GPU падает с ошибкой Type is not supported: бэкенд поддерживает только нейроны BLIFAT и синапсы Delta, без обучения STDP.
  • simple-network на GPU падает с invalid device function. В бинарнике есть кубин под sm_89 и нужные ядра, тестовое ядро на этой карте работает, причину не нашёл. Моё предположение (не проверено): регистрация шаблонных ядер ломается при раздельной компиляции.
  • Режим «обучить на CPU, запустить на GPU» недоступен: в MNIST-примере save_network объявлена, но нигде не вызывается, и --inference_only падает даже на CPU.

Изменение в вашем проекте: в knp/backends/gpu/cuda-backend/CMakeLists.txt архитектура 60 заменена на "89"; его можно откатить.

Детали проверок GPU

Проверка Результат
nvidia-smi из WSL RTX 4070 Ti SUPER, 16 ГБ, KMD 610.88, CUDA UMD 13.3
Тестовое ядро, компиляция под sm_89 работает, результат верный (42)
Тестовое ядро, компиляция под sm_60 без ошибки, но ядро не выполнилось (результат 0)
Кубины в бэкенде после сборки под "89" один, sm_89; нужные ядра (в том числе destruct_kernel) в нём есть
simple-network на GPU-бэкенде бэкенд загружен, на первом шаге invalid device function
compute-sanitizer ошибка на вызове cudaLaunchKernel из CUDAVector<...> в CUDAMessageBus::unload_messages; всего 58 ошибок
MNIST на GPU (blifat и altai) Type is not supported

Поддерживаемые GPU-бэкендом типы (из исходников): нейроны BLIFATNeuron, синапсы DeltaSynapse.

Как запускать

Всё запускается внутри WSL. Без переменной LD_LIBRARY_PATH программы не найдут библиотеки KNP, OpenCV и CUDA.

export LD_LIBRARY_PATH=$HOME/knp-build/bin:$HOME/deps/lib:$HOME/cuda-12.9/lib64:/usr/lib/wsl/lib

# C++ пример
$HOME/knp-build/bin/simple-network

# Python
cd /mnt/c/KNP/1 && .venv/bin/python main.py

# MNIST на CPU (программа ждёт ENTER, поэтому echo)
cd ~/run && echo | $HOME/knp-build/bin/mnist_learn_example -m blifat \
  --images MNIST.bin --labels MNIST.target \
  --training_backend $HOME/knp-build/bin/libknp-cpu-single-threaded-backend.so

Расположение файлов в домашней папке WSL:

Папка Что внутри
~/knp-build сборка, бинарники в bin/, wheel в knp_python_framework/dist/
~/deps OpenCV
~/cuda-12.9 тулкит CUDA
~/mamba GCC 14
~/run MNIST и логи прогонов
~/cuda-dl скачанный .run-файл (~5,8 ГБ), можно удалить

В C:\KNP добавлен только файл knp-2.0.0-py3.14-linux-built.whl (новый wheel под Python 3.14). 1/pyproject.toml всё ещё указывает на старый wheel; чтобы uv sync не вернул старый пакет, замените путь.

Не проверено и следующие шаги

Не проверялось:

  • тесты проекта (pytest, C++-тесты);
  • модель -m altai;
  • mnist-client;
  • из Python проверен только import, сети на Python не писались.

Следующие шаги:

  • Разобраться с invalid device function на маленьком тесте с одним ядром, чтобы заработал GPU
  • Прогнать модель altai и сравнить с blifat
  • Выяснить, почему сеть отвечает только на 31% картинок, и попробовать улучшить
  • Написать на Python сеть на BLIFAT и Delta и запускать её на CPU и GPU