使用 llama.cpp 对大型语言模型(LLM)进行量化
2024/10/12 21:02:50
本文主要是介绍使用 llama.cpp 对大型语言模型(LLM)进行量化,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
虽然大模型(LLMs)非常强大,但由于其庞大的规模,这些模型消耗了大量的资源。这给在资源有限的设备上部署带来了挑战,并可能减慢推理的速度和降低效率。量化则提供了一种解决方案,通过降低模型参数的精度来保持性能的同时提高效率。
在这篇文章中,我们将探讨各种量化技术,包括简单的量化、k-means聚类量化,并简单介绍一种名为qLORA的方法。
比如,乡村里的每座房子代表你LLM中的一个参数。在一个密集的模型中,房子到处都是,就像一个繁忙的城市。量化将这个城市转变成一个更易于管理的乡下,通过只保留最重要的房子(参数)并用较小的房子(低精度表示)替换其他房子,或者通过移除一些“不重要”的房子并在其之间创造空地(零值)。这样模型就变得更加稀疏了。当模型变得稀疏,包含很多零值参数时,这使得模型在计算上更有效率,处理更快,因为零值可以被轻松跳过或压缩,无需昂贵的计算。保留参数间的空地(零值)减少了整体模型的大小和复杂性,进一步增强了效率。
可视化量化过程 | 图像由作者绘制
量化技术带来了几个好处:
- 减少内存占用:通过降低参数精度,量化显著减少了模型的内存需求,这对于内存受限设备上的部署至关重要。
- 提高速度:低精度计算执行得更快,从而加快了模型的推理速度,这对实时应用尤其有利。
- 保持性能:量化旨在精简模型的同时保持其性能,确保简化后的模型仍然具备所有必要的功能。
本文简要提到了其中的两种量化方法:
简单的量化:
朴素的量化均匀地减少所有参数的精度,类似于不分房屋位置就把乡下划分成等大的正方形区域。这可能导致一些地区房屋过多,而其他地区则空无一屋。
K-均值量化
K-means通过实际数据点(房子)的位置来创建聚类,从而实现更准确和高效的表示方式。它涉及选择代表点(即质心),并将每个数据点(房子)分配到最近的质心。
某些 k-means 量化的实现可能包括一个额外的 剪枝步骤,其中将低于某个阈值的参数值精确设置为零。这可以进一步提高模型的稀疏性。
粗略的可视化,Naïve 与 K-Means 聚类之间的差异如下所示 | 图片由作者制作
稀疏性指的是一个模型中只有少数参数(即“房子”)是重要的。其余的(空闲部分)可以忽略,不影响模型性能。通过量化降低分辨率时,参数重要性的不均匀性更加明显。
这可以通过一个叫稀疏度的度量来衡量。它指的是模型中参数为0的百分比。
稀疏程度:(零值参数数量) / (总参数数量)
(指房子间的空隙)稀疏度高意味着参数值为0的比例很高。
你也可以用模型的密度函数来表示模型。
参数密度 = (非零参数的数量) / (总参数的数量)
高密度性意味着房屋非零值参数的比例高
你知道吗?在量化模型里Q#_K_M代表什么?
在 llama.cpp 的上下文中,Q4_K_M
指的是一种特定的量化方法。命名规则如下:
Q
代表量化。4
表示量化所用的位数。K
指的是量化中使用的 k-均值聚类。M
表示量化后模型的大小。(S = 小, M = 中, L = 大)。
边缘计算是一种在数据生成附近处理数据的方式,而不是将数据发送到远处的服务器进行处理。这种处理方式不仅加快了处理速度,还保护了数据的私密性,并节省了带宽。
比如说,你正在用一个手机应用,该应用使用机器学习来识别照片中的物体。如果该应用使用传统的云计算的话,它将不得不把照片发送到服务器,等待服务器处理照片内容,然后再将结果发送回你的手机。使用边缘计算的话,处理就在手机上进行,因此更快、更私密,而且数据使用量更少。
尽管量化通常与边缘计算相关联,但它在其他上下文中也很有用。——例如,企业可以使用量化来减少其机器学习模型在企业数据中心中的计算和存储需求。这可以在硬件和电力使用方面带来显著的成本节省。
对于企业数据中心而言,一个小的量化模型的运行和维护成本可能比一个更大、更精确的模型更低。这是因为量化减少了运行模型所需的记忆和计算资源,从而可以降低硬件成本并减少能耗。此外,量化还可以帮助提高机器学习模型的可扩展性,这能让企业处理更大的数据量并更快地做出预测。
在任何需要特定要求或以客户为中心的调整的领域,微调一些参数以准确反映特定需求可能会很有用。使用 QLoRA(量化和低秩适应),您可以实现一个既量化又根据您的特定需求进行微调的模型。这种方法允许在不更新大量权重的情况下优化模型,使其成为适应大型语言模型到各种领域(如客户服务、医疗保健、教育)的低成本且高效的解决方案。此方法也适用于任何需要更个性化和精确模型的领域,以增强性能和用户体验。
更多相关信息,请查看详尽的文章。
好了,理论讲到这里吧 :D 现在让我们用 llama.cpp 来试试。
这一部分将介绍如何下载并编译llama.cpp。接着,我们将从HuggingFace下载一个模型,将其量化,并进行一些性能测试。
特别感谢,Peter分享的关于llama.cpp的有用指南(https://medium.com/@phs_37551/run-an-llm-on-apple-silicon-mac-using-llama-cpp-7fbbae2012f6)
第一步:开启 Git 的大文件下载功能
#允许git下载非常大的文件;lfs是用来克隆非常大的文件的,比如模型文件 brew install git-lfs git lfs install
第二步:克隆并下载llama.cpp项目并运行make
git clone https://github.com/ggerganov/llama.cpp ...这将克隆仓库到你的本地机器 cd llama.cpp ...这将进入克隆后的文件夹
做
步骤3:从HuggingFace下载模型,就这么简单。
我会从NousResearch获取一个。请注意,你可能需要一个好的网络连接,因为这些模型可能非常大(比如几十GB)!
#克隆模型从Hugging Face,并将其本地文件夹重命名为nous-hermes-2-mistral-7B-DPO,然后移动到本地的models文件夹 #模型通常可以从Hugging Face的此链接下载 https://huggingface.co/NousResearch git clone https://huggingface.co/NousResearch/Nous-Hermes-2-Mistral-7B-DPO nous-hermes-2-mistral-7B-DPO
现在,我们可以在终端中将其移动到模型文件夹。
mv nous-hermes-2-mistral-7B-DPO models/ # 将文件移动到models目录 (jiāng wénjiàn yíndòng dào models mùlù)
步骤4:将模型转换成通用格式(GGML FP16)。
当我提到“标准”时,我指的是GGML FP16格式。GGML是由Georgi Gerganov开发的张量库,用于在普通硬件上实现大型模型和高性能的机器学习。FP16被认为是“半精度”(FP32是全精度)。精度指的是模型权重中的浮点数值。如需更多解释,请参阅这篇文章,其中对AI模型量化格式进行了清晰的介绍。
# 把模型转成FP16, .gguf格式 python convert.py models/nous-hermes-2-mistral-7B-DPO / # 这个路径指向了模型所在的位置
运行 convert.py
后,你应该会在模型目录中看到名为 ggml-model-f16.gguf 的文件 | 图片来自作者
步骤5:将模型量化为n位精度
现在,我们可以从ggml-model-f16.gguf
文件开始进行进一步的量化。
zh:4位量化技术
# 将模型量化到4位精度(使用Q4_K_M方法) ./quantize ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-f16.gguf ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-Q4_K_M.gguf Q4_K_M.
创建一个名为 Q4_K_M.gguf 的文件 | 图片由作者生成
其他量化方式又怎么样呢?
我们可以进行多种量化。具体细节请查看截图。
运行./quantize --help
即可查看所有量化选项。
在终端里运行: ./quantize --help
3比特量化
# 将模型量化为3位精度(使用Q3_K_M这种方法) ./quantize ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-f16.gguf ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-Q3_K_M.gguf Q3_K_M
创建 Q3_K_M.gguf 文件 | 图片由作者制作
5位的量化
# 将模型量化为5位精度:(使用Q5_K_M方法) ./quantize ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-f16.gguf ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-Q5_K_M.gguf Q5_K_M
创建 Q5_K_M.gguf 文件 | 图片来源:作者
zh:量化过程
# 使用Q2_K方法量化模型到2位精度 ./quantize ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-f16.gguf ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-Q2_K.gguf Q2_K
创建 Q2_K.gguf | 图片由作者制作
在终端中输入 ./batched-bench -help
什么是批处理基准测试? 批处理基准测试 这个工具用来评估llama.cpp库的批处理解码效率。
运行命令: ./batched-bench --help
我们来试一下f16版本的批量基准测试。
./batched-bench ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-f16.gguf 2048 0 999 128,256,512 128,256 1,2,4,8,16,32
注:以上命令未作翻译,仅作参考用途。
批处理文件 ggml-model-f16.gguf
对于Q4_K_M量化的部分来说:
./batched-bench ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-Q4_K_M.gguf 2048 0 999 128,256,512 128,256 1,2,4,8,16,32
批处理模型: ggml-model-Q4_K_M.gguf
批处理基准测试
我们可以使用 T_PP
(首次生成令牌的时间),S_PP
(提示处理速度)和 S_TG
(文本生成速度)来进行评估。通过比较,我们可以看到(例如)与 f16 相比,Q4 的提示处理速度大约快 50 令牌每秒。
还有其他方法可以评估经过量化的模型。其中之一是计算困惑度。
困惑度是评估语言模型时常用的一个指标。它衡量模型预测数据样本的能力。困惑度得分越低表示语言模型预测下个词的能力越强,而得分越高则表示模型对下个词的预测越不确定或越“困惑”。
计算模型的困惑度(衡量模型准确性的指标):
这大概会花1小时,如果你决定做的话。
# 计算 ggml-model-Q2_K.gguf 文件的困惑度 ./perplexity -m ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-Q2_K.gguf -f /Users/ingrid/Downloads/test-00000-of-00001.parquet
运行量化后的模型
运行 gguf 模型 注释:./main -m ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-Q4_K_M.gguf -n 128
这里事情开始变得有点棘手且耗时较多。比如说,如果我们想做XXS量化:
# XXS 量化 (XXS量化) ./quantize ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-f16.gguf ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-IQ2_XXS.gguf IQ2_XXS
…然后我们就需要创建一个优先级矩阵(imatrix),如下面截图中所示。
查看IQ2_XXS | 图片来源:作者
重要性矩阵(imatrix
)为神经网络中的每个权重或激活分配了一个重要性分数。该重要性分数通常根据模型输出对特定权重或激活变化的敏感性进行计算。重要性矩阵允许进行有针对性的量化,其中最关键的部分以更高的精度保留,而不太重要的部分则被量化,以节省内存和计算资源。在进行非常低精度(如2位或更低)量化时,这种有针对性的方法尤其重要,这样可以确保模型仍然有用。
所以,我查看了README中的imatrix创建方法,并下载了维基原始数据集,尝试了以下bash命令来创建imatrix
(如果你有8小时或者比我的计算机更强大的设备,可以试一试):
# 文档参见: https://github.com/ggerganov/llama.cpp/blob/master/examples/imatrix/README.md ./imatrix -m <某些FP模型> -f <某些训练数据> # 这是我运行的代码以生成imatrix(耗时约8小时) ./imatrix -m ./models/nous-hermes-2-mistral-7B-DPO/ggml-model-f16.gguf -f /Users/ingrid/Downloads/test-00000-of-00001.parquet
在我的32GB M1 Mac上,这会花很长时间(它估计imatrix
要花大约8小时),所以我没做。
所需时间 [imatrix] | 图片来自作者
量化是一种强大的技术,用于减少大型语言模型(LLMs)的内存占用和计算需求,而不显著影响性能。本文深入探讨了量化技术的应用,包括朴素量化、K-均值量化以及用于微调量化模型的QLoRA(量化微调)等方法。
通过使用相关的类比和示例,我们展示了量化如何将大规模语言模型(LLMs)密集的参数空间转化为更易处理的形式,从而大幅提升效率和速度。我们还讨论了量化模型的实际应用,从边缘计算到企业场景。
这份实战指南介绍了如何使用llama.cpp来量化大语言模型(LLMs),从下载模型、转换、量化技术到评估指标(如困惑度)进行了详细的介绍。
随着大型语言模型(LLMs)不断突破界限,量化将在这些强大的模型的普及和部署中发挥关键作用。不论你是研究者、开发者还是自然语言处理(NLP)爱好者,掌握量化都是你探索大型语言模型旅程中不可或缺的一环。
羊驼在家里的图片 | 作者供图
这篇关于使用 llama.cpp 对大型语言模型(LLM)进行量化的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-20获取apk的md5值有哪些方法?-icode9专业技术文章分享
- 2024-11-20xml报文没有传 IdentCode ,为什么正常解析没报错呢?-icode9专业技术文章分享
- 2024-11-20如何知道代码有没有进行 Schema 验证?-icode9专业技术文章分享
- 2024-11-20Mycat教程:新手快速入门指南
- 2024-11-20WebSocket入门:轻松掌握WebSocket基础
- 2024-11-19WebSocket入门指南:轻松搭建实时通信应用
- 2024-11-19Nacos安装资料详解:新手入门教程
- 2024-11-19Nacos安装资料:新手入门教程
- 2024-11-19升级 Gerrit 时有哪些注意事项?-icode9专业技术文章分享
- 2024-11-19pnpm是什么?-icode9专业技术文章分享