简介
最近,将LLM(Language Model)运行在计算机的CPU上引起了很大的关注,有许多工具试图使此过程更加简单和快速。本文重点介绍了Llama.cpp,展示了运行LLaMa 27b并超过我们所熟悉的深度学习模型的传统运行时基准的功能。Llama.cpp是各种LLM架构模型的推理实现,纯粹用C/C++编写,因此具有非常高的性能。
第一步:选择你的模型
Llama.cpp希望以“gguf”格式保存LLM模型。
有时候你可能需要将你的PyTorch模型权重转换为gguf格式。我们将逐步指导你完成这个过程!
安装
首先,让我们获取llama.cpp并进行设置:
git clone llama.cpp
cd llama.cpp
MAKE # If you got CPU
MAKE CUBLAS=1 # If you got GPU
接下来,我们应该从huggingface下载任何基于llama.cpp支持的模型架构之一的原始权重。
下载模型如下:
pip install transformers datasets sentencepiece
huggingface-cli download Universal-NER/UniNER-7B-type --local-dir models
检查模型文件夹以确保所有内容已下载。然后,运行llama.cpp转换脚本。
python convert.py ./modelspy ./models
脚本将原始的.pth文件转换成.gguf格式。你会看到一个名为ggml-model-f32.gguf的文件,其大小为27G。
gguf格式是最近才新出来的,于8月23日发布。它用于加载权重并运行cpp代码。
这是一个必要的步骤,以便能够后续将模型加载到llama.cpp中。
量化
深度神经网络的量化是将完整精度的权重(32位浮点数)转换为较小的近似表示,如4位/8位等等的过程。
为什么这很重要?
1. 小型模型使用的VRAM较少,对于你的GPU来说更容易。
2. 它们更轻巧。
3. 运行速度更快。
下面是使用llama.cpp缩小模型的不同方法的简要介绍:
选择较小的位点可以使模型运行更快,但可能会稍微牺牲一些准确性。我们将使用q4_1,它在速度和准确性之间取得了良好的平衡。
./quantize models/ggml-model-f32.gguf models/quantized_q4_1.gguf q4_1gguf models/quantized_q4_1.gguf q4_1
每个权重层应该减小约7倍,所以最终大小应该是原始大小的1/7!
让我们比较原始模型和量化模型的大小。
ls ./models
原始重量:26.9克|缩小后:4.2克
你的模型现在变得更小、更快了。
运行模型
你有两种主要的方式来运行你的cpp模型:
1. CLI推断:模型加载,运行提示,并一次性卸载。适用于单次运行。
2. 服务器推断:模型加载到内存中并启动服务器。只要服务器在运行,模型就会一直保持加载状态。
要运行服务器:
./server -m ./models/quantized_q4_1.gguf -c 1024
日志将告诉你服务器正在运行!
做出预测
通过API调用,我们获取预测信息。
url = f"http://localhost:8000/completion""http://localhost:8000/completion"
prompt = "<prompt_placeholder>"
req_json = {
"stream": False,
"n_predict": 400,
"temperature": 0,
"stop": [
"</s>",
],
"repeat_last_n": 256,
"repeat_penalty": 1,
"top_k": 20,
"top_p": 0.75,
"tfs_z": 1,
"typical_p": 1,
"presence_penalty": 0,
"frequency_penalty": 0,
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": "",
"n_probs": 0,
"prompt": prompt
}
res = requests.post(url, json=req_json)
result = res.json()["content"]
表现如何?
我们通过每秒能处理多少个令牌(文本片段)来衡量性能。每次运行都涉及以下内容:
1. 提示评估 - 处理提示令牌所需的时间。
2. 生成 - 生成新令牌所需的时间。
3. 采样 - 采样不同可能性所需的时间。
运行 q4_1 缩小模型给出的结果如下:
提示:"一个虚拟助手根据提供的文本回答用户的问题。用户:“除了儿童哮喘外,我没有值得一提的病史。”助手:我已阅读完这段文本。</s>用户:文本中描述了哪些医疗史?助手:"
输出:["儿童哮喘"]
结果
处理该请求所花费的总时间为804毫秒,少于1秒!
记住,在LLM的世界里,关键是能够每秒处理多少个标记,越高越好!