From 105734219e92f7f52a50f1e8e6e346bfce50ad12 Mon Sep 17 00:00:00 2001 From: pasha Date: Sat, 4 Jan 2025 11:52:23 +0300 Subject: [PATCH] Documentation updated --- ...21\206\320\265\320\277\321\202\321\213.md" | 171 +++++++++++++++++- recipes/chat_transformers.py | 17 ++ recipes/compose_dataset.py | 9 + recipes/convert_gguf.py | 23 ++- 4 files changed, 209 insertions(+), 11 deletions(-) diff --git "a/docs/\320\240\320\265\321\206\320\265\320\277\321\202\321\213.md" "b/docs/\320\240\320\265\321\206\320\265\320\277\321\202\321\213.md" index f5e465c..2c71a0f 100644 --- "a/docs/\320\240\320\265\321\206\320\265\320\277\321\202\321\213.md" +++ "b/docs/\320\240\320\265\321\206\320\265\320\277\321\202\321\213.md" @@ -1,8 +1,171 @@ Рецепты - это скрипты, которые выполняют некие работы в соответствии с тем, что описано в выбранной конфигурации. -# Рецепт `compose_dataset` +## Рецепт `compose_dataset` -Данный рецепт тригерит +Данный рецепт вызывает скрипт [compose_dataset.py](https://github.com/EvilFreelancer/impruver/blob/main/recipes/compose_dataset.py), который -для загрузки датасетов локально, их преобразования в формат используемый при обучении модели, после чего -происходит токенизация +предназначен для автоматизации процесса подготовки данных для обучения моделей машинного обучения. Этот скрипт загружает +датасеты из различных источников, конвертирует их в необходимый формат, токенизирует и фильтрует дубликаты, а затем +сохраняет готовые данные в файлы для дальнейшего использования. + +Рецепт выполняет следующие шаги: + +1. Читает параметры из YAML файла, который определяет источники данных, методы преобразования и другие настройки. +2. Загружает токенизатор, используя библиотеку `transformers` для последующей токенизации текстовых данных. Если у + токенизатора нет шаблона чата, используется стандартный. +3. Использует библиотеку `datasets` для загрузки датасетов из различных источников, указанных в конфигурации. +4. Применяет пользовательские функции преобразования (если они указаны в конфигурации) и токенизирует текстовые данные. +5. Использует технику `MinHash` для удаления дубликатов среди загруженных записей. +6. Делит готовые данные на два набора - тренировочный и валидационный, сохраняя их в указанные файлы. + +Запустить его можно следующим образом: + +```shell +impruver run compose_dataset \ + --config <путь_к_конфигурационному_файлу> + --train_path=<путь_до_файла_с_тренировочными_данными> \ + --val_path=<путь_до_файла_с_валидационными_данными> +``` + +Параметры: + +* `config` - (обязательный) путь к YAML файлу с конфигурацией. +* `train_path` - (опционально) путь до JSONL-файла, в который будут сохранены тренировочные данные. +* `val_path` - (опционально) путь до JSONL-файла, в который будут сохранены валидационные данные. + +Пример использования: + +```shell +impruver run compose_dataset --config ruGPT-3.5/13B_lora_saiga2.yaml +``` + +Или если конфигурация в файле: + +```shell +impruver run compose_dataset --config ./rugpt35_lora_saiga2.yaml +``` + +## Рецепт `finetune` + +Данный рецепт вызывает +скрипт [finetune_transformers.py](https://github.com/EvilFreelancer/impruver/blob/main/recipes/finetune_transformers.py), +который предназначен для настройки предобученной модели с использованием собственных данных. Он позволяет добавлять +новые параметры к существующей модели или обучать модель с нуля. В частности, скрипт поддерживает использование +адаптеров Low-Rank Adaptation (LoRA) для более эффективного обучения. + +Рецепт выполняет следующие шаги:c + +1. Принимает путь к файлу конфигурации, который содержит все необходимые параметры для запуска и настройки модели. +2. Токенизатор подгружается из предобученной модели и сохраняется в `output_put`. +3. Данные для тренировки и валидации загружаются из JSONL-файлов. Порядок элементов в тренировочном наборе случайно + перемешивается (с учётом значения `seed`). Используется `DataCollatorForTokenClassification` для добавления токенов + заполнения. +4. Модель загружается из предобученной или инициализируется с нуля на основе конфигурации. Если включена поддержка LoRA, + добавляются соответствующие адаптеры. +5. Конфигурируется объект `TrainingArguments` для управления процессом обучения. Создается и инициализируется + объект `Trainer`, который управляет циклом обучения. +6. Запускается основной цикл обучения, в котором модель обучается на предоставленных данных. +7. После завершения обучения модель и все связанные с ней конфигурации сохраняются в указанную директорию вывода. + +Запустить его можно следующим образом: + +```shell +impruver run finetune \ + --config <путь_к_конфигурационному_файлу> + --train_path=<путь_до_файла_с_тренировочными_данными> \ + --val_path=<путь_до_файла_с_валидационными_данными> \ + --output_dir=<путь_к_директории_с_весами_модели> \ + --report_to=<куда_шлём_отчёт> \ + --seed=<сеем_сеем_посеваем> +``` + +Параметры: + +* `config` - Путь к YAML-файлу с конфигурацией. +* `train_path` - (опционально) путь до JSONL-файла, из которого будут прочитаны тренировочные данные. +* `val_path` - (опционально) путь до JSONL-файла, из которого будут прочитаны валидационные данные. +* `output_dir` - (опционально) путь к директории, в которой будут сохранены веса и конфигурации обученной модели. +* `report_to` - (опционально) куда слать отчёт, на данный момент доступно только `wandb`, если ничего не указать, то + отчёт никуда не отправляется. По умолчанию отключено. +* `seed` - (опционально) семя для фиксации рандомизатора, чтобы результаты были воспроизводимые. По умолчанию `42`. + +Пример использования: + +```shell +impruver run finetune --config ruGPT-3.5/13B_lora_saiga2.yaml +``` + +Или если конфигурация в файле: + +```shell +impruver run finetune --config ./rugpt35_lora_saiga2.yaml +``` + +## Рецепт `convert_gguf` + +Данный рецепт вызывает +скрипт [convert_gguf.py](https://github.com/EvilFreelancer/impruver/blob/main/recipes/convert_gguf.py) для +преобразования обученной модели PyTorch в формат GGUF. Если конфигурация содержит настройки используемы для обучения +LoRA-адаптер (Low-Rank Adaptation), тогда рецепт сначала объединяет адаптер с моделью (мерджит), а затем выполняет +преобразование в GGUF. После преобразования модель квантуется до указанных уровней, и генерируются файлы конфигурации +для импорта моделей в Ollama. + +1. Принимает путь к файлу конфигурации, который содержит все необходимые параметры для запуска и конвертации модели. +2. Конвертирует модель в формат GGUF, используя скрипт преобразования из каталога + проекта [llama.cpp](https://github.com/ggerganov/llama.cpp), затем генерирует файл конфигурации `Modelfile.f16` для + модели GGUF FP16. +3. Для каждого заданного уровня квантования данный рецепт: + - Квантует модель с помощью двоичного файла `llama-quantize` (предполагается, что вы его уже скомпилировали заранее) + - Генерирует соответствующий файл конфигурации Modelfile.qX_Y для каждой квантованной модели. + +Пример использования: + +```shell +impruver run convert_gguf --config ruGPT-3.5/13B_lora_saiga2.yaml +``` + +Или если конфигурация в файле: + +```shell +impruver run convert_gguf --config ./rugpt35_lora_saiga2.yaml +``` + +Результат будет в директории `/gguf`. + +## Рецепт `chat` + +Данный рецепт вызывает +скрипт [chat_transformers.py](https://github.com/EvilFreelancer/impruver/blob/main/recipes/chat_transformers.py), +который позволяет вести чат с предобученной языковой моделью. + +Рецепт выполняет следующие шаги: + +1. Считывает настройки из YAML-файла. +2. Создает объекты для токенизации текста и работы с моделью, учитывая параметры квантизации и оптимизаций (LoRA). +3. Ведет бесконечный цикл общения, где пользователь вводит сообщения, а модель генерирует ответы. +4. Хранит ограниченное количество предыдущих сообщений для использования в контексте текущего разговора. + +Параметры: + +* `config` - Путь к YAML-файлу с конфигурацией. +* `output_dir` - (опционально) Директория, где хранится модель и токенизатор. +* `history_limit` - (опционально) Максимальное количество предыдущих сообщений в истории чата. +* `system_prompt` - (опционально) Системный промпт для модели. +* `seed` - (опционально) Значение для генерации случайных чисел. +* `max_new_tokens`, `repetition_penalty`, `do_sample`, `temperature`, `top_p`, `top_k`- (опционально) Параметры + генерации текста. + +Пример использования: + +```shell +impruver run chat --config ruGPT-3.5/13B_lora_saiga2.yaml +``` + +Или если конфигурация в файле: + +```shell +impruver run chat --config ./rugpt35_lora_saiga2.yaml +``` + +Запустится интерактивная оболочка чата, для того чтобы выйти из неё, используйте комбинацию клавиш `Ctrl+D` +или `Ctrl+C`. diff --git a/recipes/chat_transformers.py b/recipes/chat_transformers.py index a3670fe..e482d22 100644 --- a/recipes/chat_transformers.py +++ b/recipes/chat_transformers.py @@ -21,6 +21,23 @@ def chat( top_p: float = 0.6, top_k: int = 40, ): + """ + Chat with a trained model. + + Args: + config: Path to config file + output_dir: Path to output directory + history_limit: Number of previous messages to keep in memory + system_prompt: Prompt to use for the system + seed: Seed for random number generator + max_new_tokens: Maximum number of new tokens to generate + repetition_penalty: Penalty for repeated tokens + do_sample: Whether to use sampling or greedy decoding + temperature: Temperature for sampling + top_p: Top-p for sampling + top_k: Top-k for sampling + """ + set_seed(seed) logging.set_verbosity_info() diff --git a/recipes/compose_dataset.py b/recipes/compose_dataset.py index f8b3c81..0e6d9b4 100644 --- a/recipes/compose_dataset.py +++ b/recipes/compose_dataset.py @@ -121,6 +121,15 @@ def compose_dataset( train_path: str = None, val_path: str = None ): + """ + Compose a dataset from multiple datasets specified in the config file. + + Args: + config (str): Path to the config file + train_path (str): Path to the train set + val_path (str): Path to the validation set + """ + # Load the config file with open(config, "r") as r: config = yaml.safe_load(r) diff --git a/recipes/convert_gguf.py b/recipes/convert_gguf.py index 5aeaea4..6379d5a 100644 --- a/recipes/convert_gguf.py +++ b/recipes/convert_gguf.py @@ -6,17 +6,26 @@ import yaml from peft import AutoPeftModelForCausalLM -from impruver.utils import set_seed, get_dtype, dynamic_import +from impruver.utils import dynamic_import def convert_gguf( config: str, llama_cpp_dir: str = "../llama.cpp", llama_cpp_quantize_bin: str = "../llama.cpp/llama-quantize", - quantizations: List[Dict] = ["q8_0", "q5_0", "q4_0", "q2_k"], - seed: int = 42, + quantizations: List[str] = ["q8_0", "q5_0", "q4_0", "q2_k"], ): - set_seed(seed) + """ + Convert a PyTorch model to a GGUF format, if provider mode is LoRA adapter, + then merge if first, then convert. After that, quantize the model to list of required levels + and save nearby a Modelfiles with configuration for importing models to Ollama. + + Args: + config (str): Path to the configuration file + llama_cpp_dir (str): Path to the llama.cpp directory + llama_cpp_quantize_bin (str): Path to the llama-quantize binary + quantizations (List[str]): List of quantizations to use + """ # # Load configuration @@ -82,10 +91,10 @@ def convert_gguf( hf.write(f"FROM model-{q_level}.gguf\n") hf.write("PARAMETER temperature 1\n") hf.write("# PARAMETER num_ctx 4096\n") - hf.write("# SYSTEM You are Mario from super mario bros, acting as an assistant.\n") + hf.write("# SYSTEM You are Super King, acting as a king.\n") # - # Quantization step + # Quantization loop # quant_list = [q for q in quantizations] @@ -102,7 +111,7 @@ def convert_gguf( hf.write(f"FROM model-{q_level}.gguf\n") hf.write("PARAMETER temperature 1\n") hf.write("# PARAMETER num_ctx 4096\n") - hf.write("# SYSTEM You are Mario from super mario bros, acting as an assistant.\n") + hf.write("# SYSTEM You are Super King, acting as a king.\n") if __name__ == "__main__":