
点击蓝字 关注我们

导读
大型语言模型(LLM)凭借其强大的语言理解和生成能力,彻底改变了行业的格局。然而,这些通用模型在特定业务场景或专业领域中的表现往往不尽如人意。为了满足特定需求,近年来,研究人员和工程师们开发了多种LLM定制化策略,使其能够更好地适应各种应用场景。本文将详细介绍这些策略,帮助你选择最适合的定制化方法。
为何要定制大语言模型?
大语言模型的训练需要海量数据、大量训练时间以及庞大的参数规模,这使得从头开始训练一个大语言模型对于中小型团队而言几乎是不可能的任务。虽然大语言模型功能强大,但它们的开箱即用性能并不能总是满足特定的业务或领域需求。例如,在处理依赖公司内部数据的问题时,通用大语言模型就显得无能为力。正因如此,近年来涌现出了各种定制策略,旨在针对需要专业知识的场景对模型进行优化。
这些定制策略大致可分为两类:
使用固定模型:这类技术无需更新模型参数,通常通过上下文学习或提示工程来实现。它们成本效益高,能够在不产生大量训练成本的情况下改变模型行为,在工业界和学术界都得到了广泛研究,相关新论文层出不穷 。 更新模型参数:这是一种资源密集型的方法,需要使用为特定目的设计的自定义数据集对预训练的大语言模型进行微调。其中包括微调(Fine-Tuning)和基于人类反馈的强化学习(RLHF)等热门技术。
这两种主要的定制范式又衍生出了各种专业技术,如低秩自适应(LoRA)微调、思维链(Chain of Thought)、检索增强生成(RAG)、ReAct以及智能体框架(Agent)等。每种技术在计算资源需求、实现复杂度和性能提升方面都各有利弊。
如何选择大语言模型?
定制大语言模型的第一步是选择合适的基础模型作为基线。像“Huggingface”这样的社区平台提供了众多由顶尖公司或社区贡献的开源预训练模型,例如Meta的Llama系列和谷歌的Gemini模型。Huggingface还提供排行榜,如“Open LLM Leaderboard”,通过行业标准指标和任务(如MMLU)对大语言模型进行比较。此外,云服务提供商(如AWS)和人工智能公司(如OpenAI和Anthropic)也提供专有模型的访问,但通常是付费服务且访问受限。
在选择大语言模型时,需要考虑以下关键因素:
1. 开源模型与专有模型
开源模型:允许完全定制和自我托管,但需要技术专长。 专有模型:提供即时访问和通常更高质量的响应,但成本较高。
2. 任务和指标
不同模型在问答、摘要、代码生成等任务上的表现各异。 比较基准指标并在特定领域任务上进行测试,以确定合适的模型。
3. 架构
解码器模型(如GPT系列)在文本生成方面表现更好。 编码器-解码器模型(如T5)在翻译任务中表现更佳。 新兴架构(如专家混合模型“DeepSeek”)也显示出 promising results。
4. 参数数量和模型大小
大型模型(70B-175B参数)性能更好,但需要更多的计算资源。 小型模型(7B-13B参数)运行更快、成本更低,但能力可能有限。
六大LLM定制化策略

根据资源消耗程度,我们将定制化策略分为以下六种,从低到高依次为:
提示工程(Prompt Engineering) 解码和采样策略(Decoding and Sampling Strategy) 检索增强生成(RAG) 代理(Agent) 微调(Fine-Tuning) 基于人类反馈的强化学习(RLHF)
提示工程

提示是发送给大语言模型以获取AI生成回复的输入文本,它由指令、上下文、输入数据和输出指示符组成。提示工程旨在通过策略性地构建这些提示组件,来塑造和控制模型的回复。基本的提示工程技术包括零样本、一样本和少样本提示,用户在与大语言模型交互时可直接使用这些技术,使模型行为与新目标保持一致。此外,也可以通过API实现,更多细节可参考之前的文章《将大语言模型提示与知识图谱集成的简单流程》。
由于提示工程的高效性,人们进一步探索和开发了更复杂的方法,以提升提示的逻辑结构。
思维链(CoT):要求大语言模型将复杂的推理任务分解为逐步的思维过程,从而提高在多步问题上的性能。每一步都明确展示其推理结果,作为后续步骤的前置上下文,直至得出最终答案。
思维树(Tree of thoughts):是对思维链的扩展,它考虑多个不同的推理分支,并通过自我评估来决定下一步的最佳行动。这种方法在涉及初始决策、未来策略规划和多种解决方案探索的任务中更为有效。
自动推理和工具使用(ART):基于思维链过程构建,它将复杂任务解构,允许模型使用搜索和代码生成等预定义外部工具,从任务库中选择少样本示例。
协同推理与行动(ReAct):将推理轨迹与行动空间相结合,模型在行动空间中进行搜索,并根据环境观察确定下一步的最佳行动。
像思维链和ReAct这样的技术通常与智能体工作流程相结合,以增强其能力。
解码和采样策略

解码策略可以在模型推理时通过推理参数(如温度、核采样阈值top p、采样前k个最高概率词top k)进行控制,从而决定模型回复的随机性和多样性。贪婪搜索、束搜索和采样是自回归模型生成中三种常见的解码策略。
在自回归生成过程中,大语言模型根据前一个词的条件,从候选词的概率分布中每次输出一个词。默认情况下,贪婪搜索会选择概率最高的下一个词。
相比之下,束搜索解码会考虑多个下一个最佳词的假设,并选择在文本序列中所有词的组合概率最高的假设。以下代码片段使用transformers
库在模型生成过程中指定束搜索路径的数量(例如,num_beams = 5
表示考虑5个不同的假设):
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(tokenizer_name)
inputs = tokenizer(prompt, return_tensors="pt")
model = AutoModelForCausalLM.from_pretrained(model_name)
outputs = model.generate(**inputs, num_beams=5)复制
采样策略是通过调整推理参数来控制模型回复随机性的第三种方法:
温度(Temperature):降低温度会使概率分布更加尖锐,增加生成高概率词的可能性,减少生成低概率词的可能性。当温度为0时,等同于贪婪搜索(创造性最低);当温度为1时,生成的输出最具创造性。
Top K采样:该方法会过滤出K个最可能的下一个词,并在这些词中重新分配概率,模型随后从这个过滤后的词集中进行采样。
Top P采样:与Top K采样不同,Top P采样会从累积概率超过阈值p的最小可能词集中进行选择。
以下示例代码从概率最高的50个词中进行采样(top_k = 50
),且累积概率高于0.95(top_p = 0.95
):
sample_outputs = model.generate(
**model_inputs,
max_new_tokens=40,
do_sample=True,
top_k=50,
top_p=0.95,
num_return_sequences=3,
)复制
检索增强生成(RAG)

检索增强生成(RAG)最初在《用于知识密集型自然语言处理任务的检索增强生成》一文中提出,已被证明是一种很有前景的解决方案。它能够集成外部知识,并减少大语言模型在处理特定领域或专业查询时常见的“幻觉”问题。RAG可以动态地从知识领域中提取相关信息,通常无需进行大量训练来更新大语言模型的参数,是一种将通用大语言模型适配到特定领域的经济高效策略。
一个RAG系统可分为检索和生成两个阶段。检索过程的目标是通过对外部知识进行分块、创建嵌入、索引和相似性搜索,在知识库中找到与用户查询密切相关的内容。
分块(Chunking):将文档分割成较小的片段,每个片段包含一个独特的信息单元。
创建嵌入(Create embeddings):嵌入模型将每个信息片段压缩为向量表示,用户查询也通过相同的向量化过程转换为向量表示,以便在同一维度空间中进行比较。
索引(Indexing):这个过程将这些文本片段及其向量嵌入存储为键值对,实现高效且可扩展的搜索功能。对于超出内存容量的大型外部知识库,向量数据库提供了高效的长期存储方案。
相似性搜索(Similarity search):计算查询嵌入和文本片段嵌入之间的相似性分数,用于搜索与用户查询高度相关的信息。
RAG系统的生成过程随后将检索到的信息与用户查询相结合,形成增强查询,并将其输入到大语言模型中,以生成内容丰富的回复。
以下代码片段首先指定大语言模型和嵌入模型,然后对外部知识库文档进行分块,从文档创建索引,基于索引定义查询引擎,并使用用户提示查询查询引擎:
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core import VectorStoreIndex
Settings.llm = OpenAI(model="gpt-3.5-turbo")
Settings.embed_model="BAAI/bge-small-en-v1.5"
document = Document(text="\n\n".join([doc.text for doc in documents]))
index = VectorStoreIndex.from_documents([document])
query_engine = index.as_query_engine()
response = query_engine.query(
"Tell me about LLM customization strategies.")复制
上述示例展示了一个简单的RAG系统。先进的RAG在这个基础上进行改进,引入预检索和后检索策略,以减少检索和生成过程之间协同性不足等问题。例如,重排序技术使用能够理解双向上下文的模型对检索到的信息进行重新排序,并且与知识图谱集成以实现更高级的查询路由。更多用例可在llamaindex网站上找到。
智能体(Agent)

大语言模型智能体在2024年成为热门话题,并有望在2025年继续成为生成式人工智能领域的焦点。与RAG相比,智能体擅长创建查询路径和规划基于大语言模型的工作流程,具有以下优势:
维护记忆和状态:能够保留模型先前生成回复的记忆和状态。
利用多种工具:根据特定标准使用各种工具,这种使用工具的能力使智能体区别于基本的RAG系统,赋予大语言模型独立选择工具的控制权。
任务分解与规划:将复杂任务分解为较小的步骤,并规划一系列行动。
多智能体协作:与其他智能体协作形成一个协调的系统。
一些上下文学习技术(如思维链、ReAct)可以通过智能体框架来实现,这里我们详细讨论ReAct。ReAct即“协同推理与行动(Synergizing Reasoning and Acting in Language Models)”,由谷歌研究团队和普林斯顿大学提出,它基于思维链,将推理步骤与行动空间相结合,支持工具使用和函数调用。此外,ReAct框架强调根据环境观察来确定下一步的最佳行动。
以下是ReAct的一个示例,来自原文论文。在这个例子中,大语言模型生成第一个想法并通过调用“Search [Apple Remote]”函数采取行动,然后观察其第一个输出的反馈。第二个想法基于之前的观察,从而导致不同的行动“Search [Front Row]”。这个过程不断迭代,直到达到目标。研究表明,ReAct通过与简单的维基百科API交互,克服了思维链推理中常见的幻觉和错误传播问题。此外,通过实施决策跟踪,ReAct框架还提高了模型的可解释性、可信度和可诊断性。
以下代码展示了使用llamaindex
实现基于ReAct的智能体:
from llama_index.core.agent import ReActAgent
from llama_index.core.tools import FunctionTool
# 创建基本函数工具
def multiply(a: float, b: float) -> float:
return a * b
multiply_tool = FunctionTool.from_defaults(fn=multiply)
def add(a: float, b: float) -> float:
return a + b
add_tool = FunctionTool.from_defaults(fn=add)
agent = ReActAgent.from_tools([multiply_tool, add_tool], llm=llm, verbose=True)复制
当智能体工作流程与自我反思或自我修正相结合时,其优势更为显著。目前,这一领域正在不断发展,人们正在探索各种智能体架构。例如,Reflexion框架通过提供环境的语言反馈总结并将反馈存储在模型记忆中,促进迭代学习;CRITIC框架通过与代码解释器和API调用等外部工具交互,使固定的大语言模型能够进行自我验证。
微调(Fine-Tuning)

微调是指使用特定的小众数据集对大语言模型进行修改,使其更符合特定目标的过程。它与提示工程和RAG的不同之处在于,微调可以更新大语言模型的权重和参数。全量微调通过反向传播更新预训练大语言模型的所有权重,这需要大量内存来存储所有权重和参数,并且可能会导致模型在其他任务上的能力显著下降(即灾难性遗忘)。因此,参数高效微调(PEFT)更广泛地用于减轻这些问题,同时节省模型训练的时间和成本。PEFT方法主要分为三类:
选择性微调(Selective):选择初始大语言模型参数的一个子集进行微调,与其他PEFT方法相比,计算成本可能更高。 重参数化(Reparameterization):通过训练低秩表示的权重来调整模型权重。例如,低秩自适应(LoRA)就属于这一类,它通过用两个较小的矩阵表示权重更新来加速微调过程。 添加式(Additive):向模型添加额外的可训练层,包括适配器(adapters)和软提示(soft prompts)等技术。
微调过程与深度学习训练过程类似,需要以下输入:
训练和评估数据集 训练参数:定义超参数,如学习率、优化器等。 预训练大语言模型 计算指标和目标函数:算法应针对这些指标和函数进行优化。
以下是使用transformer
的Trainer
进行微调的示例代码:
from transformers import TrainingArguments, Trainer
training_args = TrainingArguments(
output_dir=output_dir,
learning_rate=1e-5,
eval_strategy="epoch"
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
compute_metrics=compute_metrics,
)
trainer.train()复制
微调有广泛的应用场景。例如,指令微调通过在提示 - 完成对(prompt-completion pairs)上进行训练,优化大语言模型的对话和遵循指令能力;领域自适应是一种无监督微调方法,帮助大语言模型专注于特定知识领域。
基于人类反馈的强化学习(RLHF)

基于人类反馈的强化学习(RLHF)是一种强化学习技术,它根据人类偏好对大语言模型进行微调。RLHF通过基于人类反馈训练奖励模型,并将该模型作为奖励函数,使用近端策略优化(PPO)来优化强化学习策略。这个过程需要两组训练数据:用于训练奖励模型的偏好数据集,以及在强化学习循环中使用的提示数据集。
具体步骤如下:
收集偏好数据集:由人类标注者对模型生成的不同完成结果进行基于人类偏好的评分,标注后的偏好数据集格式示例为 {input_text, candidate1, candidate2, human_preference}
,表示更偏好哪个候选回复。训练奖励模型:使用偏好数据集训练奖励模型,奖励模型本质上是一个回归模型,输出一个标量来表示模型生成回复的质量。奖励模型的目标是最大化获胜候选和失败候选之间的分数差异。 使用奖励模型微调大语言模型:在强化学习循环中使用奖励模型对大语言模型进行微调,目标是更新策略,使大语言模型能够生成最大化奖励模型产生的奖励的回复。这个过程使用提示数据集,其格式为 {prompt, response, rewards}
。
开源库Trlx在实现RLHF方面应用广泛,以下是其展示基本RLHF设置的模板代码:
# trl: Transformer Reinforcement Learning library
from trl import PPOTrainer, PPOConfig, AutoModelForSeq2SeqLMWithValueHead
from trl import create_reference_model
from trl.core import LengthSampler
# 从预训练检查点初始化基础模型和分词器
model = AutoModelForCausalLMWithValueHead.from_pretrained(config.model_name)
tokenizer = AutoTokenizer.from_pretrained(config.model_name)
# 定义PPO算法的超参数
config = PPOConfig(
model_name=model_name,
learning_rate=learning_rate,
ppo_epochs=max_ppo_epochs,
mini_batch_size=mini_batch_size,
batch_size=batch_size)
# 初始化PPO训练器
ppo_trainer = PPOTrainer(
config=config,
model=ppo_model,
tokenizer=tokenizer,
dataset=d复制
总结
本文详细介绍了六种常见的LLM定制化策略,包括提示工程、解码策略、RAG、代理、微调和RLHF。每种策略都有其独特的优势和权衡,选择合适的策略取决于你的具体需求和资源。
点击蓝字 关注我们

END