В продолжение предыдущего поста...
Подумал, что можно довольно дёшево обучать несколько моделей и выбирать среди них лучшую, т.е. обученную с лучшими гиперпараметрами.
На каждом шаге обучения модели можно делать у модели прямой и обратный проход, получать так градиенты, потом копировать их значения в несколько точно таких же обучающихся моделей с чуть другими гиперпараметрами и в каждой модели делать шаг оптимизатора. По окончанию эпохи по метрике на проверочной выборке оставлять только одну лучшую модель. Такие эпохи делать шагов по 10-100, чтобы изменения весов не сильно у моделей разошлись и градиенты от основной модели не стали их ломать веса у остальных моделей. Ну или усреднять веса у основной модели из весов остальных, чтобы можно было побольше шагов сделать, а может даже и всю эпоху...
Подумал, что можно довольно дёшево обучать несколько моделей и выбирать среди них лучшую, т.е. обученную с лучшими гиперпараметрами.
На каждом шаге обучения модели можно делать у модели прямой и обратный проход, получать так градиенты, потом копировать их значения в несколько точно таких же обучающихся моделей с чуть другими гиперпараметрами и в каждой модели делать шаг оптимизатора. По окончанию эпохи по метрике на проверочной выборке оставлять только одну лучшую модель. Такие эпохи делать шагов по 10-100, чтобы изменения весов не сильно у моделей разошлись и градиенты от основной модели не стали их ломать веса у остальных моделей. Ну или усреднять веса у основной модели из весов остальных, чтобы можно было побольше шагов сделать, а может даже и всю эпоху...
Учу многоголовый классификатор с двумя EMA-моделями, как описал тут https://t.me/chivinya/248 . Так вот интересно то, что по одной голове может быть лучше одна EMA-модель, а по другой - другая. Т.е. decay в EMA-модели зависит ещё и от данных, что говорит о том, что автотюнинг этого параметра - не самая худшая идея.
Telegram
Чивиня (Multi-layer Parkinson)
Реализовал свою давнюю идею.
Попробовал при обучении модели создавать две EMA-модели с немного разным decay и после каждой эпохи оставлять лучшую, из неё создавать вторую EMA-модель с чуть большим или чуть меньшим decay в зависимости от того, какая модель…
Попробовал при обучении модели создавать две EMA-модели с немного разным decay и после каждой эпохи оставлять лучшую, из неё создавать вторую EMA-модель с чуть большим или чуть меньшим decay в зависимости от того, какая модель…
Некоторое время мучался с обучением mobilenet v4 . Она крутится во float16 и соответственно учится тоже во float16. И постоянно норовит выйти на пределы точности float16, что весьма правильно, ибо так проходящий через неё сигнал несёт больше информации. Сначала пробовал ограничить значения выходов головы, но начали расти значения выходов других слоёв. В итоге ограничил выходы всех свёрток и линейных слоёв. Обучается жутко медленно, памяти надо вдвое больше, зато можно обучиться дольше и достигать лучшего качества модели... И наверное подобное ограничение можно использовать как ещё одну регуляризацию, которая возможно могла бы приводить к грокингу, например.
Вычитал весьма правильную мысль:
Она изначально писалась для другого, но в целом весьма логична. И используя её можно пробовать разгонять обучение, выбирая в каждую эпоху семплы, которые имеют не большой и не маленький лосс, а где-то посередине...
Оптимальный выбор примеров для обучения
Хорошая мысль — обучать модель на примерах из «зоны её ближайшего развития». Слишком простые примеры не развивают — модель и так хорошо умеет их решать. Слишком сложные — тоже плохо: модель не может извлечь из них стабильный сигнал. Самые ценные — те, где модель уже почти может, но ещё ошибается.
Она изначально писалась для другого, но в целом весьма логична. И используя её можно пробовать разгонять обучение, выбирая в каждую эпоху семплы, которые имеют не большой и не маленький лосс, а где-то посередине...
Доброго дня.
Возникла идея автоматического тюнинга параметра beta2 у оптимизаторов типа Adam. Есть пост про эксперименты с beta2 https://t.me/abstractDL/346 . Также часто обучают EMA-модель параллельно с основной, которая фактически имеет более сглаженные веса относительно основной модели. В комбинации с поиском оптимального коэффициента сглаживания EMA-модели https://t.me/chivinya/248 её то и можно использовать для поиска оптимального beta2. Алгоритм простой: если EMA-модель лучше основной, значит beta2 надо увеличивать (в логарифмическом масштабе), чтобы основная модель имела такие же сглаженные веса как EMA-модель. И наоборот: если обычная модель опережает EMA-модель, значит веса достаточно сглажены и можно пробовать beta2 уменьшать. Конструкция странная и громоздкая конечно, но интересно узнать, какой beta2 в итоге получится. Код примерно такой:
Возникла идея автоматического тюнинга параметра beta2 у оптимизаторов типа Adam. Есть пост про эксперименты с beta2 https://t.me/abstractDL/346 . Также часто обучают EMA-модель параллельно с основной, которая фактически имеет более сглаженные веса относительно основной модели. В комбинации с поиском оптимального коэффициента сглаживания EMA-модели https://t.me/chivinya/248 её то и можно использовать для поиска оптимального beta2. Алгоритм простой: если EMA-модель лучше основной, значит beta2 надо увеличивать (в логарифмическом масштабе), чтобы основная модель имела такие же сглаженные веса как EMA-модель. И наоборот: если обычная модель опережает EMA-модель, значит веса достаточно сглажены и можно пробовать beta2 уменьшать. Конструкция странная и громоздкая конечно, но интересно узнать, какой beta2 в итоге получится. Код примерно такой:
if ema_is_better:
new_beta2 = max(0.7, min(0.999999999999999, math.exp(math.log(beta2) * 0.9)))
else:
new_beta2 = max(0.7, min(0.999999999999999, math.exp(math.log(beta2) / 0.9)))
Telegram
AbstractDL
Gradient Accumulation Is Wasteful
Миф: чем больше батчайз, тем стабильнее и лучше учится LLM. На самом деле всё не так. Авторы этой статьи провели мега-аблейшн по гиперпараметрам претрейна LLM и обнаружили: чем МЕНЬШЕ batch size, тем ШИРЕ диапазон гиперпараметров…
Миф: чем больше батчайз, тем стабильнее и лучше учится LLM. На самом деле всё не так. Авторы этой статьи провели мега-аблейшн по гиперпараметрам претрейна LLM и обнаружили: чем МЕНЬШЕ batch size, тем ШИРЕ диапазон гиперпараметров…
В продолжение прошлого поста...
Выглядит так, что на практике хуже от придуманного не становится. Только обучение идёт возможно дольше. И наверное стоит более агрессивно менять decay для EMA-моделей, чтобы быстрее находить его оптимальное значение в то время, когда сглаживание весов уже теряет смысл.
Выглядит так, что на практике хуже от придуманного не становится. Только обучение идёт возможно дольше. И наверное стоит более агрессивно менять decay для EMA-моделей, чтобы быстрее находить его оптимальное значение в то время, когда сглаживание весов уже теряет смысл.
И стоит ещё поэкспериментировать, возможно LR не имеет смысла уменьшать по мере обучения...
Доброго дня.
Кто пробовал работать с Big Data, наверное сталкивался с проблемой, что посчитать что-то точно по большому объёму данных очень долго. Поэтому часто считают приблизительно, используя семплирование данных. Как, например, делает Clickhouse.
Примерно так же работают и семплирующий профайлер: раз в несколько миллисекунд он записывает, какая строчка кода сейчас выполняется. Хотя мог бы замерять время каждой операции, что было бы точнее и более подробно. Но семплирования на практике вполне достаточно, чтобы понять, что тормозит.
Теперь стандартная проблема в текущем подходе в LLM. Специально пишу "в текущем подходе", ибо очевидно, что он не единственный, а просто сейчас работает достаточно неплохо. Нам хочется контекст 100М и каждый токен с эмбедингом 10000. Т.е. в идеале хочется перемножить вектор размеров в 10^12 на матрицу 10^12х10^12 и получить опять вектор размером 10^12. Это делать долго.
Далее видится, что вместо точного умножения матриц можно делать семплирование их отдельных элементов, которые мы будем перемножать. Тогда описанное выше умножение можно превратить в умножение вектора 10^3 на матрицу 10^3x10^3 . Таких умножений можно сделать несколько. Результаты объединить в вектор размером 10^12, который станет сильно разряженным. И далее вопрос: как выбирать элементы при семплировании, чтобы не растерять информацию во входном сигнале.
@kraidiky решает эту проблему в момент обучения, оставляя в сильно разряженных матрицах только те элементы, которые имеют большие значения веса, умноженного на значение градиента, через него проходящего.
Я предположу, что во входном сигнале много лишней информации и при этом она может менять свою важность, если к исходному сигналу добавить ещё чуть-чуть информации, например, сгенерённый токен, или чем-то обогатить данные, добавив в них какие-то "фичи", как часто делают при работе с табличными данными. Или если изменить её как-то.
Тогда исходную. схему можно трансформировать в такую: выбираем элементы входного вектора, изменяем их и записываем на те же самые позиции, откуда их взяли. Или второй вариант: не записываем в те же позиции, а конкатенируем к уже имеющемуся вектору, увеличивая его размер. На практике можно пробовать сочетать оба подхода. И незакрытым остаётся вопрос поиска подходящих элементов входного вектора.
Как искать элементы входного вектора, которые отправляем на последующую трансформацию? Например так: делим его на кусочки, каждый кусочек пропускаем через быстрое умножение на матрицу размером 10^5х10 , так он уменьшится в 10^4 раза. Делаем это ещё два раза и получаем 10 чисел. Далее в входном векторе ищем элементы, которые ближе всего к одному из этих 10 чисел. Это и будут наши искомые семплы.
В предложенной схеме поиск видимо будет съедать компьюта больше, чем трансформация. Но это не сложно исправить, если ввести понятие "голов", как в трансформере и искать семплы сразу для нескольких голов. Или упростить поиск, заменив матричное умножение, например пулингом и каким-нибудь перемешиванием, чтобы всё не свелось к mean().
Кто пробовал работать с Big Data, наверное сталкивался с проблемой, что посчитать что-то точно по большому объёму данных очень долго. Поэтому часто считают приблизительно, используя семплирование данных. Как, например, делает Clickhouse.
Примерно так же работают и семплирующий профайлер: раз в несколько миллисекунд он записывает, какая строчка кода сейчас выполняется. Хотя мог бы замерять время каждой операции, что было бы точнее и более подробно. Но семплирования на практике вполне достаточно, чтобы понять, что тормозит.
Теперь стандартная проблема в текущем подходе в LLM. Специально пишу "в текущем подходе", ибо очевидно, что он не единственный, а просто сейчас работает достаточно неплохо. Нам хочется контекст 100М и каждый токен с эмбедингом 10000. Т.е. в идеале хочется перемножить вектор размеров в 10^12 на матрицу 10^12х10^12 и получить опять вектор размером 10^12. Это делать долго.
Далее видится, что вместо точного умножения матриц можно делать семплирование их отдельных элементов, которые мы будем перемножать. Тогда описанное выше умножение можно превратить в умножение вектора 10^3 на матрицу 10^3x10^3 . Таких умножений можно сделать несколько. Результаты объединить в вектор размером 10^12, который станет сильно разряженным. И далее вопрос: как выбирать элементы при семплировании, чтобы не растерять информацию во входном сигнале.
@kraidiky решает эту проблему в момент обучения, оставляя в сильно разряженных матрицах только те элементы, которые имеют большие значения веса, умноженного на значение градиента, через него проходящего.
Я предположу, что во входном сигнале много лишней информации и при этом она может менять свою важность, если к исходному сигналу добавить ещё чуть-чуть информации, например, сгенерённый токен, или чем-то обогатить данные, добавив в них какие-то "фичи", как часто делают при работе с табличными данными. Или если изменить её как-то.
Тогда исходную. схему можно трансформировать в такую: выбираем элементы входного вектора, изменяем их и записываем на те же самые позиции, откуда их взяли. Или второй вариант: не записываем в те же позиции, а конкатенируем к уже имеющемуся вектору, увеличивая его размер. На практике можно пробовать сочетать оба подхода. И незакрытым остаётся вопрос поиска подходящих элементов входного вектора.
Как искать элементы входного вектора, которые отправляем на последующую трансформацию? Например так: делим его на кусочки, каждый кусочек пропускаем через быстрое умножение на матрицу размером 10^5х10 , так он уменьшится в 10^4 раза. Делаем это ещё два раза и получаем 10 чисел. Далее в входном векторе ищем элементы, которые ближе всего к одному из этих 10 чисел. Это и будут наши искомые семплы.
В предложенной схеме поиск видимо будет съедать компьюта больше, чем трансформация. Но это не сложно исправить, если ввести понятие "голов", как в трансформере и искать семплы сразу для нескольких голов. Или упростить поиск, заменив матричное умножение, например пулингом и каким-нибудь перемешиванием, чтобы всё не свелось к mean().
👌1
Чивиня (Multi-layer Parkinson)
В продолжение прошлого поста... Выглядит так, что на практике хуже от придуманного не становится. Только обучение идёт возможно дольше. И наверное стоит более агрессивно менять decay для EMA-моделей, чтобы быстрее находить его оптимальное значение в то время…
После пары экспериментов с автотюнингом beta2 оптимизатора оно добралось до космических значениях beta2 вроде 0.99999987 и только там примерно начало колебаться в большую или меньшую стороны. И в этот момент я понял изъян подхода: автотюнинг decay для EMA-моделей перестаёт работать, ибо в принципе сглаживание через EMA-модель перестаёт работать. И к слову этот decay колебался всё время у 0.9995.
Хотя видимо от сложности задачи, датасета и модели зависит. Одной сети сложно обучиться, и decay для EMA-модели автотюнинг загонал к 0.999956 .
Доброго дня.
Была идея, вывести детей на восприятие такого сложного и от того интересного, что не увидишь в "щенячьем патруле".
Но на практике прослушан весь Кир Булычёв, Николай Носов, Постников, Сахарнов, сейчас Владислава Крапивина начали... А "Щенячий патруль" и прочая ерунда с примитивным языком и повторяющимся однообразным сюжетом воспринимается им на ура. 😂😂😂
Хотя, если подумать, изначальная мысль была утопична. Мне и самому иногда хочется посмотреть что-то не сложное.
Была идея, вывести детей на восприятие такого сложного и от того интересного, что не увидишь в "щенячьем патруле".
Но на практике прослушан весь Кир Булычёв, Николай Носов, Постников, Сахарнов, сейчас Владислава Крапивина начали... А "Щенячий патруль" и прочая ерунда с примитивным языком и повторяющимся однообразным сюжетом воспринимается им на ура. 😂😂😂
Хотя, если подумать, изначальная мысль была утопична. Мне и самому иногда хочется посмотреть что-то не сложное.
Практика обучения нейросетей очень помогает понимать процессы, протекающие в детях.
Предположим они сталкиваются с чем-то, что сильно их меняет. Тут важно с одной стороны дать им переварить новый опыт, а с другой - не позволить ему унести их неизвестно куда. А сделать это можно, позволяя им проживать привычное, которое никуда не должно деваться. Как-бы заземляет их.
Всё как в Self Supervised Learning: если перестал показывать старое, то оно забывается и потом приходится ему заново учить.
Предположим они сталкиваются с чем-то, что сильно их меняет. Тут важно с одной стороны дать им переварить новый опыт, а с другой - не позволить ему унести их неизвестно куда. А сделать это можно, позволяя им проживать привычное, которое никуда не должно деваться. Как-бы заземляет их.
Всё как в Self Supervised Learning: если перестал показывать старое, то оно забывается и потом приходится ему заново учить.
Доброго дня.
Как-то @kraidiky писал, что у человека есть автоэнкодеры для каждого органа восприятия.
Я некоторое время экспериментирую со своим собственным восприятием. И попытки изменить воспринимаемое зрением по моим ощущениям приводит и к изменению слышимого. Скажем так, чувствуется, что происходит перестройка или, можно сказать, переобучение нейросети, и видимо поэтому начинают замечаться глюки в восприятии. Например, работая с кубом Неккера можно получить путаницу в том, с какой стороны пришел звук. Это очень непривычно, не понимать, откуда пришел звук и потому хорошо замечается. Потом этот навык восстанавливается.
Я делаю вывод, что автоэнкодер видимо имеет несколько входов от разных органов чувств, но он он один. У меня во всяком случае.
Как-то @kraidiky писал, что у человека есть автоэнкодеры для каждого органа восприятия.
Я некоторое время экспериментирую со своим собственным восприятием. И попытки изменить воспринимаемое зрением по моим ощущениям приводит и к изменению слышимого. Скажем так, чувствуется, что происходит перестройка или, можно сказать, переобучение нейросети, и видимо поэтому начинают замечаться глюки в восприятии. Например, работая с кубом Неккера можно получить путаницу в том, с какой стороны пришел звук. Это очень непривычно, не понимать, откуда пришел звук и потому хорошо замечается. Потом этот навык восстанавливается.
Я делаю вывод, что автоэнкодер видимо имеет несколько входов от разных органов чувств, но он он один. У меня во всяком случае.