告别云端依赖!手把手教你用GGUF模型实现大模型本地化推理

博文小编

2025-06-23


随着人工智能技术的不断进步,大语言模型已成为多个行业和领域的核心驱动 力。当前,大多数大语言模型的应用都是基于云端运行的,这意味着在进行相关任务 时需要持续的网络连接,以获得实时的响应和计算结果。然而,依赖网络的模型应用 在某些场景下并不是最优的选择。例如,对于某些需要高安全性的领域,如医疗、军 事和金融等,数据可能包含敏感信息,这就需要确保数据不离开本地环境。在这种背 景下,大语言模型的本地化开发与应用逐渐受到重视,也逐渐成了研究和应用的热点。 本地化开发意味着模型不依赖外部服务器或云服务进行运算,而是直接在用户的设备 或专用服务器上进行推断和运算。这种方式既保证了数据的隐私性,又满足了离线使 用的需求。接下来,本文将以 LangChain 和 privateGPT 工具为例,详细探讨实现大 语言模型的本地化开发与应用的具体方法。

LangChain

LangChain 是一个用于开发由大语言模型驱动的应用程序的框架,旨在帮助开发 人员使用大语言模型构建端到端的应用程序。借助LangChain 提供的组件和接口,开 发人员可以方便地设计与搭建诸如问答、摘要、聊天机器人、代码生成和信息提取等 多种基于大语言模型能力的应用程序。LangChain 不仅能够调用大语言模型,还具有 数据感知的特性,能够将大语言模型连接到其他数据源;同时,它具有代理性,即允 许大语言模型与环境进行交互。
LangChain 主要包含两种应用方式——组件与链。LangChain 提供了可以与大语 言模型协同工作的抽象化组件,并且提供了这些组件的一系列实现方法。这些组件旨 在易于使用,独立于 LangChain 框架的其他部分。链是为了完成某项特定任务所需 要的一系列组件,为用户上手解决某些特定任务提供了一种更高级的接口,也能让用 户更轻松地实现定制化。
接下来,本节将以 Chinese-Alpaca-2 模型为例介绍利用 LangChain 完成生成式 摘要任务的流程。

01

工具安装

运行以下命令安装 LangChain。
pip install langchain
需要注意的是,由于 LangChain 通常需要与不同种类的大语言模型联合完成相 关任务,以上安装方式并不包含对特定大语言模型的依赖支持。本例使用的 ChineseAlpaca-2 大语言模型依赖 transformers、accelerate、sentencepiece,因此还应安装相关依赖。
$ pip install transformers sentencepiece

02

创建 LangChain 任务链

首先,加载必要的 Python 依赖,指定输入文件和模型文件的路径
import torchfrom langchain import HuggingFacePipelinefrom langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain.prompts import PromptTemplatefrom langchain.chains.summarize import load_summarize_chainfile_path = ‘text_file.txt’model_path = ‘chinese-alpaca-2-7b-hf’
定义 RecursiveCharacterTextSplitter,将输入文本切分成若干文本块。此处可以定义每个文本块的大小及文本块之间的重叠大小等。
text_splitter = RecursiveCharacterTextSplitter( chunk_size = 600, chunk_overlap = 10, length_function = len,)with open(file_path) as f: text = f.read()docs = text_splitter.create_documents([text])
通过 HuggingFacePipeline 加载大语言模型并指定推理相关的超参数。
model = HuggingFacePipeline.from_model_id( model_id=model_path, task=”text-generation”, device=0, pipeline_kwargs={ “max_new_tokens”: 400, “do_sample”: True, “temperature”: 0.2, “top_k”: 40, “top_p”: 0.9, “repetition_penalty”: 1.1}, model_kwargs={ “torch_dtype”: torch.float16, “low_cpu_mem_usage”: True})
接下来,定义 Chinese-Alpaca-2 的指令模板,并使用 PromptTemplate 加载模板。
prompt_template = ( “[INST] <>\n” “You are a helpful assistant. 你是一个乐于助人的助手。\n” “<>\n\n” “请为以下文字写一段摘要:\n{text} [/INST]”)PROMPT = PromptTemplate(template=prompt_template, input_variables=[“text”])
最后,通过调用 LangChain 预定义的文本摘要任务的链 load_summarize_chain 生成输入文本的摘要。
chain = load_summarize_chain(model, chain_type=”stuff”, prompt=PROMPT)print(chain.run(docs))

03

优化 LangChain 策略

通过上述步骤可以完成一个 LangChain 处理任务的基本流程,其中使用的策略 类型是 stuff。stuff 是最简单的策略,它会将所有的相关文本与指令模板进行拼接 并送入大语言模型,因此只需调用 1 次大语言模型即可给出任务输出。然而,多数大 语言模型都有一个上下文长度限制,例如 Llama 的最大上下文长度为 2048,Llama 2 则为 4096。当输入指令超过这个限制时,大语言模型通常无法给出合理的回复。
因此,为了处理更长的输入指令,可以将上述的 stuff 策略更改为 refine 策 略。该策略首先将第一个文本块与指令送入大语言模型,获得初始的回复。然后,将 第二个文本块和初始回复再次送入大语言模型,以期得到优化后的输出。最后,按照 以上步骤进行迭代,在送入最后一个文本块和上一轮回复之后,即得到最终的模型 输出。
实现 refine 策略也非常简单,只需定义优化指令模板并显式地调用 refine 策 略即可。首先定义优化指令模板。
refine_template = ( “[INST] <>\n” “You are a helpful assistant. 你是一个乐于助人的助手。\n” “<>\n\n” “已有一段摘要:{existing_answer}\n” “现在还有一些文字,(如果有需要)你可以根据它们完善现有的摘要。” “\n” “{text}\n” “\n” “如果这段文字没有用,返回原来的摘要即可。请你生成一个最终的摘要。” “ [/INST]”)REFINE_PROMPT = PromptTemplate(template=refine_template, input_variables=[“existing_answer”, “text”])
然后替换 load_summarize_chain 的定义。
chain = load_summarize_chain(model, chain_type=”refine”, question_prompt=PROMPT, refine_prompt=REFINE_PROMPT)print(chain.run(docs))
以下是 stuff 策略和 refine 策略的输出对比。
stuff策略:
总结起来,李白是一位杰出的浪漫主义诗人。他创作的诗歌内容广阔,形式多样,语言富有想象力和夸张的描绘能力。同时,他经常使用比喻和象征来表达自己的情感体验。李白被尊称为”诗仙””诗侠””酒仙””谪仙人”等各种美誉,他的诗歌影响了整个唐宋八大家及后代诗人,成了中国文学史上的重要人物之一。

refine策略:
李白是中国唐代一位著名的诗人,被认为是中国诗歌史上的重要人物之一。他曾经担任过多次官职,但由于桀骜不驯的性格,很快就离开了政府工作岗位。他游历了中国的很多地方并写下了很多诗篇。他的诗歌充满了想象力并且经常使用生动形象的比喻来传达情感。尽管有许多文学作品和典故与他的经历有关,但他本人的具体死亡原因一直是一个谜题。然而,他的才华和诗歌影响了许多之后的诗人和文学家。
当然,上述 refine 策略的劣势也比较明显,即需要对大语言模型进行多次的访 问,以逐步对模型输出进行优化。读者可以根据实际应用场景选择合适的策略。
由于 LangChain 是一个功能丰富的开发框架,受篇幅限制,本节仅对其最基本 的用法进行了介绍。更多功能和开发指南可以参考 LangChain 的官方文档。下一节 将介绍基于 LangChain 进行二次开发的代表性工作 privateGPT。

privateGPT

privateGPT 是基于 llama-cpp-python 和LangChain 等开发的一个开源项目, 旨在提供本地化文档分析,并利用大语言模型来实现交互问答。用户可以利用 privateGPT 对本地文档进行分析,并且利用与 GPT4All 或 llama.cpp 兼容的大语言模 型文件对文档内容进行提问和回答,确保了数据本地化和私有化。本文以 llama.cpp 中的 GGUF 格式模型为例介绍 privateGPT 的使用方法。

01

工具安装

由于 privateGPT 使用了 llama.cpp 的 GGUF 模型,因此需要提前安装 llamacpp-python 扩展。与 llama.cpp 类似,建议使用 Python 3.10 以上版本。
pip install llama-cpp-python
需要注意的是,上述安装方式未启动任何加速库。与 llama.cpp 类似,如需使 用 OpenBLAS、cuBLAS、Metal适配的版本,需要按照特定方式安装,具体请参考 llama-cpp-python 官方文档。
对于在 macOS 系统中使用 Apple 芯片(M 系列)的用户,需要确保当前安装环 境中的 Python 支持 arm64 架构,否则执行速度会慢 1/10 以上。测试方法是在安装 llama-cpp-python 之后,执行以下 Python 命令,其中模型路径请替换为本地 GGUF 模型文件。

from llama_cpp import Llama>>> llm = Llama(model_path=”ggml-model-q4_0.gguf”)
执行代码之后,屏幕输出相关的日志信息。下面给出的是支持 ARM NEON 加速 的日志示例。如果显示 NEON = 1 则表示正常,如果显示 NEON = 0 则表示并没有按 arm64 架构正确安装。
system_info: n_threads = 8 / 10 | AVX = 0 | AVX2 = 0 | AVX512 = 0 | AVX512_VBMI = 0 | AVX512_VNNI = 0 | FMA = 0 | NEON = 1 | ARM_FMA = 1 | F16C = 0 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 0 | VSX = 0 |
在正确安装 llama-cpp-python 之后,可以继续安装 privateGPT,具体命令如下。
git clone https://github.com/imartinez/privateGPT.gitcd privateGPTpip install -r requirements.txt

02

修改配置文件

在 privateGPT 根目录下创建一个名为 .env 的配置文件。以下是一个配置文件示例。
MODEL_TYPE=LlamaCppPERSIST_DIRECTORY=dbMODEL_PATH=ggml-model-q4_0.ggufMODEL_N_CTX=4096MODEL_N_BATCH=512EMBEDDINGS_MODEL_NAME=sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2TARGET_SOURCE_CHUNKS=4
其中,各字段的说明如下:
MODEL_TYPE:填写 LlamaCpp,表示加载的模型是 llama.cpp 兼容格式;
PERSIST_DIRECTORY:填写分析文件存放位置,会在 privateGPT 根目录创建一 个名为 db 的目录;
MODEL_N_CTX:模型的最大上下文窗口大小(同 llama.cpp -c 参数);
MODEL_PATH:指向模型存放位置,这里指向的是 llama.cpp 支持的 GGUF 文件;
MODEL_N_BATCH:提示的批处理大小(同 llama.cpp -b 参数);
EMBEDDINGS_MODEL_NAME:SentenceTransformers 词向量模型位置,可以指定 HuggingFace 上的路径(会自动下载);
TARGET_SOURCE_CHUNKS:用于解答问题的组块数量。

03

分析本地文件

privateGPT 支持以下常规文档格式,包括但不限于:
• Word 文件:.doc,.docx;
• PPT 文件:.ppt,.pptx;
• PDF 文件:.pdf;
• 纯文本文件:.txt;
• CSV 文件:.csv;
• Markdown 文件:.md;
• 电子邮件文件:.eml,.msg。
接下来,将需要分析的文档放到 privateGPT 根目录下的 source_documents 目 录中,支持放入多个文件。本例中放入了 3 个关于“马斯克访华”相关的 Word 文件。 目录结构类似:
$ ls source_documentsmusk1.docx musk2.docx musk3.docx
下一步,运行 ingest.py 程序对文档进行分析。
$ python ingest.py
文档分析输出如下。需要注意的是,如果配置文件中提供的是 HuggingFace 地址 而不是本地路径,当首次使用时会下载配置文件中的词向量模型。另外,如果 db 目 录中已经有相关分析文件,则会对数据文件进行积累。如果只想针对当前文档进行解 析,需要清空 db 目录后再运行 ingest.py 分析程序。
Creating new vectorstoreLoading documents from source_documentsLoading new documents: 100%|██████████████████████| 3/3 [00:02<00:00, 1.11it/s]Loaded 3 new documents from source_documentsSplit into 7 chunks of text (max. 500 tokens each)Creating embeddings. May take some minutes…Ingestion complete! You can now run privateGPT.py to query your documents
04
修改解码策略
在正式启动问答交互之前,还需要进行加速配置和指令模板配置。
(1) 加速策略。由于 privateGPT.py 实际上调用了 llama-cpp-python 的接口, 如果不对代码进行任何修改,则会采用默认的解码策略。所以,接下来需要修改模型 解码相关参数,以便获得最好的速度和效果。
打开 privateGPT.py 查找以下语句(大约 35 行,根据不同版本有所不同)。
llm = LlamaCpp(model_path=model_path, max_tokens=model_n_ctx, callbacks=callbacks, verbose=False)
这里即是 LlamaCpp 模型的定义,可根据 llama-cpp-python 的接口定义传入更多 的自定义参数,以下是一个示例。
llm = LlamaCpp(model_path=model_path, max_tokens=model_n_ctx, callbacks=callbacks, verbose=False, n_threads=8, n_ctx=model_n_ctx, n_gpu_layers=1)
其中的一些重要参数说明如下。
• n_threads:与 llama.cpp 中的 -n 参数一致,定义解码线程数量,有助于提高 解码速度,可根据实际物理核心数酌情配置;
• n_ctx:与 llama.cpp 中的 -c 参数一致,定义上下文窗口大小,默认为 512,这 里设置为配置文件的 model_n_ctx 数量,即 4096;
• n_gpu_layers:与 llama.cpp 中的 -ngl 参数一致,定义使用 GPU 加载的层数。
(2) 嵌套指令模板。默认的解码方法不包含任何嵌套的指令模板。接下来将以 Chinese-Alpaca-2 为例介绍嵌套指令模板的方法,以便使用正确的方式加载模型。
打开 privateGPT.py,查找以下语句(大约 40 行,根据不同版本有所不同)。
qa = RetrievalQA.from_chain_type(llm=llm, chain_type=”stuff”, retriever=retriever, return_source_documents=not args.hide_source)
替换为以下代码。
alpaca2_prompt_template = ( “[INST] <>\n” “You are a helpful assistant. 你是一个乐于助人的助手。\n” “<>\n\n” “{context}\n\n{question} [/INST]”)from langchain import PromptTemplateinput_with_prompt = PromptTemplate(template=alpaca2_prompt_template, input_variables=[“context”, “question”])qa = RetrievalQA.from_chain_type(llm=llm, chain_type=”stuff”, retriever=retriever, return_source_documents=not args.hide_source, chain_type_kwargs={“prompt”: input_with_prompt})
05
启动问答交互
在分析文档并且修改解码策略之后,可运行以下命令开始对文档进行提问。
python privateGPT.py
出现以下提示之后即可输入问题,例如输入以下问题。
Enter a query: 马斯克此次访华可能有什么目的?
结果如下(由于篇幅原因,略去来源文档部分):
Question:
马斯克此次访华可能有什么目的?
Answer (took 48.29 s.):
根据路透社披露的消息和报道分析,马斯克访华可能有以下一些目的:
1.加强与中国政府高层的互动沟通,推动特斯拉在中国市场的发展计划。此前中国监管部门对特斯拉在销售、售后服务等方面提出了多项整改措施,此次访问也可能涉及解决上述问题并寻求政府的支持。
2.参观特斯拉在上海拥有的超级工厂以及探索进一步扩大规模的可能性。上海工厂是目前全球最大的电动汽车工厂之一,扩建可能有利于加速产能提升和提高产量水平。
3.探讨与中国本土汽车制造商在市场上竞争的问题。随着特斯拉在中国市场的份额逐渐增加,其在与国产品牌之间的竞争关系也可能越来越重要。经过此次访问,马斯克可能会就这一问题提出建议或寻求解决办法。
4.推动电动汽车产业的全球合作和发展。作为全球最大的新能源汽车市场之一,中国市场对特斯拉的发展具有重要的战略意义。如果成功地拓展到中国,特斯拉将能够进一步扩大其在全球范围内的影响力并加速电动车的普及进程。

由于 privateGPT 主要基于 LangChain 进行开发,可进一步通过不同的处理策略 来优化 privateGPT 的输出,感兴趣的读者可进一步参考 LangChain 或 privateGPT 中的 refine 或者 map_reduce 等策略的使用方法。
本文节选自《自然语言处理:基于大语言模型的方法》(车万翔,郭江,崔一鸣,著;刘挺,主审. 电子工业出版社,2025.3)

读者评论

相关博文

  • 社区使用反馈专区

    陈晓猛 2016-10-04

    尊敬的博文视点用户您好: 欢迎您访问本站,您在本站点访问过程中遇到任何问题,均可以在本页留言,我们会根据您的意见和建议,对网站进行不断的优化和改进,给您带来更好的访问体验! 同时,您被采纳的意见和建议,管理员也会赠送您相应的积分...

    陈晓猛 2016-10-04
    5745 749 3 7
  • 迎战“双12”!《Unity3D实战核心技术详解》独家预售开启!

    陈晓猛 2016-12-05

    时隔一周,让大家时刻挂念的《Unity3D实战核心技术详解》终于开放预售啦! 这本书不仅满足了很多年轻人的学习欲望,并且与实际开发相结合,能够解决工作中真实遇到的问题。预售期间优惠多多,实在不容错过! Unity 3D实战核心技术详解 ...

    陈晓猛 2016-12-05
    3461 36 0 1
  • czk 2017-07-29
    6314 28 0 1