Процессы и информация лежат в основе каждого бизнеса. Уязвимость и возможность этого момента - это вопрос о том, может ли ваш бизнес автоматизировать ваши процессы, используя ИИ, и пожинать вознаграждения за это. Chatgpt, AI общего назначения, открыл наши глаза на то, что ИИ может сделать. Теперь важно направлять власть ИИ на ваши бизнес -проблемы и разблокировать ценность ваших запатентованных данных. В этом документе я покажу вам, как.
Вы не хотите ИИ, который просто может поговорить; То, что вы действительно хотите, это автоматизации, которые выполняют работу, которая поддерживает работу вашего бизнеса-с большой точностью и масштабированием в бизнес-процессах. Проверенный способ настроить ИИ для ваших бизнес -процессов состоит в том, чтобы точно настроить LLM на ваших данных и на действие, которое вы хотите выполнить.
Давайте поговорим специально о прекрасной настройке, которую мы собираемся сделать в этом документе, и о технологии, стоящей за ним. Ниже перечислены пять инструментов, которые мы будем использовать широко:
В конце дня вы должны убрать две вещи из этого документа:
Я собираюсь описать вам сложную, реальную проблему, что уже сделали исследователи машинного обучения, и новую границу, которую мы смогли подтолкнуть к использованию мощных инструментов SOTA. Мы собираемся обучать модели на графических процессоров в облаке. Мы также собираемся ввести в действие мощные практики MLOPS-использовать MlFlow для организации наших экспериментов и параметров. И по пути я собираюсь указать на шаблон проектирования этого проекта, чтобы вы могли настроить кодовую базу для собственных проектов глубокого обучения.
Давайте начнем с проблемы с проблемой.
Хорошим процессом для поиска подходящих проблем для машинного обучения и для качественных наборов данных является начало за счет просмотра сайтов с критериями. Бесчмамы предоставляют основу для уровня сложности проблемы для машинного обучения, которую мы используем для измерения нашего прогресса во время разработки модели. Одним из конкретных наборов данных с хорошо установленными показателями являются несправедливые условия набора данных обслуживания (несправедливости); Вот интригующее заявление о проблеме для этого: используйте ИИ, чтобы найти все несправедливые предложения с точки зрения контрактов на обслуживание. Контекст заключается в том, что европейский закон потребителей на несправедливых контрактах устанавливает, что такое несправедливые оговорки, и различные типы несправедливых положений. То, что делает несправедлив, идеально подходит для текстовой классификации, так это то, что он был вручную помечен в соответствии с тем, что было установлено в европейском законодательстве.
Chalkidis et al. (2021) применили восемь различных методов машинного обучения для несправедливых и полученных макро-F1 в диапазоне от 75 до 83, и на рисунке 1 чуть ниже мы выхищаем из их опубликованных результатов.
| Метод | Несправедливо | |
|---|---|---|
| Micro F1 | Макро F1 | |
| TFIDF-SVM | 94,7 | 75.0 |
| БЕРТ | 95,6 | 81.3 |
| Роберта | 95.2 | 79,2 |
| Деберта | 95,5 | 80.3 |
| Longformer | 95,5 | 80.9 |
| Bigbird | 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 :
Поскольку обучение нейронной сети включает в себя чередование BackProp и подачи вперед, это указывает на прямую часть, и примечательно, что аргументы forward : input_ids , attention_mask и label . Это результаты обнимающегося токенизатора лица, и они позволяют нам связывать обнимающееся лицо и пирожую молнию.
Далее, давайте посмотрим на метод _compute_metrics :
Здесь стоит отметить несколько вещей. Сначала наблюдайте, как логиты распакованы от оценки форвардной функции, а затем преобразуются в вероятности с помощью функции Softmax. Это, в свою очередь, приводит к бинарному прогнозу. Мы используем предсказание и фактическое ( batch["label"] ) для расчета точности, F1, точности и отзыва.
Наконец, давайте поговорим о training_step , validation_step и test_step .
Они выглядят почти одинаково, причем важным отличием является то, что training_step возвращают outputs["loss"] вместо metrics . Это имеет смысл, потому что BackProp итеративно минимизирует потерю; training_step - это просто абстракция Lightning Lightning Lightning.
Хорошо, теперь мы закончили с architectures , давайте погрузимся в config/train_config.py, который выглядит как рисунок 7 ниже.
Этот код является самоэкспланирующей, но есть некоторые варианты вызов. pretrained_model установлена на roberta-base , и если бы мы изменили его на любое название модели обнимающего лица, которое поддерживает AutoTokenizer, все должно работать (протестировано). Было обнаружено, что точность модели наиболее чувствительна к max_length и batch_size , поэтому они являются основными гиперпараметрами, с которыми можно играть, и они оба компромисса между точностью и вычислительной нагрузкой. На Azure ML я использовал экземпляр Standard_nc24ADS_A100_V4. VRAM на графическом процессоре A100 оказался ограничивающим фактором для этих двух гиперпараметров. Я обнаружил, что 256 был самым большим batch_size , который не заставит Cuda достать ошибку вне памяти.
Определение max_length 128 было проще, так как подавляющее большинство пунктов находилось под этим пределом токена.
Наконец, как мы увидим позже, max_epochs 10 был выбран методом проб и ошибок в качестве показателя F1, которую мы отслеживали в MLFLOW к этому моменту.
Хорошо, давайте поговорим о данных. Все, что вам нужно знать, находится в классе LexGlueDataModule в data/lex_glue.py, и это его структура:
В LexGlueDataModule есть довольно много подробных деталей, но основная идея заключается в том, что метод setup извлекает данные непосредственно от обнимающегося лица, а затем должна произойти какая-то токенизация. Детали этой токенизации приводятся в методе _shared_transform , который является лишь интерфейсом высокого уровня для метода обратного вызова _preprocess .
Наконец, мы готовы к Train.py, центральной точке контроля для всего. Помните, когда мы начали этот раздел с структуры каталогов проекта? Эта структура передает важное сообщение: что зависимости решаются вниз в дереве каталогов. Другими словами, мы ограничили код только для вызова других кодов, который находится на том же уровне или ниже. Это ограничение, безусловно, не происходит от Python; Это добровольно, и почему? Устранить догадки. Нет сомнений в том, что запутанные цепочки зависимости являются основной проблемой в крупных кодовых базах. Все это означает, что train.py собирается импортировать функциональность из каждого из других модулей, а затем приведет к движению тренировочного запуска. Давайте посмотрим на кусок кода в основе этого:
Мы создаем инстанции класса тренера Pytorch Lightning, включаем раннюю остановку и устанавливаем точность на основе машины, на которой мы находимся через 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Основные функции обернуты в наши подклассы Superclasses 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 , ) И, наконец, мы вызываем методы fit и test объекта trainer :
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 , чтобы мы проверяли как последнюю модель в времени остановки, так и лучшую модель в соответствии с нашей метрикой. Это прекрасный пример богатой функциональности, которая поставляется с питорной молнией.
И это завершает прохождение кода. Теперь давайте погрузимся в результаты модели.
Вот приборная панель, которая соединяет все вместе:
Воспользовавшись жесткой интеграцией между Azure и Mlflow, показатели нашего обучения были доступны для легкого потребления и визуализации в веб -консоли Azure ML. Mlflow запечатлел гораздо больше, чем просто метрики, но углубляясь в полную функциональность, а более широкие случаи использования MLOP - на другой день. На данный момент давайте сосредоточимся на истории, которую наша визуализация данных раскрывает нам.
Одна вещь, которая выскакивает из верхней левой диаграммы, заключается в том, что обучение, несомненно, улучшило потерю на выборке валидации. Кроме того, между 125 и 190 этапами кривая начинает сглаживать, потенциально указывает на то, что дальнейшее обучение может быть ненужным. Но, будучи монотонными, мы видим, что переосмысление еще не произошло, и, более того, кривая снова затянулась с 190 по 210, поэтому, возможно, мы должны были позволить ей бежать в течение еще 5 эпох.
Верхний правый сюжет, что интересно, рассказывает похожую историю. Наиболее заметной характеристикой является то, насколько высоки значения точности, а единица здесь процент. То, что линии достигают 90% с самого начала, имеет смысл, потому что набор данных не сбалансирован в соотношении 1: 9 между несправедливыми и справедливыми. Именно поэтому предпочтительной метрикой является F1, что мы отображаем на нижнем левом графике.
Кривые F1 здесь демонстрируют классический шаблон, где модель быстро улучшается, но в конечном итоге достигает точки уменьшения возврата. Интересный вопрос, вызванный кривыми F1, заключается в том, как мы согласовываемся между потерей и F1, когда один предлагает сужать, а другой оставляет место для дальнейшего продвижения? Следующая теория будет взломать эту загадку.
Мы наблюдаем мир в форме дискретных событий, но непрерывные конструкции (например, вероятность) часто более полезны в математике. Результаты в наборе данных «Несверно-тот» закодированы как «справедливые» или «несправедливые», и есть скрытое распределение вероятностей, которое вызвало эти результаты. Это скрытое распределение вероятностей-это то, с чем может работать функция потерь поперечной энтропии. Таким образом, в глубоком обучении мы оптимизируем для непрерывной метрики, но мы судим, насколько хороша наша модель по дискретной метрике, потому что непрерывная (скрытая) и дискретная (наблюдаемая) является приближением друг друга. Это идея.
Поэтому, когда F1 намекает на другую историю, кроме потери, есть только два возможных объяснения: случайность и дисбаланс класса. Действительно, именно поэтому точность и F1 гораздо более волатильны, чем потери.
Случайность также, по -видимому, является вероятным объяснением разрыва между лучшей проверкой F1 -баллом 70% и баллом F1 Test 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 также является тем, что вы используете, просто передайте учетные данные этой функции, и все готово. В противном случае, замените своим собственным рабочим процессом.
Шаг 4. В вашей виртуальной среде вы переключитесь на или указате свою IDE, где находится train.py и запустите:
$ python train.pyЕсли нет ошибок, он будет печатать, чтобы утешить некоторые сообщения об объятиях лица и много сообщений о молнии Pytorch. Через несколько минут он должен начать печать панели прогресса. Сядьте и дайте ему делать свое дело. Когда пробег наконец завершится, таблица ASCII, обобщающая метрики оценки для окончательной модели, будет напечатана в консоли. Это все, что нужно!
Любой вклад приветствуется. Мы используем запросы на вытягивание GitHub для проверки кода, и мы используем форматер Black для обеспечения согласованности стиля кода.
Модульные тесты и DOC -тесты также очень приветствуются.
Дорожная карта находится в стадии разработки. Зайдите в ближайшее время.
Илиас Чалкидис, Абхик Яна, Дирк Хартунг, Майкл Боммарито, Ион Андруутсопулос, Даниэль Мартин Кац, Николаос Алетрас. (2021). Lexglue: контрольный набор данных для юридического понимания языка на английском языке . Получено из Arxiv: https://arxiv.org/abs/2110.00976