Pull to refresh

Comments 27

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

Вот бы еще кто-нибудь сделал квантованные версии, и можно будет пощупать)

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

Возможно ли использовать несколько 4090 для решения вопроса нехватки vram или необходимы тяжёлые карты?

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

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

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

Через deepspeed работает, но прирост скорости не кратен количеству GPU. Для 2х 4090 для разных сеток максимум выжимал +65%

Покопался в исходных кодах проекта 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
)

О, наконец-то кто-то с нормальным железом подтянулся) Автору спасибо за упоминание моей статьи и проделанную работу!

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

Спасибо за хороший обзор!

А как результат-то, порадовал? Моделька стала для чего-то пригодна?

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

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

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

Да, знакомо. Я так Сайгу держу, только вместо Телеги - Обсидиан :)

У меня два вопроса. Один по ruGPT: проходит ли он такие тесты?

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

2) Я пошёл в магазин и купил 10 яблок. Два яблока я отдал соседу и два ремонтнику. Потом я купил ещё 5 яблок и одно из них съел. Также я отдал три банана моему брату. Сколько яблок у меня осталось?

3) Как реагирует на просьбу исправить свои ошибки?

Второй вопрос по развитию идеи персонального ИИ (что мне и самому интересно на предмет рукоделия):

Не думаете ли о возможности создавать в процессе диалогов материалы для дообучения? Т.е., например, по ходу диалога мы маркируем места, где модель ошиблась и приписываем правильный вариант, а где она прямо красавица, там тоже маркируем. Время от времени парсером собираем это в наборы дообучения, дообучиваем и подключаем. Судя по тому, как SD LoRA на лица научивают, там даже пары дюжин примеров для годной коррекции поведения может хватать.

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

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

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

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

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

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

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

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

Огромное спасибо за gist! Да, уровень понятен. Лучше, чем я ожидал.

Сайга 13bQ4 (Илья тренировал поверх Instruct) родство понимает, но ошибается в счёте и стабильно складывает яблоки и бананы. Подкупила тем, что она прямо очень логична и если в чём-то ошибается, то обычно опирается на какую-ньть объективную внутреннюю придурь. И даже иногда её объясняет. И, хотя понятно, что она объяснения генерит с нуля, они всё равно очень консистентны с суждениями.

Llama2 Saiga 13B Q4_K_M
Llama2 Saiga 13B Q4_K_M

Это имеет и drawback - переподумать свои ошибки не желает. Если про что сказала "в морг", значит "в морг" :)

А вот Llama2-chat 13BQ4 решает то и другое. Я подумываю её оттренить датасетом Сайги и на законные 4096 контекста вместо 2048. Пока разбираюсь, чего там с оформлением примеров датасета.

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

Имею в виду, что их тренировать тогда можно будет быстро и, видимо, инкрементально дообучать при расширении конкретного предметного датасета.

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

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

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

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

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

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

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

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

Спасибо!

Занятно - второй ответ, слово в слово перевод ответа Llama2-chat (очень характерный конец :)

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

Проконсультируйте, как ее можно решить?

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

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

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

Спасибо за статью! Все тоже в задумках была идея дообучить ruGPT, но никак времени не мог найти. А тут прям подстягнуло, спасибо!

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

Спасибо за статью и модельку в хабе. Собственно попытался использовать Вашу модель "evilfreelancer/ruGPT-3.5-13B-lora", но столкнулся сначала с нехваткой памяти - поменял load_in_8bit=True на load_in_4bit=True. После этого получил следующую ошибку:

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

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

Спасибо за статью! Вы не пробовали тестить вашу модель против Сайги на каком-нибудь бенчамарке, например, Russian SuperGLUE? Как вообще по ощущениям качество относительно Сайги?

Sign up to leave a comment.

Articles