英特尔物联网创新大使 黄明明

项目背景

         之前在很久之前看到这样一个设备(口袋AI设备 rabbit R1)(https://www.rabbit.tech/),可以在很小的便携设备上进行大模型交互,这种带来非常新鲜体验的感觉特别好,所以简单分析了一下,首先在本地推理有点不太可能,原因计算不足,如果计算足功耗和温升也顶不住,所以大致上为本地调用云端大语言模型,然后本地进行结果处理。这个时候有了简单的分析,那么就可以构思自己怎么做一款类似的了。

平台搭建

英特尔开发套件推理平台(https://www.intel.cn/content/www/cn/zh/developer/topic-technology/edge-5g/hardware/nezha-dev-kit.html)

         哪吒(Nezha)开发套件以信用卡大小(85 x 56mm)的开发板-哪吒(Nezha)为核心,采用英特尔®处理器 N97(Alder Lake-N),结合了高性能和低功耗的特性。它支持四核 SoC,时钟频率高达 3.60GHz,TDP 仅为 12W。 其内置 GPU 用于 高分辨率显示。哪吒保持了 85mm x 56mm 信用卡大小的外形尺寸,与树莓派相同,包括高达 8GB 的 LPDDR5 系统内存、高达 64GB 的 eMMC 存储、板载 TPM 2.0、40 针 GPIO 连接器,并支持 Windows 和 Linux 操作系统。这些功能与无风扇冷却器相结合,为各种应用构建了高效的解决方案,适用于教育、物联网网关、数字标牌和机器人等应用。

         内置 Intel® UHD Graphics Gen12,最多 24 个执行单元,这也是一个强大的 AI 引擎,可用于 AI 推理。它是基于 Xe 架构的新一代 GPU。支持包括 INT8 在内的主要数据类型。通过HDMI 1.4b端口,它支持30Hz的4K UHD(3840×2160)以实现高分辨率显示。

40引脚HAT GPIO可配置为PWM、UART、I2C、I2S、SPI和ADC。它为开发人员提供了构建解决方案的自由。

MCU界面框架(https://lvgl.io/)

         LVGL 是最流行的免费开源嵌入式图形库,可用于为任何 MCU、MPU 和显示器类型创建漂亮的 UI。从消费电子产品到工业自动化,任何应用程序都可以利用 LVGL 的 30 多个内置小部件、100 多个样式属性、受 Web 启发的布局和支持多种语言的排版系统。

MCU(https://www.espressif.com.cn/zh-hans)

         ESP32-S3 是一款集成 2.4 GHz Wi-Fi 和 Bluetooth 5 (LE) 的 MCU 芯片,支持远距离模式 (Long Range)。ESP32-S3 搭载 Xtensa® 32 位 LX7 双核处理器,主频高达 240 MHz,内置 512 KB SRAM (TCM),具有 45 个可编程 GPIO 管脚和丰富的通信接口。ESP32-S3 支持更大容量的高速 Octal SPI flash 和片外 RAM,支持用户配置数据缓存与指令缓存。

实现过程

         由于ESP32-S3 无法处理大语言模型推理,所以我们需要将用户的数据通过网络传给远端服务器。那么基于互联网通信方式可以使用HTTP、MQTT、webscoket,socket,由于我们需要双向通信,所以可以使用MQTT、websocket、socket都可以,本文采用websocket的形式。

搭建LLM服务端

         这里我们将采用官方的LLMChatbot代码,需要下载好Python编辑IDE,比如说pycharm,然后同步github上O的官方LLMChatbot代码.(https://github.com/openvinotoolkit/openvino_notebooks/blob/latest/notebooks/llm-chatbot/llm-chatbot.ipynb)。

         注意需要按照教程一步步安装依赖,注意该步骤至少需要5G空间,安装完成之后实际只用2G左右的空间。

%pip install -Uq pip

%pip uninstall -q -y optimum optimum-intel

%pip install --pre -Uq "openvino>=2024.2.0" openvino-tokenizers[transformers] --extra-index-url https://storage.openvinotoolkit.org/simple/wheels/nightly

%pip install -q --extra-index-url https://download.pytorch.org/whl/cpu\

"git+https://github.com/eaidova/optimum-intel.git@transformers_4.43"\

"git+https://github.com/openvinotoolkit/nncf.git"\

"torch>=2.1"\

"datasets" \

"accelerate"\

"gradio>=4.19"\

"onnx" "einops" "transformers_stream_generator" "tiktoken" "transformers>=4.40" "bitsandbytes"

%pip install -q "transformers>=4.43" --extra-index-url https://download.pytorch.org/whl/cpu

下载模型

         建议下载一个比较小的模型:TinyLlama/TinyLlama-1.1B-Chat-v1.0.该模型同样最好预留5G的空间,实际模型转换为OpenVINO.XML大小大约600MB,电脑大约8G 左右,然后CPU 或者 GPU推理都可以带动。需要改动的地方为:

model_id = widgets.Dropdown(

    options=model_ids,

    value=model_ids[1],

    description="Model:",

    disabled=False,

)

         所有模型配置可以看:https://github.com/openvinotoolkit/openvino_notebooks/blob/latest/utils/llm_config.py   SUPPORTED_LLM_MODELS 就是所有支持的模型,建议是下载TinyLlama/TinyLlama-1.1B-Chat-v1.0,当然如果你具备好的CPU+GPU,可以下载比较好的模型进行测试。

编写websocket服务端

         当前面的步骤完成之后,理论上我们的LLM模型已经可以通过OpenVINO™进行推理了,所以接下来需要创建一个Websocket的服务器。

import websockets

async def handler(websocket, path):

    # 当有新客户端连接时,将其加入连接集合

    chats.add(websocket)

    print("new socjer")

    try:

        async for message in websocket:

            # 收到消息后,向所有客户端广播消息]

            psss

    except Exception as e:

        # 捕获异常并打印异常信息

        print("websocket an exception:", e)

    finally:

        # 当客户端断开连接时,将其从连接集合中移除

        chats.remove(websocket)

start_server = websockets.serve(handler,"当前主机IP", 18765)

server = await start_server

MCU客户端编写

         所有步骤完成之后,我们在MCU上编写连接WiFi的代码,然后通过MCU连到该websocket,以下是参考代码。

#include "esp_websocket_client.h"

esp_websocket_client_config_t websocket_cfg = {};



websocket_cfg.uri = "ws://电脑ip:18765";

esp_websocket_client_handle_t websocket_client = esp_websocket_client_init(&websocket_cfg);

esp_websocket_register_events(websocket_client, WEBSOCKET_EVENT_ANY, websocket_event_handler, (void *)websocket_client);

 esp_websocket_client_start(websocket_client);



static void websocket_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)

{

    esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data;

    switch (event_id) {

    case WEBSOCKET_EVENT_CONNECTED:

        ESP_LOGI(TAG, "WEBSOCKET_EVENT_CONNECTED");

        break;

    case WEBSOCKET_EVENT_DISCONNECTED:

        ESP_LOGI(TAG, "WEBSOCKET_EVENT_DISCONNECTED");

        break;

    case WEBSOCKET_EVENT_DATA:

        ESP_LOGI(TAG, "WEBSOCKET_EVENT_DATA");

        break;

    case WEBSOCKET_EVENT_ERROR:

        ESP_LOGI(TAG, "WEBSOCKET_EVENT_ERROR");

        break;

    }

}

然后给lvgl的button绑定点击事件,当点击之后,我们就通过websocket发送给llmchat即可。

最终效果(gif)

总结

         本文深入探讨了如何将微控制单元(MCU)与OpenVINO™ LLM(大语言模型)有效结合,实现在智能终端设备上的本地化自然语言处理。文章不仅提供了详尽的实施流程,还展望了在此基础上开发更多创新功能的可能性。通过这种端侧的大语言模型实现技术,不仅能够提升交互性能,还能为各类智能设备提供更加人性化的服务。

         通过本文的介绍,读者可以了解到,在智能设备中集成MCU与OpenVINO™ LLM的端侧大语言模型技术,不仅能够增强设备的智能化水平,还能够为用户提供更加个性化和高效的服务体验。未来,随着技术的不断发展和优化,我们有望看到更多基于此技术的创新应用和解决方案的出现。

Logo

为开发者提供丰富的英特尔开发套件资源、创新技术、解决方案与行业活动。欢迎关注!

更多推荐