Auto Byte

专注未来出行及智能汽车科技

微信扫一扫获取更多资讯

Science AI

关注人工智能与其他前沿技术、基础学科的交叉研究与融合发展

微信扫一扫获取更多资讯

研究完llama.cpp,我发现手机跑大模型竟这么简单

在一些大模型的推理任务上,瓶颈不是算力 FLOPS。

最近在开源社区,很多人都在探索大模型的优化方法。有一个叫 llama.cpp 的项目用原始 C++ 重写了 LLaMa 的推理代码,效果极好,获得了人们的广泛关注。

图片

通过一些优化和量化权重,它能让我们在各种以前无法想象的硬件上本地运行 LLaMa 模型。其中:

  • 在谷歌 Pixel5 手机上,它能以 1 token/s 的速度运行 7B 参数模型。

  • 在 M2 芯片的 Macbook Pro 上,使用 7B 参数模型的速度约为 16 token/s

  • 我们甚至于可以在 4GB RAM 的树莓派上运行 7B 模型,尽管速度只有 0.1  token/s

图片

GitHub 链接:https://github.com/ggerganov/llama.cpp

我们知道,除了通用化能力,大模型落地的关键在于推理性能的优化,然而如今这个优化程度超出了我们的预料。llama.cpp 至今在 GitHub 上已经收获了 3.8 万个 Star,几乎和 LLaMa 模型本身一样多。以至于到了 6 月份,llama.cpp 的作者 Georgi Gerganov 干脆开始创业,宣布创立一家新公司 ggml.ai,旨在用纯 C 语言框架降低大模型运行成本。

很多人看到这里都会发问:这怎么可能?大语言模型不是需要英伟达 H100 之类的 GPU 才能跑的吗?为了解决这个疑惑,最近有人深入研究了围绕大模型推理的数学,并试图进行解答。

让我们从「为什么 AI 训练都需要用 GPU?」开始,GPU 对深度学习有两个主要好处:

  • 它们具有很大的内存带宽(如 A100:1935 GB/s,RTX 4090:1008 GB/s)

  • 它们具有很大的算力(A100:FP16 有 312 TFLOPS,RTX 4090:FP16 有 82.6 TFLOPS)

内存带宽之所以重要,是因为它关系到数据从 HBM 内存(即 RAM)移动到片上内存需要花费的时间。在实际使用 GPU 进行数学计算时,我们需要将相关矩阵移至片上内存,该内存相当小(A100 上为 40MB,而 RAM 为 40-80GB)。内存带宽比计算性能小约 2 个数量级 —— 这稍后会很重要,因为内存带宽往往是推理的瓶颈。

从计算机体系结构的角度而言,我们需要把不同速度和容量的 memory 分出层级,以追求效率和成本之间的平衡。需要频繁访问的数据放在速度最快,但又容量最小的寄存器和 L1 cache 里,访问量最少的数据放在最慢最大的内存条里。

这在 LLaMa 推理任务上意味着什么?让我们从一些推理数学计算开始。我们可以使用 Kipply 的文章(https://kipp.ly/transformer-param-count/)对 LLM 的推理性能进行一些粗略的计算。

首先有关模型尺寸:

  • Q、K 和 V 权重矩阵的形状都是 [ d_model, d_head],每层有 n_heads;注意力输出矩阵具有相同的形状,总共 4 * [ d_model, n_heads * d_head]。按照惯例,GPT 风格的网络具有 d_head * n_heads = d_model。

  • MLP 有两个权重矩阵,形状为 [d_model, 4 * d_model] 和 [4 * d_model,d_model]

  • 嵌入矩阵的大小为 [d_vocab, d_model]。

这为我们提供了一个方便的类 GPT 模型参数数量方程:

图片

在这里,我们将重点讨论在本地运行类 ChatGPT 服务的情况,这就是 llama.cpp 所做的事情,让我们假设 batch size 为 1。为了高效推理,KV 缓存必须存储在内存中;KV 缓存需要存储每一层的 KV 值,这相当于存储:图片

这里使用 n_bytes 来表示每个参数的字节数;对于 float32 是 4,对于 float16 是 2,以此类推。中间的 2 是因为我们必须为 K 值存储一组权重,为 V 存储一组权重

给定一个 n 层模型,KV 缓存的总内存为:图片

除了将 KV 缓存存储在内存中之外,我们还需要将权重本身存储在内存中;这需要 n_bytes * P 字节。

图片

这是量化的主要优点之一。通过使用较低的精度,我们可以从根本上减少存储模型所需的内存量。请注意,在 int4 精度下,所有这些模型都适合英伟达的 A100(也是目前数据中心里常见的 GPU)上的内存,并且除了最大的模型之外,所有这些模型都适合高端消费级 GPU(如 RTX 3090/4090,具有 24GB RAM)。

现在,当谈到实际运行推理时,每个 token 大约需要 2P FLOPS,因为我们正在使用总共 P 个参数进行一系列矩阵乘法,与之相乘的矩阵尺寸是 (m, n) 向量 ( n,),成本为 200 mn。

完成所有数学计算后,让我们计算一下使用 LLaMa 运行推理的要求。sampling 的主要要求是:

  • 除了所有参数之外,还将 KV 缓存保留在内存中。

  • 将 HBM 中的所有权重读入片上存储。因为我们是自回归采样,所以我们必须对采样的每个 token 重复此操作。

  • 进行实际的矩阵乘法来计算我们网络的输出。

延迟是计算延迟或内存延迟的最大值,因为在所有现代张量编程库中将参数读取到片上内存中都是异步发生的。因此,我们写道:

图片

其中 B 是 batch size。由于内存带宽约为 1.935e12,需要的 FLOPS 量约为 3.12e14,所以只要 batch size 小于 161,模型就会受到内存限制。

当 batch size 为 1,即在计算机上仅生成单个预测流时,这是相同的等式,就像在大多数硬件(如英伟达的 GPU)上一样,当你降低精度时,会出现线性加速:使用 fp16 代替 fp32 时,FLOPS 会翻倍,转到 int 8,FLOPS 会再增加一倍,用 int4 时再次加倍。

由于 llama.cpp 使用目前深度学习推理中较为激进的 int4 格式,因此 KV 缓存的 RAM 需求减少到 1.33GB,模型参数的 VRAM 减少到 16.25GB。这看起来很不错

由于内存带宽几乎总是远小于 FLOPS 数,因此内存带宽是瓶颈所在。

请注意,FLOPS/token 的数量与所需的内存带宽相同,因为我们必须 1) 将所有参数加载到片上内存中,然后 2) 使用这些参数来计算结果。这些都是同时发生的,因为所有现代张量编程框架都能够异步处理「加载到内存」位,因此所需的总时间是 max(compute time, memory time)。

在英伟达 A100 上运行 LLaMa

图片

在 A100 (80GB PCIe) 上,内存带宽为 1935GB/s。int4 计算量为 1248 TOPS。因此,该模型较严重地受到内存的限制。我们预计 65B 模型的速度约为 30 token/s,7B 模型的速度约为 277 token/s。

在 MacBook 上运行 LLaMa

接下来是正片了,苹果 MacBook 上常见的 M1 芯片,其 GPU 的带宽为 68.25 GB/s,而 M1 GPU 可执行高达 5.5 TFLOPS 的 fp16 计算。因此,我们预计使用 int4 的 65B 模型采样的上限为大约 1 token/s,使用 7B 模型的采样上限为 10 token/s。

由于 M2 Pro 芯片具有 200 GB/s 的带宽,而 M2 Max 具有 400 GB/s 的带宽,因此我们应该期待它们在这里可以获得巨大的性能提升,使用 65B 版模型时 M2 Max 可以达到 6 token/s。这对于笔记本电脑来说已经很不错了。

在树莓派 4 上运行 LLaMa

Raspberry Pi 4 具有 13.5 GFLOPS 的计算能力和约 4GB/s 的内存带宽。鉴于此,如果 7B 模型受内存限制,我们预计会看到大约 2 token/s 的推理速度。然而我们目前看到的是约 0.1 token/s,有理由怀疑这实际上是因为算力受限导致的。这个尝试是在不知道硬件性能的条件下进行的 —— 我们无法找到有关 Raspberry Pi 低精度运算规格的足够信息来确定这一点。

总结

内存带宽几乎是与 transformer 采样相关的最大限制因素。任何降低这些模型内存需求的方法都会使它们更容易提供服务 —— 比如量化!这是蒸馏(或者只是长时间训练较小的模型)非常重要的另一个原因。

OpenAI 科学家 Andrej Karpathy 对于这个观察进行了进一步解释。

图片

他表示:除了并行推理和训练之外,提示编码即使在 batch_size = 1 时也是可并行的,因为提示标记可以由 LLM 并行编码,而不是一一串行解码。随着提示越来越长,MacBook 的推理性能就会越落后于 A100。

但另一方面,苹果的 M2 芯片看起来在大模型的推理任务上展示了强大的实力。「因此,M2 Ultra 是当今体量最小、最漂亮、开箱即用、最简单、最强大的个人 LLM 节点。」

陈天奇也对这种观点表示赞同。

图片

当然这一切并不是免费的午餐。从本质上讲,使用低精度会损失一些准确性,并且可能会出现一些奇怪的答案,让大模型的回应偏离轨道或产生幻觉。不过随着模型参数越多,质量损失就越低。因此,对于非常大的模型体量,差异或许可以忽略不计。此外,这只是推理成本。训练就完全是另一回事了。

通过对于各种性能参数的权衡,或许我们很快就会真正拥有更加「智能」的设备。

参考内容:

https://finbarrtimbers.substack.com/p/how-is-llamacpp-possible

https://news.ycombinator.com/item?id=37140013

https://twitter.com/karpathy/status/1691571869051445433

工程大模型
相关数据
陈天奇人物

陈天奇,华盛顿大学计算机系博士生,此前毕业于上海交通大学ACM班,研究方向为大规模机器学习。陈天奇曾获得KDD CUP 2012 Track 1第一名,并开发了SVDFeature,XGBoost,cxxnet等著名机器学习工具,是最大开源分布式机器学习项目DMLC的发起人之一。

深度学习技术

深度学习(deep learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。 深度学习是机器学习中一种基于对数据进行表征学习的算法,至今已有数种深度学习框架,如卷积神经网络和深度置信网络和递归神经网络等已被应用在计算机视觉、语音识别、自然语言处理、音频识别与生物信息学等领域并获取了极好的效果。

权重技术

线性模型中特征的系数,或深度网络中的边。训练线性模型的目标是确定每个特征的理想权重。如果权重为 0,则相应的特征对模型来说没有任何贡献。

参数技术

在数学和统计学裡,参数(英语:parameter)是使用通用变量来建立函数和变量之间关系(当这种关系很难用方程来阐述时)的一个数量。

张量技术

张量是一个可用来表示在一些矢量、标量和其他张量之间的线性关系的多线性函数,这些线性关系的基本例子有内积、外积、线性映射以及笛卡儿积。其坐标在 维空间内,有 个分量的一种量,其中每个分量都是坐标的函数,而在坐标变换时,这些分量也依照某些规则作线性变换。称为该张量的秩或阶(与矩阵的秩和阶均无关系)。 在数学里,张量是一种几何实体,或者说广义上的“数量”。张量概念包括标量、矢量和线性算子。张量可以用坐标系统来表达,记作标量的数组,但它是定义为“不依赖于参照系的选择的”。张量在物理和工程学中很重要。例如在扩散张量成像中,表达器官对于水的在各个方向的微分透性的张量可以用来产生大脑的扫描图。工程上最重要的例子可能就是应力张量和应变张量了,它们都是二阶张量,对于一般线性材料他们之间的关系由一个四阶弹性张量来决定。

参数模型技术

在统计学中,参数模型是可以使用有限数量的参数来描述的分布类型。 这些参数通常被收集在一起以形成单个k维参数矢量θ=(θ1,θ2,...,θk)。

5G技术

第五代移动通信系统(5th generation mobile networks),简称5G,是4G系统后的延伸。美国时间2018年6月13日,圣地牙哥3GPP会议订下第一个国际5G标准。由于物理波段的限制,5G 的网络也将会与其他通信技术并用,包含长距离的其他传统电信波段。

语言模型技术

统计式的语言模型是借由一个几率分布,而指派几率给字词所组成的字串。语言模型经常使用在许多自然语言处理方面的应用,如语音识别,机器翻译,词性标注,句法分析和资讯检索。

量化技术

深度学习中的量化是指,用低位宽数字的神经网络近似使用了浮点数的神经网络的过程。

推荐文章
暂无评论
暂无评论~