乱谈府

乱谈府

大模型调优技术

14
2025-04-11
大模型调优技术

本文是书籍 # AI Engineering: Building Applications with Foundation Models 读书笔记的一部分。结合个人知识的经验思考摘录,体系很庞大,随时同步笔记更新。

大模型不能直接运用于实际生产,通常需要加上或多或少的操作。即便是最简单的问答,本质上也可以理解为简化的有 prompt 的提问(query),在经过大模型后得到对应响应(response)。为了实现复杂的功能或者工作流,不同的调优技术需要添加到基础大模型上。
每种不同的技术都有着海量的细节,钻研细节固然重要,但是自上而下梳理整体的框架更为重要,接下来是我做一些简短的思路梳理。

Prompt Engineering 提示词工程

Prompt 基本上是最简单的调优方法,通过添加合适的提示词,让模型实现较为复杂的功能。
Prompt 通常由以下一个或多个部分组成:

  • Task description 任务说明。希望模型实现的功能,包括模型扮演的角色和输出格式等。
  • Example (s) of how to do this task 任务的示例。一个或多个具体的例子。
  • Task 具体的任务。
    image.png

Zero-shot 和 few-shot:在 prompt 中提示的例子称为 shot,zero-shot 表示没有提示示例。过多的示例会增加响应延迟和成本。

Prompt 分为 system prompt 和 user prompt。通常会制定模板,将应用程序开发人员提供的说明放入 system prompt 中,而用户提供的说明则放入 user prompt 中。

精心制作的 system prompt 可以提高性能。可能原因如下:

  • system prompt 通常第一个出现,而模型会更好处理第一个说明。
  • 模型可能经过 post-train,本身会更加关注 system prompt。
    研究表明 (Liu et al., 2023),一个模型在理解开始和结束时的 prompt 要好得多。

如何写更好的 Prompt

  1. 写出清晰明确的说明:
    • 在没有歧义的情况下解释希望模型做什么:比如明确的评分标准(离散值)等等
    • 要求模型扮演的角色
    • 提供完整的例子
    • 指定的输出格式:结构化输出
  2. 提供足够的上下文知识,或者限定特定的上下文知识,不过这需要借助 RAG 和 Web 搜索等技巧。
  3. 将复杂的任务分解为更为简单的子任务:例如针对一个聊天机器人,先进行意图分类,再针对不同的意图,根据不同的 prompt 生成对应响应。对于具体的分类和操作方法,需要根据成本和延迟进行测试权衡。可以使用较弱的模型进行意图分类,较强的模型进行后续生成响应。
  4. 给模型更多思考的时间:chain-of-thought (CoT) 明确要求模型进行逐步思考以达到更好的性能。最简单的方法是在 prompt 中加入 think step by stepexplain your decision ,以鼓励模型进行深度思考。
  5. 不断更新迭代模型的 Prompt:每个模型的 prompt 都会不一致。

评估 Prompt 的工具

旨在自动化整个自动化工程流程的工具包括 OpenPrompt (Ding et al., 2021) and DSPy (Khattab et al., 2023) 。任务指定输入和输出格式,评估指标和评估数据。这些提示优化工具会自动找到提示或提示链,以最大程度地提高评估数据的评估指标。这个过程类似于一般模型中的超参数调参。

有些工具用于快速构建 prompt,例如 GuidanceOutlinesInstructor 指导模型进行结构化输出。

一些 prompt 分享网站:PromptHero and Cursor Directory

建议将 prompt 和代码分开,这样利于复用,测试,可读性也更高。有些工具提出了特殊的格式来存储 Prompt,例如 Google Firebase’s DotpromptHumanloopContinue Dev, and Promptfile

Prompt 安全性防御

有时候模型可能会收到攻击导致如下影响:

  • prompt 提取:应用被复制复用。
  • 越狱(Jailbreaking and prompt injection):让模型做坏事。
  • 信息提取:上下文信息和训练数据被提取泄露。`

许多攻击被串联为大量的指令,导致模型无法区分系统指令和恶意指令。OpenAI 在这篇论文“The Instruction Hierarchy: Training LLMs to Prioritize Privileged Instructions” (Wallace et al., 2024) 中提出一个包含四个优先级的指令层次结构。
System prompt - User prompt - Model outputs - Tool outputs
image.png

在对模型进行安全性微调时,重要的不仅是训练模型识别恶意提示,还要训练它在处理边缘请求时生成安全的回复(所谓边缘请求,是指那些可能引发安全或不安全回复的请求)。

如何进行防御:

  • Prompt 级别防御:创建一些鲁棒性更强的 system prompt,明确禁止某些行为。一个简单方法是在 user prompt 之前和之后都重复一次 system prompt。
  • 系统级别防御:尽可能的孤立特定数据间的联系。MCP 逐渐可以做到这些事情。

对于需要较为复杂的上下文构建工作,2 个主导的模式是 RAGAgent

  • RAG (retrieval-augmented generation):让模型从外部数据源检索相关信息。
  • Agent:构建大的工作流,让模型使用 Web 搜索和新闻 API 等工具来收集信息。

RAG 检索增强生成

RAG 主要目的是克服模型上下文限制。但即便模型上下文信息逐渐变大,RAG 依旧很重要,原因如下:

  • 无论模型上下文多大,总会有需要更长上下文的存在。
  • 即便能够处理更多的上下文,但不一定能很好的使用,一些冗余或者格式的偏差会导致性能骤降,依旧需要借助其他技术改进。

your knowledge base is smaller than 200,000 tokens (about 500 pages of material), you can just include the entire knowledge base in the prompt that you give the model, with no need for RAG or similar methods” (Anthropic, 2024)

RAG 的架构

RAG 主要由 2 部分组成:

  • retriever 检索器:用于从外部存储器检索信息。RAG 的好坏取决于检索器功能的质量,可分为以下 2 个步骤:
    • indexing 索引:涉及数据处理,以便之后可以快速检索
    • querying 查询:发送查询内容以检索相关数据
  • generator 生成器:基于检索到的信息生成对应响应。
    image.png

Retrieval 算法可分为两个方面:

  1. Term-based retrieval 基于术语的检索
    给定查询,查找相关文档的最直接方法是找到与其相关的关键词。
    文档中一个项出现的次数称为术语频率 (TF, term frequency)。同时一个术语的重要性与它出现的文档数量成反比,称为逆文档频率 (IDF, inverse document frequency)。TF-IDF 是一种结合这两个指标的算法。

两个常见的基于术语的检索解决方案是 ElasticsearchBM25

  1. Embedding-based retrieval 基于嵌入的检索
    主要基于嵌入后语义信息对目标查询进行查询,也可以称为 semantic retrieval。
    该种方法的 index 需要将原始数据块进行嵌入,存储为矢量数据库 (vector database)。Query 过程需要将查询先转化嵌入,后检索与原始数据嵌入最接近的 K 个数据块进行后续操作。
    image.png

这个过程会涉及到 vector search,对于大型数据集,通常使用 近似最近邻 (ANN, approximate nearest neighbor) 算法,该类算法专门用于在高维空间中高效查找近似最近邻的数据点。

ANN-Benchmarks 展示了在多个数据集上比较了不同的 ANN 算法,并考虑了索引和查询之间的权衡。具体参考实现:FAISS (Facebook AI Similarity Search) (Johnson et al., 2017), Google’s ScaNN (Scalable Nearest Neighbors) (Sun et al., 2020), Spotify’s Annoy (Bernhardsson, 2013), and Hnswlib (Hierarchical Navigable Small World) (Malkov and Yashunin, 2016).

用于评估 RAG 性能的指标如下:

  • context precision : 在所有检索到的文件中,与查询有关的百分比。即正确使用的上下文数/模型使用所有上下文数。
  • context recall:在所有与检索有关的文件中(对比参考),与查询有关的百分比。即正确使用的上下文数/所有应使用的上下文数(参考标准)。

对于嵌入检索,同样需要评估嵌入的质量。

image.png

通常以上两种方法可以结合起来一起使用用于提高性能,统称为混合搜索 (hybrid search)。用于组合不同排名的算法称为 reciprocal rank fusion (RRF) (Cormack et al., 2009).

Retrieval 优化

  1. Chunking strategy 分块策略
    最简单的是基于特定单元长度将文档分为相同长度的块。或者使用越来越小的单元长度来递归拆分文档。注意拆分的时候需要设定一定部分的重叠块,以免在关键上下文处丢失信息。例如如果将块大小设置为 2,048 个字符,则可以将重叠大小设置为 20 个字符。

更多的块会给模型提供更好的信息,但同时可能因为单个块字符减少而丢失信息,所有参数设置都需要实验尝试。

  1. Reranking
    对于特定任务,重排可以优化性能。文档也可以根据时间来重新排序,从而使更新的数据给予更高的权重。

  2. Query rewriting
    查询重写有时候也被称为 query reformulation, query normalization 或 query expansion。主要是防止在上下文分块过程中语句产生歧义。在传统的搜索引擎中,查询重写通常是使用启发式方法完成的。在 AI 应用程序中,还可以使用其他 AI 模型进行查询重写。

  3. Contextual retrieval
    上下文检索背后的想法是增加具有相关上下文的每个块,以使检索相关的块更容易。例如分块后可以增加原始文档的上下文(例如原始文档的标题和摘要)增强每个块。
    image.png

评估 retrival 方法需要考虑但不限于以下几点:

  • 支持哪些检索机制,是否支持混合检索。
  • 如果使用了矢量数据库,支持哪些嵌入模型和矢量搜索算法。
  • 在数据存储和查询方面是否有扩展性。
  • 索引数据需要多长时间,一次可以批处理多少数据。

结合多种模式的 RAG

图像:如果图像元数据(例如标题,标签和字幕),则可以使用元数据检索。或者使用 CLIP (Radford et al., 2021) 作为多模态的嵌入模型。
表格数据:需要模型有着生成和查询 SQL 的能力 (Text-to-SQL)

image.png

Agent

代理 (Agent) 是由它所处的环境和它能执行的动作决定的。代理两个重要的概念是工具(Tools)和计划(Planning),借助这些概念根据不同需求制造复杂的程序。

这个概念总体来说比较宽泛且抽象,在我看来实际上你构建的每个任务和程序一定程度上都可以理解为 Agent,这里不做过多的展开。

Tool 工具能力

工具主要是一些可以让大模型与其他各流程交互的能力。
最近火热的 MCP (Model Context Protocal) 概念可以理解为 LLM 到 Agent 中间的协议层,一方面更利于模型与具体不同程序的交互,而这其中也可以避免数据的影响,这点和 Agent 的 Tools 思想是相符合的。越来越多的 MCP 开源项目表明大模型与万物互联的能力大大增加,不用重复去造轮子。

Planning 计划能力

计划是 Agent 在处理过程中的尝试。通常实施一项任务,为了避免无效的执行而浪费资源,应该将 计划 过程和 执行 过程解耦。先让 Agent 生成计划,验证后再继续执行,通常可以使用启发式算法进行验证。

如果一个计划评估后是不成功的,可以要求 计划者(planner)再生成一个计划,最后进行执行。而这个 计划者 是可以要求模型自己生成。
image.png

Finetuning 微调

Finetuning 是迁移学习的一种技术,旨在提高模型在特定领域的功能性与质量。与以往简单 CNN 等模型不同的是,大模型的 inetuning 需要耗费大量的资源。很多情况下,进行 finetuning 只会提供一个很小的增量改进,但实际任务的优先级可能并不值得这样做。

Finetuning 技术

大模型中通常使用 PEFT (parameter-efficient finetuning) 技术进行实现。通过将其他参数插入正确的位置中,可以使用少量可训练的参数实现强大的微调性能。使模型的原始参数保持不变,并且仅更新适配器 (adapter) 的参数(可训练参数)。

PEFT 方法分为多种:

  • Adapter-based methods 通常指所有涉及模型权重附加模块的方法,增加可训练参数,其中 LoRA 最为突出也最常用。
  • Soft prompt-based methods 通过引入特殊的、可训练的 token(类似于向量嵌入),改变模型对输入的处理方式。

更多不同的 finetuning 策略可以参考 OpenAI’s finetuning best practices document,可以采取 progression path 和 distillation path。

模型合并

针对不同任务,finetuning 后可能会达到众多模型,模型合并的目的是创建一个单个模型,该模型比单独使用所有组成模型提供了更多的价值。本质上是联合学习 (federated learning) 的一种方式。不同的组合方法如下:

  1. Sum 加法
    将模型输出的权重值求和,注意需要先进行维度的统一。组合方法可以通过线性组合或球形线性差值 (Spherical LinEar inteRPolation, SLERP)。合并过程中考虑修剪掉冗余特定任务参数。
  2. Layer Stacking 层堆叠
    通常选用一个或多个模型中不同的层,将其堆叠起来,通常之后还需进行 finetuning 以达到更好的效果。该种方法可以用于训练 MoE (mixture-of-experts) 模型,参考“Sparse Upcycling: Training Mixture-of-Experts from Dense Checkpoints” (Komatsuzaki et al., 2022).
  3. Concatenation
    同一般深度学习的 concat,是在某个维度的堆叠。不过实际上不推荐使用这种方法,因为会增加模型的参数,增加的性能可能不足以额外的参数量。

image.png

一些 finetuning 的框架:LLaMA-FactoryunslothPEFTAxolotlLitGPT.

关于 Memory

Memory mechanisms 记忆机制

Memory mechanisms 是指允许模型保留和利用信息的机制。AI 模型有三种记忆机制:

  • Internal knowledge:AI 模型自身训练学习的知识。
  • Short-term memory:将以往对话的消息添加到模型上下文,以生成后续的响应。通常不会跨任务存在。
  • Long-term memory:通过 RAG 等技术,模型可以检索外部的数据来源,可跨任务持续存在。

AI 模型的存储系统主要有两个方面组成:

  • 记忆管理:控制在 Short-term memory和 Long-term memory 中应该存储哪些信息。通常需要增加和删除操作,最简单的方法是 FIFO (first in, first out),仅保存特定个数最近的消息。或者使用各种策略消除之前的冗余,例如用大模型对之前的消息做总结摘要。
  • 记忆检索:从 Long-term memory中检索与任务相关的信息。该流程类似与 RAG 检索。
    ``

Memory Bottlenecks

在 Finetuning过程中涉及训练,相较于一般的推断过程,需要耗费更多的计算资源。

内存计算

推断过程参数计算,加载模型所需内存为 N × M,N 为模型的权重大小 (model weights),M 为每个参数所需的内存。实际中 Transformer 中 key-value vectors 需要额外数值,外加激活函数值,通常可以认为这两部分所需内存为模型权重的 20%。因此推断模型所需内存为 $$ N \times M \times 1 . 2$$
考虑一个 13B 参数模型。如果每个参数需要 2 个字节,则模型内存将需要 13b×2bytes= 26 GB。推理的总内存将为 26 GB×1.2 = 31.2 GB。

而训练过程中,所需内存会增加,可以理解为Training memory = model weights + activations + gradients + optimizer states。一个简单的估算,这几个部分为模型权重的 3 倍。此时 13B 参数模型,若每个参数需要 2 个字节,训练总内存为 13b×3×2bytes=78 GB。

内存数值表示

  • FP32 使用 32bits(4bytes)代表一个浮点,称为单精度。
  • FP64 使用 64bits(8bytes)代表一个浮点,称为双精度。
  • FP16 使用 16bits(2bytes)代表一个浮点,称为半精度。

Quantization 量化

量化的目的主要是减少模型的内存(减少精度),更易于推断和训练。有些模型也会使用混合精度 (mixed precision),在减少精度的情况下同时保持较高的精度。
一般量化模型有 q2、q3、q4、q5、q6 和 q8。数字越小同样可以简单理解模型压缩率更高。模型名称中也有「K_M」或 「K_S」,其中是 K 量化,S 代表“小”,M 代表“中”,L 代表“大”。

如何选择合适的技术

通常来说如果如要改进某项任务的性能,先进行 Prompt,达到最大性能后,再考虑使用 RAG 或 Finetuning。如何选择需要判断模型现存的问题是 information-basedbehavior-based

  • 若模型是 information-based 的问题,可以使用 RAG 方法。这里主要原因是模型输出是错误或过时的,由于没有足够的信息最终会导致幻觉等问题。
  • 若模型是 behavior-based 的问题,可以考虑 finetuning 方法。这个时候模型的输出大体内容通常是正确的,但是基础模型训练时缺少相关细节,导致输出细节与预想不符合。再有就是一些需要特定而小众的语法输出(包括对话语言,编程语言等),由于训练样本较少导致输出不好。

简而言之,Finetuning 是用于形式的,RAG 是用于事实的。如果同时存在这两种问题,可以先从最基础的 term-based 的 RAG 开始尝试(例如 BM25)。
整体调节模型的工作流如下(来自 OpenAI (2023)),不过要注意每个步骤都要进行评估:

  1. 使用单独的 Prompt 执行任务,评估效果。
  2. 在 prompt 中加入更多的示例,示例数在 1~50。
  3. 如果此时模型由于缺少相关信息而效果不好,使用 RAG 连接到相关信息的数据源,并从简单的检索方法开始尝试。
  4. 根据不同的效果展示,进行后续操作:
    • 如果仍然是由于缺少信息而效果不好,尝试更好的 RAG 技术,例如嵌入工程。
    • 如果模型存在行为问题,例如生成无关,畸形或不安全的响应,可以尝试 finetuning。注意 finetuning 的工作和计算资源要求是巨大的。
  5. 结合 RAG 和 Finetuning 技术以达到更好的效果。

image.png


喜欢我的文章吗?请不要吝啬自己的思考想法,欢迎在留言区讨论或提出建议。