本项目搭建思路:

使用 LLaMA-Factory 微调大语言模型,通过 one-api 转发微调后大语言模型端口,部署 QQ 机器人进行聊天通讯。大体结构图如下所示:

test

无 GPU 资源的可以参考 如何廉价使用GPU服务器
本机环境:

  • 显卡:2080Ti (11G)
  • OS:Linux

# 微调大语言模型

# 下载模型

参考 LLaMA-Factory 的硬件要求,选择你要微调的合适模型。

Method Bits 7B 13B 30B 70B 8x7B 8x22B
Full AMP 120GB 240GB 600GB 1200GB 900GB 2400GB
Full 16 60GB 120GB 300GB 600GB 400GB 1200GB
Freeze 16 20GB 40GB 80GB 200GB 160GB 400GB
LoRA/GaLore/BAdam 16 16GB 32GB 64GB 160GB 120GB 320GB
QLoRA 8 10GB 20GB 40GB 80GB 60GB 160GB
QLoRA 4 6GB 12GB 24GB 48GB 30GB 96GB
QLoRA 2 4GB 8GB 16GB 24GB 18GB 48GB

根据我们的配置,选择用 QLoRA (8bits) 方法微调 ChatGLM3-6B 模型。从魔搭社区找到要下载的模型

git clone https://www.modelscope.cn/ZhipuAI/chatglm3-6b.git

# 部署 LLaMA-Factory

根据 GitHub 指引进行拉取库和安装依赖:

git clone https://github.com/hiyouga/LLaMA-Factory.git
conda create -n llama_factory python=3.10
conda activate llama_factory
cd LLaMA-Factory
pip install -e .[metrics]

以下面格式准备我们要训练的数据集

[
  {
    "instruction": "用户指令(必填)",
    "input": "用户输入(选填)",
    "output": "模型回答(必填)",
    "system": "系统提示词(选填)",
    "history": [
      ["第一轮指令(选填)", "第一轮回答(选填)"],
      ["第二轮指令(选填)", "第二轮回答(选填)"]
    ]
  }
]

更新 data/dataset_info.json 文件,在末尾加上文件名字和对应的哈希值

"self_cognition": {
    "file_name": "self_cognition.json",
    "file_sha1": "a0be89bae5fa455b9eccc347e2a8f784a93242c5"
  }
# 微调模型

python src/train_web.py 启动 LLM-Factory,根据自己情况修改对应的配置。

image-20240426193329909

在 80 条身份数据的情况下 10 个 epoch,学习率 1e-4, lora rank 为 4 的情况下,其余默认。发现已经让模型能够重新定义模型的 “自我身份”,说明微调起作用了。之后也简单问了一下常规的问题,以检查是否造成了灾难性遗忘:

image-20240426204811421

# 部署 ChatGLM3

拉取 https://github.com/THUDM/ChatGLM3 项目。

更改 openai_api_demo\api_server.py 下的模型权重路径(MODEL_PATH)为微调后的模型路径,如果不需要加入知识库索引,则取消加载 Embedding,把倒数第二行的代码注释掉,否则下载 m3e 模型权重,并更改对应的权重路径。

启动脚本

python openai_api_demo/api_server.py

chat Curl 测试

curl -X POST "http://YOUR_IP:YOUR_PORT/v1/chat/completions" \
-H "Content-Type: application/json" \
-d "{\"model\": \"chatglm3-6b\", \"messages\": [{\"role\": \"user\", \"content\": \"你是谁\"}], \"stream\": false, \"max_tokens\": 100, \"temperature\": 0.8, \"top_p\": 0.8}"

image-20240427133430860

# 部署 One-api

通过 one-api 转发 key 给其他应用端使用。

  1. 拉取源码并编译:

    git clone https://github.com/songquanpeng/one-api.git
    
    # 构建前端
    cd one-api/web/default
    npm install
    npm run build
    
    # 构建后端
    cd ../..
    go mod download
    go build -ldflags "-s -w" -o one-api
    
  2. 运行:

    chmod u+x one-api
    ./one-api --port 3000 --log-dir ./logs
  3. 访问 http://localhost:3000/ 并登录。初始账号用户名为 root ,密码为 123456

  4. 添加 chatglm3 的渠道。 Base_URL 是部署大模型的服务器的 ip 地址 + 端口号,秘钥随便填,记住此刻的模型名字,后面要用到。

    image-20240428134214976

  5. 测试。

    image-20240427203736092

  6. 添加对应的令牌,名称随便取即可,模型范围选择上步设定的 chatglm3-6b 。创建完成之后复制 key。

# 部署 QQ 机器人

先手动部署消息平台,Lagrange 是一个 QQNT 协议逆向工程框架,比 Shamrock 或 Mirai 更加轻便,在目前也较为稳定。根据官网教程部署,并配置反向 ws 为以下内容。

{
            "Type": "ReverseWebSocket",
            "Host": "127.0.0.1",
            "Port": 8080,
            "Suffix": "/ws",
            "ReconnectInterval": 5000,
            "HeartBeatInterval": 5000,
            "AccessToken": "abcd"
        },

再部署 qchatgpt,先运行生成配置文件,安装官网要求按需更改自己配置。

用 one-api 接口部署聊天机器人,

  1. config/provider.jsonkey 列表中增加一个 key。

    "chatglm3":[
    	"sk-oOtNy2BIBWL8GrjK18Be0a09214047C3A8AeA4175471A7A0"
    ]
  2. config/provider.json 设置配置项 openai-chat-completionsbase-url 为 One API 后端地址 + v1(eg:"https://YOUR_IP:PORT/v1")

  3. 并更改 config/provider.json 配置项 completion_api_paramsmodel 参数设置为 One API 支持的模型名称(也就是上面你创建的模型名字!)。

  4. metadata/llm-models.json 中添加受支持的大语言模型。

    {
        "name": "chatglm3-6b",
        "token_mgr": "chatglm3"
    }

# 展示效果图:

QQ 聊天如下所示:

image-20240428133427341

QchatGPT 响应如下:

image-20240428133927266