调整LLM创建一个克隆的自己

释放你的数字的双胞胎

11分钟阅读 7月10

- - -

生成的图像稳定的扩散。

本文旨在说明如何调整表现LLM高效低成本在一个自定义的数据集。我们将探讨利用Falcon-7B模型与罗拉适配器使用Lit-GPT

有没有想过会是什么感觉,有数字的双胞胎吗?虚拟的复制品自己可以交谈,学习,甚至是反映你的思想吗?人工智能(AI)的最新进展已使这个once-futuristic想法实现。

人工智能社区的努力导致了许多高质量的开源llm的发展,包括但不限于开放的骆驼,猎鹰,StableLM,皮提亚。您可以调整这些模型在自定义指令集来适应您的特定任务,如培训聊天机器人回答金融问题。此外,它还可以提供一个数据隐私的优势当数据无法上传或共享与云api。

模型在我的例子中,我想学会说我的风格通过模仿我,使用我的笑话和填充词。

数据收集和准备

在我们深入了解细节之前,我想指出,微调GPT-like模型是非常复杂的。不过,我决定把它进一步训练模型在俄罗斯语言:

  • 这是一个额外的挑战,因为模型主要是训练英语文本。
  • 考虑到俄罗斯是我的母语,我拥有一个巨大的数据集包括我个人的通讯。

数据收集

我选择了电报,因为它提供了一个方便的API,用于数据收集。此外,它是我的大部分的主要平台与朋友沟通。这种选择提供了有价值的数据集,允许模型获得更深入地理解我的独特的沟通方式,使它更有效地模仿我。

后,文档,我写了一个小脚本,下载所有信件从私人聊天并保存到一个文件:

  1. 启动电报客户:
从电视节目。同步导入TelegramClient

客户= TelegramClient (PHONE_NUMBER TELEGRAM_APP_ID TELEGRAM_APP_HASH)
client.start ()

2。被过滤的列表对话框组和渠道:

def get_dialogs(限制:int | = 100) - >列表(对话框):
”“从电报获得所有对话框”。“
对话框:列表(对话框)= client.get_dialogs(限制=限制)
对话框=[对话框对话框在对话框对话框。is_user] #删除组或通道
logger.info (f“发现{len(对话框)}对话框”)
返回对话框

3所示。下载对应的历史:

def parse_messages(对话框:对话框中,限制:int = 1000) - >列表(dict类型):
”“从对话框获得所有消息”。“
all_messages_list = []
offset_id = 0

而真正的:
消息:[信息]=客户列表(
GetHistoryRequest (
同行=对话框中,
offset_id = offset_id,
offset_date =没有
add_offset = 0,
限制=极限,
max_id = 0,
min_id = 0,
散列= 0,
)
).messages
如果没有消息:
打破

all_messages_list.extend (
{
“日期”:message.date.isoformat (),
“信息”:message.message,
“出去”:message.out,
}
消息的消息
#过滤音频或视频内容
如果消息。消息,而不是message.is_bot
)
[1].id offset_id = offset_id =消息
返回all_messages_list

你可以找到完整的脚本在这里

值得一提的是,我故意排除音频和视频信息的数据集和只关注文本的内容。因此,一些信息的对话可能是迷路了。从这些数据中提取文本是一个全面的话题,会更适合一个单独的文章。

数据准备

在这一点上,你必须认真处理数据来调整LLM的指令。

微调通常涉及培训pre-trained模型遵循指令或执行另一个特定的目标任务(例如,情绪分类)。ChatGPT(开始调整版本的GPT-3基础模型)是一个典型的例子的模型调整遵循指令。指令数据集通常有三把钥匙:指令,输入(可选给定指令上下文),预期的响应LLM。下面是一个示例指令数据的例子:

(
{
“指令”:“猫交流吗?”
“上下文”:“猫需要为键相互通信,和彼此有关;他们需要合作,玩,共享资源……”
“响应”:“猫叫声已经分类根据一系列特点…”,
}
]

示意图,微调过程可以表示如下:

微调pretrained LLM遵循指令。

重要的是要记住,你可以修改数据格式,以适应您的需要。例如,您可以输入一个函数和要求作为响应模型生成文档。然而,根据我的经验,较小的模型(如7 b)可能纠结复杂的提示。

为了克服这一点,尽量简化提示或把它们分解成一系列连续的指令。通过这种方式,您可以实现更好的结果和改进模型的性能。

构建指令根据我的聊天,我雇佣了几个方法:

  1. 把谈话分成两个批次的时候差距超过一天的消息。通过这种方式,我们认为这是开始一个新的交流的话题,因此,没有上下文从先前的谈话。
  2. 从相同的用户连续消息连接在一个消息。正如我们所知,有些人倾向于写多个连续短消息。
  3. 设置一个最大上下文长度加速训练过程。
  4. 标签添加到我的反应和对话者的反应模型来帮助更好地理解上下文。
预处理的聊天信息。

我也清除聊天记录个人密码等敏感信息或电子邮件。

我结束了51 k指令,媲美多莉2.0指令集砖(~ 15 k指令)羊驼数据集(~ 52 k指令)。

模型

我决定选择猎鹰——最新发布的开源大语言模型技术创新研究所。这是一个自回归decoder-only模型有两个变种:400亿70亿参数模型和参数模型。40 b模型变体训练384 gpu AWS为2个月。

打开LLM排行榜。

基于什么是已知的关于模型、猎鹰架构非常类似于GPT-3和骆驼,除了使用多查询关注(Shazeer 2019),RefinedWeb语料库作为训练数据集(可以成功的关键)。

与罗拉Parameter-efficient LLM微调

如果我们考虑如何提高LLM(大语言模型)模型,一个宝贵的资源是OpenAI文章手掌:训练前一个Autoencoder潜模型序列生成。本文论述了使用微调,包括培训模型使用与原始的相同技术培训学习速率较低但~0.1。这个过程可以让我们培养模型具体数据,从而提高其响应所需的域。

除了微调外,还有其他方法,比如使用适配器。适配器需要添加额外的小层到现有层的原始模型,训练只有这些新添加的层。这种方法能使你更快的学习涉及的权重相对较小。

基于适配器的知识注入llm的体系结构。

罗拉的概念的灵感来自观察关于矩阵的权重如何改变在训练,强调工作的Aghajanyan et al。(2020)。这些观察表明,矩阵可以有效地近似使用一个低维空间,同时仍然保留大部分的基本信息和结构。

每一个矩阵W代表的总和吗W + A * B在培训。最初的矩阵W冻结,只有矩阵一个B是训练有素的。因此,更新后的重量了ΔW = W + A * B。通过确保矩阵一个B保持小,学习过程变得更快,需要更少的资源。简而言之,这是罗拉方法,见下图。

提出通过更新模型。

请注意,r在上图中,hyperparameter在这里,我们可以使用它来指定用于适应的低秩矩阵的秩。小r会导致一个更简单的低秩矩阵,从而导致更少的参数在适应学习。选择一个较小的r在罗拉之间的权衡模型复杂性、适应能力,underfitting或过度拟合的风险。

为进一步的细节和深入的信息,我推荐以下资源:

实验

进行我的实验中,我使用了Lit-GPT图书馆,其中包括开源LLM的实现,是由闪电织物。至于硬件设置,我使用一个单一A100 GPU 40 GB的内存容量。

下载模型权重

启动实验中,第一步是下载模型权重和转换的lit-gpt格式。这是很容易做的事:

#下载模型权重:
python脚本/下载。py——repo_id tiiuae / falcon-7b

#把重量转换成标准化的形式:
python脚本/ convert_hf_checkpoint。py——checkpoint_dir检查点/ tiiuae / falcon-7b

你能找到说明书下载RedPajama等其他支持权重howto部分

准备数据集

微调包括两个主要步骤,第一:我们处理数据集Lit-Parrot格式然后我们处理过的数据集上运行调整脚本。

我修改了现有的羊驼脚本提供准备函数加载的原始指令集,创建提示,并首先标记它们。就我个人而言,我需要改变函数来生成提示:

def generate_prompt(例如:dict (str, str)) - > str:
”““生成一个标准化的信息提示模式”“
回报(
“你(我)和一个用户r .编写一个回复他的信息。\ n \ n”
f”# # #你以前的交流:\ n{例子['环境']}\ n \ n”
f”# # #他的新消息:\ n{例子(“指令”)}\ n \ n”
f“# # #你的回应:{例子[“响应”]}”
)

更改后,您可以启动数据准备过程:

python脚本/ prepare_dataset_my。py \
——checkpoint_dir检查点/ tiiuae / falcon-7b /

它不会花很长时间准备提示。在我的例子中,它只花了2分钟51 k指令:

微调“猎鹰”模型

一旦你已经准备好你的数据集,它整合模型很简单。

我改变了一些参数微调脚本为更好的结果,这是hyperparameter设置我的概述:

bfloat16精度(我写更多关于bfloat16在这篇文章中7的方法来加快你的推理llm托管)。

  • 此外,脚本配置为训练模型51 k迭代使用一个有效的批处理大小为128与梯度积累(渐变条积累的更多细节整合在一个GPU llm使用渐变积累)。
  • 罗拉,我使用一个排名16得到一个更高质量的训练有素的适配器。并设置α为32(α是一个比例因子,调整的幅度相结合的结果,这平衡pretrained模型的知识和新的特定于任务的适应)。

然后你需要运行整合/ lora.py脚本通过提供您的数据路径。

python threshold / lora_my。py \
——checkpoint_dir检查点/ tiiuae / falcon-7b / \
——data_dir数据/猎鹰/ \
——out_dir /猎鹰\
——精密bf16-true

监控微调

您可以使用Linux命令重复运行nvidia-smi第二:每半

表0.5 - n nvidia-smi
GPU负载。

你可以找到模型的检查点/猎鹰文件夹,并使用生成脚本模型。

它大约需要10个小时30 GB内存使用整合模型在一个A100 GPU。此外,值得注意的是,适配器本身是轻量级的,称重只有40 mb。这是小得多的猎鹰模型相比,它有一个16 gb的大小。

运行与调整模型推理

您可以使用微调LLM生成文本检查点。Lit-Parrot提供生成脚本。它支持int8int4量化设备用更少的GPU内存,也可以改变精度和使用几个多个GPU设备:

python生成/罗拉。py \
——checkpoint_dir检查点/ tiiuae / falcon-7b \
——lora_path /猎鹰/ lit_model_lora_finetuned.pth \
——提示“你怎么了?告诉我" \
——max_new_tokens 300
——精密bf16-true

在我的例子中,我跑模型1 GPU设备上,没有量化bfloat16精度。我也改变了原来的罗拉脚本并把它分割为两个部分:

  1. Web界面使用streamlitstreamlit-chat测试模型更快。你可以找到我的版本在这里
  2. RestAPI使用FastAPIweb框架模型推理。这允许模型加载到内存中,然后再次使用它。

演示(我翻译的文本说明):

调整模型的演示。

重要的是要注意,这是我收到的最好的一个例子。其他人则明显恶化。

模型的响应时间,即使没有量化,以每秒45.51令牌非常快。如果你想加快文本生成或者减少内存使用,我建议你检查我的前一篇文章7的方法来加快你的推理llm托管

质量比较

同时详细的性能指标对真实世界的任务是检查这个博客文章,我可以分享我的个人观察调整模型的利用率。

在测试过程中,我得到了特殊的行为,如代无关的文本,偶尔漠视上下文,和困难保持连贯的对话。

我的感觉是,这可以固定在几个方面:

  • 提高数据清洗过程,以确保更高的数据质量。
  • 数据集包含额外的注释对话。
  • 增加罗拉排名从16到32。
  • 利用模型与一个更大的尺寸,如Falcon-40B。
  • 减少上下文或简化它的长度。
  • 简化提示提供清晰的指令。

限制

Lit-GPT提供了一个广泛的功能,我建议主要利用它用于假设检验。在我看来,这是没有完全准备生产使用。例如,写这篇文章的时候,Lit-GPT缺乏一个内置的实现转换模型回HuggingFace格式。然而,它仍然是有可能的,图书馆提出两个解决方案:

  1. 做一个改变转换为每个HuggingFace类。
  2. Сreating版本的高频变压器模型lit_gpt.model

注意,第一个方法不支持罗拉和适配器的修改。

记住这些限制在开发你的解决方案。如果你是微调llm生产,我建议使用纯PyTorch这样做。您可以参考本文通过亚马逊为更多的信息。

结论

能够调整llm仅使用一个GPU和几个小时是真正令人印象深刻。您可以构建许多小罗拉模块不同的任务。为实时推测这些调整模型部署时,您只需要加载相同的基础模型。鉴于LLM 100 + GB的物理尺寸,这种优势是不容忽视的。

然而,它与现实的期望方法过程至关重要。很可能与各种hyperparameters实验将需要实现最优的结果。此外,数据集注释和清洁是至关重要的步骤,以确保最好的结果。也要注意哪些数据LLM训练,和检查基准任务类似于你的。

通过以下步骤努力,我相信可以取得优异的成绩。

- - -

- - -

Baidu