Pull to refresh
16
-2
Pavel Zloi @efreelancer

Software Developer

Send message

Приветствую! Уточните пожалуйста ошибку, если получится то ссылочкой на Gist, чтобы не писать много текста.

В корне проекта будет файл test_gigasaiga.py, он как-раз демонстрирует то как можно запустить дообученный мною слой LoRA адаптера. У Вас получилось его запустить? Заработало ли?

Покопался в исходных кодах проекта rulm, нашёл в скрипте train одну любопытную незадокументированную переменную окружения WORLD_SIZE, по умолчанию она равна 1, а если сделать больше 1, то включается режим DataParallel.

...

world_size = int(os.environ.get("WORLD_SIZE", 1))
ddp = world_size != 1

...

if ddp:
  device_map = {"": int(os.environ.get("LOCAL_RANK") or 0)}
  gradient_accumulation_steps = trainer_config["gradient_accumulation_steps"]
  gradient_accumulation_steps = gradient_accumulation_steps // world_size
  trainer_config["gradient_accumulation_steps"] = gradient_accumulation_steps

И дальше эти параметры передаются модели.

Пример использования:

WORLD_SIZE=2 python3 -m "src.train" ...

У меня сегодня тоже возникла задача решить проблему с нехваткой памяти (уже правда в рамках обучения другой нейросети), поэтому полез настраивать device_map и max_memory опции, чтобы тренировка, если места мало, могла залезать в системную оперативную память, вот как сделал:

model = model_types[model_type].from_pretrained(
  model_name,
  load_in_8bit=True,
  device_map='auto',
  max_memory={0: f'{int(torch.cuda.mem_get_info()[0] / 1024 ** 3) - 2}GB'},
  torch_dtype=torch_dtype,
  use_flash_attention_2=use_flash_attention_2
)

Попробуйте Mistral дообученную на датасетах rulm (есть демка на HuggingFace).

У Серёжи есть мама Татьяна и папа Денис. И ещё у Серёжи есть брат Иван. Кем Ивану приходится Татьяна?
Иван - сын Татьяны, так как он является братом Серёжи, а мама Серёжи - Татьяна.

Я пошёл в магазин и купил 10 яблок. Два яблока я отдал соседу и два ремонтнику. Потом я купил ещё 5 яблок и одно из них съел. Также я отдал три банана моему брату. Сколько яблок у меня осталось?
Вы купили 10 яблок, отдали два соседу и два ремонтнику, что составляет 4 яблока. Затем вы купили ещё 5 яблок и съели одно из них, что оставляет вам 4-3=1 яблоко. Также вы отдали три банана своему брату, но это не влияет на количество яблок у вас. Осталось вам 1 яблоко.

Приветствую! Рад что публикация пригодилась, я как-раз и хотел чтобы как можно больше людей смогло попробовать дообучить свою версию ruGPT-3.5.

Мельком видел несколько примеров, в которых LoRA слои подключали к модели передавая массив строк (вероятно потом в цикле выполнялся merge_and_unload), но не предал этому значения, однако, после Вашего объяснения до меня дошло, что их похоже подключали "гирляндой".

Идея натренировать множество разных LoRA слоёв и подключать их по надобности в момент инференса мне кажется отличной (хотя я и не совсем уверен в том насколько это эффективный способ, возможно какой-нибудь reload по таймеру будет проще чем при каждом запросе), обязательно попробую этот вариант, технически он выглядит не сложно и таким образом будет очень легко выполнять плавное обновление модели "на лету" или собрать свою модель словно из деталей пазла.

Теперь даже любопытно попробовать обучить ruGPT-3.5 на каждом из 7 датасетов Saiga по отдельности, после чего собрать в кучу, полагаю будет хуже чем "всё и сразу", но если получится примерно на одном и том же уровне, то это будет очень хорошо. Наверняка будет очень важна очерёдность вливания слоёв.

В общем над этой темой надо будет очень основательно подумать, спасибо за наводку.

Насчёт размера контекста, мне попадалось пару любопытных моделей: LLaMA 2 7b 32k (32k токенов), MosaicML 7b и вариации (8к токенов) среди которых самая примечательная была MosaicML 7b-storywriter (65к токенов), возможно ссылочки пригодятся. У меня один из планов попробовать дообучить StoryWriter версию, она как-раз удовлетворяет некоторым моим потребностям связанных с кодингом.

проходит ли он такие тесты?

Попробовал задать модели предложенные вопросы, получилось конечно не очень, но с этим в принципе можно работать, вот тут можно посмотреть Gist с результатами.

На просьбы исправить реагирует не очень адекватно, вероятно в датасетах на которых выполнялось обучение подобного мало.

Не думаете ли о возможности создавать в процессе диалогов материалы для дообучения?

Вот это любопытный момент, как-раз задумываюсь о том как бы это хорошо реализовать, быть может получится хороший датасет собрать, у меня скопилась уже большая пачка диалогов с ChatGPT, их надо бы подчистить да собрать в кучку.

Полагаю многие крупные компании нечто подобное делают со своими продуктами (только само собой у них выборка побольше будет), а для энтузиастов есть к примеру портал ShareGPT, с него полагаю возможно спарсить диалоги после чего выполнить перевод и собрать датасет, подобный подход использовался для Saiga (смотри IlyaGusev/ru_sharegpt_cleaned на HuggingFace).

там даже пары дюжин примеров для годной коррекции поведения может хватать.

С этим дело как-раз и хочется разобраться, пока не совсем понятно возможно ли в принципе корректировать веса как-то на лету (в смысле без переобучения постоянного), например если мне не понравился или наоборот понравился ответ.

Добрый день, рад что статья пригодилась!

То что отображается в консоли не критическая ошибка, а скорее предупреждение, вылезает оно потому что датасеты Saiga (rulm) оптимизированы под модели семейства LLaMA, а у лам размер окна контекста 4096 токенов. В то же время модель ruGPT-3.5 имеет контекст 2048 токенов поэтому на этапе валидации датасета отображается это сообщение.

Но не переживайте, на качество обучения модели это если и повлияет, то на уровне погрешности.

Мне давно хотелось сделать себе просто универсального помощника в виде self-hosted нейросети, доступной через телеграм-бота, которую я бы мог дорабатывать под свои нужды (ещё до релиза ChatGPT-3.5), а получившееся решение может поддерживать осмысленный диалог на правильном русском языке и выполнять многие из поставленных мною задачек (навроде исправления опечаток, создания скелета публикаций по описанию, выполнения простых математических расчетов, брейнсторминга и так далее).

Хотя из-за маленького контекста (всего 2048 токенов) она забывает начало продолжительного диалога, но в пределах 3-5 вопросов-ответов контекст держит приемлемо, однако, судя по тому что рассказывали ребята из Sber AI на Sber SmartDev 2023 скоро будет релиз ruGPT-4, а размер контекста на слайдах был помечен как NDA, то есть, полагаю, он изменится и скорее всего в большую сторону.

Пока что текущее решение умеет далеко не всё, что мне хотелось бы, прежде всего хочется чтобы она стала чуть лучше писать код, для этого нужен датасет и благодаря проекту rulm я теперь знаю как подобные датасеты собирать и могу спокойно заниматься доработкой.

А Вам спасибо за статью, которая меня вдохновила!

Приветствую! Насколько мне известно возможно использовать как несколько видеокарт на одной машине (DataParallel), так и кластер из нескольких машины с видеокартами (DistributedDataParallel).

У меня к сожалению не было возможность попробовать данные режимы для обучения нейросетей так как это для меня хобби и железо покупаю не часто, но я видел множество решений использующих упомянутые выше классы torch. Например ребята из Сбера для обучения моделей используют проект DeepSpeed он задействует упомянутые выше механизмы (если я правильно понял), ещё читал про mpirun.

Мне если честно и самому интересно как обучать сетки на множестве видеокарт (а ещё интереснее как это делать на kubernetes кластере у которого на каждой ноде есть видеокарта), поэтому как у меня появится возможность эти механизмы попробовать постараюсь всё подробно описать.

В публикации я упоминал карточку на HuggingFace с квантованными GGML версиями, там есть q4_0/1. q5_0/1 и q8_0, ну и про load_in_8bit и load_in_4bit через bitsanbytes по ходу дела упомянул. Так что можете смело пользоваться уже хоть сейчас.

Рад бы помочь! Мне просто очень хотелось дообучить именно ruGPT-3.5.

Благодарю за комментарий! Есть ряд моментов из-за которых был выбран именно этот вариант, как Вам скорее всего известно, у RouterOS помимо ARM есть вариант под x86 (имею ввиду 32х битные процессоры). Иными словами, заставить работать в докере через прямую распаковку файловой системы нетривиальная задача, на данный момент она решена при помощи Qemu без режима KVM который можно включить при желании.


А по поводу KVM было сказано в статье, он отключен по умолчанию, так как первые эксперименты показали наличие проблем у людей, которые запускали контейнер на VPS'ках работающих под KVM, потому как KVM in KVM хостеры обычно не включают.


Vagrant хорошая штука, но на большинстве CI систем её обычно нет из коробки (а вот Docker есть), к тому же лично для меня она кажется избыточной надстройкой над qemu (в контексте CI систем разумеется), хотя у меня в Vagrant работает Docker чтобы не захламлять рабочую операционную систему. Ну и задумка была именно в создании Docker контейнера, если бы был выбран Vagrant то этой статьи и проекта бы не было.


Резюмируя, данная статья как раз и была задумана чтобы показать возможность запуска RouterOS в Docker, согласен, что вариант с прямым доступом к файловой системе был бы оптимальным, но за месяцы изысканий у меня до сих пор не получилось его реализовать. И я очень надеюсь что найдётся человек способный подсказать решение, для этого эта статья и была написана.

Благодарю за вопрос! Вариант с ENV и коммитами в репозиторий (меняя при этом версию имеджа) был выбран в основном из-за особенностей работы Autobuild Docker Hub, чтобы затригерить сборку надо запушить коммит или новый тег, а ещё мне хотелось сделать максимально не зависящую от меня сборку (формата добавил в кронтаб и забыл), специально чтобы сразу после появлении новой версии RouterOS на сайте Mikrotik (с небольшим лагом конечно же) собранный имедж появлялся в списке доступных тегов на Docker Hub автоматически.


В принципе можно было бы настроить сборку имеджей у себя локально и через docker push публиковать новые теги или на каком-нибудь стороннем CI, или даже на домашнем Jenkins, но зачем когда есть Docker Hub?


Однако, мне нравится Ваше предложение о добавлении ARG в конфиг, там где указывается версия, это позволит пользователям собирать инстансы локально через --build-arg не загружая какую-то определённую версию из докерхаба. Спасибо за идею!

Добрый день! Благодарю за замечание, заголовок поправил.


В приведённом Вами примере используется Vagrant, что не совсем минималистичное решение как по мне, плюс его тоже необходимо устанавливать в окружение CI, в то время как Docker доступен из коробки.


Travis-CI лишь частный случай, там выполняются тесты библиотеки над которой я работаю в свободное время (в ближайшее время планирую перейти на Scrutinizer-CI), вариант работы через KVM является опциональным и он обычно недоступен на хостинге пользователей проекта, а у некоторых на хостинге есть только Docker сервис и нет возможности установить дополнительный софт.


KVM не задействован не просто потому что я так захотел, а потому что были жалобы людей и отключение его через опции помогло людям настроить виртуальный роутер там где раньше возникали проблемы. (но его всегда можно включить передав соответсвующую команду на этапе запуска контейнера, такая возможность тоже учтена)

Благодарю за критику! Позвольте пойду по попрядку, заголовок соответсвует описанию потому как RouterOS на самом деле удалось заставить работать в Docker и проект на самом деле решает поставленную задачу площадки для выполнения интеграционных тестов, а уж через что запускается операционная система и каким образом функционал становится доступен пользователю — уже не так важно. В первой строчке описания на GitHub сказано, что этот проект создан исключительно для тестов и не рекомендуется для продакшен использования, так как есть намного более удачные решения поставленный задачи и даже они используют идею с виртуальной машиной.


Исходные коды RouterOS закрыты и создать полноценный контейнер (наподобии Alpine или Debian) в данный момент не представляется возможным, как Вы могли заметить проекту два года и конечно же я думал об этом много раз, однако, к сожалению на данный момент этого не удалось достигнуть.


По поводу хлама было сказанно в статье и даже перечисленны моменты, на которые стоит обратить внимание, вроде списка пакетов и генератора конфигурации udhcpd, но к сожалению в сутках слишком мало времени, а других проектов помимо этого более чем достаточно (это не считая работу и подработки), поэтому всё привести в порядок — задача не из простых. И это ещё одна из причин написания статьи, возможно найдутся заинтересованные люди готовые помочь.


По поводу ansible, под пользователями я имел ввиду не коллег по работе (для которых да, можно было бы создать конфиг и мы в дамках), а обычных людей, которые хотят использовать RouterOS для скажем тестирования своих маленьких хобби проектов. Времена хитроумных скриптов на bash для меня прошли уже очень давно, примерно в то же время когда я только начал читать Хабрахабр, с интерпретаторами bash точно такая же проблема как и с qemu, у некоторых CI систем bash может работать иначе, у некоторых будет невозможно поставить bash и придётся учитывать логику под dash/csh/zsh/etc. вставить нужное, Docker же всегда и везде работает одинаково. Да и статья не про ещё один bash скрипт для запуска RouterOS, а про идею воплощения контейнера для решения поставленных задач, если бы разговор был только про bash скрипт то этой статьи бы не было и я бы не пытался привлечь к проблематике Docker контейнера внимание уважаемой аудитории, потому как моя мечта заставить RouterOS работать в Docker полноценно без эмуляции.


Надеюсь мне удалось прояснить непонятные моменты и ещё раз спасибо за критику!

Благодарю за вопрос! На это есть несколько причин:


  • Не факт, что версия qemu установленная на CI через пакетный менеджер будет работать точно так же как версия установленная на моей машине, имею ввиду набор и режим работы ключей, от версии к версии он может меняться. Используя докер контейнер я свожу к минимум потенциальную вероятность возникновения проблем с совместимостью.
  • Большинство CI систем с которыми мне доводилось работать уже имеют предустановленный Docker сервис, что отменяет необходимость ставить что-либо ещё.
  • Пользователей столкнувшихся с Docker и имеющих представление о том как он работает и что нужно для того чтобы запустить приложение (на мой личный взгляд) гораздо больше, чем пользователей умеющих работать с qemu.
  • Спортивный интерес и любопытство.

Помимо этого есть ещё ряд других причин, которые касаются конкретных способов использования, мониторинга, запуска в фоновом режиме нескольких виртуальных роутеров, использование в составе композиции контейнеров (пода), нескольких сетевых адаптеров и так далее.

Information

Rating
Does not participate
Location
Россия
Registered
Activity

Specialization

Backend Developer, ML Engineer
Lead
Linux
PHP
Python
Multiple thread
Neural networks
Machine learning
Kubernetes
Golang
High-loaded systems