История о том, как фронтендер YaLM 100B на одной RTX 3070 TI запускал +17


В июне Яндекс опубликовал нейросеть YaLM 100B. Нейросеть умеет генерировать тексты. А это очень мощная вещь, можно попробовать массу всего полезного (и не очень) создать с ее помощью, от сюжетов для книг, игр и приложений, заканчивая рерайтом статей или того хуже, дорвеями.

Эта штука имеет лицензию Apache 2.0. Но чтобы запустить нужно ~ 200GB GPU  видеопамяти!

И еще есть нюанс, проверить нейронку в работе, не так-то просто. Яндекс не предоставили ни демок, ни инструкций, как запустить бюджетно YaLM 100B. Пока все ждут урезанную или онлайн версию, я познакомился с ней поближе. Об этом и лонгрид. 

Спойлер, дальше рассказ пойдёт о том, через что я прошёл и результаты. Исходников не будет.

Почему я в это ввязался? 

  1. Я оставил корпоративную карьеру в этом самом Я, чтобы поиграться в алготрейдинг, торговых роботов и ML. Писал детальнее здесь: https://habr.com/ru/post/672274/

  2. В торгах финансовые прогнозы это все. Пришла мысль, что скажет нейросеть, если ей в контекст задать новость или другие финансовые вводные. 

  3. YaLM 100B это реально крутая работа мирового масштаба, и я просто не могу ждать, пока появится более доступная версия.

  4. А у меня сейчас куча свободного времени и энергии, чтобы разобраться, как бюджетно запустить YaLM 100B простому смертному, не обладающему 200 GB видеопамяти.

  5. Я реально заинтересован ее использовать. Попробовав в облаке, результатом остался доволен. Не идеально, конечно, но сильно зависит от контекста. Примеры выложил на opexflow.com)

Первые шаги 

  • Первым делом я перечитал интернеты, в которых потенциальные пользователи огорчены тем, что нельзя попробовать.

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

  • Подкрепилась моя уверенность и вот этими комментариями

https://github.com/yandex/YaLM-100B/issues/7#issuecomment-1168699780
https://github.com/yandex/YaLM-100B/issues/7#issuecomment-1168699780
https://github.com/yandex/YaLM-100B/issues/19#issuecomment-1179723154
https://github.com/yandex/YaLM-100B/issues/19#issuecomment-1179723154

Просто нужно сделать так, чтобы оно последовательно обрабатывалось на GPU, а хранилось где-либо ещё. Осталось дело за малым. Подключить. 

Как и положено, я посмотрел доки, посмотрел код на питоне, подумал что я фронтендер, у меня лапки и мне с этим не справиться. Потом вспомнил, что я фундаментально обученный магистр системный программист и принялся за дело. 

Две недели боли, слёз и страданий

Первыми делом, докупил NVMe на 1Tb, чтобы было место и развернуть, и выкачать, и сгрузить туда всё во время выполнения. Так говорилось в статье от арбитражников. 

Нахрапом взять и приткнуть код не получилось. Но через время код в YaLM-100B мне стал как родной. От незнания предметной области пришлось обложиться документацией и дебажить по строкам не только его, но и часть библиотек. И сравнивать результат в основном репо, и с моими изменениями.

Это всё было приправлено тем, что всё выполнялось достаточно долго, пока я не нашёл что можно на первом этапе безболезненно выбросить чекпоинты и уменьшить до одного слоя. Благодаря чему всё стало запустаться за минуту, а не за час.

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

Но, изо дня в день у меня что-то получалось. Пару раз хотел бросить, но мне было надо и я не сдавался. Кроме того, по репозиторию были разбросаны напутствия, что всё получится.

Например, в репозитории лежит файл с конфигом zero offload. Который нужен, чтобы запуск модели не падал по памяти, а выгружался в NVMe. Оставалось только понять, куда это приткнуть.

Настал момент, когда я

  • перечитал всю документацию;

  • раздебажил каждую строку;

  • знал не только что в какой переменной лежит, но и то что моя сборка буква в букву совпадает с оригинальным результатом. 

Появилась 100%-я уверенность, что я смогу запустить полную сборку, это лишь вопрос времени. Себе я все доказал и пришло время подключить здравый смысл, а стоит ли продолжать? 

Юзкейс я видел следующий. 

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

Отложив разработку в сторону менеджер вошёл в чат.

  1. Сколько нужно вложить в железо, чтобы выполнялось за адекватное время?

  2. Это должен быть сервер или облако? А на домашнем железе?

  3. Нанять человека с нужными скиллами на эти деньги не дешевле ли?

Понятно было только одно, что на домашнем компе не собрать. Нужно 256 ГБ RAM. На nvme оно будет выполняться вечность. Вкладывать в железо с непонятным результатом мне не подходило. Особенно с учётом того, что есть опция обратиться к человеческому ресурсу.

Прикинув всё это, решил выжать максимум из текущего конфига и продолжить исследования. Докупил 64 Гб RAM, чтобы ускорить запуск и на этом вложения решил прекратить.

Заработало! 

Дальше стало проще. И даже ночные зависания ПК починил. Всего-то надо было прикрутить вентилятор над nvme памятью, которая спряталась под видеокартой.

Как и предполагал, всё получилось. Даже нашёл два решения, одно супер простое из нескольких строк. Но требующее х2 времени и  памяти при старте. Второе сложнее, зато без вот этих неоптимальностей.

Теперь я тоже могу говорить, что добавить zero offload очень просто.

Это "просто" мне стоило:

  1. Время: две недели (на раздебажить с самых низов имея поверхностные знания в python и полное отстутствие знаний про используемые библиотеки).

  2. Деньги: ~ 35к рублей (nvme, ram, cloud).

За это я получил опыт в python, Megatron-LM, deepspeed, zero offload. Ну и само собой радость от выполненной задачи + знания и опыт для новых экспериментов с ML.

Итак, мы находимся в точке, когда можем запустить YaLM 100B на любом ПК, даже домашнем. Но смысла в этом нет, т.к. расчёт идёт по слоям. 

Как я понял, если их порезать и считать только то что в ОЗУ, то будет быстрее. Но когда часть лежит в nvme, пусть даже пару Гб, то расчёт становится вечным. Т.к. nvme не умеет быстро работать с непоследовательными чтениями-записями, скорость падает в лучшем случае до сотен МБ, а в критические моменты вообще до десятков.

Для понимания, простой эксперимент. Берём 1 слой (1 / 80 от всей модели, ~1.2 млрд. параметров), отправляем в GPU без zero offload. Оно считается моментально, за единицу времени. Берём этот же слой, включаем zero offload cpu и всё то же самое считается в 10 раз медленнее, т.к. задействована ОЗУ. А теперь включаем zero offload nvme и всё считается в 100 раз медленнее, т.к. проходит через nvme. Точных значений у меня нет, но порядки примерно такие. Напомню, это идеальные условия, когда всё помещается в память GPU. А теперь представим, что мы пытаемся на nvme запускать полную модель из 100 млрд параметров, когда в память всё не помещается. Это будет оооочень долго. Для сравнения, один текст на одной видеокарте + CPU offload генерируется порядка 20-40 минут. Боюсь представить сколько будет на NVMe, неделя?

  • Тут, кстати, возникает вопрос к статье от арбитражников. Как им удалось? =)

Пока остаётся надеяться на вот это.

https://github.com/yandex/YaLM-100B/issues/3#issuecomment-1164555600
https://github.com/yandex/YaLM-100B/issues/3#issuecomment-1164555600

Вместо выводов:

  1. Все возможно. 

  2. Подробная инструкция по запуску YaLM 100b в облаке на GPU. На CPU ещё нужно доразбираться.

  3. Качество текста можно оценить здесь (как и обещали, чем лучше контекст, тем лучше результат).

  4. Открыт к обратной связи и взаимодействию по проектам.

  5. Если кто-то учится фронту, хочет пообщаться, парнопопрограммировать, покодревьювить и получить адекватный фидбек — велкам.

  6. Поддержать меня можно: донатом на развитие алготрейдинга, начинающих фронтендеров и опенсорса http://sobe.ru/na/S2d2i0i6X1u0

  7.  Лайки и репосты статьи также приветствуются, а ссылка на автора обязательна.




Комментарии (17):

  1. rzerda
    /#24616228 / +3

    Технический вопрос: что это был за NVMe на терабайт, и как его показатели во время нагрузки (хотя бы количество iops, хотя latency тоже неплохо было бы) согласуются с его же спецификацией?

    • nidalee
      /#24617352

      Да практически любой современный SSD по скорости проседает, что на запись, что на чтение. На запись просто более явно.

      Даже топовые, вроде Samsung 980.
      image
      image

      В 2022 SSD без просадок по скорости нужно искать специально. Либо брать что-то старое или вообще б\у серверное.
      Я год назад собрал под кеши нулевой рейд из SATA SSD Samsung не первой свежести, потому что точно знал, что они не проседают.
      У большинства современных дисков сейчас грошевые SLC\MLC-кеши, перегрев и прочие счастливые моменты ради достижения красивых маркетинговых «6000 MB\s* на PCI-E 5!» на дай бог 10 минут.
      Далее цитата:
      Конструкция без DRAM обеспечивает исключительнуое быстродействие, включая головокружительную скорость последовательного чтения / записи до 3500/3000 МБ / с *, что в 6,2 раза превышает скорость твердотельных накопителей с интерфейсом SATA.


      согласуются с его же спецификацией?
      О, очень легко согласуются. Вот из спецификации:
      Sequential and random write performance was measured with Intelligent TurboWrite technology being activated. Intelligent TurboWrite operates only within a specific data transfer size. Performance may vary depending on SSD’s firmware, system hardware & configuration and other factors.
      А дальше хоть в спортлото. Причем в datasheet даже не потрудились воткнуть «up to», я удивлен, если честно. Значит доверия им меньше, чем маркетинговым картинкам на странице продукта.

      • rzerda
        /#24617474

        Samsung 980 не является топовым диском, он же DRAM-less.

        • nidalee
          /#24617500

          Ну как минимум ценовой сегмент у него вполне себе. А на деле…

    • pskucherov
      /#24617370

      Kingston NV1 [SNVS/1000G]. На swap выделен отдельный раздел.

      Максимальная скорость последовательной чтения / записи: 2100 / 1700 Мбайт/сек. В тестах такую скорость показывает, при копировании больших файлов тоже.

      Но вот при генерации текста iostat и близко такие значения не показывает. Завтра поисследую и чуть больше чисел про это напишу.

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

      • nidalee
        /#24617388 / +3

        Максимальная скорость последовательной чтения / записи: 2100 / 1700 Мбайт/сек. В тестах такую скорость показывает, при копировании больших файлов тоже.
        Вы на 15 минут тест запустите.
        image

        И на десерт
        image


        Если окажется, что дело в диске, могу взять что-то поменьше и побыстрее.
        Дело в диске. Перед покупкой гуглите у диска скорость после исчерпания кеша. В идеале этого кеша быть не должно. Ну или хотя бы так (после половины диска скорость все равно больше 1000). Если по деньгам 20,000 за 1ТБ дорого, берите два SATA SSD на 1ТБ (не проседающих по скорости, опять же) и собирайте в RAID0. Те же деньги, 2ТБ, скорость стабильная.
        Хотя для вашего сценария я бы осторожно на SATA смотрел, не уверен, что там по IOPS.

        А иначе рискуете купить что-то, у чего после исчерпания кеша скорость меньше, чем у HDD.

        • pskucherov
          /#24617412 / +2

          Спасибо, обязательно посмотрю и попробую исправить ситуацию.

          • nidalee
            /#24617424

            Сейчас уже задним числом — возможно стоило бы купить под это дело у китайцев джентельменский серверный набор на каком-нибудь 2680v2 и воспользоваться тем фактом, что DDR3 нынче продается практически на развес (у меня в закладках модели на 32ГБ ECC лежат по 3 тысячи за штуку) и собираться там. Вот сходу на 128ГБ RAM и 10 ядер набор — 23 тысячи рублей. По отдельности можно и дешевле.
            Это если расширение объема оперативки бы помогло. NVME можно в PCI-E слот добавить.

            • pskucherov
              /#24617458

              Думал об этом, но побоялся собирать, т.к. в случае неудачи это стало бы мёртвым грузом, неизвестно когда пригодившимся. Теперь хотя бы понятно, что смысл в этом есть.

              • nidalee
                /#24617462

                Всегда можно прицепить пару HDD и закинуть под кровать, будет самосборный NAS.
                Я смотрю у вас там и так 96 гигов, 128 сильно бы изменили ситуацию?

                • pskucherov
                  /#24617470

                  NAS вариант, да

                  По объёму памяти — надо всё что в swap лежит отправить в озу, чтобы к диску обращений не было. В идеале нужно 256 гб памяти. Ну или диск сделать таким же быстрым, как озу.

                  • nidalee
                    /#24617496

                    Да, 256 на DDR3 это уже серверное железо, со всеми вытекающими.
                    А на DDR4 дорого.
                    Тогда посмотрите б\у серверные SSD SATA на каком-нибудь Avito, если нужны IOPS, а не просто скорости чтения\записи. Только как следует покурите гугл предварительно, какие вам подходят, а какие нет.
                    А так лично я достаточно дешево себе 1ТБ урвал с 80% ресурса.

      • rzerda
        /#24617466

        Ох, диск этот значительно превосходит свою спецификацию по случайному вводу-выводу, так как в спецификации про этот самый случайный ввод-вывод решительно ничего нет.

        Я тоже не думаю, что даже Optane (светлая ему, хм, память) прямо на порядки всё ускорит, но если у Вас есть возможность как-нибудь бесплатно на время заиметь SSD, который хотя бы что-нибудь обещает для случайного чтения/записи QD1, то ради науки можно сравнить. Типичные бытовые диски типа популярного Samsung 970 EVO Plus будут обещать 15-20 тысяч iops, серверные SATA за двукратную цену - до 80 тысяч iops, а дальше идут серверные PCIe диски с сотнями тысяч iops, и, хоть и можно купить 1.5 Тбайт всего за 50-60 тысяч рублей, оно того наверняка не стоит.

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

        • pskucherov
          /#24617494

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

  2. SADKO
    /#24616628 / +1

    Не совсем понятно, как это приладить к реальной торговле, хотя лет двадцать тому...
    ...новостные ленты успешно парсились куда более простыми методами, и отрабатывалась задержка реакции мяса, но это было возможно благодаря обучению в ходе которого эта реакция выявлялась... Здесь-же модель обученная писать годные сочинения на тему, и критерии годности у неё иные чуть более чем совсем. Да и параметры то вы сами задаёте, тогда зачем? Получается какая то причинно следственная шляпа. Post hoc, non est propter hoc.

  3. combo_breaker
    /#24617378

    Генерация будет более релевантной, если контекст будет структурно похож на данные, на которых модель обучалась. Если нет возможности посмотреть на исходные данные для обучения, можно погадать. Например - попробовать использовать конкретный формат подачи новостей:
    "Москва. 9 апреля. INTERFAX.RU - ..."
    Или формат РБК: рубрика, дата, время, число просмотров, заголовок материала, краткая выдержка, и только потом основной текст. Ну и в конце спровоцировать на то, что вам нужно - "Акции компании на утренней торговой сессии", "Консенсус-прогноз экспертов" и т.п.

    • pskucherov
      /#24617430 / +1

      Да, всё так. В примерах контекст это случайные фразы на разные темы из интернета. В том числе и абсурдные, которые предложили в комментариях к посту про yalm, как если бы спрашивал тестировщик :)

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