写点什么

用纯 CPU 环境搭建大模型环境

作者:SkyFire
  • 2023-11-05
    中国香港
  • 本文字数:6098 字

    阅读完需:约 20 分钟

背景

大模型现在正处于高速发展时期,各厂商都推出了自己的大模型,各种开源模型也层出不穷。尽管各厂商都有应用接入 API,但在使用过程中还是存在一些问题:


  1. 数据安全:接入其他厂商的大模型,就需要将自己的数据交给对方处理,这些数据可能存在一些敏感信息,存在安全风险。

  2. 费用:大模型应用通常是按照 Token 数量收费的,对于普通开发者来说,长时间使用也是一个不小的开销。


既然开源大模型那么多,是否可以在本地搭建一个大模型的应用呢?目前开源的很多大模型,如 ChatGLM、Baichuan 等部署都需要 GPU 支持,这对个人开发者来说是一个小门槛,对于一个不玩游戏、不做图像处理开发的开发者来说,可能还真没有一块像样点的 GPU,但是可能有一颗强劲的 CPU,那么,是否可以在 CPU 上跑大模型呢?当然可以!今天就介绍一个开源项目,将大模型跑在 CPU 上。

ChatGLM.cpp 介绍

ChatGPM.cpp 是一个纯 C++实现的大模型运行时,可以将经过转换的开源大模型放在 CPU 上运行。这里是开源地址:https://github.com/li-plus/chatglm.cpp


ChatGLM.cpp 具有以下特点:


  • 基于 ggml,纯 C++实现

  • 具有 int4/int8 量化、优化 KV 缓存和并行计算的加速内存高效 CPU 推理

  • 具有打字机效果的流式生成

  • Python 绑定,Web 演示,API 服务器和更多的可能性

部署流程

部署流程基本上就是按照项目 readme 进行,但是其中有一些隐藏的坑需要注意,接下来就一步步进行,中间的注意点会着重描述。

纯源码物理机部署

纯源码物理机部署是指不使用 docker 虚拟化的情况下部署。

源码获取

从 github 下载源码:


git clone --recursive https://github.com/li-plus/chatglm.cpp.git && cd chatglm.cpp
复制代码


这里的--recursive参数是为了将子模块也拉取下来。


如果拉取的时候没有带此参数,也可以在拉取之后使用以下命令拉取子模块。


git submodule update --init --recursive
复制代码

依赖安装

ChatGLM.cpp 依赖 python 转换模型,因此需要安装 python。


此处有一个坑,对 python 版本是有要求的,因为转换过程中还需要用到 torch 包,而某些版本的 python 没有对应的 torch 包。


这里推荐使用 Anaconda 来安装环境。


Anaconda 就是可以便捷获取包且对包能够进行管理,同时对环境可以统一管理的发行版本。Anaconda 包含了 conda、Python 在内的超过 180 个科学包及其依赖项。


这里是官网:https://www.anaconda.com/


安装配置好 conda 之后,创建并切换到虚拟环境:


conda create -n chatglm-cppconda activate chatglm-cpp
复制代码


查找 pytorch 纯 cpu 版本支持的 python 版本:


conda search pytorch | grep cpu
复制代码


以下是输出:


pytorch                        1.2.0 cpu_py27h00be3c6_0  pkgs/mainpytorch                        1.2.0 cpu_py36h00be3c6_0  pkgs/mainpytorch                        1.2.0 cpu_py37h00be3c6_0  pkgs/mainpytorch                        1.3.1 cpu_py27h62f834f_0  pkgs/mainpytorch                        1.3.1 cpu_py36h62f834f_0  pkgs/mainpytorch                        1.3.1 cpu_py37h62f834f_0  pkgs/mainpytorch                        1.4.0 cpu_py36h7e40bad_0  pkgs/mainpytorch                        1.4.0 cpu_py37h7e40bad_0  pkgs/mainpytorch                        1.4.0 cpu_py38h7e40bad_0  pkgs/mainpytorch                        1.5.0 cpu_py37hd91cbb3_0  pkgs/mainpytorch                        1.7.1 cpu_py37h6a09485_0  pkgs/mainpytorch                        1.7.1 cpu_py38h6a09485_0  pkgs/mainpytorch                        1.7.1 cpu_py39h6a09485_0  pkgs/mainpytorch                        1.8.1 cpu_py37h60491be_0  pkgs/mainpytorch                        1.8.1 cpu_py38h60491be_0  pkgs/mainpytorch                        1.8.1 cpu_py39h60491be_0  pkgs/mainpytorch                       1.10.2 cpu_py310h6894f24_0  pkgs/mainpytorch                       1.10.2 cpu_py37hfa7516b_0  pkgs/mainpytorch                       1.10.2 cpu_py38hfa7516b_0  pkgs/mainpytorch                       1.10.2 cpu_py39hfa7516b_0  pkgs/mainpytorch                       1.12.1 cpu_py310h9dbd814_1  pkgs/mainpytorch                       1.12.1 cpu_py310hb1f1ab4_1  pkgs/mainpytorch                       1.12.1 cpu_py310he8d8e81_0  pkgs/mainpytorch                       1.12.1 cpu_py37h9dbd814_1  pkgs/mainpytorch                       1.12.1 cpu_py37hb1f1ab4_1  pkgs/mainpytorch                       1.12.1 cpu_py37he8d8e81_0  pkgs/mainpytorch                       1.12.1 cpu_py38h9dbd814_1  pkgs/mainpytorch                       1.12.1 cpu_py38hb1f1ab4_1  pkgs/mainpytorch                       1.12.1 cpu_py38he8d8e81_0  pkgs/mainpytorch                       1.12.1 cpu_py39h9dbd814_1  pkgs/mainpytorch                       1.12.1 cpu_py39hb1f1ab4_1  pkgs/mainpytorch                       1.12.1 cpu_py39he8d8e81_0  pkgs/mainpytorch                       1.13.1 cpu_py310h92724a6_0  pkgs/mainpytorch                       1.13.1 cpu_py310h9dc8d95_0  pkgs/mainpytorch                       1.13.1 cpu_py310ha02dd7b_1  pkgs/mainpytorch                       1.13.1 cpu_py311h92724a6_0  pkgs/mainpytorch                       1.13.1 cpu_py311h9dc8d95_0  pkgs/mainpytorch                       1.13.1 cpu_py311ha02dd7b_1  pkgs/mainpytorch                       1.13.1 cpu_py38h92724a6_0  pkgs/mainpytorch                       1.13.1 cpu_py38h9dc8d95_0  pkgs/mainpytorch                       1.13.1 cpu_py38ha02dd7b_1  pkgs/mainpytorch                       1.13.1 cpu_py39h92724a6_0  pkgs/mainpytorch                       1.13.1 cpu_py39h9dc8d95_0  pkgs/mainpytorch                       1.13.1 cpu_py39ha02dd7b_1  pkgs/mainpytorch                        2.0.1 cpu_py310hab5cca8_0  pkgs/mainpytorch                        2.0.1 cpu_py310hdc00b08_0  pkgs/mainpytorch                        2.0.1 cpu_py311h53e38e9_0  pkgs/mainpytorch                        2.0.1 cpu_py311h6d93b4c_0  pkgs/mainpytorch                        2.0.1 cpu_py38hab5cca8_0  pkgs/mainpytorch                        2.0.1 cpu_py38hdc00b08_0  pkgs/mainpytorch                        2.0.1 cpu_py39hab5cca8_0  pkgs/mainpytorch                        2.0.1 cpu_py39hdc00b08_0  pkgs/main
复制代码


可以看到最新支持到 python 3.11 了。


安装 python 3.11


conda install python==3.11
复制代码


安装依赖包:


pip install torch tabulate tqdm transformers==4.33.2 accelerate sentencepiece aiohttp
复制代码


这里需要注意的是,transformers 包的版本指定到 4.33.2,因为更高版本的 transformers 的 api 发生了变化,导致模型转换中出错。


另外增加了 aiohttp 包,因为 openai 包依赖这个包,但是没有被自动安装。


至此,转换模型的环境已经搭建好了。

模型转换

模型转换过程中需要和模型相当大小的内存(chatglm 模型需要 25G 内存),如果本机没有这么大的内存,可以使用以下方法解决:


  • 找一台大内存的机器

  • 使用在其他机器转换好的模型。我这里有两个转换后的模型:

  • 链接:https://pan.baidu.com/s/1nXcd6NMOtIvPGX_i_rIaAQ提取码:s7g9

  • 在一些免费的云服务器上转换,如:https://gitpod.io(gitpod 创建环境的时候选择大存储,有 50G 存储空间,否则默认只有 30G,可能不太够)

下载

接下来下载大模型。


当前支持的大模型如下:


  • ChatGLM-6B: THUDM/chatglm-6b, THUDM/chatglm-6b-int8, THUDM/chatglm-6b-int4

  • ChatGLM2-6B: THUDM/chatglm2-6b, THUDM/chatglm2-6b-int4

  • ChatGLM3-6B: THUDM/chatglm3-6b

  • CodeGeeX2: THUDM/codegeex2-6b, THUDM/codegeex2-6b-int4

  • Baichuan & Baichuan2: baichuan-inc/Baichuan-13B-Chat, baichuan-inc/Baichuan2-7B-Chat, baichuan-inc/Baichuan2-13B-Chat


可以使用 git 直接从 Hugging Face 直接下载模型,这里需要注意的是,git 需要支持 lfs,才能将大模型完整下载下来。各软件仓库应该都有 git-lfs 包,安装过程这里就省略了。


安装配置完 lfs 后,就可以下载大模型了,这里以 chatglm 模型举例:


git clone https://huggingface.co/THUDM/chatglm-6b
复制代码


其他模型类似。


注意一点是这个命令会卡住,实际上不是卡住了,是 lfs 正在拉取二进制的模型。可以另开一个终端使用du -h命令查看目录的大小变化。


chatglm-6b 模型大约 25G,因此这个下载时间取决于网速,git 不支持断点续传,所以一定不要断开网络。还有一些其他下载模型的方式,可以自行搜索。

转换

使用以下命令转换模型为 gglm 模型:


python3 chatglm_cpp/convert.py -i THUDM/chatglm-6b -t q4_0 -o chatglm-ggml.bin
复制代码


其中 THUDM/chatglm-6b 是模型路径(上一步模型 git 库的路径),chatglm-ggml.bin 是输出的 CPU 模型文件。


q4_0 为转换类型,解释如下:


  • q4_0: 使用 fp16 标度的 4 位整数量化。

  • q4_1: 具有 fp16 标度和最小值的 4 位整数量化。

  • q5_0: 基于 fp16 标度的 5 位整数量化。

  • q5_1: 具有 fp16 标度和最小值的 5 位整数量化。

  • q8_0:8 位整数量化与 fp16 尺度。

  • f16: 无量化的半精度浮点权重。

  • f32: 无量化的单精度浮点权重。


不同类型效果不同,消耗的资源也不同,可以多尝试几个。


这里选用了资源消耗最小的 q4_0 类型。


执行后生成 chatglm-ggml.bin 文件。

构建可执行文件

进入到 ChatGLM.cpp 的源码所在目录,执行:


python setup.py build_ext --inplace
复制代码


编译后生成 ./build/bin/main

命令行运行

使用命令行:


./build/bin/main -m chatglm-ggml.bin -p "你好,介绍一下你自己"
复制代码


chatglm-ggml.bin 就是前面转换出来的 gglm 模型。


我这边得到的输出如下:


你好,我是 ChatGLM-6B,是清华大学KEG实验室和智谱AI公司共同训练的语言模型。我的目标是通过回答用户提出的问题来帮助他们解决问题。由于我是一个计算机程序,所以我没有自我意识,也不能像人类一样感知世界。我只能通过分析我所学到的信息来回答问题。
复制代码

交互式运行

-p参数替换为-i就可以进入交互式运行:


./build/bin/main -m chatglm-ggml.bin -i
复制代码


    ________          __  ________    __  ___   / ____/ /_  ____ _/ /_/ ____/ /   /  |/  /_________  ____  / /   / __ \/ __ `/ __/ / __/ /   / /|_/ // ___/ __ \/ __ \ / /___/ / / / /_/ / /_/ /_/ / /___/ /  / // /__/ /_/ / /_/ / \____/_/ /_/\__,_/\__/\____/_____/_/  /_(_)___/ .___/ .___/                                              /_/   /_/
Welcome to ChatGLM.cpp! Ask whatever you want. Type 'clear' to clear context. Type 'stop' to exit.
Prompt > 你好ChatGLM > 你好👋!我是人工智能助手 ChatGLM-6B,很高兴见到你,欢迎问我任何问题。Prompt > 介绍一下你自己ChatGLM > 我是一个大型语言模型,被训练用来回答人类提出的问题。我使用了大规模数据和算法来生成回答,可以帮助人们解决各种问题。我的能力覆盖了许多主题,包括历史、科学、技术、文化、语言和娱乐等等。Prompt > GPT的原理是什么ChatGLM > GPT(Generative Pretrained Transformer)是一种基于Transformer架构的自然语言处理模型。它的原理是使用大量文本数据进行预训练,以便在后续任务中能够生成自然语言文本。在预训练期间,GPT学习到了大量的语言模式和规律,这些知识和模式可以用于生成自然语言文本。在后续任务中,GPT可以根据这些知识和模式生成文本,帮助人们完成各种任务,例如回答问题、撰写文章、翻译文本等等。GPT是由 OpenAI开发的,它被广泛应用于自然语言处理领域。Prompt >
复制代码

web 执行

前面介绍了在命令行运行大模型的步骤,如果想要在 web 中运行,需要安装一些额外的包。


安装 chatglm_cpp 包:


pip install .
复制代码


或者直接从仓库安装:


pip install -U chatglm-cpp
复制代码


安装 chatglm-cpp 包之后,就可以使用 python 直接调用 ChatGLM.cpp 了:


import chatglm_cpp
pipeline = chatglm_cpp.Pipeline("../chatglm-ggml.bin")pipeline.chat(["你好"])
# '你好👋!我是人工智能助手 ChatGLM-6B,很高兴见到你,欢迎问我任何问题。'
复制代码


作者提供了一些 demo,位于 examples 目录下,运行其中的 web demo:


pip install -U gradiopython3 examples/web_demo.py -m chatglm-ggml.bin
复制代码


打开浏览器,访问http://127.0.0.1:7860



开放 API

可以将聊天能力开放出来,供其他应用程序使用。


要想使用开放 API,需要安装 chatglm-app[api] 包:


pip install 'chatglm-cpp[api]'
复制代码

LangChain API

启动 API Server:


MODEL=./chatglm-ggml.bin uvicorn chatglm_cpp.langchain_api:app --host 127.0.0.1 --port 8000
复制代码


测试:


curl http://127.0.0.1:8000 -H 'Content-Type: application/json' -d '{"prompt": "你好"}'
复制代码

OpenAI API

启动 API Server:


MODEL=./chatglm-ggml.bin uvicorn chatglm_cpp.openai_api:app --host 127.0.0.1 --port 8000
复制代码


测试:


curl http://127.0.0.1:8000/v1/chat/completions -H 'Content-Type: application/json' \    -d '{"messages": [{"role": "user", "content": "你好"}]}'
复制代码

docker 部署

本地构建镜像

使用以下命令构建并运行本地镜像:


docker build . --network=host -t chatglm.cpp# cpp demodocker run -it --rm -v $PWD:/opt chatglm.cpp ./build/bin/main -m /opt/chatglm-ggml.bin -p "你好"# python demodocker run -it --rm -v $PWD:/opt chatglm.cpp python3 examples/cli_chat.py -m /opt/chatglm-ggml.bin -p "你好"# langchain api serverdocker run -it --rm -v $PWD:/opt -p 8000:8000 -e MODEL=/opt/chatglm-ggml.bin chatglm.cpp \    uvicorn chatglm_cpp.langchain_api:app --host 0.0.0.0 --port 8000# openai api serverdocker run -it --rm -v $PWD:/opt -p 8000:8000 -e MODEL=/opt/chatglm-ggml.bin chatglm.cpp \    uvicorn chatglm_cpp.openai_api:app --host 0.0.0.0 --port 8000
复制代码


启用 CUDA 支持:


docker build . --network=host -t chatglm.cpp-cuda \    --build-arg BASE_IMAGE=nvidia/cuda:12.2.0-devel-ubuntu20.04 \    --build-arg CMAKE_ARGS="-DGGML_CUBLAS=ON"docker run -it --rm --gpus all -v $PWD:/chatglm.cpp/models chatglm.cpp-cuda ./build/bin/main -m models/chatglm-ggml.bin -p "你好"
复制代码

使用预构建的镜像

使用以下命令使用预构建的镜像:


docker run -it --rm -v $PWD:/opt liplusx/chatglm.cpp:main \    ./build/bin/main -m /opt/chatglm-ggml.bin -p "你好"
复制代码


或者:


docker run -it --rm -v $PWD:/opt ghcr.io/li-plus/chatglm.cpp:main \    ./build/bin/main -m /opt/chatglm-ggml.bin -p "你好"
复制代码

总结

本教程基本是按照 Chat GLM.cpp 项目中的 README 编写的,但是中间有一些坑在 README 中没有提到,按照本教程可以有效避坑。

发布于: 刚刚阅读数: 7
用户头像

SkyFire

关注

这个cpper很懒,什么都没留下 2018-10-13 加入

会一点点cpp的苦逼码农

评论

发布
暂无评论
用纯CPU环境搭建大模型环境_大模型_SkyFire_InfoQ写作社区