返回

GPT4All提速指南:Python中加速文本处理

Ai

搞定 Python 里 GPT4All 跑得慢的问题

最近我琢磨着要用 GPT4All 来批量处理上千个文本文件, 提取些信息。我弄了个示例文本 [链接到:https://home.treasury.gov/system/files/261/FSOC_20240223_Minutes.pdf],然后写了点 Python 代码,结果发现,这速度,慢得让人抓狂!

就算我用了 GPU 加速,跑一个文件也要两三分钟, 而且输出的结果还不太行。我看别人在网上用 GPT4All,那速度飞快, 输出结果也好得很,真是纳闷了。我到底是哪儿搞错了?有什么办法能让它跑快点吗?

先看看我的代码:

llama_path = r"C:\Users\User\AppData\Local\nomic.ai\GPT4All\Meta-Llama-3.1-8B-Instruct-128k-Q4_0.gguf"
llama = GPT4All(llama_path, allow_download=False, n_ctx=16384, device='kompute:NVIDIA GeForce RTX 4070 Laptop GPU', ngl=200)

prompt = """

Can describe the role of each of the attendees? Give a dictionary with the job of each attendee in JSON format. 

"""

with open(file_path, 'r', encoding='utf-8') as file:
    content = file.read()

with llama.chat_session(system_prompt='You are a researcher analyzing board minutes. Your job is to provide scores in JSON format.<|eot_id|>'):
    output = llama.generate(prompt=f"{prompt} The text: {content}", max_tokens=1024, temp=0)

而且跑出来的结果是这样的:

To provide scores in JSON format, I'll need to analyze the text and identify key points related to each attendee's role.

Here is a dictionary with the job of each attendee:

```json
{
    "Janet L. Yellen": {
        "Role": "Secretary of the Treasury and Chairperson of the Financial Stability Oversight Council",
        "Responsibilities": [
            "Leading the Financial Stability Oversight Council"
        ]
    }, ...
}

Please let me know if you'd like me to add any other attendees or details!

我还想要把结果里开头和结尾的那些废话去掉,只留下 JSON。

一、 为什么 GPT4All 这么慢?

好,咱们来捋一捋,GPT4All 慢,可能的原因有这么几个:

  1. 模型大小和硬件: 你用的 Meta-Llama-3.1-8B-Instruct-128k-Q4_0.gguf 这个模型,块头不小。虽然你用了 RTX 4070 Laptop GPU,但笔记本的 GPU 性能还是比不上台式机的。而且,ngl=200可能有些激进,让所有层都在GPU运行或许让一些层在CPU反而效果更好。
  2. 上下文窗口(n_ctx): 你把 n_ctx 设成了 16384,这对于处理长文本可能是有必要的。但过大的上下文窗口会拖慢速度。
  3. 文件读取方式: 你直接用了 file.read(),把整个文件内容一次性读到内存里。要是文件特别大,这可能会导致内存不足,进而影响速度。
  4. Prompt 的设计: 你让模型生成 JSON 格式的输出,这对于有些模型来说,可能有点“费劲”。
  5. Python 解释器 : 巨蟒出击是很棒,但有时直接调用C/C++更快。

二、 提速大法,挨个试!

针对上面分析的原因,我们可以试试这些办法:

1. 调整硬件和模型加载

  • 试试小点的模型: 如果你觉得结果质量还行, 也许小一点的模型也能搞定。在 GPT4All 软件里下几个别的模型试试。

  • 优化 ngl 参数: ngl 参数控制有多少层在 GPU 上跑。你可以试试调小这个值,比如设成 35,看看速度有没有变化。或者设置为 -1 让gpt4all自己选择。不同的模型和硬件,最佳的 ngl 值可能不一样。

    llama = GPT4All(..., ngl=35, ...)
    

2. 调整上下文窗口 (n_ctx)

  • 别一口吃成胖子: n_ctx 不是越大越好。如果你的文本文件没有那么长,可以把 n_ctx 调小点,比如 2048 或 4096。

    llama = GPT4All(..., n_ctx=2048, ...)
    
  • 对内容切块, 然后将不同结果结合: 如果你的文本文件真的很长,超过了模型的最大上下文窗口长度,你可以考虑把文本切成几块,分别处理,最后再把结果拼起来。

3. 更聪明地读取文件

  • 逐行读取: 如果文件特别大,可以考虑逐行读取,处理完一行就扔掉,避免占用太多内存。

    with open(file_path, 'r', encoding='utf-8') as file:
        for line in file:
            # 处理每一行
            ...
    

    或者按需读取, 更灵活。

4. 改进 Prompt

  • 简单点,再简单点: 尽量让你的 prompt 更直接,更明确。避免使用复杂的措辞或要求模型做太多事情。

  • 示例的力量: 如果可能,给模型提供一个输出示例,让它知道你想要什么样的结果。这样模型更容易“照猫画虎”。
    例如:

prompt = """
Extract the attendees and their job titles from these board minutes.
Format the response in JSON.  Here's an example for a single person.  Only respond in JSON.

Example Input:
Mr. John Smith, Chief Financial Officer, introduced the topic.

Example output:
{"attendees":[{"name":"John Smith", "title": "Chief Financial Officer"}]}

Input:
"""

5. 处理输出结果,只要 JSON

要去掉开头和结尾的废话,只保留JSON,最简单的处理办法是:

import json, re

# 假设 output 是模型返回的字符串

# 用正则表达式提取 JSON 部分
match = re.search(r'\{.*\}', output, re.DOTALL)

if match:
    json_string = match.group(0)
    try:
        data = json.loads(json_string)
        # 成功解析成 JSON,现在 data 就是你想要的字典了
        print(data)
    except json.JSONDecodeError:
        print("解析 JSON 出错!")
else:
    print("没找到 JSON!")

这个代码使用一个正则表达式从文本中搜索看起来像JSON的文本 (开头 { , 结尾 }). 它接着调用 json.loads 来将其变为 Python 字典.

6. 进阶玩法:自己编译 GPT4All(适合高手)

如果以上方法都不能满足你的速度需求,而且你对技术有一定了解,可以考虑自己编译 GPT4All。

  • 针对硬件优化: 自己编译的时候,可以针对你的 CPU 和 GPU 进行优化,比如启用特定的指令集(AVX2、AVX512 等),充分发挥硬件性能。
  • 使用更快的后端: GPT4All 支持多个后端,比如 llama.cpp。你可以试试不同的后端,看看哪个速度最快。

7. 考虑 C++ 版本的 gpt4all-backend (对C++用户)

如果你的项目是基于 C++ 的,或者你能方便地调用 C++ 库,考虑一下直接使用 gpt4all-backend,能实现对python版本的极大加速.

额外的小贴士

  • 温度(Temperature):temp 设置为 0,可以让模型的输出更确定,减少随机性。
  • 批量处理: 如果你要处理很多文件,可以考虑一次性把多个文件的内容传给模型,减少模型加载的次数。
  • 注意:为了保持模型的良好表现,如果结果不佳,可以调高温度参数 temp

总之,解决 GPT4All 速度慢的问题,需要综合考虑多个方面,从硬件、模型、代码到 prompt,都需要进行调整和优化。要多尝试, 别放弃!