12 KiB
Отчёт: запуск 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.
Что сделано
- Собрал минимальный OpenCV 4.10 (core, imgproc, highgui, imgcodecs) в
~/deps: CMake требовал OpenCV, а в системе его не было. - Поставил
mypy,build,pytestв~/toolvenv: нуженstubgen, иначе Python-фреймворк не собирается. - Собрал KNP из исходников (
make -j20): CPU-бэкенды, Python-фреймворк, примеры, wheel под Python 3.14. - Установил 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-файла. nvcc12.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