本文翻译整理自:🦙 How to Finetune Llama-3 and Export to Ollama
https://docs.unsloth.ai/tutorials/how-to-finetune-llama-3-and-export-to-ollama
文章目录
1、什么是Unsloth? 2、什么是Ollama? 3、安装Unsloth 4、选择要微调的模型 5、微调参数 6、Alpaca 数据集 7、多列微调 8、多轮对话 9、可定制的聊天模板 10、训练模型 11、推理/运行模型 12、保存模型 13、导出到 Ollama 14、自动创建`Modelfile` 15、Ollama 推理 16、交互式ChatGPT风格 你做到了!创建自定义个人助理(如ChatGPT)以在Ollama上本地运行的初学者指南
在本教程结束时,您将通过微调Llama-3和Unsloth 免费创建一个自定义聊天机器人。
它可以通过PC上的Ollama在本地运行,也可以通过Google Colab在免费的GPU实例中运行。
您将能够像下面这样与聊天机器人交互:
Unsloth使微调变得更加容易,并且可以通过集成的自动Modelfile
创建自动将微调模型 导出到Ollama!
如果您需要帮助,您可以加入我们的 discord :https://discord.com/invite/unsloth
1、什么是Unsloth?
Unsloth使Llama-3、Mistral、Phi-3和Gemma等微调LLM的速度提高了2倍,使用的内存减少了70%,并且精度没有下降!在本教程中,我们将使用提供免费GPU的Google Colab。
您可以访问下面的免费笔记本:
您还需要登录您的Google帐户!
2、什么是Ollama?
Ollama允许您以快速简单的方式从自己的计算机运行语言模型!它悄悄地启动了一个程序,可以在后台运行语言模型,如Llama-3。
如果你突然想问语言模型一个问题,你可以简单地向Ollama提交一个请求,它会很快把结果返回给你!我们将使用Ollama作为我们的推理引擎!
3、安装Unsloth
如果您从未使用过Colab笔记本,请快速了解笔记本本身:
1、每个“单元格”上的播放按钮。单击此按钮可运行该单元格的代码。
您不得跳过任何单元格,并且必须按时间顺序运行每个单元格。
如果遇到任何错误,只需重新运行之前未运行的单元格。
如果您不想单击播放按钮,另一种选择是单击CTRL+ENTER。
2、顶部工具栏中的运行时按钮。
您也可以使用此按钮并点击“全部运行”一次运行整个笔记本。
这将跳过所有自定义步骤,并且可以是一个很好的首次尝试。
3、连接/重新连接T4按钮。
您可以单击此处获取更高级的系统统计信息。
第一个安装单元格如下所示:记得点击括号[]中的PLAY按钮。
我们获取我们的开源Github包,并安装其他一些包。
4、选择要微调的模型
现在让我们选择一个模型进行微调!我们默认使用 Meta/Facebook的 Llama-3,它被训练在一个巨大的15万亿“令牌”上。
假设一个令牌就像一个英语单词。这大约相当于35万厚的百科全书!
其他流行的模型包括米斯特拉尔、Phi-3(使用GPT-4输出训练)和谷歌的 Gemma(13万亿令牌!)。
Unsloth支持这些模型以及更多!事实上,只需从HugingFace model hub 中键入一个模型,看看它是否有效!如果它不起作用,我们会出错。
您可以切换其他3个设置:
max_seq_length = 2048
这决定了模型的上下文长度。
例如,双子座有超过100万的上下文长度,而骆驼-3有8192个上下文长度。
我们允许您选择任何数字——但我们建议将其设置为2048以供测试。
Unsloth还支持非常长的上下文微调,我们展示了我们可以提供比最好的上下文长度长4倍的上下文长度。
dtype = None
将其保持为无,但您可以为较新的GPU选择torch. float16或torch.bfloat16。
load_in_4bit = True
我们在4位量化中进行微调。
这将内存使用量减少了4倍,使我们能够在免费的16GB内存GPU中进行微调。
4位量化本质上是将权重转换为一组有限的数字,以减少内存使用。
这样做的一个缺点是精度下降了1-2%。
如果您想要微小的额外精度,请在H100s等更大的GPU上将其设置为False。
如果您运行单元格,您将获得一些Unsloth版本的打印输出、您使用的模型、您的GPU有多少内存以及一些其他统计信息。
暂时忽略这个。
5、微调参数
现在要自定义您的finetune,您可以编辑上面的数字,但您可以忽略它,因为我们已经选择了相当合理的数字。
目标是改变这些数字以提高准确性,但也抵消过度拟合。
过度拟合是指你让语言模型记住一个数据集,而不能回答新的问题。
我们想要一个最终的模型来回答看不见的问题,而不是记忆。
r = 16, # Choose any number > 0 ! Suggested 8, 16, 32, 64, 128
微调过程的等级。
较大的数字会使用更多的内存,并且会更慢,但可以提高更困难任务的准确性。
我们通常建议使用8(用于快速微调)和128这样的数字。
太大的数字会导致过度拟合,损害模型的质量。
target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",],
我们选择所有模块进行微调。
您可以删除一些以减少内存使用并加快训练速度,但我们强烈不建议这样做。
只需在所有模块上进行训练!
lora_alpha = 16,
微调的缩放因子。
较大的数字将使微调了解更多关于您的数据集,但可能会促进过度拟合。
我们建议这等于秩r
,或者加倍。
lora_dropout = 0, # Supports any, but = 0 is optimized
将此保留为0以进行更快的训练!可以减少过度拟合,但没那么多。
bias = "none", # Supports any, but = "none" is optimized
将此保留为0,以获得更快、更少的过度健身训练!
use_gradient_checkpointing = "unsloth", # True or "unsloth" for very long context
选项包括True
、False
和"unsloth"
。
我们建议"unsloth"
,因为我们额外减少了30%的内存使用,并支持极长的上下文finetunes.You可以在这里阅读:https://unsloth.ai/blog/long-context了解更多细节。
random_state = 3407,
确定确定性运行的数字。
训练和微调需要随机数,因此设置这个数字可以使实验重现。
use_rslora = False, # We support rank stabilized LoRA
自动设置lora_alpha = 16
的高级功能。
如果你愿意,你可以使用这个!
loftq_config = None, # And LoftQ
将LoRA矩阵初始化为权重的前r个奇异向量的高级功能。
可以在一定程度上提高准确性,但会使内存使用在开始时爆炸式增长。
6、Alpaca 数据集
我们现在将使用通过调用GPT-4本身创建的 Alpaca 数据集。
这是一个包含52,000条指令和输出的列表,在Llama-1发布时非常流行,因为它使微调基本LLM与ChatGPT本身具有竞争力。
您可以在此处访问GPT4版本的 Alpaca 数据集:https://huggingface.co/datasets/vicgalle/alpaca-gpt4。
该数据集的旧第一个版本在此处:https://github.com/tatsu-lab/stanford_alpaca。
下面显示了该数据集的一些示例:
你可以看到每行有3列——一条指令,输入和输出。
我们基本上把每一行组合成一个大提示符,如下所示。
然后我们用它来微调语言模型,这使得它非常类似于ChatGPT。
我们称之为监督指令微调。
7、多列微调
但是一个大问题是对于ChatGPT风格的助手,我们只允许1个指令/1个提示,而不是多个列/输入。
例如在ChatGPT中,您可以看到我们必须提交1个提示,而不是多个提示。
这本质上意味着我们必须将多个列“合并”成一个大提示,以便微调才能真正发挥作用!
例如,非常著名的泰坦尼克号数据集有许多列。
你的工作是根据乘客的年龄、乘客等级、票价等来预测乘客是幸存还是死亡。
我们不能简单地将其传递到ChatGPT,而是必须将这些信息“合并”到一个大提示中。
例如,如果我们用包含该乘客所有信息的“合并”单一提示询问ChatGPT,我们可以要求它猜测或预测该乘客是死亡还是幸存。
其他微调库要求您通过将所有列合并到1个提示符中来手动准备微调数据集。
在Unsloth中,我们简单地提供了名为to_sharegpt
的函数,它可以一次完成!
要访问泰坦尼克号微调笔记本,或者如果您想上传CSV或Excel文件,请访问此处:https://colab.research.google.com/drive/1VYkncZMfGFkeCEgN2IzbZIKEDkyQuJAS?usp=sharing
现在这有点复杂,因为我们允许很多定制,但有几点:
必须将所有列用花括号{}
括起来。
这些是实际CSV/Excel文件中的列名。
可选的文本组件必须括在[[]]
中。
例如,如果列“输入”为空,合并函数将不显示文本并跳过此。
这对于缺失值的数据集很有用。
选择output_column_name
中的输出或目标/预测列。
对于 Alpaca 数据集,这将是output
。
例如,在Titanic数据集中,我们可以创建一个大型合并提示格式,如下所示,其中每一列/一段文本都是可选的。
例如,假设数据集看起来像这样,有很多缺失的数据:
上船 年龄 票价 S 23 18岁 7.25那么,我们不希望结果是:
1、The passenger embarked from S. Their age is 23. Their fare is EMPTY.
2、The passenger embarked from EMPTY. Their age is 18. Their fare is $7.25.
相反,通过使用[[]]
可选地包围列,我们可以完全排除此信息。
1、[[The passenger embarked from S.]] [[Their age is 23.]] [[Their fare is EMPTY.]]
2、[[[The passenger embarked from EMPTY.]] [[Their age is 18.]] [[Their fare is $7.25.]]
变成:
1、The passenger embarked from S. Their age is 23.
2、Their age is 18. Their fare is $7.25.
8、多轮对话
如果你没有注意到,一个小问题是 Alpaca 数据集是单轮的,而记住使用ChatGPT是交互式的,你可以多轮与之交谈。
例如,左边是我们想要的,但是右边是 Alpaca 数据集,只提供单数对话。
我们希望微调语言模型以某种方式学习如何像ChatGPT一样进行多轮对话。
所以我们引入了conversation_extension
参数,它本质上是在你的单回合数据集中选择一些随机行,并将它们合并成1个对话!
例如,如果你设置为3,我们随机选择3行并将它们合并成1!
设置太长会使训练变慢,但会使你的聊天机器人和最终的微调变得更好!
然后将output_column_name
设置为预测/输出列。对于 Alpaca 数据集,它将是输出列。
然后我们使用standardize_sharegpt
函数使数据集以正确的格式进行微调!总是这样称呼!
9、可定制的聊天模板
我们现在可以指定聊天模板来微调自己。
非常著名的 Alpaca 格式如下:
但还记得我们说过这是一个坏主意,因为ChatGPT样式的finetunes只需要1个提示吗?
由于我们成功地将所有数据集列合并为1个,因此我们基本上可以创建以下样式的聊天模板,其中包含1个输入列(指令)和1个输出:
我们只要求您必须为指令输入{INPUT}
字段,为模型输出字段输入{OUTPUT}
字段。
事实上,我们还允许一个可选的{SYSTEM}
字段,这对于自定义系统提示很有用,就像ChatGPT中一样。
例如,下面是一些很酷的例子,您可以将聊天模板自定义为:
对于OpenAI模型中使用的ChatML格式:
或者您可以使用Llama-3模板本身(它仅通过使用Llama-3的说明版本来运行):我们实际上还允许一个可选的{SYSTEM}
字段,这对于自定义系统提示很有用,就像在ChatGPT中一样。
或者在泰坦尼克号预测任务中,您必须在这个Colab笔记本中预测乘客是否死亡或幸存,其中包括CSV和Excel上传:https://colab.research.google.com/drive/1VYkncZMfGFkeCEgN2IzbZIKEDkyQuJAS?usp=sharing
10、训练模型
让我们现在训练模型!我们通常建议人们不要编辑下面的内容,除非您想微调更长的步骤或想在大批量上进行训练。
我们通常不建议更改上述参数,但对其中一些进行详细说明:
per_device_train_batch_size = 2,
如果您想更多地利用GPU的内存,请增加批处理大小。
还要增加批处理大小,以使训练更加流畅,并使过程不会过度拟合。
我们通常不建议这样做,因为由于填充问题,这可能会使训练实际上变慢。
我们通常会要求您增加gradient_accumulation_steps
,这只会对数据集进行更多的传递。
gradient_accumulation_steps = 4,
相当于增加批处理大小,但不会影响内存消耗!如果您想要更平滑的训练损失曲线,我们通常建议人们增加这一点。
max_steps = 60, # num_train_epochs = 1,
我们将步骤设置为60以加快训练速度。
对于可能需要数小时的完整训练运行,请将其注释掉max_steps
,并将其替换为num_train_epochs = 1
。
将其设置为1意味着在您的数据集上进行1次完整通过。
我们通常建议1到3次通过,不能更多,否则您将过度拟合您的finetune。
learning_rate = 2e-4,
如果您想使微调过程变慢,但也很可能收敛到更高精度的结果,请降低学习率。
我们通常建议2e-4、1e-4、5e-5、2e-5作为尝试的数字。
你会看到一些数字的日志!这是训练损失,你的工作是设置参数,使其尽可能接近0.5!如果你的微调没有达到1、0.8或0.5,你可能不得不调整一些数字。
如果你的损失为0,这可能也不是一个好兆头!
11、推理/运行模型
现在让我们在完成训练过程后运行模型!您可以编辑黄色下划线部分!
事实上,因为我们创建了一个多圈聊天机器人,我们现在也可以调用模型,就好像它看到了过去的一些对话,如下所示:
提醒Unsloth本身也提供了2倍更快的推理,所以永远不要忘记调用 FastLanguageModel.for_inference(model)
。
如果您希望模型输出更长的响应,请将max_new_tokens = 128
设置为更大的数字,如256或1024。
请注意,您也必须等待更长的结果!
12、保存模型
我们现在可以将微调模型保存为一个100MB的小文件,称为 LoRA adapter ,如下所示。
如果你想上传你的模型,你也可以推送到 Hugging Face 中心!记得通过 https://huggingface.co/settings/tokens 获取 Hugging Face 令牌并添加你的令牌!
保存模型后,我们可以再次使用Unsloth运行模型本身!再次使用FastLanguageModel
调用它进行推理!
13、导出到 Ollama
最后,我们可以将微调模型导出到Ollama本身!首先,我们必须在Colab笔记本中安装Ollama:
然后我们将我们必须的finetuned模型 导出为 llama. cpp 的GGUF格式,如下所示:
提醒1行要将False
转换为True
,不要将每一行都更改为True
,否则您将等待很长时间!我们通常建议将第一行设置为True
,因此我们可以将finetuned模型快速导出为Q8_0
格式(8位量化)。
我们还允许您导出到整个量化方法列表,其中一个流行的是q4_k_m
。
前往 https://github.com/ggerganov/llama.cpp了解更多关于GGUF的信息。
如果您愿意,我们还有一些关于如何导出到GGUF的手动说明:https://github.com/unslothai/unsloth/wiki#manually-saving-to-gguf
您将看到一长串如下所示的文本-请等待5到10分钟!!
最后在最后,它看起来像下面:
然后,我们必须在后台运行Ollama本身。
我们使用subprocess
,因为Colab不喜欢异步调用,但通常只需在终端/命令提示符下运行ollama serve
。
14、自动创建Modelfile
Unsloth提供的技巧是我们自动创建Ollama需要的Modelfile
!
这只是一个设置列表,包括我们用于finetune过程的聊天模板!您还可以打印生成的Modelfile
,如下所示:
然后我们要求Ollama创建一个与Ollama兼容的模型,通过使用Modelfile
15、Ollama 推理
如果您想调用在您自己的本地机器上运行的Ollama服务器本身/在后台的免费Colab笔记本中,我们现在可以调用模型进行推理。
请记住,您可以编辑黄色下划线部分。
16、交互式ChatGPT风格
但是要像ChatGPT一样运行finetuned模型,我们必须做得更多!首先单击终端图,然后会弹出一个终端。它在左侧边栏上。
然后,您可能需要按两次ENTER来删除终端窗口中的一些奇怪输出。
等待几秒钟,键入ollama run unsloth_model
然后按ENTER。
最后,您可以像实际ChatGPT一样与微调模型交互!点击 CTRL+D 退出系统,点击ENTER与聊天机器人交谈!
你做到了!
您已经成功微调了一个语言模型并将其导出到Ollama,速度提高了2倍,VRAM减少了70%!所有这些都在Google Colab笔记本中免费提供!
如果你想学习如何做奖励建模、继续预训练、导出到vLLM或GGUF、完成文本或了解更多关于微调技巧和窍门的信息,请访问我们的Github。
如果您在微调方面需要任何帮助,您也可以在这里加入我们的Discordserver。
如果您需要Ollama方面的帮助,您也可以在这里加入他们的服务器。
最后,我们要感谢您阅读并关注到这里!我们希望这让您理解了微调语言模型背后的一些细节,我们希望这是有用的!
要访问我们的 Alpaca 数据集示例,请单击此处,我们的CSV/Excel微调指南就在这里。
2024-08-24(六)
总结