人工智能
微调大型语言模型的完整指南

By
阿尤什·米塔尔
大型语言模型 GPT-4、LaMDA、PaLM 等法学硕士(LLM)凭借其在广泛主题上理解和生成类人文本的卓越能力,席卷了世界。这些模型是在包含来自互联网、书籍和其他来源的数十亿单词的海量数据集上进行预先训练的。
这个预训练阶段为模型注入了有关语言、主题、推理能力甚至训练数据中存在的某些偏差的广泛常识。然而,尽管其范围令人难以置信,这些经过预先培训的法学硕士缺乏针对特定领域或任务的专业知识。
这就是微调的用武之地——调整预先训练的法学硕士以在特定应用程序或用例中表现出色的过程。通过在较小的、特定于任务的数据集上进一步训练模型,我们可以调整其功能以适应该领域的细微差别和要求。
微调类似于将受过高等教育的通才的广泛知识转移到专门从事某一领域的主题专家。在本指南中,我们将探讨微调法学硕士的内容、原因和方法。
什么是微调?
其核心, 微调 涉及采用大型预训练模型,并使用针对您的目标任务或领域定制的数据集的第二训练阶段来更新其参数。这使得模型能够学习并内化特定于该较小区域的细微差别、模式和目标。
虽然预训练可以从庞大且多样化的文本语料库中获取广泛的语言理解,但微调则专门针对一般能力。这类似于将一位文艺复兴时期的人塑造成行业专家。
预训练模型的权重编码其一般知识,用作微调过程的起点或初始化。然后对模型进行进一步训练,但这次是在与最终应用直接相关的示例上进行训练。
通过将模型暴露于这种专门的数据分布并相应地调整模型参数,我们使法学硕士对于目标用例更加准确和有效,同时仍然受益于广泛的预训练功能作为基础。
为什么要微调法学硕士?
您可能想要微调大型语言模型有几个关键原因:
- 域名定制:每个领域,从法律到医学再到软件工程,都有自己细致入微的语言约定、术语和上下文。微调允许您自定义通用模型来理解和生成针对特定领域的文本。
- 任务专业化:法学硕士可以针对各种自然语言处理任务进行微调,例如文本摘要、机器翻译、问答等。这种专业化可以提高目标任务的绩效。
- 数据合规:医疗保健和金融等受到高度监管的行业有严格的数据隐私要求。微调允许对专有组织数据进行法学硕士培训,同时保护敏感信息。
- 有限的标记数据:从头开始获取用于训练模型的大型标记数据集可能具有挑战性。微调可以通过利用预训练模型的功能,从有限的监督示例中实现强大的任务性能。
- 模型更新:随着领域中新数据的不断出现,您可以进一步微调模型以纳入最新的知识和功能。
- 减少偏见:法学硕士可以从广泛的预培训数据中发现社会偏见。对精选数据集进行微调可以帮助减少和纠正这些不良偏差。
从本质上讲,微调弥合了通用、广泛的模型与专门应用程序的重点需求之间的差距。它提高了目标用例的模型输出的准确性、安全性和相关性。
提供的图表概述了专门针对企业应用程序的大型语言模型 (LLM) 的实现和利用过程。最初,像 T5 这样的预训练模型会被输入结构化和非结构化公司数据,这些数据可能采用各种格式,例如 CSV 或 JSON。这些数据经过监督、无监督或传输微调过程,增强了模型与公司特定需求的相关性。
一旦模型根据公司数据进行微调,其权重就会相应更新。然后,经过训练的模型会迭代进一步的训练周期,随着时间的推移,使用新的公司数据不断改进其响应。该过程是迭代和动态的,模型通过学习和再训练来适应不断变化的数据模式。
然后,将经过训练的模型的输出(代表单词的标记和嵌入)部署到各种企业应用程序。这些应用程序的范围从聊天机器人到医疗保健,每个应用程序都需要模型理解并响应行业特定的查询。在金融领域,应用包括欺诈检测和威胁分析;在医疗保健领域,模型可以协助患者询问和诊断。
经过训练的模型随着时间的推移处理和响应新公司数据的能力确保了其效用的持续和增长。因此,企业用户可以通过应用程序与模型进行交互,提出问题并接收反映模型对特定领域数据的训练和微调的明智答复。
该基础设施支持广泛的企业应用程序,展示了法学硕士在业务环境中正确实施和维护时的多功能性和适应性。
微调方法
微调大型语言模型有两种主要策略:
1)全模型微调
在完全微调方法中,预训练模型的所有参数(权重和偏差)都会在第二个训练阶段进行更新。该模型暴露于特定于任务的标记数据集,并且标准训练过程针对该数据分布优化整个模型。
这使得模型能够进行更全面的调整并整体适应目标任务或领域。然而,完全微调有一些缺点:
- 与预训练阶段类似,它需要大量的计算资源和时间来进行训练。
- 存储要求很高,因为您需要为每个任务维护一个单独的、经过微调的模型副本。
- 存在“灾难性遗忘”的风险,即微调会导致模型丢失在预训练期间学到的一些通用功能。
尽管存在这些限制,当资源允许并且目标任务与通用语言显着不同时,完全微调仍然是一种强大且广泛使用的技术。
2)高效的微调方法
为了克服完全微调的计算挑战,研究人员开发了有效的策略,在微调期间仅更新模型参数的一小部分。这些参数高效的技术在专业化和减少资源需求之间取得了平衡。
一些流行的高效微调方法包括:
前缀调整:在这里,引入并训练少量特定于任务的向量或“前缀”,以调节预训练模型对目标任务的注意力。微调期间仅更新这些前缀。
LoRA(低阶适应): 劳拉 在微调期间将可训练的低秩矩阵注入到预训练模型的每一层中。这些小的排名调整有助于使模型专业化,可训练的参数比完全微调少得多。
当然,我可以提供 LoRA(低秩适应)的详细解释以及数学公式和代码示例。 LoRA 是一种流行的参数高效微调 (PEFT) 技术,在大语言模型 (LLM) 适应领域获得了巨大的关注。
什么是LoRA?
LoRA 是一种微调方法,它向预训练的 LLM 引入少量可训练参数,从而能够有效适应下游任务,同时保留大部分原始模型的知识。 LoRA 不是微调 LLM 的所有参数,而是将特定于任务的低秩矩阵注入到模型的层中,从而在微调过程中显着节省计算和内存。
数学公式
LoRA(低秩适应)是一种针对大型语言模型(LLM)的微调方法,它引入了对权重矩阵的低秩更新。对于权重矩阵 0εW0 ∈Rd×k,LoRA添加了一个低秩矩阵 BA, A∈Rr×k 和 B∈Rd×r,其中 r 是军衔。这种方法显着减少了可训练参数的数量,从而能够以最少的计算资源有效地适应下游任务。更新后的权重矩阵由下式给出 W=W0 +B⋅A.
这种低秩更新可以解释为通过添加低秩矩阵$BA$来修改原始权重矩阵$W_{0}$。这个公式的主要优点是,LoRA 只需要优化 $A$ 和 $B 中的 $r \times (d + k)$ 个参数,而不需要更新 $W_{0}$ 中的所有 $d \times k$ 个参数$,显着减少了可训练参数的数量。
这是一个使用 Python 的示例 peft
将 LoRA 应用于预训练的 LLM 进行文本分类的库:
</div> <div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><span class="token" data-darkreader-inline-color="">from</span> transformers <span class="token" data-darkreader-inline-color="">import</span> AutoModelForSequenceClassification </code></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><span class="token" data-darkreader-inline-color="">from</span> peft <span class="token" data-darkreader-inline-color="">import</span> get_peft_model<span class="token" data-darkreader-inline-color="">,</span> LoraConfig<span class="token" data-darkreader-inline-color="">,</span> TaskType </code></div> <div data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><span class="token" data-darkreader-inline-color=""># Load pre-trained model</span> </code></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color="">model <span class="token" data-darkreader-inline-color="">=</span> AutoModelForSequenceClassification<span class="token" data-darkreader-inline-color="">.</span>from_pretrained<span class="token" data-darkreader-inline-color="">(</span><span class="token" data-darkreader-inline-color="">"bert-base-uncased"</span><span class="token" data-darkreader-inline-color="">,</span> num_labels<span class="token" data-darkreader-inline-color="">=</span><span class="token" data-darkreader-inline-color="">2</span><span class="token" data-darkreader-inline-color="">)</span> </code></div> <div data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><span class="token" data-darkreader-inline-color=""># Define LoRA configuration</span> </code></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color="">peft_config <span class="token" data-darkreader-inline-color="">=</span> LoraConfig<span class="token" data-darkreader-inline-color="">(</span>task_type<span class="token" data-darkreader-inline-color="">=</span>TaskType<span class="token" data-darkreader-inline-color="">.</span>SEQ_CLS<span class="token" data-darkreader-inline-color="">, </span>r<span class="token" data-darkreader-inline-color="">=</span><span class="token" data-darkreader-inline-color="">8</span><span class="token" data-darkreader-inline-color="">,</span> <span class="token" data-darkreader-inline-color=""># Rank of the low-rank update</span> lora_alpha<span class="token" data-darkreader-inline-color="">=</span><span class="token" data-darkreader-inline-color="">16</span><span class="token" data-darkreader-inline-color="">,</span></code><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><span class="token" data-darkreader-inline-color=""># Scaling factor for the low-rank update</span> </code></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""> target_modules<span class="token" data-darkreader-inline-color="">=</span><span class="token" data-darkreader-inline-color="">[</span><span class="token" data-darkreader-inline-color="">"q_lin"</span><span class="token" data-darkreader-inline-color="">,</span> <span class="token" data-darkreader-inline-color="">"v_lin"</span><span class="token" data-darkreader-inline-color="">]</span><span class="token" data-darkreader-inline-color="">,</span> <span class="token" data-darkreader-inline-color=""># Apply LoRA to the query and value layers</span> <span class="token" data-darkreader-inline-color="">)</span> </code></div> <div data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><span class="token" data-darkreader-inline-color=""># Create the LoRA-enabled model</span> </code></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color="">model <span class="token" data-darkreader-inline-color="">=</span> get_peft_model<span class="token" data-darkreader-inline-color="">(</span>model<span class="token" data-darkreader-inline-color="">,</span> peft_config<span class="token" data-darkreader-inline-color="">)</span> </code></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><span class="token" data-darkreader-inline-color=""># Fine-tune the model with LoRA</span> </code></div> <div data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><span class="token" data-darkreader-inline-color=""># ... (training code omitted for brevity)</span></code></div> </div> <div data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color="">
在此示例中,我们加载用于序列分类的预训练 BERT 模型并定义 LoRA 配置。这 r
参数指定低秩更新的秩,以及 lora_alpha
是更新的缩放因子。这 target_modules
参数指示模型的哪些层应接收低等级更新。创建支持 LoRA 的模型后,我们可以使用标准训练程序进行微调过程。
适配器层:与 LoRA 类似,但不是低阶更新,而是在预训练模型的每个变压器块中插入薄“适配器”层。仅训练这几个新的紧凑层的参数。
及时调整:这种方法使预训练模型完全冻结。相反,引入可训练的“提示”嵌入作为输入,以激活模型针对目标任务的预先训练的知识。
与完全微调相比,这些高效的方法可以减少高达 100 倍的计算量,同时在许多任务上仍能实现具有竞争力的性能。它们还通过避免完全模型重复来减少存储需求。
然而,对于与通用语言截然不同或需要更全面的专业化的任务,它们的性能可能落后于全面微调。
微调过程
无论微调策略如何,专业化法学硕士的整体流程都遵循一个总体框架:
- 数据集准备:您需要获取或创建一个标记数据集,将输入(提示)映射到目标任务所需的输出。对于摘要等文本生成任务,这将是摘要输出对的输入文本。
- 数据集拆分:遵循最佳实践,将标记的数据集分为训练集、验证集和测试集。这将模型训练、超参数调整和最终评估的数据分开。
- 超参数调整:需要调整学习率、批量大小和训练计划等参数,以便对数据进行最有效的微调。这通常涉及一个小的验证集。
- 模型训练:使用调整后的超参数,在完整训练集上运行微调优化过程,直到模型在验证集上的性能停止改进(提前停止)。
- 评价:评估微调模型在保留测试集上的性能,最好包含目标用例的真实示例,以估计真实世界的功效。
- 部署和监控:一旦令人满意,就可以部署微调模型来推断新输入。随着时间的推移监控其性能和准确性以防止概念漂移至关重要。
虽然这概述了整个过程,但许多细微差别可能会影响特定法学硕士或任务的微调成功。课程学习、多任务微调和少量提示等策略可以进一步提高绩效。
此外,有效的微调方法需要额外的考虑。例如,LoRA 需要通过组合层调节预训练模型输出等技术。提示调整需要精心设计的提示来激活正确的行为。
高级微调:结合人类反馈
虽然使用标记数据集进行标准监督微调是有效的,但一个令人兴奋的前沿是直接使用人类偏好和反馈来训练法学硕士。这种人机交互方法利用强化学习技术:
聚苯醚(近端政策优化):在这里,法学硕士被视为强化学习代理,其输出是“行动”。训练奖励模型来预测这些输出的人类评级或质量分数。然后,PPO 优化 LLM 以生成最大化奖励模型分数的输出。
RLHF(从人类反馈中强化学习):这通过直接将人类反馈纳入学习过程来扩展 PPO。奖励不是固定的奖励模型,而是来自微调期间对法学硕士输出的迭代人类评估。
虽然计算量很大,但这些方法允许根据人类评估的所需特征更精确地塑造法学硕士行为,超出了静态数据集中可以捕获的特征。
像 Anthropic 这样的公司使用 RLHF 来提高他们的语言模型(例如 Claude)的真实性、道德和安全意识,而不仅仅是任务能力。
潜在风险和限制
虽然法学硕士非常强大,但微调也并非没有风险,必须谨慎管理:
偏置放大:如果微调数据包含有关性别、种族、年龄或其他属性的社会偏见,则模型可能会放大这些不良偏见。整理具有代表性和去偏见的数据集至关重要。
事实漂移:即使在对高质量数据进行微调之后,语言模型也可能会“幻觉”出不正确的事实或与较长对话或提示中的训练示例不一致的输出。可能需要事实检索方法。
可扩展性挑战:像 GPT-3 这样的大型模型的全面微调需要大量的计算资源,这对于许多组织来说可能是不可行的。有效的微调可以部分缓解这种情况,但也需要权衡。
灾难性遗忘:在全面微调期间,模型可能会经历灾难性遗忘,失去在预训练期间学到的一些通用功能。可能需要多任务学习。
知识产权和隐私风险:用于微调的专有数据可能会泄漏到公开发布的语言模型输出中,从而带来风险。差异隐私和信息危害缓解技术是活跃的研究领域。
总的来说,虽然微调非常有用,但它是一个微妙的过程,需要关注数据质量、身份考虑、降低风险以及根据用例要求平衡性能与效率之间的权衡。
未来:大规模语言模型定制
展望未来,微调和模型适应技术的进步对于释放跨不同应用程序和领域的大型语言模型的全部潜力至关重要。
更有效的方法可以在资源有限的情况下对 PaLM 等更大的模型进行微调,从而使访问民主化。自动化数据集创建管道和提示工程可以简化专业化。
从没有标签的原始数据中进行微调的自我监督技术可能会开辟新的领域。结合在不同任务或数据上训练的微调子模型的组合方法可以允许按需构建高度定制的模型。
最终,随着法学硕士变得越来越普遍,针对每个可以想象的用例无缝定制和专门化它们的能力将变得至关重要。微调和相关的模型适应策略是实现大型语言模型作为灵活、安全和强大的人工智能助手的愿景的关键步骤,可以增强人类在各个领域和努力中的能力。
在过去的五年里,我一直沉浸在机器学习和深度学习的迷人世界中。 我的热情和专业知识使我为 50 多个不同的软件工程项目做出了贡献,特别关注人工智能/机器学习。 我持续的好奇心也吸引了我对自然语言处理的兴趣,这是我渴望进一步探索的领域。