流程和信息都是每个业务的核心。这一刻的脆弱性和机会是您的业务是否可以使用AI自动化流程,并获得这样做的回报。通用AI Chatgpt睁开了眼睛,对AI可以做什么。现在重要的是将AI的力量引向您的业务问题并解锁您的专有数据的价值。在本文档中,我将向您展示如何。
您不想要可以聊天的AI;您真正想要的是执行工作的自动化,从而使您的业务运行 - 通过业务流程的准确性和规模来推动。将AI自定义为业务流程的验证方法是在数据和希望AI执行的操作上微调LLM。
让我们专门讨论我们将在本文档及其背后的技术中进行的微调。下面列出的是我们将广泛使用的五个工具:
归根结底,您应该从本文档中取出两件事:
我将向您描述一个棘手的现实问题,机器学习研究人员已经做了什么以及我们能够推动使用功能强大的SOTA工具的新边界。我们将在云中的GPU上训练模型。我们还将将强大的MLOP实践付诸实践 - 使用MLFlow来组织我们的实验和参数。在此过程中,我将指出该项目的设计模式,以便您可以为自己的深度学习项目自定义代码库。
让我们从问题背景开始。
寻找适合机器学习和高质量数据集问题的好过程是从浏览基准测试的站点开始。基准为机器学习难度的水平提供了参考框架,我们用来衡量模型开发过程中的进度。一个具有良好基准的特定数据集是服务数据集的不公平条款(不公平的TOS);这是一个有趣的问题声明:使用AI在服务合同方面找到所有不公平条款。背景是,欧洲消费者关于不公平合同的法律确定了不公平的条款和不同类型的不公平条款。不公平的TOS非常适合文本分类的原因是,它是按照欧洲法律所设定的手动标记的。
Chalkidis等。 (2021)将八种不同的机器学习方法应用于不公平的TOS,并获得了从75到83的宏F1,在下面的图1中,我们从它们发布的结果中摘录。
| 方法 | 不公平的 | |
|---|---|---|
| 微F1 | 宏F1 | |
| TFIDF-SVM | 94.7 | 75.0 |
| 伯特 | 95.6 | 81.3 |
| 罗伯塔 | 95.2 | 79.2 |
| Deberta | 95.5 | 80.3 |
| longformer | 95.5 | 80.9 |
| 大鸟 | 95.7 | 81.3 |
| 法律 - 伯特 | 96.0 | 83.0 |
| Caselaw-Bert | 96.0 | 82.3 |
我们可以从此表中推断出的有趣的事情是:
查看数据,班级不平衡当然是存在的,这是上述第一点和第二点的一个很好的理由。
有八种不同类型的不公平条款。该论文的作者为八种类型开发了多标签分类模型,但是我们只是要构建一个将子句归类为公平或不公平的二进制分类模型。
让我们设计一下我们将如何做。
__init__.py揭示了该模块的公共API,因此我们可以方便地缩短以下示例的深层插入功能的导入: from . fine_tune_clsify_head import TransformerModule architectures/__init__.py使代码可以外部architectures导入TransformerModule ,而不必记住面包屑,导致此功能所在的位置,例如:
from architectures import TransformerModule这是项目结构从Lightning_mlflow模块的根中的样子:
.
├── architectures
│ ├── __init__.py
│ └── fine_tune_clsify_head.py
├── config
│ ├── __init__.py
│ └── train_config.py
├── data
│ ├── __init__.py
│ └── lex_glue.py
└── train.py
关键问题是为什么该项目是这样构建的。答案是,在3个子模型和1个入口点之间建立了关注点的分离。让我们依次浏览这些模块中的每个模块:
architectures :本质上指定Pytorch除了数据以外需要知道的一切config :保留所有参数,可以细分为train_config.py和inference_config.py和其他任何内容data :保留所有数据处理逻辑和设置train.py :控制点;这是唯一可以看到architectures , config和data的代码; MLFlow SDK呼叫转到这里借助此简短的介绍,让我们卷起袖子,并尝试真正理解每个模块中的代码。让我们从架构/fine_tune_clsify_head.py开始。该代码的组织方式如下图3。

很明显,该课程中要理解的关键方法是:构造函数,向前通过网络,指标和步骤。我们将依次讨论其中的每一个。让我们从构造函数开始。该代码是该代码的样子:
这里真正至关重要的是,构造函数从拥抱面上加载了概括的模型,并设置了参数有效的微调(PEFT)。 PEFT是微调大语言模型的出血边缘方式,并且是Qlora的拥抱面孔实现,这是三种不同效率策略的组合:量化,低级和适配器。量化是单字节整数具有足够的数值精度,可以在深度学习中进行梯度计算。低等级来自线性代数概念,即矩阵的等级是向量空间的非冗余维度的数量。适配器调整可以理解为通过在许多层中重新装饰一部分权重来调整网络头的一种概括。
让我们看一下forward方法:
当训练神经网络涉及向后求和馈送之间的交替时,这指定了前部部分,值得注意的是, forward的论点是: input_ids , attention_mask和label 。这些是拥抱脸令牌的输出,它们使我们能够将拥抱的脸和Pytorch Lightning绑在一起。
接下来,让我们看一下_compute_metrics方法:
这里有一些值得注意的事情。首先,观察如何从前向功能评估中解开逻辑,然后通过软磁函数转换为概率。反过来,这导致了二进制预测。我们使用预测和实际( batch["label"] )来计算准确性,F1,精度和召回率。
最后,让我们谈谈training_step , validation_step和test_step 。
它们看起来几乎相似,重要的区别是training_step返回outputs["loss"]而不是metrics 。这是有道理的,因为反向推销可以迭代地降低损失。 training_step只是Pytorch Lightning的训练循环的抽象。
好的,现在我们已经完成了architectures ,让我们深入研究config/train_config.py,它看起来像下面的图7。
该代码是不言自明的,但是有一些选择要召集。 pretrained_model _model设置为roberta-base ,如果我们将其更改为支持自动传动器的任何拥抱面部模型名称,则一切都应该可以工作(测试)。发现模型精度对max_length和batch_size最敏感,因此这些是要使用的主要超参数,并且在精度和计算负载之间均进行了折衷。在Azure ML上,我使用了standard_nc24ads_a100_v4实例。 A100 GPU上的VRAM被证明是这两个超参数的限制因素。我发现256是最大的batch_size ,不会导致Cuda丢下不可存储的错误。
由于绝大多数子句在该令牌限制之下,因此确定max_length为128。
最后,正如我们稍后将看到的那样,通过反复试验选择了10的max_epochs作为验证F1度量,我们在MLFlow中跟踪的验证f1度量已在此点之前变平。
好的,让我们谈谈数据。您需要知道的所有内容都在数据/lex_glue.py中的LexGlueDataModule类中,这是其结构:
LexGlueDataModule中有很多细节的细节,但是主要思想是, setup方法直接从拥抱面中获取数据,然后必须发生某种令牌化。该令牌化的详细信息在_shared_transform方法中,这只是_preprocess回调方法的高级接口。
最后,我们已经准备好训练Train.py,这是一切控制的中心点。还记得我们从项目目录结构开始本节时吗?该结构传达了一个重要的消息:依赖关系在目录树中向下解析。换句话说,我们将代码限制为仅调用其他级别或更低级别的代码。这种限制当然不是来自Python。这是自我强加的,为什么?消除猜测。毫无疑问,令人困惑的依赖链是大型代码库中的主要问题。所有这些都意味着train.py将从每个其他模块中导入功能,然后将训练运行设置为运动。让我们看一下它核心的代码:
我们正在实例化Pytorch Lightning Trainer课程,提前停止,并根据机器设置精度,我们通过precision="bf16-mixed" if torch. cuda.is_available() else "32-true" 。我们配置MLFLOW以跟踪所有内容。为了将所有内容整合在一起,我们从我们前面描述的其他三个模块中导入功能:
from architectures . fine_tune_clsify_head import TransformerModule
from config import TrainConfig
from data import LexGlueDataModule核心功能包裹在我们的Pytorch Lightning超类的子类中,因此我们实例化:
model = TransformerModule (
pretrained_model = config . pretrained_model , num_classes = config . num_classes ,
lr = config . lr , )
datamodule = LexGlueDataModule (
pretrained_model = config . pretrained_model , max_length = config . max_length ,
batch_size = config . batch_size , num_workers = config . num_workers ,
debug_mode_sample = config . debug_mode_sample , )最后,我们调用trainer对象的fit和test方法:
trainer . fit ( model = model , datamodule = datamodule )
best_model_path = checkpoint_callback . best_model_path
# Evaluate the last and the best models on the test sample.
trainer . test ( model = model , datamodule = datamodule )
trainer . test (
model = model , datamodule = datamodule , ckpt_path = best_model_path , )我们曾两次打电话给test ,以便根据我们的指标测试最后一个模型和最佳模型。这是Pytorch Lightning带来的丰富功能的完美示例。
这总结了代码演练。现在,让我们研究模型结果。
这是一个仪表板,将所有内容融合在一起:
利用Azure和MLFlow之间的紧密整合,我们的培训运行中的指标已被提供在Azure ML Web控制台中易于消费和可视化。 MLFlow捕获的方式不仅仅是指标,但是更深入地介绍了其全部功能和更广泛的MLOP用例,这是另一天。就目前而言,让我们关注我们的数据可视化向我们揭示的故事。
从左上图中弹出的一件事是,训练毫无疑问改善了验证样本的损失。此外,在125到190步之间,曲线开始变平,这可能是不必要的进一步训练的潜在迹象。但是,以单调的态度,我们看到尚未发生过度拟合,而且,此外,曲线再次从190到210,所以也许我们应该让它再进行5个时代。
有趣的是,右上角的情节讲述了类似的故事。最值得注意的特征是准确性值的高度,而这里的单元是百分比。从一开始就达到90%的线是有意义的,因为数据集在不公平和公平之间的比率下不平衡。这就是为什么首选度量是F1的原因,这就是我们在左下图中显示的内容。
这里的F1曲线展示了经典模式,其中模型起初会迅速改善,但最终达到了回报率的减少。 F1曲线引起的一个有趣的问题是,当一个人建议逐渐变细而另一个人留出进一步的空间时,我们如何调和损失和F1之间?以下理论将破坏这个难题。
我们以离散事件的形式观察世界,但是连续构造(例如概率)通常在数学中更有用。不公平的数据集中的结果被编码为“公平”或“不公平”,并且有一个潜在的概率分布生成这些结果。该潜在概率分布是交叉渗透损失函数可以使用的。因此,在深度学习中,我们对连续度量进行了优化,但是我们通过离散度量来判断我们的模型的良好程度,因为连续(潜在)和离散(观察到的)是彼此的近似值。那就是主意。
因此,当F1暗示一个与损失不同的故事时,只有两个可能的解释:随机性和阶级失衡。的确,这就是为什么准确性和F1比损失更易变的原因。
随机性似乎也可能是对最佳验证F1分数的差距的可能性解释,而测试F1得分为78%(从右下表)。
通过对模型评估指标的播放分析将此部分结束。接下来,动手实践自己的项目。下面的安装指南将帮助您开始修补代码。
步骤1。克隆此存储库中的本地工作目录:
$ git clone https://github.com/zjohn77/lightning-mlflow-hf.git
$ cd lightning-mlflow-hf步骤2。所有项目依赖性都在environment.yml中。下面的说明是针对conda的,但是这些依赖性中没有任何东西阻止了venv或poetry 。
$ conda env create -n lightning-mlflow-hf -f environment.yml步骤3。在训练运行结束时, copy_dir_to_abs函数将将输出复制到Azure Blob存储。如果Azure也是您正在使用的,只需将凭据传递给此功能,您就可以设置了。否则,用自己的工作流程替换。
步骤4。在您的虚拟环境中,您将更改或将IDE指向train.py所在的位置:
$ python train.py如果没有错误,它将打印以安慰一些拥抱的面部消息和许多Pytorch闪电消息。几分钟后,它应该开始打印进度栏。坐着,让它做事。当运行最终完成时,将将最终模型评估指标的ASCII表打印到控制台上。这就是一切!
欢迎任何贡献。我们使用GitHub拉动请求进行代码审核,并使用Black Formatter来确保代码样式的一致性。
单位测试和DOC测试也非常欢迎。
路线图正在进行中。尽快回来。
Ilias Chalkidis,Abhik Jana,Dirk Hartung,Michael Bommarito,Ion Androutsopoulos,Daniel Martin Katz,Nikolaos Aletras。 (2021)。 Lexglue:用英语理解法律语言理解的基准数据集。取自Arxiv:https://arxiv.org/abs/2110.00976