大语言模型驱动的物联网AI探究

        与当下热门的AI类似,曾几何时,物联网(Internet of thing)实现“万物互联"给人类带来了无限的遐想。但是往往事与愿违,美好的愿景并没有如约而至。十几年来,物联网远没有实现”万物互联“的美好愿景。

      随着chatGPT 为主的AI热潮,人们又一次提出了 AIoT (artificial intelligence of thing) 的新概念。AI 会给IoT 带来新的生机么?这是有趣的话题。 

        多年的实践表明,IoT 实现的难点在于没有广泛被接纳的IoT 协议,目前只有各个公司内部形成的各种IoT 生态,比如小米,华为,苹果的智能设备,它们自成一体。 它们成为了一个又一个信息孤岛,令人沮丧。

      哪怕是不同公司的遥控器都互不兼容。出于各自的商业利益,人类难以达成共识。

        各种自主无人系统的快速发展,增加了机器的内生智能,使智能机器之间的功能协作成为可能。然而,传统的智能机器协作协议在功能、效率和可扩展性方面存在局限性。此外,现有的智能机器协作研究尚未接近一种统一的范式,以促进机器之间以及机器与人类之间的交互。

       在我看来,chatGPT 的出现,为IoT 行业打开了另一条道路-”让机器说人话“.

        在人类文明进步过程中,自然语言成为人类最为广泛接纳的交流语言,相比于机器语言而言,人类语言非常丰富,对语法和语义的要求并严格。如果让设备采用人类的语言来交流,能够最大程度地实现设备之间的相互交流和理解。

     自然语言的通信仍然需要底层的协议承载,最简单和普及的通信协议莫过于TCP/IP 协议了,但是考虑到物联网设备需要点对多点通信,所以使用基于MQTT 的PUB/SUB 通信协议最为合适。

本文记录了如何使用自然语言/MQTT作为物联网设备的通信协议。

实验的主要内容

  • MQTT Broker :mosquitto
  • 大语言模型:本地部署ollama/llama-3 ,远程调用kimi。
  • 程序设计语言 :Python
  • 准备工作

    安装mosquitto

        要在 Windows 上安装 Mosquitto,请从 mosquitto.org(64 位或 32 位)中选择所需的安装文件,下载并运行它。  

    具体过程请参考:

    How to Install Mosquitto MQTT Broker on Windows

    运行 

    PS C:\Windows\system32> mosquitto

    订阅

    PS C:\Users\Yao> mosquitto_sub -i mosq_sub1 -t "Test topic" -d

    发布

    PS C:\Users\Yao> mosquitto_pub -i mosq_pub1 -t "Test topic" -m "Test message" -d

    python MQTT Client

    安装 paho-mqtt

    pip3 install -i https://pypi.doubanio.com/simple paho-mqtt

    发布

    # python 3.6
    
    import random
    import time
    
    from paho.mqtt import client as mqtt
    
    
    broker = '127.0.0.1'
    port = 1883
    topic = "python/mqtt"
    # generate client ID with pub prefix randomly
    client_id = f'python-mqtt-{random.randint(0, 1000)}'
    
    
    def connect_mqtt():
        def on_connect(client, userdata, flags, rc,properties):
            if rc == 0:
                print("Connected to MQTT Broker!")
            else:
                print("Failed to connect, return code %d\n", rc)
    
        client =  mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id) 
        client.on_connect = on_connect
        client.connect(broker, port)
        return client
    
    
    def publish(client):
        msg_count = 0
        while True:
            time.sleep(1)
            msg = f"messages: {msg_count}"
            result = client.publish(topic, msg)
            # result: [0, 1]
            status = result[0]
            if status == 0:
                print(f"Send `{msg}` to topic `{topic}`")
            else:
                print(f"Failed to send message to topic {topic}")
            msg_count += 1
    
    
    def run():
        client = connect_mqtt()
        client.loop_start()
        publish(client)
    
    
    if __name__ == '__main__':
        run()
    

    订阅

    # python3.6
    
    import random
    
    from paho.mqtt import client as mqtt
    
    
    broker = '127.0.0.1'
    port = 1883
    topic = "/python/mqtt"
    # generate client ID with pub prefix randomly
    client_id = f'python-mqtt-{random.randint(0, 100)}'
    
    
    def connect_mqtt() -> mqtt:
        def on_connect(client, userdata, flags, rc,properties):
            if rc == 0:
                print("Connected to MQTT Broker!")
            else:
                print("Failed to connect, return code %d\n", rc)
    
        client =  mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id) 
        client.on_connect = on_connect
        client.connect(broker, port)
        return client
    
    
    def subscribe(client: mqtt):
        def on_message(client, userdata, msg):
            print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
    
        client.subscribe(topic)
        client.on_message = on_message
    
    
    def run():
        client = connect_mqtt()
        subscribe(client)
        client.loop_forever()
    
    
    if __name__ == '__main__':
        run()
    

    实验 

    Device1 通过自然语言控制 Device2。

    GPTAgent 调用大语言模型,完成语言的理解,调用本地llama-3 或者远程调用kimi大模型。

    Device2 模仿一个空调设备。

    topic 定义

    Device To ChatGPT Device/GPT
    chatGPT to Device GPT/Device
    Device to Device Device/Device

    仿真程序

     为了做实验,编写了两个设备和一个Chat GPT Agent的仿真软件.使用Python 编写。

    Device1  传感器

     定时地采集温度,并向Device2 发送控制命令。

    Devices2 控制器

    接收Device 1 发送的控制命令,控制空调。

    具体的方法

  • TurnOn- 开启空调
  • TurnOff-关闭空调
  • Up-调高温度
  • Down-调低温度
  • 控制流程

  •  订阅Device/Device 主题的信息
  • 订阅Device/GPT 主题的信息
  • 当接收到 Device1 发送来的消息后,组织大语言模型的Prompt ,发送给chatGPT IoT Agent(主题为Device/GPT),chatGPT 解析自然语言,将结果发布给Device 2 设备(主题为GPT/Device )
  • Device2 根据chatGPT 解析的结果,控制设备。
  • chatGPT Agent

            订阅 Device/GPT 主题的信息,做出自然语言命令的解释,然后将结果返回给发送的设备。

    为了提高大语言模型服务的实时性,在PC 机上部署了ollama /llama-3 大模型。

    源代码

    GPTAgent

    # python3.6
    
    import random
    from openai import OpenAI
    from paho.mqtt import client as mqtt
    
    
    broker = '127.0.0.1'
    port = 1883
    topic = "Device/GPT"
    # generate client ID with pub prefix randomly
    client_id = f'python-mqtt-{random.randint(0, 100)}'
    #LLM = OpenAI(base_url="http://localhost:11434/v1", api_key="lm-studio")
    LLM=OpenAI(
        api_key="sk-xxxxxxx",
        base_url="https://api.moonshot.cn/v1",
    )
    def connect_mqtt() -> mqtt:
        def on_connect(client, userdata, flags, rc,properties):
            if rc == 0:
                print("Connected to MQTT Broker!")
            else:
                print("Failed to connect, return code %d\n", rc)
    
        client =  mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id) 
        client.on_connect = on_connect
        client.connect(broker, port)
        return client
    
    
    def subscribe(client: mqtt):
        def on_message(client, userdata, msg):
            print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
            
            history = [
                {"role": "system", "content": "你是一个聪明的助手。你总是提供合理、准确且有帮助的答案。总是用中文简体回答"},
                {"role": "user", "content": msg.payload.decode()},
            ]
            completion = LLM.chat.completions.create(
                model="moonshot-v1-8k",
                messages=history,
                temperature=0,
               
            )
            Response=completion.choices[0].message.content
            print(Response)
            result = client.publish("GPT/Device", Response.encode('utf-8'))
            # result: [0, 1]
            status = result[0]
            if status == 0:
                print(f"Send `{msg}` to topic `{topic}`")
            else:
                print(f"Failed to send message to topic {topic}")
            
        client.subscribe(topic)
        client.on_message = on_message
    
    
    def run():
        client = connect_mqtt()
        subscribe(client)
        client.loop_forever()
    
    
    if __name__ == '__main__':
        run()
    

    Device2

    # python3.6
    
    import random
    import json
    from paho.mqtt import client as mqtt
    
    
    broker = '127.0.0.1'
    port = 1883
    #topic = "GPT/Device"
    # generate client ID with pub prefix randomly
    client_id = f'python-mqtt-{random.randint(0, 100)}'
    
    
    def connect_mqtt() -> mqtt:
        def on_connect(client, userdata, flags, rc,properties):
            if rc == 0:
                print("Connected to MQTT Broker!")
            else:
                print("Failed to connect, return code %d\n", rc)
    
        client =  mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id) 
        client.on_connect = on_connect
        client.connect(broker, port)
        return client
    
    
    def subscribe(client: mqtt):
        def on_message(client, userdata, msg):
            print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
            if msg.topic=="Device/Device":
                print("Device to Device")
                Prefix='''针对下面的命令,判断应该调用哪个工具执行:
                          工具:
                            TurnOn:打开空调
                            TurnOff:关闭空调
                            Up: 调高温度
                            Down:调低空调
                          命令:  
                       '''
                Suffix='''请以JSON 格式输出,格式为:
                    /`/`/`json
                       {"ToolName":"The Name Of Tool"}
                       /`/`/`
                       '''
                Prompt=Prefix+msg.payload.decode()+ Suffix      
                client.publish("Device/GPT", Prompt)
            else:
                if msg.topic=="GPT/Device":
                   print("GPT/Device")
                   Result=msg.payload.decode()
                   p=Result.find("```json")
                   print(p)
                   if p>=0:
                      Temp=Result.replace("```json","")
                      e=Temp.find("```") 
                      print(e)
                      print(Temp[p:e])
                      JsonContent=json.loads(Temp[p:e]) 
                      print(JsonContent)
                      if JsonContent["ToolName"]=="TurnOn":
                             print("打开空调!")
                      else:
                          if JsonContent["ToolName"]=="TurnOff":
                                 print("关闭空调!")
                          else:
                              if JsonContent["ToolName"]=="Up":
                                     print("调高空调温度!")
                              else:
                                 if JsonContent["ToolName"]=="Down":
                                        print("调低空调温度!") 
                              
        client.subscribe("GPT/Device")
        client.subscribe("Device/Device")
        client.on_message = on_message
    
    
    def run():
        client = connect_mqtt()
        subscribe(client)
        client.loop_forever()
    
    
    if __name__ == '__main__':
        run()
    

    Device1

    # python 3.6
    
    import random
    import time
    
    from paho.mqtt import client as mqtt
    
    
    broker = '127.0.0.1'
    port = 1883
    topic = "Device/Device"
    # generate client ID with pub prefix randomly
    client_id = f'python-mqtt-{random.randint(0, 1000)}'
    
    
    def connect_mqtt():
        def on_connect(client, userdata, flags, rc,properties):
            if rc == 0:
                print("Connected to MQTT Broker!")
            else:
                print("Failed to connect, return code %d\n", rc)
    
        client =  mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id) 
        client.on_connect = on_connect
        client.connect(broker, port)
        return client
    
    
    def publish(client):
        msg_count = 0
        while True:
            time.sleep(5)
            #msg = f"messages: {msg_count}"
            if (msg_count & 1) == 0: 
                 msg="请打开空调!"
            else:
                 msg="请关闭空调!"  
            result = client.publish(topic, msg.encode('utf-8'))
            # result: [0, 1]
            status = result[0]
            if status == 0:
                print(f"Send `{msg}` to topic `{topic}`")
            else:
                print(f"Failed to send message to topic {topic}")
            msg_count += 1
    
    
    def run():
        client = connect_mqtt()
        client.loop_start()
        publish(client)
    
    
    if __name__ == '__main__':
        run()
    

    结果

      Device1 的发送周期为5秒钟,kimi 大模型响应自如。而本地llama-3 速度还是不行。

    应用场景

    使用自然语言作为物联网的通信语言的缺点是

  •    延时长
  •   成本高
  •  对于实时性要求不高的应用场景,有一定的应用场景。

    设备添加一个维护接口

            为设备添加一个自然语言的维护接口,具有很大的好处,以前的设备通常也保留了一个字符终端的命令行接口,当设备发生故障,或者需要配置,维护时,使用命令行控制设备,现在可以转换成自然语言来维护。自然语言适合远程操作。不需要记忆各种命令的格式。

      另一个好处是当设备发生故障时,可以手动操作。

            自然语言命令接口也有利于与上层软件的兼容。使上层软件更加灵活,并且与各种厂商的设备互联互通。

    不同生态系统的互联

            例如小米的设备与华为的设备互联互通,可以采用自然语言通信。

    进一步的思考

            实现IoT 设备的自然语言通信,只需要一个小型的语言模型就可以实现,并且在IoT 领域增强,这种小型的IoTModel 部署在云端,或者边缘。随着AI 成本的下降,也许很快能够出现IoT GPT 服务器产品出现。基于自然语言的IoT 通信将会流行起来。他们将会在智慧城市,工业,智能家居,农业,环境等行业流行起来。

          笔者相信,除了物联网应用之外,自然语言通信协议的另一个巨大的潜在市场是政府,大企业之间异构系统的互联互通。比如在一个医院信息管理系统中,医生的电脑要调用各种检查报告,查询病例,床位信息。这都要通过复杂的API 实现,当需要更新API,或者添加一项新的数据科目时,所有相关的软件都需要做相应的更新。除了医院信息管理系统的厂商能够做软件的更新之外,别的厂商难以介入。这就人为地设置了各种“数据墙”,难以挖掘医学数据。使用“自然语言”协议能够解决异构系统的信息共享。

            信息共享是人们朝思暮想的目标,但是长期以来难以实现,为此还不断地推广类似DDS,OPCUA 等统一的协议,老实说,许多年过去了,收效甚微。也许,自然语言将成为异种机互联的终结协议,我们将迎来“让机器说人话”的时候了!

    作者:姚家湾

    物联沃分享整理
    物联沃-IOTWORD物联网 » 大语言模型驱动的物联网AI探究

    发表回复