大型语言模型推理性能瓶颈排查

使用 lmstudio 来部署大模型,但是 gpu 使用率过低

First day

本地环境

8块 p40 GPUs

Ubuntu 22.04.1 LTS

deepseek-v2.5-1210-Q5_K_L

deepseek-v2.5-1210-Q4_0

开发日志:大型语言模型推理性能瓶颈排查

项目目标: 使用本地大型语言模型进行推理,并优化性能。

1. Ollama 初探

  • 下载 Ollama:

    • 开始尝试使用 Ollama 运行大型语言模型。

    • 具体下载方式和版本未知,但推测为官方网站下载。

  • 使用代理下载模型:

    • 由于网络限制,使用了代理来下载模型文件,通过下载 clash for linux 配置了一个代理

  • Ollama Cpp Merge:

    • 尝试使用 Ollama Cpp 的 merge 功能,将多个 guff 文件合并为一个文件。

    • 类似于 ollama cpp merge <guff_files> output.guff

  • 运行 Ollama 模型:

    • 尝试运行合并后的模型。

  • 报错 EOF:

    • 运行过程中遇到 EOF 错误,导致模型无法正常运行。

    • 具体错误信息未知。

2. 转向 LM Studio

  • 放弃 Ollama:

    • 由于 Ollama 遇到 EOF 错误,决定尝试使用 LM Studio。

  • LM Studio 下载和安装:

    • 下载并安装 LM Studio。

  • 加载模型:

    • 在 LM Studio 中加载之前使用的模型文件。

  • 初步测试:

    • 开始运行模型,发现 GPU 利用率极低 (10-30%)。

3. 性能瓶颈排查

  • GPU 利用率低:

    • 使用 nvtop 监控 GPU 利用率,发现始终维持在 10-30% 左右,即使调整 Batch Size 也无改善。

    • 显存占用率高 (80-90%),但 PCIe 带宽利用率低。

  • CPU 利用率:

    • 使用 htop 监控 CPU 利用率,发现 LM Studio 进程存在单线程瓶颈,导致一个 CPU 核心 100% 占用,其他核心空闲。

  • 尝试调整 Batch Size:

    • 尝试调整 LM Studio 的 Batch Size,但 GPU 利用率没有明显改善。

  • 尝试调整 CPU 线程池大小:

    • 尝试调整 LM Studio 的 CPU 线程池大小,包括设置为 1,但问题仍然存在。

  • 模型文件存储位置:

    • 最初模型文件存储在机械硬盘上,后将模型文件移至 SSD。

    • 测试了硬盘和内存读写速度,确认硬盘和内存性能正常。

  • 单线程瓶颈确认:

    • nvtophtop 显示,LM Studio 进程存在单线程瓶颈,导致一个 CPU 核心 100% 占用,其他核心空闲。

    • htop 中发现,lm-studio 进程的某个线程 CPU 占用率高达 101%。

  • top 命令分析:

    • 使用 top 命令查看进程 CPU 使用率,发现 lm-studio 进程的 CPU 使用率并没有达到理论上限 (5600%),印证了单线程瓶颈。

    • 使用 top 并按下 1 来查看每个 CPU 核心的利用率。

  • htop 命令分析:

    • 使用 htop 命令查看每个 CPU 核心的利用率,发现 CPU 核心 0 的利用率非常高,其他核心利用率低。

    • 使用 Shift + H 查看进程内部的线程,确认某个线程的 CPU 使用率特别高。

    • 使用 F6 键按 CPU 使用率排序进程。

    • 使用 F2 进入设置界面, 然后进入 Columns, 选择 PROCESS 分组下的 Command,并按下空格键启用,然后按 F10 保存退出,查看 lm-studio 进程的完整命令行参数。

  • LM Studio 配置调整:

    • 尝试将 CPU 线程池大小设置为 1,但问题仍然存在。

    • 确认 GPU 卸载 设置为 60/60,确保所有层加载到 GPU。

  • 问题总结:

    • 问题可能源于 LM Studio 本身、底层库、模型特性或硬件兼容性。

    • 单线程瓶颈是导致 GPU 利用率低下的主要原因。

    • 即使将 CPU 线程池大小设置为 1,问题仍然存在,表明问题并非简单的 CPU 线程数配置问题。

4. 寻求帮助

  • 建议:

    • 联系 LM Studio 开发者,寻求帮助。

    • 尝试其他模型,看看是否存在同样的问题。

    • 更新或降级 NVIDIA 驱动程序。

    • 在不同的硬件上测试 LM Studio。

5. 持续排查

  • 确认单线程瓶颈:

    • 使用 htop 进一步确认是否始终是同一个 CPU 核心占用 100%。

    • 尝试使用 top -H -p <PID> 查看该进程内部各个线程的 CPU 占用情况。

  • 进一步调整 LM Studio 配置:

    • 尝试调整 n_threads 参数 (如果有的话)。

    • 确认异步加载是否启用。

  • 尝试其他模型或框架:

    • 尝试加载其他模型,看看是否也存在同样的单线程瓶颈。

    • 考虑尝试其他的深度学习框架和推理引擎。

未解决的问题:

  • LM Studio 的性能瓶颈依然存在,GPU 利用率仍然很低。

  • 单线程瓶颈的根本原因尚未找到。

下一步计划:

  • 联系 LM Studio 开发者,提供详细的日志和截图。

  • 继续尝试其他模型和配置。

  • 尝试更新或降级驱动程序。

  • 考虑在其他硬件上进行测试。

  • 考虑别的框架

第二天

这一次我使用 ollama 再次运行,q4 版本的 deepseek,成功的运行了,但是问题依然是 gpu 使用率过低

这里我们记录一下网上寻找的一些方案:https://github.com/ollama/ollama/issues/7648#issuecomment-2473561990

根据里面的回答,得出一些结论:

  1. LLM 推理的串行性质:

    • 大型语言模型的推理过程是串行的,每一层计算的输出必须作为下一层的输入。

    • 这意味着,对于单个推理请求,GPU 之间需要频繁地传递中间结果,而 CPU/PCIe 接口成为了瓶颈。

  2. 多 GPU 的负面影响:

    • 在单个推理请求中,增加 GPU 数量会导致 token 生成速度下降,因为数据需要在 GPU 之间传输,引入了额外的开销。

    • Issue 中提供的 llama3.1:70b 模型在不同 GPU 数量下的 token 生成速度数据证实了这一点:

      • 1 个 GPU: 24.21 tokens/s

      • 2 个 GPU: 22.66 tokens/s

      • 3 个 GPU: 20.21 tokens/s

      • 4 个 GPU: 20.14 tokens/s

  3. 多 GPU 的适用场景:

    • 多 GPU 适用于处理多个并发请求(OLLAMA_NUM_PARALLEL)。

    • 在这种情况下,不同的 GPU 可以并行处理不同的请求,从而提高整体吞吐量。

    • 然而,Ollama 的调度机制可能无法完美地将请求均匀分配到各个 GPU 上。

  4. 单 GPU 的优化:

    • 对于单个推理请求,优化重点应放在模型选择、管理上下文长度、使用 OLLAMA_FLASH_ATTENTION 等选项上。

    • Ollama 本身在推理性能方面的可调整参数较少。

  5. 其他推理引擎的性能:

    • Issue 中提到,像 vLLM 这样的其他推理引擎可能在单次推理速度上优于 Ollama,特别是结合 AWQ 量化技术时。

    • vLLM 可以实现更高的 GPU 利用率,从而加快推理速度。

but unfortunately vLLM only supports Volta or later GPUs. P40 is not officially supported.

Last updated