地平线的Nodehub前一段时间推出了一个适用于旭日X3派的LLM(大语言模型),叫做harbot_llm。
我因为工作上几乎天天使用GPT4,而且最近基于GPT4和LangChain开发知识库聊天机器人,所以对于这个能部署在端侧的LLM非常好奇,就尝试了一下,以下是具体的步骤和过程。


一、安装

1. OriginBot系统安装

目前OriginBot系统有V1和V2两个版本,只有V2才支持harbot_llm,所以一定要给OriginBot安装V2,具体的安装过程可以参考:https://www.originbot.org/guide/image_install/#originbot-sd_1

2. hobor_llm 安装

  1. 安装 transformers

     pip3 install transformers -i https://mirrors.aliyun.com/pypi/simple/
    

    安装的时候会提示部分依赖包版本冲突,我没有修复也能直接运行,所以看起来问题不大

  2. 安装hobot-dnn

        sudo apt update
     sudo apt install -y tros-hobot-llm
    
  3. 下载模型文件

    wget http://archive.sunrisepi.tech/llm-model/llm_model.tar.gz
    sudo tar -xf llm_model.tar.gz -C /opt/tros/lib/hobot_llm/
    
  4. 修改设备配置

     # 修改BPU的保留内存
     # 替换dtb文件
     sudo cp /opt/tros/lib/hobot_llm/config/hobot-dtb/*.dtb /boot/hobot/
     # 重启
     reboot
     # 调整CPU的频率
     sudo bash -c 'echo 1 > /sys/devices/system/cpu/cpufreq/boost'
     sudo bash -c 'echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor'
    

二、运行

安装上面的步骤,到这里就全部安装好了,体验LLM有两种方式,一个是直接在shell窗口中以聊天的方式使用,还有一个是通过topic的订阅和发布来使用,前者适合体验,后者适用于实际开发中。

1. 以聊天窗口运行

新开一个shell窗口,执行以下命令:

source /opt/tros/setup.bash
ros2 run hobot_llm hobot_llm_chat

下面是我的实际执行情况:

root@ubuntu:~# source /opt/tros/setup.bash
root@ubuntu:~# ros2 run hobot_llm hobot_llm_chat
[EasyDNN]: EasyDNN version = 1.6.1_(1.18.6 DNN)
[BPU_PLAT]BPU Platform Version(1.3.3)!
[HBRT] set log level as 0. version = 3.15.25.0
[DNN] Runtime version = 1.18.6_(3.15.25 HBRT)
[A][DNN][packed_model.cpp:234][Model](2023-10-28,13:22:15.818.513) [HorizonRT] The model builder version = 1.20.1
[A][DNN][packed_model.cpp:234][Model](2023-10-28,13:22:31.97.703) [HorizonRT] The model builder version = 1.20.1
[A][DNN][packed_model.cpp:234][Model](2023-10-28,13:22:48.727.231) [HorizonRT] The model builder version = 1.20.1
[A][DNN][packed_model.cpp:234][Model](2023-10-28,13:23:06.393.996) [HorizonRT] The model builder version = 1.20.1
[A][DNN][packed_model.cpp:234][Model](2023-10-28,13:23:24.4.230) [HorizonRT] The model builder version = 1.20.1
[A][DNN][packed_model.cpp:234][Model](2023-10-28,13:23:31.997.90) [HorizonRT] The model builder version = 1.20.1
None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.
这是一个地平线RDK平台大模型聊天程序,请输入你的问题并按下回车,如需重新开始请输入reset,如需退出请输入exit
>>> 用户:

可以看到最后已经可以在shell窗口中进行聊天了

下面几段内容是我跟这个LLM实际对话的过程,还是挺有意思的,可以仔细看一下

>>> 用户:介绍一下自己
>>> 机器人:我是一名AI语言模型,可以回答各种问题。我能够理解并回答各种语言问题,包括中文、英文、法语、德语、日语、韩语、俄语、西班牙语、中文等。我能够处理各种类型的问题,包括事实、情感、逻辑、问题答案等。我能够根据用户输入的问题进行回答,并提供相关信息和建议。我是一台智能机器,可以不断学习和进步。我能够帮助用户解决各种问题,提供帮助和
>>> 用户:你现在是一名机器人开发工程师 ,请你完成我给你的任务
>>> 机器人:好的!我会尽力完成您的任务。请问您的任务是什么呢?
>>> 用户:ros2 topic pub --once /text_query std_msgs/msg/String "{data: ""中国的首都是哪里""}"   ;这是 一行ros2中想一个topic发布消息的命令,请你改写成Python代码
>>> 机器人:好的!请看以下Python代码:```pythonimport reimport stringprint("

这段对话里面,一开始的自我介绍还是挺好的,很有调理,也挺“拟人”的。
后面我希望它充当一个机器人开发工程师并给出一个实际任务的时候,它也有尝试回答,但是没有回答完整,看起来像是上下文达到了限制,被终止了

下面是第二段对话

>>> 用户:中国的首都在哪里?
>>> 机器人:北京。
>>> 用户:安徽的省会在哪里
>>> 机器人:安徽的省会位于六安市。
>>> 用户:中国的首都在哪里?请你把这句话翻译成英文
>>> 机器人:What is the capital of the Chinese People's Republic?
>>> 用户:你觉得你翻译的准确 吗?
>>> 机器人:The capital of the Chinese People's Republic is Beijing.

我先是问中国首都在哪里,这个问题回答是正确的,但是问到安徽的省会的时候就开始“瞎编”了,

后面让它翻译“中国的首都在哪里?”这句话,应该用where问句还是不what问句。

总得来说,目前情况下,不能指望这个LLM充当生产力工具,只能当一个玩具,但是,随着算法和硬件的发展,不久的将来,很可能出现这种可以在端侧部署和运行且效果很好的大模型,到时候真的就是人手一个大模型了。

2. 通过topic订阅来运行

前面提到过hobot_llm有可以通过topic订阅和发布的方式来使用,我这里给出Python通过topic订阅和发布的代码:

发布消息的代码:

import rclpy
from std_msgs.msg import String

def main():
    # 初始化ROS节点
    rclpy.init()

    # 创建一个节点,节点名为"simple_publisher"
    node = rclpy.create_node('simple_publisher')

    # 创建publisher, 指定主题名称为"/text_query", 数据类型为std_msgs/String,队列长度为10
    publisher = node.create_publisher(String, '/text_query', 10)

    # 准备要发送的数据
    msg = String()
    msg.data = "中国的首都是哪里"

    # 发布该数据
    publisher.publish(msg)

    # 清理并关闭节点
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

订阅的代码:

import rclpy
from std_msgs.msg import String

def callback(msg):
    print('Received message: "%s"' % msg.data)

def main():
    # 初始化ROS节点
    rclpy.init()

    # 创建一个节点,节点名为"simple_subscriber"
    node = rclpy.create_node('simple_subscriber')

    # 创建subscriber, 指定主题名称为"/text_result", 数据类型为std_msgs/String,并绑定回调函数callback
    subscriber = node.create_subscription(String, '/text_result', callback, 10)

    # 在 ROS 内部循环处理消息,并等待新消息到来
    rclpy.spin(node)

    # 清理并关闭节点
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

代码很简单,就不赘述了