Hugging Face 05月14日 00:51
大模型评估排障指南 | 关于推理
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文针对大模型推理过程中常见的速度慢、内存占用大以及OOM等问题,提供了详细的排障和优化建议。主要包括调整batch size、采用数据并行、选择合适的推理库、调整计算精度等方法来提升推理速度;通过估算内存需求、量化模型、采用模型并行以及CPU卸载等技术来降低内存占用。此外,还针对模型装进GPU但仍报OOM错误的情况,提出了与上下文大小相关的解决方案。旨在帮助开发者更高效地进行大模型推理。

🚀 **推理加速技巧**:通过调整 batch size,增大 batch size 可以加快推理速度(硬件条件允许),选择合适的推理库,不同的推理库由于代码优化的差异,推理速度不尽相同。以及调整精度,降低精度为 blfoat16 或 float16 可以加速一倍。

💾 **内存优化方案**:针对模型内存占用过大的问题,文章给出了估算模型内存需求的公式,并提出了量化、模型并行(包括管线并行和张量并行)以及 CPU 卸载等多种解决方案,以降低内存占用。

🧩 **模型并行策略**:详细介绍了模型并行的两种方法:管线并行和张量并行。管线并行在 layer 级拆分模型,而张量并行在矩阵计算级拆分模型,并分析了各自的优缺点及适用场景。

⚠️ **OOM问题排查**:如果模型装进 GPU 后仍然报 OOM 错误,建议同时加载模型以及 dummy 数据测试 GPU 是否会内存溢出,并确保输入模型的样本的上下文大小是按从大到小的顺序排列。

原创 Hugging Face 2025-04-24 23:00 广东

宝子们如果在执行推理时遇到棘手的问题,来看看这里有没有妙招

这是 大模型评估排障指南 系列文章的第一篇,敬请关注系列文章:

    关于推理
    关于  公式解析
    关于可复现性

模型运行非常慢怎么办?

调整 batch size

如果你想要评估结果完全可复现 (在特定的输入 prompt 和硬件条件下),你可以把 batch size 可以设为 1。但如果增大 batch size (硬件条件允许的话) 将会加快推理速度。

数据并行

你可以将模型加载到多个 GPU 上,然后将数据集分为多个子集并分配给每个 GPU,最后汇总全部计算结果。 这意味着每个数据流是被并行同时处理的,从而将总执行时间缩短至 GPU 数分之一。尽量把 GPU 都放在一个节点上来避免跨节点传输瓶颈。

调整代码

不同的推理库由于代码优化的种种差异,推理速度不尽相同。你可能需要做一些对比试验来选出速度最快的库。如果模型层面你使用 pytorch 实现,建议可以参考这份推理优化清单https://pytorch.org/serve/performance_checklist.html

调整精度

你可以通过调整计算精度来减小模型大小,进而加快推理速度。虽然 float32 精度 (每个数字使用 32 位存储) 的模型计算非常精确,但其消耗的内存和计算资源却非常大。降低精度为 blfoat16 或 float16 (半精度) 可以加速一倍,而且不会影响计算结果。如果需要更进一步加速,可以尝试量化为更低精度,如 8 比特或 4 比特 (可以使用 gptq 或 bitsandbytes 库完成量化)。低位矩阵计算速度更快 (不过有些量化库反而有些慢,最好在你自己的模型上测试一下),模型占用内存也更少。

内存占用非常大怎么办?

估算内存需求

你可以用以下 公式 估算模型加载 (特定硬件) 所需的最小理论内存:

<内存 (GB)> = <参数量 (G)> * <精度因子>

模型所需总内存等于总参数量乘以一个参数所需的字节数。其中 1 个字节 (Byte) 是 8 比特 (bit),精度因子视情况取值 (float32 为 4、float16 或 bfoat16 为 2、8bit 为 1、4bit 为 0.5)。

这就是基本的估算方法。

实际使用时我建议这样计算: <内存 (GB)> = <参数量 (G)> * (<精度因子> * 110%)。因为推理阶段除了加载模型还需要加载数据,总内存需求会更多。

一个 GPU 都装不下怎么办?

量化

第一个明显的方法是降低 <精度因子>: 从 float32 降低到 4bit 可以降低 8 倍的内存占用! 不过精度太低也会导致结果变差。对于一些模型 (尤其是中等规模的模型) float16 或 8bit 就足够 (低精度对大型模型的影响较小,可能是因为信息冗余)。

模型并行

模型并行包含一系列技术:拆分大模型为多个小型子模型、分配子模型到不同的 GPU 上运行等。这种方法不会一次性地加载整个模型,因此减少了内存需求,但可能会更慢。

模型并行有两种方法:

    管线并行。即在 layer 级拆分模型,不同的 layer 被分配到不同的 GPU 上。由于推理时前向过程是线性的,例如 layer 1 的输出是 layer 2 的输入,因此 layer 2 分配的 GPU 需要等待 layer 1 的计算结束才能开始 (也叫 “冒泡 (bubble)”),同时数据和中间结果也需要 GPU 间传输,这也就导致执行速度较慢。不过可以通过将输入拆分为更小的批次来缓解冒泡,Pytorch 的原生库PiPPy就支持这一功能,也是 accelerate 库后台实现并行的方法。https://github.com/pytorch/PiPPy
    张量并行。即在矩阵计算级拆分模型,矩阵按行或者列被拆分且分配到不同的 GPU 上计算以及合并结果。如果多个 GPU 在同一个节点上 (避免跨节点传输瓶颈),这种并行方法会非常高效,但是代码实现有些困难。好在 vllm 库已经实现了,加速效果 非常明显

更多并行方法 (包括数据并行等) 可以参考这篇文档https://hf.co/docs/transformers/v4.15.0/en/parallelism

用 CPU 减负

CPU 卸载可以将部分模型和计算从 GPU 转移到 CPU 上,以减少 GPU 内存占用。不过相比于其他方法,CPU 卸载要 慢得多,主要原因是需要将数据在设备之间频繁移动。

例如,Deepspeed 的ZeRO-Offload可以将参数同时分配到 CPU 和 GPU (在 ZeRO-2 论文中有更详细的优化说明) 上。其中梯度、优化器状态、以及优化过程中的 fp32 模型参数在 CPU 上传递,而前向和反向过程中的 fp16 参数可以在 GPU 上传递,从而利用 CPU 内存优化并优化 GPU 计算,同时减少两者之间的通信。

ZeRO-Offloadhttps://arxiv.org/abs/2101.06840

模型装进 GPU 但还是报 OOMs 错误怎么办?

你可能遇到了上下文大小相关的问题。

我们建议:

    同时加载模型以及 dummy 数据,测试 GPU 是否会内存溢出,注意 dummy 数据的上下文长度应足够大 (能够代表你的任务)。
    降低 batch size,或者关闭自动搜索 batch size 功能 (如果启用,有时会导致 OOM 错误)。
    更一般地,确保输入模型的样本的上下文大小是按从大到小的顺序,这样如果上下文大小过大,模型就会直接报错,避免了模型一开始正常运行,直到某个时间才出问题。

英文原文:https://raw.githubusercontent.com/huggingface/evaluation-guidebook/refs/heads/main/translations/zh/contents/troubleshooting/troubleshooting-inference.md

原文作者: clefourrier

译者: SuSung-boy

审校: adeenayakup

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

大模型推理 模型优化 内存管理 OOM问题
相关文章