今年的话,AI这个概念可谓非常火,大家都在谈论AI可能带来的变化,很多公司的产品也都希望狠狠的增一波热度。除了现在市面上有的很多提供接口的大型语言模型外,还有很多在huggingface提供模型文件的,可以离线部署的大型语言模型可供选择。

SakuraLLM则是一个目前正在活跃的,专注于ACGN方面日语翻译中文的基于百川(V0.8版本)大模型进行微调和与训练的大模型。目前最新的版本是0.8,当然未来将会有更多语料训练的版本发布。

了解SakuraLLM的最新消息,可以参考官方Github库或是Huggingface

https://github.com/SakuraLLM/Sakura-13B-Galgame
https://huggingface.co/sakuraumi/Sakura-13B-Galgame

对于个人开发者或者爱好者,想要训练大型语言模型是非常困难的,动辄20G往上的显存需求让很多游戏卡望而却步。很多常见的游戏卡,甚至连执行推理所需要的显存都无法达到。于是使用llama.cpp加速CPU推理就非常有意义了。

同时llama.cpp也支持多种方式的加速,以及CUDA支持,可以说是非常全面了。同时,llama.cpp社区目前非常活跃,相信今后支持的模型和功能将会更多。

考虑到需要加载huggingface上动辄30G往上的模型,以及加载模型的大量的内存需求,我考虑不在我本机上运行推理,而是选择Intel提供的DevCloud平台,该平台向AI开发者提供Intel的硬件进行开发测试,要注意的是免费用户仅可以选择英特尔的CPU和核心显卡进行训练或推理。

为何选择Intel Devcloud

Intel DevCloud 目前有两种免费资源提供,一种是Developer Cloud For the Edge,该资源提供JupyterLab环境,提供一些轻量级的CPU资源,可以运行一些小型的任务,最大执行时间为8小时。另一种是DevCloud for oneAPI,该资源提供shell访问,提供一些高性能的CPU资源,包括Core i9以及较新的至强CPU,最大执行时间24小时。

具体信息可以参考intel官网,注册和登录系统在这里不做赘述。以下所有操作都是在OneAPI的shell中进行的。

使用DevCluod运行大型语言模型推理

登录后的shell是用于提交任务的,这个环境有限制,不允许运行长时间的负载操作,经过测试,甚至拉取git repo都会超时被杀死,所以所有的高负载或长时间运行的任务应该提交到计算节点。首先可以使用如下命令查看所有的计算节点详情:

pbsnodes

实际上没有必要看那么详细,我们一般使用命令筛选一下属性详情即可,至于节点是否有工作,是否在线不是咱们需要关注的内容,通常来说会有多个节点在线,但是有些时候会存在全部节点都在工作的情况,这时候就需要排队。

pbsnodes | sort | grep properties

通过上面的命令,我们得到了一大串属性列表,我们只需要找一下我们需要的计算节点配置即可,比方说,我想要酷睿I9的计算节点,那么找开头是Core的即可,如果要找至强的,则需要看一下第三列的CPU型号,通常来讲,运行大型语言模型推理,需要较高的内存,同时为了更快速的运行推理,CPU的性能也十分重要,我推荐使用志强的CPU作为运行的计算节点

在Intel DevCloud上的所有任务需要使用qsub提交到计算节点,如果大学有超算资源或者用过计算集群的可能会用过这个工具。我们要进入计算节点来拉取模型文件,当然,我推荐是你把这个拉取文件操作写到shell脚本中,通过qsub提交到后台去运行,拉去时间非常长,你不会希望由于网络原因导致shell中断最终拉取失败的。

我这里就不展现我拙略的shell语言技巧了,有问题的可以让gpt帮你写,这点小事,他还是能搞定的。由于huggingface使用git lfs管理模型文件,所以需要给git安装lfs插件。实际上,git lfs是一个可执行文件,你只需要吧这个文件下载并放到bin目录里就行,devcloud的所有计算节点的path环境变量中都有用户目录下的bin目录,也就是说,你在用户主目录下新建一个bin目录放进去就可以直接执行了。

接下来执行如下命令设置 git lfs模块

git lfs install

然后就可以拉取你需要的模型了,huggingface上的部门模型文件需要权限,比方说llama2,你需要先去申请,并且拉取的时候需要登陆,其他不需要权限的则可以直接拉取。

qsub -l nodes=1:net1gbe:ppn=2,walltime=24:00:00 -d . <拉取脚本名>
#提交任务,需求1个net1gbe的节点,最大执行时间为24小时,执行目录为当前目录,任务脚本是<拉取脚本名>

获取到huggingface上的模型后,如果希望使用llama.cpp进行CPU加速推理的话,还需要将模型文件量化和转换为gguf格式。

配置环境并转换模型

那么首先我们需要激活一个Python的虚拟环境,Intel Devcloud的计算节点为我们准备了conda对python环境进行管理,我们可以利用conda进行环境管理。

首先进入一个计算节点,由于我们将在计算节点进行网络操作,那么我们选择一个1G宽带的节点,由于需要进行命令行操作,我们使用I参数进行终端操作。

qsub -I -l nodes=1:gold6128:ppn=2 -d .
#提交任务,进入终端,需求一个gold6128的节点(gold6128CPU的节点内存为192G,足够我们转换),执行目录为当前目录

进入计算节点后,你会看到节点的主机名变成s**-n**这是计算节点的主机名。接下来在计算节点上运行以下命令:

conda create --name SakuraLLM python=3.10
#创建Conda虚拟环境,名称为SakuraLLM,使用python3.10,创建环境期间会有确认,按Y键确认
conda activate SakuraLLM
#激活环境
conda install pytorch torchvision torchaudio cpuonly -c pytorch
#使用conda按照pytroch组件,由于计算节点多没有GPU,这里安装CPU版本的pytorch。安装组件期间会有确认,按Y键确认
pip install gguf
#使用pip安装gguf组件,用于转换和使用gguf模型
wget https://raw.githubusercontent.com/ggerganov/llama.cpp/master/convert-hf-to-gguf.py
#下载转换模型的代码,这个是llama.cpp官方提供的,官方仓库中还有其他模型和通用模型的转换代码,你可以到https://github.com/ggerganov/llama.cpp确认
python convert-hf-to-gguf.py <HF/模型路径> --outfile <输出文件路径+名称>
#转换需要一段时间,请耐心等候,也可以写成bash脚本提交计算节点后台执行

转换结束后,我们已经拥有了适用于llama.cpp使用的模型文件了,接下来根据实际情况,我们可以量化这个模型。量化模型会牺牲精度但会换来更小的内存占用和更快的推理速度,我推荐量化模型至少量化的q8_0,必要时也可以量化到q4_0,具体模型量化后的显存(内存)占用,可以查看项目主页。

量化模型需要编译llama.cpp,由于我们演示的SakuraLLM提供了基于llama-cpp-python的翻译代码和服务器代码,所以我们本身不需要在编译一份llama.cpp(llama-cpp-python安装时会编译一份),但是量化模型需要quantize程序,所以我也写一下如何编译llama.cpp

以下操作依然需要进入计算节点进行

git clone https://github.com/ggerganov/llama.cpp.git
#克隆llama.cpp项目源码
cd llama.cpp
#进入代码目录
mkdir build
cd build
#创建并进入编译目录
cmake .. -DLLAMA_BLAS=ON -DLLAMA_BLAS_VENDOR=Intel -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx
#启用Intel MKL加速,这个Intel devcloud的计算节点应该都支持
cmake --build . --config Release
#编译llama.cpp

接下来在llama.cpp根目录已经生成了必要的可执行文件,我们执行quantize程序进行量化

./quantize <gguf模型> <量化后的模型存放路径> <量化版本>
#具体支持的版本请参考quantize的帮助输出

运行Sakura大模型

我们现在已经转换好SakuraLLM的模型文件了,接下来就是执行Sakura大模型的推理,SakuraLLM提供的用于翻译纯文本和epub小说的脚本,已经可以通过接口请求的简易API,我们可以分别测试一下。由于两个脚本的依赖不同,这里分开来写,首先是翻译文本文件使用的脚本。

如果你已经退出计算节点,记得重新进入计算节点,如果还在计算节点,记得激活conda虚拟环境

https://github.com/SakuraLLM/Sakura-13B-Galgame.git
#拉取翻译脚本文件
conda activate SakuraLLM
#激活环境
conda install -c huggingface transformers=4.33.2
conda install sentencepiece
pip install bitsandbytes
#安装依赖
CMAKE_ARGS="-DLLAMA_BLAS=ON -DLLAMA_BLAS_VENDOR=Generic -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx" pip install llama-cpp-python
#安装llama-cpp-python(llama.cpp正处在积极更新状态,在使用时推荐定期更新依赖)
cd Sakura-13B-Galgame
#进入翻译脚本目录
python translate_novel.py --model_name_or_path <gguf模型路径> --model_version 0.8 --data_path <输入的日文文本.txt> --output_path <输出的中文文本.txt> --llama_cpp --trust_remote_code
# 参数说明:
# --model_name_or_path:GGUF格式模型本地路径。
# --model_version:模型版本,本仓库README表格中即可查看。可选范围:['0.1', '0.4', '0.5', '0.7', '0.8']
# --text_length:文本分块的最大单块文字数量。
# --compare_text:是否需要输出中日对照文本,如需要,则需加此项;如不需要则不要添加。
# --data_path:日文原文文件路径
# --output_path:翻译(或对照)文本输出文件路径
# --trust_remote_code:是否允许执行外部命令(对于0.5,0.7,0.8版本模型需要加上这个参数,否则报错)
# --llama_cpp:使用llama.cpp载入模型
# --use_gpu:使用GPU载入llama.cpp支持的模型
# --n_gpu_layers:设置载入GPU的模型层数。如果指定了use_gpu同时此处设置为0(或者不设置),则会将模型所有层都放入GPU中。如果没有指定use_gpu同时此处设置为0(或者不设置),则会进入纯CPU推理模式。

执行翻译脚本后便开始进行翻译,由于这个脚本是在所有内容翻译完成后才写入输出文件,所以推荐提交给计算节点后台执行,因为一直连接SSH可能出现中断,一旦SSH断开,计算节点即视为任务完成。

运行API服务器需要稳定的网络,因为需要计算节点在前端执行,计算节点的端口需要通过SSH转发到本地。

https://github.com/SakuraLLM/Sakura-13B-Galgame.git -b dev_server
#克隆带有API Server的仓库
conda activate SakuraLLM
#激活环境
conda install -c huggingface transformers=4.33.2
conda install sentencepiece
pip install bitsandbytes
#假如装过,可以不用再安装
pip install coloredlogs 
pip install dacite
pip install hypercorn
pip install fastapi
#安装API服务器依赖
python server.py --listen 0.0.0.0:5000 --llama_cpp --trust_remote_code --model_name_or_path <模型位置> --model_version 0.8 --no-auth --log info
#运行API服务器

运行上面的代码后,API服务器监听在5000端口,由于计算节点有防火墙,我们需要使用SSH将计算节点的端口转发到本地

ssh -L 5000:<计算节点主机名>:5000 devcloud

我们可以使用127.0.0.1:5000访问到在计算节点上的API服务器。API接口文档在127.0.0.1:5000/docs下,目前Lunatranslator已经支持调用SakuraLLM大模型。

使用llama.cpp内置服务器接口

llama.cpp也提供了一个简易的API服务器,可以直接提供API服务而不需要依赖其他的开发语言。

./server -m <gguf模型位置> -t <线程数> -c <上下文大小> --host 0.0.0.0 --port 5000 --numa <如果指定该选项可能会在部分Xeon内核下提高效率> 

llama.cpp后端启动后,也需要进行端口转发才能在本地访问接口,请参考上面的转发方法。直接访问5000端口,llama.cpp也提供了建议的WebUI界面,具体的请求参数请参考官方文档。

https://github.com/ggerganov/llama.cpp/tree/master/examples/server

GPU加速推理(以Q4_0模型在WSL执行)

llama.cpp支持使用cuBLAS通过CUDA核心加速推理,由于我的PC是Windows系统,所以我们已WSL进行演示。Ubuntu系统的WSL是支持CUDA的,具体如何安装英伟达驱动程序请参考官方文档

https://docs.nvidia.com/cuda/wsl-user-guide/index.html#getting-started-with-cuda-on-wsl-2

由于我的PC内存不够,所以只能运行量化模型,同时我的显卡显存也不够,所以只能吧部分模型放到显卡来加速推理。如果显存足够,也可以吧整个模型放到显卡加速。当然如果显存足够的话,直接运行大模型不使用llama.cpp也是可以的。

<内容施工中…>