Запуск сети Qwen на orangePi AI Pro

В данной статье будет рассмотрен пример использования NPU ускорителя Ascend, встроенный в SoC на плате orangePi Ai Pro.

Для этого будут запущены примеры с сетями Qwen, DeepSeek…

С чего начать

Приобрести плату можно через интернет магазин, например: Onpad или Aliexpress.

После получения необходимо использовать SD карточку не менее чем на 32 ГБ.
Качаем прошивку со страницы: https://openscaler.ru/2025/06/11/firmware-orangepi-ai-pro-20t/ можно взять как прошивку на базе OpenScaler 24.03 PS1 так и на базе OpenScaler 22.03 SP4, выбирайте что больше нравится.

Подготовка

Скачанную прошивку необходимо распаковать (используется алгоритм xz), пример команды для прошивки на базе 22.03 SP4:

[mc@gentoo-book /mnt/extras]$ xz -d opiaipro_20t_openScaler22.03sp4_server_aarch64_20250605.img.xz

Затем необходимо записать распакованный образ на SD карту памяти, пример команды для устройства /dev/sdb:

[gentoo-book /mnt/extras]# dd if=opiaipro_20t_openScaler22.03sp4_server_aarch64_20250605.img of=/dev/sdb bs=512 status=progress
17177969152 bytes (17 GB, 16 GiB) copied, 4399 s, 3,9 MB/s
33554432+0 records in
33554432+0 records out
17179869184 bytes (17 GB, 16 GiB) copied, 4422,76 s, 3,9 MB/s

Запуск

После завершения копирования, вставляем SD карточку в плату, подключаем Ethernet кабель и включаем.

Примерно через 2 минуты, когда шум от вентиляторов стихнет, можно найти IP адрес (например в логах роутера или DHCP сервера) платы и зайти на неё по ssh используя следующую пару логин/пароль: HwHiAiUser / Mind@123.

[mc@gentoo-book ~]$ ssh HwHiAiUser@192.168.0.236
HwHiAiUser@192.168.0.236’s password:

Welcome to 5.10.0+

System information as of time:  Mon Jun 16 11:41:02 MSK 2025

System load:    17.02
Memory used:    1.2%
Swap used:      0.0%
Usage On:       22%
IP address:     192.168.0.236
Users online:   1
To run a command as administrator(user “root”),use “sudo <command>”.
[HwHiAiUser@openScaler-2203-AI-Pro ~]$ 

Чтобы убедиться, что система успешно загрузила драйверы для Ascend и видит сам NPU выполним команду

[HwHiAiUser@openScaler-2203-AI-Pro ~]$ npu-smi info
+——————————————————————————————————–+
| npu-smi 23.0.0                                   Version: 23.0.0                                       |
+——————————-+—————–+——————————————————+
| NPU     Name                  | Health          | Power(W)     Temp(C)           Hugepages-Usage(page) |
| Chip    Device                | Bus-Id          | AICore(%)    Memory-Usage(MB)                        |
+===============================+=================+======================================================+
| 0       310B1                 | Alarm           | 0.0          58                15    / 15            |
| 0       0                     | NA              | 0            644  / 23673                            |
+===============================+=================+======================================================+ 


Видно что используется 1 чип типа 310B1.

Запуск модели

В прошивке уже всё включено для использования и запуска модели. Для быстро старта можно обратиться к проекту на github https://github.com/mindspore-courses/orange-pi-mindspore.

Данный проект уже находится на борту и готов к использованию, если же каталог был случайно удалён, то можно скачать заново:

[HwHiAiUser@openScaler-2203-AI-Pro ~]$ git clone https://github.com/mindspore-courses/orange-pi-mindspore
Cloning into ‘orange-pi-mindspore’…
remote: Enumerating objects: 701, done.
remote: Counting objects: 100% (85/85), done.
remote: Compressing objects: 100% (66/66), done.
remote: Total 701 (delta 29), reused 19 (delta 19), pack-reused 616 (from 2)
Receiving objects: 100% (701/701), 81.18 MiB | 9.44 MiB/s, done.
Resolving deltas: 100% (289/289), done.

Qwen1.5-0.5b

Для первого запуска рекомендую использовать модель Qwen, перейдём в каталог с примером:

[HwHiAiUser@openScaler-2203-AI-Pro ~]$ cd orange-pi-mindspore/Online/inference/14-qwen1.5-0.5b/

Рекомендуется внести следующие изменения в код скрипта:

— qwen1.5-0.5b.py-orig        2025-06-16 12:35:23.010430590 +0300
+++ qwen1.5-0.5b.py     2025-06-16 12:37:14.865661927 +0300
@@ -51,6 +51,6 @@
# Setting up the Gradio chat interface.
gr.ChatInterface(predict,
                 title=”Qwen1.5-0.5b-Chat”,
–                 description=”问几个问题”,
–                 examples=[‘你是谁?’, ‘介绍一下华为公司’]
–                 ).launch()  # Launching the web interface.
+                 description=”Задайте несколько вопросов:”,
+                 examples=[‘Кто ты?’, ‘Расскажи о llm’]
+                 ).launch(server_name=”0.0.0.0″)  # Launching the web interface.

Так как проект изначально создавался китайцами для китайцев, то и большинство сообщений там тоже на китайском, исправим это, так же заставим скрипт слушать все сетевые интерфейсы, а не только localhost.

Для запуска модели используется команда:

[HwHiAiUser@openScaler-2203-AI-Pro 14-qwen1.5-0.5b]$ python3 qwen1.5-0.5b.py

Первый запуск может занят много времени, в моем случае до 3х чсасов, связано это с медленной скоростью скачивания кода модели с серверов в Китае.

Ожидание запуска может выглядеть примерно так:

/home/HwHiAiUser/.local/lib/python3.9/site-packages/numpy/core/getlimits.py:549: UserWarning: The value of the smallest subnormal for <class ‘numpy.float64’> type is zero.
 setattr(self, word, getattr(machar, word).flat[0])
/home/HwHiAiUser/.local/lib/python3.9/site-packages/numpy/core/getlimits.py:89: UserWarning: The value of the smallest subnormal for <class ‘numpy.float64’> type is zero.
 return self._float_to_str(self.smallest_subnormal)
/home/HwHiAiUser/.local/lib/python3.9/site-packages/numpy/core/getlimits.py:549: UserWarning: The value of the smallest subnormal for <class ‘numpy.float32’> type is zero.
 setattr(self, word, getattr(machar, word).flat[0])
/home/HwHiAiUser/.local/lib/python3.9/site-packages/numpy/core/getlimits.py:89: UserWarning: The value of the smallest subnormal for <class ‘numpy.float32’> type is zero.
 return self._float_to_str(self.smallest_subnormal)
1.26kB [00:00, 2.42MB/s]
2.65MB [00:01, 1.58MB/s]
1.59MB [00:02, 769kB/s]
6.70MB [00:01, 4.37MB/s]
661B [00:00, 1.57MB/s]
62%|█████████████████████████████████████████████████████████████████████████████████████████▋                                                      | 736M/1.15G [1:54:08<1:09:10, 113kB/s]
Failed to download: (‘Connection broken: IncompleteRead(771556747 bytes read, 467616605 more expected)’, IncompleteRead(771556747 bytes read, 467616605 more expected))
Retrying… (attempt 0/5)
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.15G/1.15G [57:12<00:00, 136kB/s]
Qwen2ForCausalLM has generative capabilities, as `prepare_inputs_for_generation` is explicitly overwritten. However, it doesn’t directly inherit from `GenerationMixin`.`PreTrainedModel` wi
ll NOT inherit from `GenerationMixin`, and this model will lose the ability to call `generate` and other related functions.
 – If you are the owner of the model architecture code, please modify your model class such that it inherits from `GenerationMixin` (after `PreTrainedModel`, otherwise you’ll get an excep
tion).
 – If you are not the owner of the model architecture class, please contact the model code owner to update it.
Sliding Window Attention is enabled but not implemented for `eager`; unexpected results may be encountered.
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 206/206 [00:00<00:00, 377kB/s]

Итак после загрузки кода модели, будет примерно такое сообщение:

[HwHiAiUser@openScaler-2203-AI-Pro 14-qwen1.5-0.5b]$ python3 qwen1.5-0.5b.py
/home/HwHiAiUser/.local/lib/python3.9/site-packages/numpy/core/getlimits.py:549: UserWarning: The value of the smallest subnormal for <class ‘numpy.float64’> type is zero.
 setattr(self, word, getattr(machar, word).flat[0])
/home/HwHiAiUser/.local/lib/python3.9/site-packages/numpy/core/getlimits.py:89: UserWarning: The value of the smallest subnormal for <class ‘numpy.float64’> type is zero.
 return self._float_to_str(self.smallest_subnormal)
/home/HwHiAiUser/.local/lib/python3.9/site-packages/numpy/core/getlimits.py:549: UserWarning: The value of the smallest subnormal for <class ‘numpy.float32’> type is zero.
 setattr(self, word, getattr(machar, word).flat[0])
/home/HwHiAiUser/.local/lib/python3.9/site-packages/numpy/core/getlimits.py:89: UserWarning: The value of the smallest subnormal for <class ‘numpy.float32’> type is zero.
 return self._float_to_str(self.smallest_subnormal)
Qwen2ForCausalLM has generative capabilities, as `prepare_inputs_for_generation` is explicitly overwritten. However, it doesn’t directly inherit from `GenerationMixin`.`PreTrainedModel` wi
ll NOT inherit from `GenerationMixin`, and this model will lose the ability to call `generate` and other related functions.
 – If you are the owner of the model architecture code, please modify your model class such that it inherits from `GenerationMixin` (after `PreTrainedModel`, otherwise you’ll get an excep
tion).
 – If you are not the owner of the model architecture class, please contact the model code owner to update it.
Sliding Window Attention is enabled but not implemented for `eager`; unexpected results may be encountered.
Running on local URL:  http://0.0.0.0:7860

To create a public link, set `share=True` in `launch()`.

Значит пора открыть браузер с адресом: http://192.168.0.236:7860:

Введя запрос мы иницирируем дмалог с чат ботом на базе Qwen1.5-0.5B.

Первый запуск может занять до 5 минут, так как будет происходить низкоуровневая компиляция.

Примеры запросов: 

В процессе получения ответа, можнонаблюдать за нагрузкой NPU:

[root@openScaler-2203-AI-Pro ~]# npu-smi info
+——————————————————————————————————–+
| npu-smi 23.0.0                                   Version: 23.0.0                                       |
+——————————-+—————–+——————————————————+
| NPU     Name                  | Health          | Power(W)     Temp(C)           Hugepages-Usage(page) |
| Chip    Device                | Bus-Id          | AICore(%)    Memory-Usage(MB)                        |
+===============================+=================+======================================================+
| 0       310B1                 | Alarm           | 0.0          67                1060  / 1060          |
| 0       0                     | NA              | 18           12715/ 23673                            |
+===============================+=================+======================================================+ 

Из примера ниже следует, что на английском система общается лучше, чем на русском, возможно это общее повоедение всех LLM из-за бугра, а может из-за малого размера используемой LLM в данном примере:

Что бы остановить сервис достаточно нажать комбинацию клавишь Ctrl+C.

Deepseek R1 Distill Qwen-1.5b

В качестве второго примера запустим Deepseek, на базе дисцилированной Qwen-1.5B.
Для этого сменим каталог и поправим скрипт запуска:

[HwHiAiUser@openScaler-2203-AI-Pro ~]$ cd ~/orange-pi-mindspore/Online/inference/17-DeepSeek-R1-Distill-Qwen-1.5B/

изменения:

— deepseek-r1-distill-qwen-1.5b.py-orig       2025-06-17 17:24:08.249645994 +0300
+++ deepseek-r1-distill-qwen-1.5b.py    2025-06-17 17:25:01.646698778 +0300
@@ -57,6 +57,6 @@
# Setting up the Gradio chat interface.
gr.ChatInterface(predict,
                 title=”DeepSeek-R1-Distill-Qwen-1.5B”,
–                 description=”问几个问题”,
–                 examples=[‘你是谁?’, ‘你能做什么?’]
–                 ).launch()  # Launching the web interface.
+                 description=”Задайте несколько вопросов:”,
+                 examples=[‘Кто ты?’, ‘Расскажи о llm’]
+                 ).launch(server_name=”0.0.0.0″)  # Launching the web interface.

Для запуска надо дать команду:

[HwHiAiUser@openScaler-2203-AI-Pro 17-DeepSeek-R1-Distill-Qwen-1.5B]$ python3 deepseek-r1-distill-qwen-1.5b.py

Скачивание сетки также займет довольно много времени. НО!, Оказалось что Deepseek сетка скачивается со своростью 10Mbit/sec, против 100 Kbit/sec для Qwen…

Итоговая картина, при успешном запуске в консоли будет выглядеть так:

[HwHiAiUser@openScaler-2203-AI-Pro 17-DeepSeek-R1-Distill-Qwen-1.5B]$ python3 deepseek-r1-distill-qwen-1.5b.py
/home/HwHiAiUser/.local/lib/python3.9/site-packages/numpy/core/getlimits.py:549: UserWarning: The value of the smallest subnormal for <class ‘numpy.float64’> type is zero.
 setattr(self, word, getattr(machar, word).flat[0])
/home/HwHiAiUser/.local/lib/python3.9/site-packages/numpy/core/getlimits.py:89: UserWarning: The value of the smallest subnormal for <class ‘numpy.float64’> type is zero.
 return self._float_to_str(self.smallest_subnormal)
/home/HwHiAiUser/.local/lib/python3.9/site-packages/numpy/core/getlimits.py:549: UserWarning: The value of the smallest subnormal for <class ‘numpy.float32’> type is zero.
 setattr(self, word, getattr(machar, word).flat[0])
/home/HwHiAiUser/.local/lib/python3.9/site-packages/numpy/core/getlimits.py:89: UserWarning: The value of the smallest subnormal for <class ‘numpy.float32’> type is zero.
 return self._float_to_str(self.smallest_subnormal)
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3.00k/3.00k [00:00<00:00, 4.86MB/s]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 6.71M/6.71M [00:01<00:00, 3.78MB/s]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 679/679 [00:00<00:00, 2.00MB/s]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3.31G/3.31G [08:38<00:00, 6.86MB/s]
Qwen2ForCausalLM has generative capabilities, as `prepare_inputs_for_generation` is explicitly overwritten. However, it doesn’t directly inherit from `GenerationMixin`.`PreTrainedModel` wi
ll NOT inherit from `GenerationMixin`, and this model will lose the ability to call `generate` and other related functions.
 – If you are the owner of the model architecture code, please modify your model class such that it inherits from `GenerationMixin` (after `PreTrainedModel`, otherwise you’ll get an excep
tion).
 – If you are not the owner of the model architecture class, please contact the model code owner to update it.
Sliding Window Attention is enabled but not implemented for `eager`; unexpected results may be encountered.
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 181/181 [00:00<00:00, 393kB/s]
Running on local URL:  http://0.0.0.0:7860

To create a public link, set `share=True` in `launch()`.

Открываем страницу в бразуере и пишем боту: 

Заключение

Примерами выше было показано как использовать одноплатный компьютер для запуска инференса сетей Qwen и Deepseek.