Личный копилот тренируйте своего собственного помощника по кодированию
Обучите личного копилота тренируйте своего собственного помощника по кодированию
В постоянно изменяющейся области программирования и разработки программного обеспечения поиск эффективности и продуктивности привел к замечательным инновациям. Одной из таких инноваций является появление моделей генерации кода, таких как Codex, StarCoder и Code Llama. Эти модели проявили замечательные возможности в генерации кодовых фрагментов, похожих на код, проявляя огромный потенциал в качестве помощников по программированию.
Однако, хотя эти ранее обученные модели могут выполнять впечатляющие задачи, есть захватывающая возможность, которая лежит за горизонтом: возможность настроить модель генерации кода под ваши конкретные потребности. Представьте себе персонализированных помощников по программированию, которые могут быть использованы в масштабах предприятия.
В этом блоге мы покажем, как мы создали HugCoder 🤗, уточнили модель LLM кода на основе содержимого кода из общедоступных репозиториев huggingface
GitHub организации. Мы расскажем о нашем рабочем процессе сбора данных, экспериментах с обучением и некоторых интересных результатах. Это позволит вам создать своего собственного помощника по программированию на основе вашей собственной кодовой базы. Мы оставим для вас пару дополнительных расширений этого проекта для экспериментов.
Давайте начнем 🚀
- 14 Захватывающих проектов и тем на Python для начинающих
- Искусственный интеллект и юридическая идентичность
- AskEllyn Bridges поддержку разрыва для пациентов с раком груди через искусственный интеллект
Процесс сбора данных
Наш набор данных является концептуально простым, мы организовали его следующим образом:
Скрапинг содержимого кода с GitHub проще всего сделать с помощью Python GitHub API. Однако, в зависимости от количества репозиториев и количества файлов кода в репозитории, можно легко столкнуться с проблемами ограничений API.
Чтобы избежать таких проблем, мы решили клонировать все общедоступные репозитории локально и извлекать содержимое из них, а не через API. Мы использовали модуль multiprocessing
из Python для параллельной загрузки всех репозиториев, как показано в этом сценарии загрузки.
В репозитории часто могут содержаться файлы, не относящиеся к коду, такие как изображения, презентации и другие ресурсы. Нас не интересует их скрапинг. Мы создали список расширений для их фильтрации. Чтобы разбирать файлы кода не являющиеся блокнотами Jupyter, мы просто использовали кодировку «utf-8». Для блокнотов мы рассматриваем только кодовые ячейки.
Мы также исключили все пути к файлам, которые не имели непосредственного отношения к коду. К ним относятся: .git
, __pycache__
и xcodeproj
.
Чтобы сохранение этого содержимого оставалось относительно дружественным к памяти, мы использовали фрагментацию и формат feather. См. этот сценарий для полной реализации.
Итоговый набор данных доступен на Hub’e, и выглядит так:
Для этого блога мы рассмотрели топ-10 общедоступных репозиториев Hugging Face на основе старгазеров. Вот они:
[‘transformers’, ‘pytorch-image-models’, ‘datasets’, ‘diffusers’, ‘peft’, ‘tokenizers’, ‘accelerate’, ‘text-generation-inference’, ‘chat-ui’, ‘deep-rl-class’]
Вот код, который мы использовали для создания этого набора данных, а вот сам набор данных в Hub. Вот снимок экрана того, как оно выглядит:
Чтобы упростить проект, мы не учитывали удаление дубликатов в наборе данных. Если вас интересуют техники удаления дубликатов для рабочего приложения, эта статья в блоге является отличным ресурсом по этой теме в контексте ЛЛМ-кода.
Настройка индивидуального помощника для работы
В этом разделе мы покажем, как настроить следующие модели: bigcode/starcoder
(15.5B параметров), bigcode/starcoderbase-1b
(1B параметров), Deci/DeciCoder-1b
(1B параметров). Мы будем использовать один Colab Notebook с одной A100 40GB для всех экспериментов, используя 🤗 PEFT (Parameter-Efficient Fine-Tuning). Кроме того, мы покажем, как полностью настроить модель bigcode/starcoder
(15.5B параметров) на машине с 8 A100 80GB GPU, используя интеграцию FSDP от 🤗 Accelerate. Цель обучения – заполнить пропуски в середине, где части обучающей последовательности перемещаются в конец, и предсказывается переупорядоченная последовательность с помощью авторегрессии.
Почему PEFT? Полная настройка требует больших затрат. Вот несколько цифр для понимания:
Минимальный объем памяти GPU, необходимый для полной настройки:
- Вес: 2 байта (обучение смешанной точности)
- Градиент веса: 2 байта
- Состояние оптимизатора при использовании Adam: 4 байта для исходных весов FP32 + 8 байт для оценок первого и второго момента
- Стоимость на параметр с учетом всех перечисленного: 16 байт на параметр
- Модель с 15.5B параметров -> 248GB памяти GPU, даже не учитывая большие требования к памяти для хранения промежуточных активаций -> требуется не менее 4X A100 80GB GPU
Так как требования к аппаратному обеспечению огромны, мы будем использовать параметр-эффективную настройку, используя QLoRA. Вот минимальные требования к памяти GPU для настройки StarCoder с использованием QLoRA:
обучаемые параметры: 110,428,160 || все параметры: 15,627,884,544 || % обучаемых: 0,7066097761926236
- Вес базовой модели: 0.5 байта * 15,51B замороженных параметров = 7.755 GB
- Вес адаптера: 2 байта * 0.11B обучаемых параметров = 0.22 GB
- Градиент веса: 2 байта * 0.11B обучаемых параметров = 0.12 GB
- Состояние оптимизатора при использовании Adam: 4 байта * 0.11B обучаемых параметров * 3 = 1.32 GB
- Суммируя все вышеперечисленное -> 9.51 GB ~10 GB -> необходим 1 A100 40GB GPU 🤯. Причиной выбора A100 40GB GPU является то, что промежуточные активации для длинных последовательностей длиной 2048 и размером пакета 4 для обучения требуют большего объема памяти. Как мы увидим ниже, требуется 26 ГБ памяти GPU, которую можно разместить на A100 40GB GPU. Кроме того, A100 GPU лучше совместим с Flash Attention 2.
В указанных выше расчетах мы не учитывали память, необходимую для промежуточного контроля активации, которая значительна. Мы используем Flash Attention V2 и Gradient Checkpointing, чтобы преодолеть эту проблему.
- Для QLoRA вместе с flash attention V2 и gradient checkpointing общий объем памяти, занимаемый моделью на одном графическом процессоре A100 40GB, составляет 26 GB при размере пакета 4.
- Для полной донастройки с использованием FSDP вместе с Flash Attention V2 и Gradient Checkpointing, память, занимаемая на одном графическом процессоре, составляет от 70 GB до 77.6 GB с размером пакета 1.
Пожалуйста, обратитесь к использованию памяти модели, чтобы легко рассчитать, сколько vRAM необходимо для обучения и выполнения большой модельного вывода на модели, размещенной на 🤗 Hugging Face Hub.
Полная донастройка
Мы рассмотрим, как выполнить полную донастройку bigcode/starcoder
(15B параметров) на 8 графических процессорах A100 80GB с использованием техники PyTorch Fully Sharded Data Parallel (FSDP). Для получения дополнительной информации о FSDP ознакомьтесь с Fine-tuning Llama 2 70B using PyTorch FSDP и Accelerate Large Model Training using PyTorch Fully Sharded Data Parallel.
Ресурсы
- Исходный код: ссылка. Он использует недавно добавленную поддержку Flash Attention V2 в Transformers.
- FSDP-конфигурация: fsdp_config.yaml
- Модель: bigcode/stacoder
- Набор данных: smangrul/hf-stack-v1
- Донастроенная модель: smangrul/peft-lora-starcoder15B-v2-personal-copilot-A100-40GB-colab
Команда для запуска обучения указана в файле run_fsdp.sh.
accelerate launch --config_file "configs/fsdp_config.yaml" train.py \ --model_path "bigcode/starcoder" \ --dataset_name "smangrul/hf-stack-v1" \ --subset "data" \ --data_column "content" \ --split "train" \ --seq_length 2048 \ --max_steps 2000 \ --batch_size 1 \ --gradient_accumulation_steps 2 \ --learning_rate 5e-5 \ --lr_scheduler_type "cosine" \ --weight_decay 0.01 \ --num_warmup_steps 30 \ --eval_freq 100 \ --save_freq 500 \ --log_freq 25 \ --num_workers 4 \ --bf16 \ --no_fp16 \ --output_dir "starcoder-personal-copilot-A100-40GB-colab" \ --fim_rate 0.5 \ --fim_spm_rate 0.5 \ --use_flash_attn
Общее время обучения составило 9 часов. С учетом стоимости $12.00/час на основе lambdalabs для 8 графических процессоров A100 80GB, общая стоимость составит $108.
PEFT
Мы рассмотрим, как использовать QLoRA для точной настройки bigcode/starcoder
(15B параметров) на одном графическом процессоре A100 40GB с помощью 🤗 PEFT. Для получения дополнительной информации о методах QLoRA и PEFT, пожалуйста, обратитесь к статьям Making LLMs even more accessible with bitsandbytes, 4-bit quantization and QLoRA и 🤗 PEFT: Parameter-Efficient Fine-Tuning of Billion-Scale Models on Low-Resource Hardware.
Ресурсы
- Исходный код: ссылка. Он использует недавно добавленную поддержку Flash Attention V2 в Transformers.
- Заметки Colab: ссылка. Убедитесь, что выбрали графический процессор A100 с настройкой высокой оперативной памяти.
- Модель: bigcode/stacoder
- Набор данных: smangrul/hf-stack-v1
- QLoRA Fine-tuned Model: smangrul/peft-lora-starcoder15B-v2-personal-copilot-A100-40GB-colab
Команда для запуска обучения указана в файле run_peft.sh. Общее время обучения составляет 12.5 часов. Рассчитывая стоимость в $1.10/час на основе lambdalabs, общая стоимость составит $13.75. Это довольно неплохо 🚀! С точки зрения стоимости, она на 7.8 раза ниже стоимости полной настройки.
Сравнение
На графике ниже показаны оценочная ошибка, ошибка обучения и планировщик скорости обучения для QLoRA по сравнению с полной настройкой. Мы видим, что полная настройка приводит к немного более низкой ошибке и сходится немного быстрее по сравнению с QLoRA. Скорость обучения для feft fine-tuning в 10 раз выше, чем для полной настройки.
Чтобы убедиться, что наша модель QLoRA не приводит к катастрофическому забыванию, мы запускаем ее на Python Human Eval. Ниже приведены результаты, которые мы получили. Pass@1
измеряет процент успешных завершений, рассматривая только одного кандидата на генерацию кода для каждой проблемы. Мы можем видеть, что производительность на humaneval-python
сравнима между базовой моделью bigcode/starcoder
(15B параметров) и моделью, обученной с помощью PEFT smangrul/peft-lora-starcoder15B-v2-personal-copilot-A100-40GB-colab
.
Теперь давайте рассмотрим некоторые качественные примеры. В ходе нашего анализа мы заметили, что QLoRA приводит к небольшому переобучению, и поэтому мы уменьшаем его вес, создавая новый адаптер взвешенного ввода с весом 0.8 с помощью утилиты add_weighted_adapter
PEFT.
Мы рассмотрим 2 примера дополнения кода, в которых задачей модели является заполнение части, обозначенной заполнителем <FILL_ME>
. Мы будем рассматривать дополнения из GitHub Copilot, QLoRA fine-tuned модели и модели с полной настройкой.
Пример качественного сравнения 1
В приведенном выше примере завершение от GitHub Copilot идет в правильном направлении, но не помогает особо. С другой стороны, завершения от QLoRA и полностью откалиброванных моделей правильно заполняют всю функцию вызова с необходимыми параметрами. Однако они также добавляют намного больше шума после этого. Это можно контролировать с помощью постобработки, чтобы ограничить завершения закрывающими скобками или новыми строками. Обратите внимание, что как QLoRA, так и полностью откалиброванные модели дают результаты с похожим качеством.
Качественный пример 2
Во втором приведенном выше примере GitHub Copilot не дал никакого завершения. Это может быть связано с тем, что 🤗 PEFT является недавней библиотекой и еще не является частью обучающих данных Copilot, что именно тот тип проблемы, который мы пытаемся устранить. С другой стороны, завершения от QLoRA и полностью откалиброванных моделей правильно заполняют всю функцию вызова с необходимыми параметрами. Снова отметим, что как QLoRA, так и полностью откалиброванные модели дает поколения схожего качества. Код вывода с различными примерами для полностью откалиброванной модели и модели peft доступен по адресам Full_Finetuned_StarCoder_Inference.ipynb и PEFT_StarCoder_Inference.ipynb соответственно.
Таким образом, мы можем наблюдать, что поколения из обоих вариантов соответствуют ожиданиям. Замечательно! 🚀
Как использовать это в VS Code?
Вы можете легко настроить индивидуальное автозаполнение кода LLM в VS Code с использованием 🤗 расширения llm-vscode для VS Code, вместе с хостингом модели через 🤗 конечные точки вывода. Мы рассмотрим необходимые шаги ниже. Более подробная информация о развертывании конечной точки доступна в документации по конечным точкам вывода.
Настройка конечной точки вывода
Ниже приведены скриншоты с шагами, которые мы выполнили для создания нашей индивидуальной конечной точки вывода. Мы использовали нашу модель QLoRA, экспортированную в виде полномасштабной объединенной модели, которую можно легко загрузить в transformers
.
Настройка расширения VS Code
Просто следуйте инструкциям по установке. В настройках замените конечную точку в поле ниже, чтобы она указывала на развернутую конечную точку HF Inference.
Использование будет выглядеть следующим образом:
На данный момент модели, которые мы обучили, специально обучены как личные сопровождающие для задач автозаполнения кода. Они не обучены для проведения разговоров или ответов на вопросы. Octocoder
и StarChat
– отличные примеры таких моделей. В этом разделе кратко описано, как добиться этого.
Ресурсы
- Кодовая база: ссылка. Она использует поддержку Flash Attention V2, недавно добавленную в Transformers.
- Заметка Colab: ссылка. Убедитесь, что выбрана GPU A100 с настройкой High RAM.
- Модель: bigcode/stacoderplus
- Набор данных: smangrul/code-chat-assistant-v1. Смесь
LIMA+GUANACO
с правильным форматированием в готовом для обучения формате. - Обученная модель: smangrul/peft-lora-starcoderplus-chat-asst-A100-40GB-colab
Если вы знакомы с моделями Stable Diffusion и LoRAs для создания своих собственных моделей Dreambooth, вам, возможно, знакомы концепции комбинирования различных LoRA с различными весами, использования модели LoRA с базовой моделью, отличной от той, на которой она была обучена. В области текста/кода этот подход остается неисследованным. Мы проводим эксперименты в этой области и обнаруживаем очень многообещающие результаты. Вы готовы? Поехали! 🚀
Комбинирование LoRA
PEFT в настоящее время поддерживает 3 способа комбинирования моделей LoRA: linear
, svd
и cat
. Дополнительные детали см. в разделе tuners#peft.LoraModel.add_weighted_adapter.
Наша записная книжка Dance_of_LoRAs.ipynb содержит весь код вывода и различные комбинации загрузки LoRA, такие как загрузка ассистента чата поверх starcoder
вместо starcodeplus
, на базе которого мы провели донастройку.
Здесь мы рассмотрим 2 навыка (чат/QA
и завершение кода
) на 2 распределениях данных (10 лучших общедоступных HF-кодов
и общий код
). Это дает нам 4 оси, на которых мы выполним некоторые качественные анализы оценки.
Во-первых, рассмотрим задачу чат/QA
.
Если мы отключим адаптеры, мы увидим, что задача не работает для обоих наборов данных, поскольку базовая модель (starcoder
) предназначена только для завершения кода и не подходит для общения/ответа на вопросы
. Включение адаптера copilot
работает так же, как и в случае его отключения, так как этот LoRA также был специально настроен для завершения кода.
А теперь давайте включим адаптер assistant
.
Вопросы и ответы на основе общего кода
Вопросы и ответы на основе HF-кода
Мы можем наблюдать, что общий вопрос, касающийся scrapy
, получает правильный ответ. Однако вопросы о HF-коде, которые не входили в его данные предварительного обучения, не решаются.
Теперь рассмотрим задачу завершения кода
.
При отключении адаптеров мы видим, что завершение кода для общего кода two-sum работает, как и ожидалось. Однако завершение кода для HF-кода не выполняется правильно из-за неправильных параметров LoraConfig
, поскольку базовая модель не видела их в данных предварительного обучения. Включение адаптера assistant
работает так же, как и в случае его отключения, поскольку он обучался на разговорах на естественном языке, которые не содержат репозиториев Hugging Face.
Теперь давайте включим адаптер copilot
.
Мы можем наблюдать, что адаптер copilot
справляется с обоими случаями. Поэтому он работает ожидаемым образом как для автодополнения кода при работе с кодовой базой HF, так и для общих кодовых баз.
Теперь, как пользователь, я хочу объединить функциональность assistant
и copilot
. Это позволит мне использовать его для автодополнения кода при работе в среде разработки и также использовать его как чат-бота для ответов на мои вопросы о API, классах, методах, документации. Он должен быть в состоянии давать ответы на вопросы вроде Как использовать x
, Пожалуйста, напишите фрагмент кода для Y
в моей кодовой базе.
PEFT позволяет это сделать с помощью add_weighted_adapter
. Давайте создадим новый адаптер code_buddy
с равными весами для адаптеров assistant
и copilot
.
Сочетание нескольких адаптеров
Теперь давайте посмотрим, как code_buddy
справляется с задачами chatting/question_answering
.
Мы можем наблюдать, что code_buddy
справляется гораздо лучше, чем отдельные адаптеры assistant
или copilot
! Он способен давать ответы на запросы написать фрагмент кода, чтобы показать, как использовать конкретное API репозитория HF. Однако он также неправильно интерпретирует ссылки/объяснения, что остается открытой проблемой для LLM (языковой модели с ограниченной обратной связью).
Ниже представлены результаты работы code_buddy
для задач автодополнения кода.
Мы можем наблюдать, что code_buddy
работает наравне с copilot
, который был специально дообучен для этой задачи.
Перенос LoRAs на другие базовые модели
Мы также можем перенести модели LoRA на другие базовые модели. Мы возьмем свежую модель Octocoder
и применим к ней нашу обученную модель LoRA с базовой моделью starcoder
. Пожалуйста, ознакомьтесь с этим блокнотом PEFT_Personal_Code_CoPilot_Adapter_Transfer_Octocoder.ipynb для просмотра полного кода.
Производительность в задаче автодополнения кода
Мы можем наблюдать, что octocoder
работает отлично. Он может завершать конкретные фрагменты кода HF. Он также может завершать общие фрагменты кода, как видно в блокноте.
Производительность в задаче чатинга/QA
Поскольку Octocoder обучен отвечать на вопросы и проводить беседы о кодировании, давайте посмотрим, может ли он использовать наш адаптер LoRA для ответа на вопросы, относящиеся к HF.
Ура! Он правильно отвечает на вопрос, как создать LoraConfig
и связанную модель PEFT, правильно используя имя модели, имя набора данных и параметры LoraConfig. При отключении адаптера он не справляется с использованием API LoraConfig
или созданием модели PEFT, что указывает на то, что это не является частью обучающих данных для Octocoder.
После всего этого вы хотите настроить starcoder на вашем кодовой базе и использовать его локально на вашем оборудовании, таком как ноутбуки Mac с графическими процессорами M1, Windows с графическими процессорами RTX 4090/3090… Не волнуйтесь, у нас есть решение.
Мы будем использовать эту супер крутую библиотеку с открытым исходным кодом mlc-llm 🔥. В частности, мы будем использовать эту ветвь pacman100/mlc-llm, в которой внесены изменения для работы с расширением Hugging Face Code Completion для VS Code. На моем ноутбуке Mac с графическим процессором M1 15B-модель работала медленно. Поэтому мы будем работать с маленькими моделями PEFT LoRA и полным запуском bigcode/starcoderbase-1b
. Ссылки на тренировочные блокноты Colab приведены ниже:
- Блокнот Colab для полноценной донастройки и донастройки PEFT LoRA модели
starcoderbase-1b
: link
Внизу показаны графики потерь при тренировке, потерь при оценке и графики изменения скорости обучения:
Теперь мы рассмотрим подробные шаги для локального размещения объединенной модели smangrul/starcoder1B-v2-personal-copilot-merged и использования ее с помощью 🤗 расширения llm-vscode для VS Code.
- Клонируйте репозиторий
git clone --recursive https://github.com/pacman100/mlc-llm.git && cd mlc-llm/
- Установите mlc-ai и mlc-chat (в режиме редактирования):
pip install --pre --force-reinstall mlc-ai-nightly mlc-chat-nightly -f https://mlc.ai/wheelscd pythonpip uninstall mlc-chat-nightlypip install -e "."
- Скомпилируйте модель с помощью:
time python3 -m mlc_llm.build --hf-path smangrul/starcoder1B-v2-personal-copilot-merged --target metal --use-cache=0
- Обновите конфигурацию с следующими значениями в файле
dist/starcoder1B-v2-personal-copilot-merged-q4f16_1/params/mlc-chat-config.json
:
{ "model_lib": "starcoder7B-personal-copilot-merged-q4f16_1", "local_id": "starcoder7B-personal-copilot-merged-q4f16_1", "conv_template": "code_gpt",- "temperature": 0.7,+ "temperature": 0.2,- "repetition_penalty": 1.0, "top_p": 0.95,- "mean_gen_len": 128,+ "mean_gen_len": 64,- "max_gen_len": 512,+ "max_gen_len": 64, "shift_fill_factor": 0.3, "tokenizer_files": [ "tokenizer.json", "merges.txt", "vocab.json" ], "model_category": "gpt_bigcode", "model_name": "starcoder1B-v2-personal-copilot-merged"}
- Запустите локальный сервер:
python -m mlc_chat.rest --model dist/starcoder1B-v2-personal-copilot-merged-q4f16_1/params --lib-path dist/starcoder1B-v2-personal-copilot-merged-q4f16_1/starcoder1B-v2-personal-copilot-merged-q4f16_1-metal.so
- Измените конечную точку расширения HF Code Completion в VS Code, чтобы указывать на локальный сервер:
- Откройте новый файл в VS Code, вставьте приведенный ниже код и установите курсор между кавычками документации, чтобы модель попыталась заполнить документацию:
Готово! ⭐️
Демонстрация в начале этого поста показывает работу этой модели объемом 1 миллиард, выполняющейся локально на моем ноутбуке Mac.
Заключение
В этом блоге мы рассмотрели, как настроить starcoder
, чтобы создать персонального помощника по кодированию, который разбирается в нашем коде. Мы назвали его 🤗 HugCoder, так как обучили его на коде Hugging Face 🙂 После рассмотрения рабочего процесса сбора данных мы сравнили обучение с использованием QLoRA и полное дообучение. Мы также провели эксперименты по комбинированию различных LoRA, что является незаполненной техникой в области текста/кода. Для развертывания мы рассмотрели удаленное выполнение с использованием 🤗 Inference Endpoints, а также показали выполнение на устройстве с использованием модели меньшего размера с помощью VS Code и MLC.
Пожалуйста, дайте нам знать, если вы используете эти методы для своей собственной кодовой базы!
Благодарности
Мы хотели бы поблагодарить Pedro Cuenca, Leandro von Werra, Benjamin Bossan, Sylvain Gugger и Loubna Ben Allal за помощь в написании этого блогпоста.