在快速发展的人工智能领域中,有效地利用大型语言模型(LLM)变得越来越重要。然而,有许多不同的方式可以使用大型语言模型,这可能会让我们感到困惑。实际上,可以使用预训练的大型语言模型进行新任务的上下文学习并进行微调。
那么,什么是上下文学习?又如何对大模型进行微调呢?
1. 上下文学习与索引
自从GPT-2和GPT-3出现以来,可以发现在预训练的通用文本语料库上的生成式大型语言模型(LLM)具备了上下文学习的能力,这意味着如果我们想要执行LLM没有明确训练的特定或新任务,不需要进一步训练或微调预训练的LLM。同时,我们可以通过输入提示直接提供一些目标任务的示例。
In Context Learning(ICL)的关键思想是从类比中学习。下图给出了一个描述语言模型如何使用 ICL 进行决策的例子。首先,ICL 需要一些示例来形成一个演示上下文。这些示例通常是用自然语言模板编写的。然后 ICL 将查询的问题(即需要预测标签的 input)和一个上下文演示(一些相关的 cases)连接在一起,形成带有提示的输入,并将其输入到语言模型中进行预测。
如果无法直接访问模型,例如通过 API 使用模型,上下文学习非常有用。与上下文学习相关的是“硬提示微调”的概念,可以通过修改输入来期望改善输出。将直接修改输入的单词或标记的微调称为“硬”提示微调,另一种微调方式称为“软”提示微调或通常称为“提示微调”。这种提示微调方法提供了一种更为节省资源的参数微调替代方案。然而,由于它不会更新模型参数以适应特定任务的微小差异,因此可能会限制其适应能力。此外,由于通常需要手动比较不同提示的质量,提示微调可能需要耗费大量人力。
另一种利用纯粹的上下文学习方法的方法是索引。在LLM的范围内,索引可以被视为一个上下文学习的解决方法,它使得LLM可以转换为信息检索系统,用于从外部资源和网站中提取数据。在此过程中,索引模块将文档或网站分解为较小的段落,并将它们转换为可以存储在向量数据库中的向量。然后,当用户提交查询时,索引模块计算嵌入式查询与数据库中每个向量之间的向量相似度。最终,索引模块获取前k个最相似的嵌入式向量以生成响应。索引的示意图如下:
2. 基于三种特征的微调方法
上下文学习是一种有价值且用户友好的方法,适用于直接访问大型语言模型受限的情况,例如通过API或用户界面与LLM进行交互。然而,如果可以访问LLM,则使用来自目标领域的数据对其进行适应和微调通常会导致更好的结果。那么,我们如何将模型适应到目标任务?下图概述了三种常规的基于特征的微调方法。
除了微调编码器风格的LLM之外,相同的方法也适用于GPT般的解码器风格LLM。此外,还可以微调解码器风格的LLM生成多句话的答案,而不仅仅是分类文本。
2.1 基于特征的方法
在基于特征的方法中,需要加载预训练的LLM,并将其应用于目标数据集。在这里,需要特别关注生成训练集的输出嵌入,这些嵌入可以用作训练分类模型的输入特征。虽然这种方法在以嵌入为重点的模型(如BERT)中特别常见,但也可以从生成式GPT-style模型中提取嵌入。
分类模型可以是逻辑回归模型、随机森林或XGBoost ,也可以任何我们想要的模型。一般地,在这里线性分类器如逻辑回归表现最佳。
从概念上讲,可以用以下代码说明基于特征的方法:
代码语言:javascript
model = AutoModel.from_pretrained("distilbert-base-uncased")
# ...
# tokenize dataset
# ...
# generate embeddings
@torch.inference_mode()
def get_output_embeddings(batch):
output = model(
batch["input_ids"],
attention_mask=batch["attention_mask"]
).last_hidden_state[:, 0]
return {"features": output}
dataset_features = dataset_tokenized.map(
get_output_embeddings, batched=True, batch_size=10)
X_train = np.array(imdb_features["train"]["features"])
y_train = np.array(imdb_features["train"]["label"])
X_val = np.array(imdb_features["validation"]["features"])
y_val = np.array(imdb_features["validation"]["label"])
X_test = np.array(imdb_features["test"]["features"])
y_test = np.array(imdb_features["test"]["label"])
# train classifier
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(X_train, y_train)
print("Training accuracy", clf.score(X_train, y_train))
print("Validation accuracy", clf.score(X_val, y_val))
print("test accuracy", clf.score(X_test, y_test))
2.2 基于输出层更新的微调
与上述基于特征的方法相关的一种流行方法是微调输出层。与基于特征的方法类似,保持预训练LLM的参数不变,只训练新添加的输出层,类似于在嵌入特征上训练逻辑回归分类器或小型多层感知器。在代码中,将如下所示:
代码语言:javascript
model = AutoModelForSequenceClassification.from_pretrained(
"distilbert-base-uncased",
num_labels=2
)
# freeze all layers
for param in model.parameters():
param.requires_grad = False
# then unfreeze the two last layers (output layers)
for param in model.pre_classifier.parameters():
param.requires_grad = True
for param in model.classifier.parameters():
param.requires_grad = True
# finetune model
lightning_model = CustomLightningModule(model)
trainer = L.Trainer(
max_epochs=3,
...
)
trainer.fit(
model=lightning_model,
train_dataloaders=train_loader,
val_dataloaders=val_loader)
# evaluate model
trainer.test(lightning_model, dataloaders=test_loader)
理论上,这种方法应该具有与基于特征的方法同样的良好建模性能和速度。然而,由于基于特征的方法使预计算和存储嵌入特征更加容易,因此在特定的实际情况下,记忆特征的方法可能更加方便。
2.3 面向所有层更新的微调
尽管原始的BERT论文声称,仅微调输出层可以实现与微调所有层相当的建模性能,但后者涉及更多参数,因此成本更高。例如,BERT基本模型约有1.1亿个参数。然而,BERT基本模型用于二元分类的最后一层仅包含1,500个参数。此外,BERT基本模型的最后两层占据60,000个参数,仅占总模型大小的约0.6%。]
由于目标任务和目标领域与模型预训练的数据集相似程度的不同,几乎总是通过微调所有层来获得更优秀的模型性能。因此,当优化模型性能时,使用预训练LLM的黄金标准是更新所有层。从概念上讲,这种方法与输出层更新非常相似。唯一的区别是不冻结预训练LLM的参数,而是对其进行微调。
代码语言:javascript
model = AutoModelForSequenceClassification.from_pretrained(
"distilbert-base-uncased",
num_labels=2
)
# don't freeze layers
# for param in model.parameters():
# param.requires_grad = False
# finetune model
lightning_model = LightningModel(model)
trainer = L.Trainer(
max_epochs=3,
...
)
trainer.fit(
model=lightning_model,
train_dataloaders=train_loader,
val_dataloaders=val_loader)
# evaluate model
trainer.test(lightning_model, dataloaders=test_loader)
多层微调通常会导致更好的性能,但代价也会增加,各种方法的计算和模型性能如下图所示。
上面的情景突出了微调的三种极端情况:基于特征,仅训练最后一层或几层,或者训练所有层。当然,根据模型和数据集的不同,在各种选项之间探索也可能是值得的。
3. 参数高效微调
参数高效微调允许我们在最小化计算和资源占用的同时重复使用预训练模型。总的来说,参数高效微调至少有以下5个优点:
- 减少计算成本(需要更少的GPU和GPU时间);
- 更快的训练时间(更快地完成训练);
- 更低的硬件要求(可以使用更小的GPU和更少的存储器);
- 更好的模型性能(减少过拟合);
- 更少的存储空间(大部分权重可以在不同任务之间共享)。
如前所述,微调更多的层通常会导致更好的结果。如果想要微调更大的模型,例如重新生成的LLM,这些模型只能勉强适合GPU内存,该怎么办呢?人们开发了几种技术,只需训练少量参数便可通过微调提升LLM的性能。这些方法通常被称为参数高效微调技术(PEFT)。
在huggingface提供的PEFT工具中,可以很方便地实现将普通的HF模型变成用于支持轻量级微调的模型,使用非常便捷,目前支持4种策略,分别是:
- LoRA
- Prefix Tuning
- P-Tuning
- Prompt Tuning
下图总结了一些最广泛使用的PEFT技术。
那么这些技术是如何工作的呢?简而言之,它们都涉及引入少量的额外参数,而不是对所有层都进行修改。从某种意义上讲,输出层微调也可以被视为一种参数高效的微调技术。然而,像前缀微调、适配器和低秩适应等技术,它们“修改”多个层,以极低的成本实现更好的预测性能。
4.RHLF
在人类反馈增强学习中,预训练模型使用监督学习和强化学习相结合进行微调。这种方法是由原始的ChatGPT模型推广而来,而该模型又基于InstructGPT。RLHF通过让人类对不同的模型输出进行排名或评分来收集人类反馈,从而提供奖励信号。然后,可以使用收集的奖励标签来训练奖励模型,进而指导LLM对人类偏好的适应。
奖励模型本身是通过监督学习进行学习的,通常使用预训练的LLM作为基本模型。接下来,奖励模型用于更新预训练的LLM,以适应人类的偏好。训练使用了一种称为近端策略优化的强化学习方法。InstructGPT论文中概述了RLHF的过程。
为什么要使用奖励模型而不是直接训练预先训练好的模型并使用人类反馈?主要原因是将人类纳入学习过程会造成瓶颈,我们无法实时获取反馈。
5.小结
微调预训练LLM的所有层仍然是适应新目标任务的黄金准则。但是,诸如基于特征的方法、上下文学习和参数高效微调技术等方法,可以在最小化计算成本和资源的同时,有效地将LLM应用到新任务中。此外,带有人类反馈的强化学习(RLHF)作为有监督微调的替代方法,也可以提高模型性能。
如何系统的去学习大模型LLM ?
作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。
但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的 AI大模型资料
包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
所有资料 ⚡️ ,朋友们如果有需要全套 《LLM大模型入门+进阶学习资源包》,扫码获取~
一、全套AGI大模型学习路线
AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!
二、640套AI大模型报告合集
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
三、AI大模型经典PDF籍
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。
四、AI大模型商业化落地方案
阶段1:AI大模型时代的基础理解
- 目标:了解AI大模型的基本概念、发展历程和核心原理。
- 内容:
- L1.1 人工智能简述与大模型起源
- L1.2 大模型与通用人工智能
- L1.3 GPT模型的发展历程
- L1.4 模型工程
- L1.4.1 知识大模型
- L1.4.2 生产大模型
- L1.4.3 模型工程方法论
- L1.4.4 模型工程实践 - L1.5 GPT应用案例
阶段2:AI大模型API应用开发工程
- 目标:掌握AI大模型API的使用和开发,以及相关的编程技能。
- 内容:
- L2.1 API接口
- L2.1.1 OpenAI API接口
- L2.1.2 Python接口接入
- L2.1.3 BOT工具类框架
- L2.1.4 代码示例 - L2.2 Prompt框架
- L2.2.1 什么是Prompt
- L2.2.2 Prompt框架应用现状
- L2.2.3 基于GPTAS的Prompt框架
- L2.2.4 Prompt框架与Thought
- L2.2.5 Prompt框架与提示词 - L2.3 流水线工程
- L2.3.1 流水线工程的概念
- L2.3.2 流水线工程的优点
- L2.3.3 流水线工程的应用 - L2.4 总结与展望
- L2.1 API接口
阶段3:AI大模型应用架构实践
- 目标:深入理解AI大模型的应用架构,并能够进行私有化部署。
- 内容:
- L3.1 Agent模型框架
- L3.1.1 Agent模型框架的设计理念
- L3.1.2 Agent模型框架的核心组件
- L3.1.3 Agent模型框架的实现细节 - L3.2 MetaGPT
- L3.2.1 MetaGPT的基本概念
- L3.2.2 MetaGPT的工作原理
- L3.2.3 MetaGPT的应用场景 - L3.3 ChatGLM
- L3.3.1 ChatGLM的特点
- L3.3.2 ChatGLM的开发环境
- L3.3.3 ChatGLM的使用示例 - L3.4 LLAMA
- L3.4.1 LLAMA的特点
- L3.4.2 LLAMA的开发环境
- L3.4.3 LLAMA的使用示例 - L3.5 其他大模型介绍
- L3.1 Agent模型框架
阶段4:AI大模型私有化部署
- 目标:掌握多种AI大模型的私有化部署,包括多模态和特定领域模型。
- 内容:
- L4.1 模型私有化部署概述
- L4.2 模型私有化部署的关键技术
- L4.3 模型私有化部署的实施步骤
- L4.4 模型私有化部署的应用场景
学习计划:
- 阶段1:1-2个月,建立AI大模型的基础知识体系。
- 阶段2:2-3个月,专注于API应用开发能力的提升。
- 阶段3:3-4个月,深入实践AI大模型的应用架构和私有化部署。
- 阶段4:4-5个月,专注于高级模型的应用和部署。
这份完整版的所有 ⚡️ 大模型 LLM 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费
】
全套 《LLM大模型入门+进阶学习资源包》↓↓↓ 获取~