我就是微调模型界的达纳·卡哈特。如果你还不信,可以看看这段视频,在2022年5月,我用GPT-3微调了一个电影剧本生成器模型。https://youtu.be/cOz3QJT1zU8 项目地址:https://github.com/daveshap/MovieScriptGenerator
大型语言模型(LLM)如GPT-3和Llama展现出了巨大的潜力和可能性。有了充足的数据和计算资源后,这些模型能够产生非常接近人类写作的文本。然而,现成的大型语言模型仍存在一些局限性。它们生成的文本可能会显得平淡、不连贯,或者无法满足您的特定需求。
这就是微调发挥作用的地方。微调是指将一个预训练的大型语言模型以适应特定任务或数据集。通过微调,您可以让LLM生成您想要的文本。
在本文中,我将分享作为一名专家从业者,在调整大规模语言模型(LLM)方面的经验和最佳实践。我从GPT-2开始,逐步扩展到GPT-3,微调了数百个模型。我还训练了开源模型,比如NVIDIA的NeMo。通过下面的步骤,你也可以利用这些大规模语言模型的强大功能来处理自然语言任务。
先来个预告:您可以在这里浏览我最著名的微调数据集项目:
https://github.com/daveshap/GPT3_Finetunes
在读这篇文章之前,你也应该看看我的Prompt Maestro文章和视频。如果你不是个好的提示工程师,你就不是一个好的微调工程师!首先得掌握好提示工程!
https://medium.com/@dave-shap/become-a-gpt-prompt-maestro-943986a93b81
从2019年GPT-2发布以来,我一直在对LLM进行微调。早期的LLM,比如GPT-2和GPT-3,缺少如今模型的智能和校准性,因此需要进行微调。对于GPT-3,我需要提供数百或数千个示例来获得我想要的一致表现。
随着时间的推移,LLM们开箱即用的能力越来越强。有了像Anthropic的Claude和Google的PaLM这样的模型,你可能根本不需要做太多的微调。核心能力已经非常强大。
然而,,微调仍然是在你希望使模型更专精时一种有价值的技巧。例如,你可能希望引导生成的文本朝某个方向发展,或者让模型与自定义的数据集或API进行交互。微调使你能够将通用的大规模语言模型适配为更个性化的工具。
在这份指南中,我将分享多年来微调这么多模型所积累的经验。这些技巧将帮助你更有效地指挥大型语言模型达到你的目标。
关于微调,最关键的一点是理解,它主要是让LLM学会生成模式,而不是记住知识。当你给某个任务提供例子的时候,模型学会了一套将输入转化为预期输出的方法。但这只是表面上的模式匹配。
微调过程并不意味着大型语言模型获得了更深的理解或记忆能力。整个模型没有重新训练,只是调整了顶层,起到轻微的调节作用,类似于轻轻修正方向的角色。
我要强调的是,微调训练仅仅是在学习模式。
作为类比,可以把“微调(fine-tuning)”想象成给汽车喷上定制的油漆和贴上贴花。这使其外观如你所愿。但你没有改动引擎盖下的任何部件。核心发动机依旧不变。
这种区分很重要。许多从业者高估了微调能做什么。你无法仅仅通过几个例子就把知识或推理能力灌输给一个大语言模型。模型只会进行模式匹配,而不能真正学习。
我无法强调理解模式和知识的不同的重要性。LLM们仅仅在它们的主要训练阶段或检查点更新时吸收通用知识。
所以什么是“文本模式”,微调可以教什么样的文本模式?我们可以把模式定义为语言使用中的任何一致惯例或结构。
小说写作遵循特定的模式来讲述故事。角色间的对话、情节描述、推动情节发展的行动描述以及揭示内心想法的内心独白,这些元素的巧妙搭配形成了一种独特的叙述方式。
从更结构化的角度来看,比如大纲和笔记这样的文档使用项目符号简洁地总结信息。项目符号将内容分割成易于阅读的部分。目录也用简短的项目符号帮助导航。
相关地,对话模式出现在从戏剧、剧本到即时消息中的对话模式无处不在。对话者交替发言,标点符号标明说话者。这种一来一往的对话节奏感地推进了对话的进展。
即使是学术论文中的写作,也有固定的模式。通常包括摘要、引言、方法、结果和结论这些标准部分。特殊的惯例,比如使用被动语态和避免使用第一人称代词,让这种写作显得更加正式。作者姓名、所属机构、引用和专业术语也是其特色的一部分。
从更广阔的视角来看,模式可以在许多层级上出现,而不仅仅局限于体裁层面。文本生成的长度也可以根据模板来定。例如,调整可以使模型生成长篇论文或短摘要,取决于具体应用场景。甚至像换行符、括号、逗号和圆括号这样的格式也可以形成模式,这些模型能学会如何恰当地使用这些格式。
文本具有以下几个特点:
最后,模式也存在于诸如语调、风格以及其他编辑惯例方面。微调可以让模型学会模仿海明威简洁有力的文风,或是简·奥斯汀那种优雅的长句风格。它可以转向专业商务语言或普通对话。
关键是持之以恒。任何具有规律性的语言使用——无论是实用的还是风格上的——都可以形成模式让LLM学习和模仿。这种多样性强调了微调在文本生成中的作用。
你知道ChatGPT有它独特的模式和风格吗?它常常用列表和正式语言。这就是它的模式。
另一种方式来理解模式是将其看作一系列字符。
9cb3008b-6f5c-48db-8339–3a9143fae368
上面的是UUIDv4(版本4的通用唯一标识符)。我们可以把它看作是一个字符模式。
所以你可以看到这两条规则创造了一个非常严格、独特的模式。同样,JSON也严格遵循着一个模式。即使是虚构的内容也有自己的模式,每个作者都有自己独特的风格。
这是思考你在调整的数据集中字符排列的另一种方式。
记住,LLM 会一次生成一个 token,就像在打字一样。你可以把它想象成一台打字机,一台在纸上打字的机器。即使是换行符,也只是改变了文本显示,但它本身仍然是一系列字符。
这不仅仅是针对某些文本输出进行微调,模型还需要学习输入与预期输出之间的联系。
输入形式在不同任务中可以大不相同。输入可以包括自然语言指令、结构化数据,还有需要总结的原始文本等。在微调数据中体现这种多样性很重要。
理想情况下,理想的训练数据应该包括模型可能遇到的各种类型的输入。这有助于稳健地适应各种情况。举个例子,如果任务是处理各种表单,数据应包括简短的表单、较长的表单、字段不同的表单、格式奇怪的表单等。
把训练数据中的每个样本当作一个方程式来思考。输入对应左边,输出对应右边。输入和输出是一一对应的。它们是一对匹配的配对。
在模型微调过程中暴露其在边缘情况下的表现也有助于处理意外输入。这样,模型学会在格式奇怪或指令不清楚时不会严重失败。
简单来说,微调训练的是各种输入与目标输出之间的关联。希望模型能将某些输入准确地映射到你期望的输出。
可以把大型语言模型想象成一条文本生产线。输入的原材料可以是任何东西。微调优化了这个过程,每次都能输出所需的结果。这种输入与输出之间的关联至关重要。
有了足够多样化的训练数据后,模型就能很好地适应新的输入。输入-输出的映射被提炼出一种可泛化的模式。这使模型能够灵活处理新的数据。
微调就像是学习任何新技能一样。以驾驶汽车为例,一开始,你会在理想条件下练习驾驶同样的路线。但是要成为一个真正的驾驶高手,你还需要在各种不同的情境下积累经验。不同的车、地方、天气、交通情况等。
当你积累了足够的多样化驾驶经验,你就能灵活运用这项技能。你可以根据不同的情况顺利驾驶任何到来的车辆。丰富的实践使你能够灵活应对各种情况。
这个原则同样适用于微调LLM,你不希望使用过于狭窄的专业化训练数据,这些示例需要广泛覆盖模型应处理的内容范围。
假设你想让模型总结长篇新闻文章。训练数据不应该仅仅使用同一出版物或同一主题的文章。应该包含多样性的有:
这种多样性有助于模型在问题空间中进行泛化能力。这样模型就能可靠地总结各种新的文章,即使这些文章有不寻常的格式。
记住,微调(fine-tuning)遵循GIGO原则:垃圾进,垃圾出。仔细策划训练数据集,使其涵盖广泛的输入和期望输出。这将实现从任何A到任何B的稳健映射。
我们现在来到了这篇文章的核心:飞镖盘的比喻
假设你的数据集就像一块飞镖板,你需要精准地击中靶心以“调整到最佳状态”,使性能达到最优。
想象你的数据集是一把飞镖,每把飞镖就是数据集中的一个样本。你的目标是训练一个模型,让它能每次都精准地击中靶心,达到最佳性能。
如果你的所有飞镖都聚集在靶板的一个小区域里,你的数据集就会非常不平衡,甚至危险。这就像你只练习从离靶子很近的地方投掷飞镖一样。到了比赛时,一旦需要从更远的地方投掷,你就很难击中靶心了。
这种聚类会限制模型的功能。经过微调的模型只会产出限制在那个狭窄聚类里的文本,无论是什么样的输入。
例如,假设你想微调一个烹饪助手AI。如果训练数据里只有金枪鱼三明治的食谱,那就是你的数据集过于单一。因此,你的微调模型只会不断输出金枪鱼三明治的食谱。即使你让它做意大利面食谱,它也会不停输出金枪鱼三明治食谱!
相反,你希望飞镖均匀分布在整个飞镖板上。你的训练数据应涵盖所有预期用途。对于我们烹饪AI来说,应包括各种不同菜系、食材、烹饪方法和菜肴形式的食谱。
这种多样性鼓励模型广泛地应用,并且能够准确回答任何烹饪提示。当你的飞镖能覆盖整个靶盘时,模型学会了按需击中靶盘的任何部分。
所以在你的微调数据集中的样本,有意识地让采样多样化,就像一个射手练习从各个角度射箭那样。评估数据分布,确保覆盖范围广泛,而不是形成偏斜的聚类。广泛的多样性可以解锁灵活的文本生成能力。
即使是针对特定小众领域,也包含一些变化来进一步优化性能。对于金枪鱼三明治模型来说,融入不同的配方、食材、准备步骤和风格等。这可以更好地控制在特定领域的调校。
简而言之,广泛分布的样本赋予你的模型更多多样性和细腻性。注意过于紧密的样本集会过度限制模型的灵活性。确保你的训练数据具有广泛的多样性,使你的微调模型始终准确命中目标。
微调不应被用作向大型语言模型传递重要知识或记忆的主要手段。它不适合用于存储和检索知识。训练过程仅调整网络的顶层权重。这主要是引导文本模式,而不是编码复杂概念。
像检索增强生成(RAG)这样的技术更适合用于知识功能。RAG允许模型在生成过程中实时从文档中检索并结合外部知识。这提供了比微调所能获得的知识能力更强的知识支持。
相反,最好专注于涉及文本模式的窄且专门的任务上的微调。识别你想要链接的关键输入和输出文本特征。这些可能包括内容、风格、语气、结构、长度等。一次为一个明确的任务进行微调,而不是一次塞入多个目标。微调的目的是专业化,而不是构建万能工具。
此外,使用多样化的训练数据,包括各种边缘情况。现实中的数据往往杂乱无章,因此需要使用各种各样的例子来微调模型。也包括对抗性或损坏的数据样本。如果模型在训练过程中没有见过脏数据,那么在实际部署后的测试中就可能无法很好地处理这些数据。
在整个微调过程中,逐步检查输出以确保正确对齐。采用这种方法,我们能确保微调可以可靠地将输入映射到特定任务所需的输出,从而实现目标。但请注意,强行一次性灌输大量知识可能会带来风险。可以尝试使用其他技术,比如RAG,来实现稳健的知识功能需求。
精细调整需要一个严格的方法来达到预期效果。这里有一些重要的注意事项,请参考。
首先,一次只针对一个具体的任务来微调模型,而不是同时处理多个任务。微调得到的是一个专门的文本生成工具,而不是知识库。保持范围狭窄且明确。可以把微调想象成定制一把厨师刀,而不是瑞士军刀。
其次,密切关注将特定输入映射到期望输出的过程。将微调过程看作是一个将原始文本材料转化为成品文本的流水线。详细描述您希望在输入和输出之间建立联系的文本模式,比如。系统地分析输入和输出双方的内容、风格、语气、结构、格式、长度等方面。模型将学会可靠地将任何输入映射到期望的输出结果。
第三,使用高度多样化的训练数据,涵盖各种边缘情况。改变类型、内容形式、来源和长度,并包含对抗性样本。广泛的多样性可以促使模型泛化整个问题空间,而不仅仅是记住示例。在多样性方面,宁多勿少,因为更多的训练数据可以帮助模型更好地适应实际情况。在实际测试中,输入往往是嘈杂且混乱的,因此通过稳健的训练来准备模型是非常重要的。
第四,记住微调遵循GIGO(垃圾进,垃圾出)原则。仔细整理、筛选和清洗训练数据,让模型能够在各种可能性上实现全面泛化。粗心或局限的数据会导致较差的表现。
第五,也是最后一点,确保你始终包含对抗性样本。你的微调后的模型可能不会直接与客户互动,但它仍然会遇到潜在失败情况或漏洞。考虑不正确的格式或损坏的数据如何影响你的系统。你可能需要通过额外的检查措施来弥补这一点,而不是通过进一步的微调来解决。
通过遵循这些严格的最佳实践,微调过程能够生成高度有效的专门化文本生成模型,符合所需的输入和输出映射。严格遵守这一纪律化的方法是确保微调成功的要点。
您可以在LinkedIn、Upwork或Patreon上Ping我,如果需要调优的帮助。