Go语言精选:Mochi-MQTT——高性能的可嵌入MQTT服务‌

Go语言精选:Mochi-MQTT——高性能的可嵌入MQTT服务

随着物联网与微服务的普及,MQTT(Message Queuing Telemetry Transport)已成为轻量级消息传输协议的首选。对于需要在Go项目中快速嵌入MQTT Broker 的场景,Mochi-MQTT 提供了高性能、可配置、易扩展的解决方案。本文将带你从架构原理功能特性嵌入用法代码示例、以及实战图解等方面,深入浅出地解读如何在 Go 应用中使用 Mochi-MQTT 构建高效的 MQTT 服务。


目录

  1. 什么是 Mochi-MQTT?
  2. 核心功能与特性
  3. Mochi-MQTT 架构浅析
  4. 快速入门:环境准备与安装
  5. 嵌入式使用示例
    5.1. 启动一个最简 Broker
    5.2. 客户端连接与基本操作
    5.3. 安全配置与持久化配置
  6. 源码解析:Mochi-MQTT 的核心模块
    6.1. 网络层与协议解析
    6.2. 会话管理(Session)
    6.3. 主题路由与消息转发
    6.4. 持久化与离线消息
  7. Mermaid 图解:Mochi-MQTT 数据流与模块协作
  8. 性能与调优建议
  9. 常见场景与实战案例
  10. 总结与展望

1. 什么是 Mochi-MQTT?

Mochi-MQTT 是一款用 Go 语言编写的 高性能、可嵌入的 MQTT Broker 实现。它遵循 MQTT 3.1.1 及部分 MQTT 5.0 规范,具备以下优势:

  • 轻量级:仅需引入一行依赖,即可将 Broker 嵌入到任意 Go 服务中,无需单独部署独立 MQTT Server。
  • 高性能:利用 Go 的协程(goroutine)和非阻塞 IO(netpoll)机制,能够轻松支持数万个并发连接。
  • 可扩展:内置插件机制,支持自定义认证、存储后端、插件 Hook 等,开发者可根据业务场景插拔功能。
  • 持久化方案灵活:内置内存和文件持久化,也可对接 Redis、LevelDB 等外部存储。

简而言之,Mochi-MQTT 让你能够在 Go 应用内快速启动一个轻量且高效的 MQTT Broker,省去了额外部署、运维独立 Broker 的麻烦,尤其适合边缘设备嵌入式系统、或 微服务内部通信 等场景。


2. 核心功能与特性

在深入代码示例前,先看看 Mochi-MQTT 提供了哪些常用功能,便于理解接下来的示例内容。

  1. 协议支持

    • 完整实现 MQTT 3.1.1 协议规范;
    • 部分支持 MQTT 5.0(如订阅选项、用户属性等)。
  2. 多种监听方式

    • 支持 TCP、TLS、WebSocket 等多种网络协议;
    • 可以同时监听多个端口,分别提供不同的接入方式。
  3. 会话与持久化

    • 支持 Clean Session 与持久 Session;
    • 支持订阅持久化、离线消息存储;
    • 内置文件持久化,也可接入 LevelDB、BoltDB、Redis 等外部存储插件。
  4. 主题路由与 QoS

    • 支持 QoS 0/1/2 三种消息质量;
    • 主题模糊匹配(+#)路由;
    • 支持 Retain 消息、遗嘱消息。
  5. 插件与钩子

    • 支持在客户端连接、断开、订阅、发布等关键时机注入自定义逻辑;
    • 可以实现 ACL 授权、审计日志、限流、消息修改等操作。
  6. 集群与扩展(正在持续完善中)

    • 通过外部一致性存储(如 etcd、Redis)可实现多节点同步;
    • 支持共享订阅、负载均衡、长连接迁移。

3. Mochi-MQTT 架构浅析

了解基本能力后,我们来简要分析 Mochi-MQTT 的核心架构。整个 Broker 主要由以下模块构成:

  1. 网络层(listener)

    • 负责监听 TCP/SSL/WebSocket 端口;
    • 接收到原始字节流后交给协议解析器(parser)解码为 MQTT Control Packet;
  2. 协议解析与会话管理

    • 将字节流解析为 CONNECT、PUBLISH、SUBSCRIBE 等包类型;
    • 根据 ClientID、清理标志等参数,创建或加载会话(session);
    • 管理会话状态、保持心跳、处理遗嘱消息;
  3. 主题路由与消息分发

    • 存储所有订阅信息(topic → client 列表);
    • 当收到 PUBLISH 包时,根据订阅信息将消息分发给对应 Client;
    • 支持 QoS1/2 的确认与重发机制;
  4. 持久化层(store)

    • 提供内存、文件或外部存储后端;
    • 持久化会话、订阅、离线消息、Retain 消息等;
    • 在 Broker 重启后,能够迅速恢复会话与订阅状态;
  5. 事件回调与插件机制

    • 连接认证订阅校验消息到达等生命周期钩子触发时,回调自定义函数;
    • 插件可拦截并修改 Publish 消息、实现 ACL 验证、统计监控等。

Mermaid 架构图示意

flowchart TB
    subgraph Listener[网络层 (listener)]
        A[TCP/TLS/WebSocket] --> B[协议解析器]
    end
    subgraph Session[会话管理]
        B --> C[CONNECT 解码] --> D[创建/加载 Session]
        D --> E[心跳维护 & 遗嘱处理]
    end
    subgraph Router[主题路由 & 分发]
        F[PUBLISH 解码] --> G[查找订阅列表]
        G --> H[QoS1/2 确认+重发]
        H --> I[发送给客户端]
    end
    subgraph Store[持久化层]
        D --> J[会话持久化]
        G --> K[订阅持久化]
        H --> L[离线消息 & Retain 存储]
        J & K & L --> M[文件/LevelDB/Redis]
    end
    subgraph Plugin[插件钩子]
        Event1(连接认证) & Event2(发布拦截) & Event3(订阅校验) --> PluginLogic
        PluginLogic --> Router
    end

4. 快速入门:环境准备与安装

Mochi-MQTT 的安装仅需在 Go 模块中引入依赖即可,无需额外编译 C/C++ 代码。

  1. 初始化 Go 项目(需 Go 1.16+):

    mkdir mochi-demo && cd mochi-demo
    go mod init github.com/youruser/mochi-demo
  2. 引入 Mochi-MQTT

    go get github.com/mochi-mqtt/server/v2
    go get github.com/mochi-mqtt/server/v2/system
    • github.com/mochi-mqtt/server/v2 是核心 Broker 包;
    • 可根据需要再安装持久化后端,如 github.com/mochi-mqtt/store/leveldb

5. 嵌入式使用示例

下面通过代码示例,展示如何在 Go 应用中快速嵌入并启动一个最简 MQTT Broker。

5.1 启动一个最简 Broker

package main

import (
    "log"

    "github.com/mochi-mqtt/server/v2"
    "github.com/mochi-mqtt/server/v2/hooks"
)

func main() {
    // 1. 创建一个新的 Broker 实例
    srv := server.NewServer(nil)

    // 2. 注册一个简单的日志钩子,用于打印连接/断开、发布等事件
    srv.AddHook(new(hooks.Logger))

    // 3. 在默认的 TCP 端口 1883 启动 Broker
    log.Println("Starting Mochi-MQTT Broker on :1883")
    go func() {
        if err := srv.ListenAndServe(":1883"); err != nil {
            log.Fatalf("无法启动 Broker: %v", err)
        }
    }()

    // 4. 阻塞主协程
    select {}
}
  • server.NewServer(nil):创建一个不带任何配置的默认 Broker;
  • srv.AddHook(new(hooks.Logger)):注册系统自带的 Logger 钩子,会在控制台打印各种事件日志;
  • srv.ListenAndServe(":1883"):监听 TCP 1883 端口,启动 MQTT 服务。

此时,只需编译并运行该程序,就拥有了一个基本可用的 MQTT Broker,无需外部配置。

5.2 客户端连接与基本操作

我们可以用任何 MQTT 客户端(例如 mosquitto_pub/mosquitto_sub 或 Go 内置客户端)进行测试。以下示例展示用 Go 内置客户端发布与订阅消息。

5.2.1 安装 Paho MQTT 客户端(Go 版)

go get github.com/eclipse/paho.mqtt.golang

5.2.2 发布与订阅示例

package main

import (
    "fmt"
    "time"

    mqtt "github.com/eclipse/paho.mqtt.golang"
)

func main() {
    // 1. 连接到本地 Broker
    opts := mqtt.NewClientOptions().AddBroker("tcp://localhost:1883").SetClientID("go-pub")
    client := mqtt.NewClient(opts)
    if token := client.Connect(); token.Wait() && token.Error() != nil {
        panic(token.Error())
    }

    // 2. 订阅示例
    go func() {
        optsSub := mqtt.NewClientOptions().AddBroker("tcp://localhost:1883").SetClientID("go-sub")
        subClient := mqtt.NewClient(optsSub)
        if token := subClient.Connect(); token.Wait() && token.Error() != nil {
            panic(token.Error())
        }
        subClient.Subscribe("topic/test", 0, func(c mqtt.Client, m mqtt.Message) {
            fmt.Printf("收到消息: topic: %s, payload: %s\n", m.Topic(), string(m.Payload()))
        })
    }()

    // 3. 发布示例
    time.Sleep(1 * time.Second) // 等待订阅端启动
    if token := client.Publish("topic/test", 0, false, "Hello Mochi-MQTT"); token.Wait() && token.Error() != nil {
        panic(token.Error())
    }

    // 4. 等待消息接收
    time.Sleep(2 * time.Second)
    client.Disconnect(250)
}
  • 首先创建两个客户端:go-pub(用于发布)和 go-sub(用于订阅);
  • subClient.Subscribe("topic/test", 0, ...):订阅主题 topic/test,QoS 为 0;
  • client.Publish("topic/test", 0, false, "Hello Mochi-MQTT"):发布一条 QoS 0 消息;
  • 订阅端会收到并打印。

5.3 安全配置与持久化配置

在实际生产环境中,我们往往需要身份验证加密传输、以及持久化存储会话。例如,添加简单密码认证、启用 TLS、以及使用 LevelDB 存储。

5.3.1 密码认证示例

package main

import (
    "log"

    "github.com/mochi-mqtt/server/v2"
    "github.com/mochi-mqtt/server/v2/hooks"
    "github.com/mochi-mqtt/server/v2/hooks/auth"
)

func main() {
    srv := server.NewServer(nil)

    // 1. 创建一个简单的用户密码认证插件
    basicAuth := auth.NewStaticAuthenticator(map[string]string{
        "user1": "password123",
        "user2": "pass456",
    })
    srv.AddHook(basicAuth)

    srv.AddHook(new(hooks.Logger))

    log.Println("Starting secure Mochi-MQTT Broker on :8883")
    go func() {
        if err := srv.ListenAndServe(":8883"); err != nil {
            log.Fatalf("无法启动 Broker: %v", err)
        }
    }()

    select {}
}
  • auth.NewStaticAuthenticator(map[string]string):创建一个静态用户-密码映射认证;
  • 客户端在连接时必须提供正确的用户名/密码才能成功 CONNECT。

5.3.2 启用 TLS

package main

import (
    "log"

    "github.com/mochi-mqtt/server/v2"
    "github.com/mochi-mqtt/server/v2/hooks"
    "github.com/mochi-mqtt/server/v2/system"
)

func main() {
    // 1. 定义 TLS 证书和私钥文件路径
    tlsConfig := system.NewTLSConfig("server.crt", "server.key")

    // 2. 创建 Broker 并配置 TLS
    srv := server.NewServer(nil)
    srv.AddHook(new(hooks.Logger))

    // 3. 监听 TLS 端口
    log.Println("Starting TLS-enabled Broker on :8883")
    go func() {
        if err := srv.ListenAndServeTLS(":8883", tlsConfig); err != nil {
            log.Fatalf("无法启动 TLS Broker: %v", err)
        }
    }()

    select {}
}
  • system.NewTLSConfig(certFile, keyFile):加载服务器证书与私钥生成 TLS 配置;
  • ListenAndServeTLS 方法会启动一个支持 TLS 的 MQTT 监听,客户端需要使用 tls://localhost:8883 进行连接。

5.3.3 LevelDB 持久化示例

package main

import (
    "log"

    "github.com/mochi-mqtt/server/v2"
    "github.com/mochi-mqtt/server/v2/hooks"
    "github.com/mochi-mqtt/store/leveldb"
)

func main() {
    // 1. 创建 LevelDB 存储后端,数据存放在 ./data 目录
    db, err := leveldb.New("./data")
    if err != nil {
        log.Fatalf("无法打开 LevelDB: %v", err)
    }
    // 2. 配置 Broker,传入持久化存储
    config := &server.Options{
        Store: db, // 使用 LevelDB 做持久化
    }
    srv := server.NewServer(config)
    srv.AddHook(new(hooks.Logger))

    log.Println("Starting persistent Broker on :1883")
    go func() {
        if err := srv.ListenAndServe(":1883"); err != nil {
            log.Fatalf("无法启动 Broker: %v", err)
        }
    }()

    select {}
}
  • leveldb.New("./data"):将所有持久化数据(会话、离线消息、Retain 等)保存到 ./data 目录;
  • 下次 Broker 重启时会从 LevelDB 中加载持久化数据,恢复会话和离线消息。

6. 源码解析:Mochi-MQTT 的核心模块

为了更深入理解 Mochi-MQTT 的工作原理,下面挑选几个核心模块进行简要解析。

6.1 网络层与协议解析

  • 监听server/listener.go 中通过 net.Listen("tcp", addr)tls.Listen 等方式启动监听。
  • Accept 循环:每个新连接都会被包裹成 net.Conn,并交给 processor 任务,运行 connReader 协程读取数据。
  • 协议解析:借助 go.mochi.co/mqtt 仓库中提供的 MQTT Packet 编解码器,将字节流解析为 packet.ControlPacket,包括 CONNECT、PUBLISH、SUBSCRIBE 等。
// 伪代码:连接读取和包解析
func (srv *Server) handleConnection(conn net.Conn) {
    defer conn.Close()
    for {
        packet, err := packet.ReadPacket(conn)
        if err != nil { break }
        srv.processPacket(conn, packet)
    }
}

6.2 会话管理(Session)

  • SessionKey:根据客户端提供的 ClientID、CleanSession 标志来生成唯一会话 key;
  • 创建/加载:当收到 CONNECT 包时,根据 CleanSession 决定是否从持久化存储加载旧会话,或者新建一个 Session 对象。
  • 心跳管理:定期检查 KeepAlive 超时,如果超时则断开连接并触发遗嘱消息。
// 伪代码:CONNECT 处理
func (srv *Server) handleCONNECT(conn net.Conn, pkt *packet.Connect) {
    sessKey := makeSessionKey(pkt.ClientID, pkt.CleanStart)
    session := srv.store.LoadSession(sessKey)
    if session == nil || pkt.CleanStart {
        session = NewSession(pkt.ClientID, conn)
    }
    srv.sessions[sessKey] = session
    session.KeepAlive = pkt.KeepAlive
    // 发送 CONNACK
}

6.3 主题路由与消息转发

  • 订阅注册:当收到 SUBSCRIBE 包后,将 (topic → session) 信息写入一个路由表(map[string]map[*Session]QoS)。
  • 消息发布:当收到 PUBLISH 包时,根据 topic 查找所有匹配订阅的会话,并按各自 QoS 进行转发;
  • QoS1/2:实现 PUBACK、PUBREC、PUBREL、PUBCOMP 等流程,保证至少一次、仅一次投递。
// 伪代码:PUBLISH 处理
func (srv *Server) handlePUBLISH(session *Session, pkt *packet.Publish) {
    subs := srv.router.FindSubscribers(pkt.Topic)
    for _, sub := range subs {
        switch sub.QoS {
        case 0:
            sub.Session.WritePacket(pkt) // 直接转发
        case 1:
            sub.Session.WritePacket(pkt)
            // 等待 PUBACK
        case 2:
            // 四次握手流程
        }
    }
}

6.4 持久化与离线消息

  • Retain 消息:当 PUBLISH 包带有 Retain 标志时,Broker 会将该消息持久化在一个 retain 表中,以便后续新的订阅客户端连接时能够收到最新消息。
  • 离线消息:对于持久化 Session,当目标客户端不在线时,如果 QoS ≥1,会将消息写入离线队列;当客户端重新上线后,将这些离线消息一次性推送。
// 伪代码:离线消息存储
func (s *Session) storeOffline(pkt *packet.Publish) {
    s.offlineQueue = append(s.offlineQueue, pkt)
}

// 客户端重连后
func (s *Session) deliverOffline() {
    for _, pkt := range s.offlineQueue {
        s.WritePacket(pkt)
    }
    s.offlineQueue = nil
}

7. Mermaid 图解:Mochi-MQTT 数据流与模块协作

下面通过几个 Mermaid 图示,直观展示 Mochi-MQTT 在处理连接、订阅、发布、离线等场景时,各模块是如何协作的。

7.1 客户端连接与会话恢复流程

sequenceDiagram
    participant C as Client
    participant L as Listener(网络层)
    participant S as Server
    participant M as Store(持久化)

    C->>L: TCP 连接 → 发送 CONNECT(ClientID, KeepAlive, CleanStart)
    L->>S: 接收 CONNECT 包
    S->>M: 查询 ClientID 对应 Session(若 CleanStart=false)
    alt 存在持久化 Session
        M-->>S: 返回旧 Session 状态(订阅、离线队列)
        S->>C: 发送 CONNACK(0, SessionPresent=true)
        S->>S: 恢复离线消息推送
    else 新建 Session
        S->>S: 创建新 Session
        S->>C: 发送 CONNACK(0, SessionPresent=false)
    end

7.2 主题订阅与消息转发流程

sequenceDiagram
    participant Pub as 发布者
    participant S as Server
    participant Sub1 as 订阅者1
    participant Sub2 as 订阅者2

    Pub->>S: PUBLISH(topic/foo, QoS=1, payload)
    S->>S: 查找所有匹配 "topic/foo" 的订阅列表
    alt Subscriber1 QoS=1
        S->>Sub1: 转发 PUBLISH(QoS=1)
        Sub1-->>S: 回复 PUBACK
    end
    alt Subscriber2 QoS=0
        S->>Sub2: 转发 PUBLISH(QoS=0)
    end

7.3 离线消息存储与恢复流程

sequenceDiagram
    participant Pub as 发布者
    participant S as Server
    participant Sub as 订阅者(离线中)
    participant M as Store

    Pub->>S: PUBLISH(topic/offline, QoS=1, payload)
    S->>Sub: Sub 不在线,进入离线逻辑
    S->>M: 持久化 pkt 到 离线队列(topic/offline)
    
    %% 客户端重新连接时
    Sub->>S: CONNECT(ClientID, CleanStart=false)
    S->>M: 加载离线队列(topic/offline)
    loop
        M-->>S: 返回一条离线 PUBLISH
        S->>Sub: 转发离线 PUBLISH
        Sub-->>S: PUBACK
    end
    S->>M: 清空已投递离线队列

8. 性能与调优建议

为了充分发挥 Mochi-MQTT 的高性能优势,以下几点建议值得参考:

  1. 合理设置 Go 运行时参数

    • 增加 GOMAXPROCS 至 CPU 核数或更高;
    • 根据负载调整 GODEBUG 相关调度参数,如 schedtracescheddetail,用于调试与性能监控。
  2. 网络层优化

    • 如果连接数量巨大,可启用 SO\_REUSEPORT(在 Linux 下),让多个监听器在同一端口上分担负载;
    • 使用长连接复用,避免客户端频繁断连重连导致的系统调用开销;
  3. 持久化存储调优

    • 对于文件持久化模式,可将 FlushInterval 调整得略大,以减少硬盘写入次数;
    • 对于 LevelDB 后端,可设置合适的 LRU 缓存大小、写缓冲区大小等参数,提升写入与读取性能;
  4. 线程与协程数量控制

    • 避免在业务钩子中启动大量阻塞性 Goroutine;
    • 对于需要长时间运行的异步操作(如日志落盘、消息转发到二级队列),使用缓存池或限流队列,避免无限制 Goroutine 泄露;
  5. 监控与健康检查

    • 在 Broker 上集成 Prometheus 监控插件,可实时收集连接数、订阅数、消息收发率等指标;
    • 定期检查时延、消息队列长度,如果发现突增,应考虑水平扩容或降级策略。

9. 常见场景与实战案例

以下列举两个典型的实战场景,展示 Mochi-MQTT 在实际项目中的应用。

9.1 边缘设备网关

在工业物联网场景中,往往需要在边缘设备上运行一个轻量级的 MQTT Broker,将多个传感器节点通过 MQTT 协议上报数据,边缘网关再将数据汇总并转发到云端。

func main() {
    // 边缘网关初始化
    db, _ := leveldb.New("/var/edge-gateway/data")
    srv := server.NewServer(&server.Options{
        Store: db,
    })
    srv.AddHook(new(hooks.Logger))

    // 启动本地 TCP Broker,供内部传感器连接
    go srv.ListenAndServe(":1883")

    // 连接云端 MQTT Broker 并将本地消息转发
    cloudOpts := mqtt.NewClientOptions().AddBroker("tcp://cloud-mqtt:1883").SetClientID("edge-forwarder")
    cloudClient := mqtt.NewClient(cloudOpts)
    cloudClient.Connect()

    // 订阅本地所有传感器上报
    srv.AddHook(hooks.OnPublish(func(cl *hooks.Client, pkt hooks.PublishPacket) {
        // 将消息转发至云端
        cloudClient.Publish(pkt.Topic, pkt.QoS, pkt.Retain, pkt.Payload)
    }))

    select {}
}
  • 边缘网关启动一个嵌入式 Mochi-MQTT Broker,监听内部传感器;
  • 在发布钩子中,实时将本地消息转发至云端 Broker,实现 双边桥接

9.2 微服务内部消息总线

在微服务架构中,可以利用 Mochi-MQTT 作为内部轻量级消息总线,让各服务模块通过 MQTT Topic 进行异步解耦通信。

func main() {
    srv := server.NewServer(nil)
    srv.AddHook(new(hooks.Logger))
    go srv.ListenAndServe(":1883")

    // 服务 A 发布用户注册事件
    go func() {
        time.Sleep(time.Second)
        client := connectMQTT("service-A")
        client.Publish("users/registered", 1, false, "user123")
    }()

    // 服务 B 订阅注册事件并处理
    go func() {
        client := connectMQTT("service-B")
        client.Subscribe("users/registered", 1, func(c mqtt.Client, m mqtt.Message) {
            fmt.Println("收到注册事件,处理业务: ", string(m.Payload()))
        })
    }()

    select {}
}

func connectMQTT(clientID string) mqtt.Client {
    opts := mqtt.NewClientOptions().AddBroker("tcp://localhost:1883").SetClientID(clientID)
    client := mqtt.NewClient(opts)
    client.Connect()
    return client
}
  • 各服务仅需通过独立的 MQTT 客户端连接到本地 Broker;
  • Service A 发布事件,Service B 即可订阅并异步处理,实现松耦合。

10. 总结与展望

本文从 Mochi-MQTT 的基本概念、核心模块、嵌入示例、源码解析、性能调优、以及实战场景等方面做了全面讲解。总结如下:

  1. Mochi-MQTT 是一款专为 Go 生态打造的高性能、可嵌入 MQTT Broker,支持多种网络协议、会话持久化、插件钩子等功能;
  2. 快速上手:只需 go get 引入依赖,创建 server.NewServer(…),即可启动一个可用的 MQTT 服务;
  3. 高度可配置:支持密码认证、TLS 加密、LevelDB 持久化,以及自定义插件,实现 ACL、限流、审计等需求;
  4. 高性能:基于 Go 的并发模型与非阻塞事件循环,能够轻松处理数万并发连接和高吞吐消息;
  5. 灵活嵌入:适用于边缘网关、微服务消息总线、嵌入式设备等场景,不需要单独部署独立 Broker,降低运维成本。

未来,Mochi-MQTT 将在多节点集群、跨数据中心同步、消息转码、QoS 优化等方向持续迭代。如果你正在用 Go 构建物联网、微服务通信中间件,强烈建议亲自体验 Mochi-MQTT,快速搭建、轻松开发,让你的项目既具备 MQTT 的高效与可扩展,又免除额外服务的运维负担。

最后修改于:2025年06月04日 11:09

评论已关闭

推荐阅读

AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日
python之plot()和subplot()画图
2024年11月26日
理解 DALL·E 2、Stable Diffusion 和 Midjourney 工作原理
2024年12月01日