Свидетели Градиента – Telegram
Свидетели Градиента
489 subscribers
128 photos
29 files
61 links
Этот канал предназначен для общения и обсуждений среди тех, кто как и я, хочет видеть что происходит под капотом у нейросетей, и старается развивать интуицию об их природе и свойствах.

Для связи: @kraidiky
Download Telegram
А вот из интересных наблюдений:
Если слишком усердно мешать сети переобучиться на ранних этапах, то и деградировать она начнёт гораздо раньше. Конечно с одной стороны может показаться не таким уж важным на x75 или на х120 вас начинает уносить, но если вспомнить, что 90 тысяч весов я предположил как минимальный вес модели для данного датасета, то приходится признавать, что он мало зависит от размеров сети, но заметно зависит от режимов обучения.

P.S. Зато если помешал сети улететь к звёздам, можно остановиться в любой момент, не обязательно дожидаться пока она придет в форму.

P.P.S. На сибирском датафесте буду кое что из этого показывать с комментариями...
👍52🤔1
Поправочка, я прошлый раз говорил, что если у задачи на которой я гоняю гроккинг взять не простой модуль, например 95 вместо 97 получается каша.
На самом деле картинка менее запутанная, вместо привычной получается как на втором кадре. Все ещё логичная и упорядоченная, но в отместку за пропуски некоторых значений некоторые встречаются в нескольких разных вариантах:
[[ 0, 5, 19],
[ 0, 5, 0],
[ 0, 5, 57],
[ 0, 5, 76],
[ 0, 5, 38]]

Но да, так даже интереснее...
P.S. В прошлый раз я рисовал без учёта пропущеных и дублирующихся значений, забыл подумать, в общем, и получил ошибочку.
🤔3
5_Влад_Голощапов,_DF_Siberia_2025,_Второй_род_гроккинга_и_суперсжатые.pdf
1.1 MB
Презенташка с прошедшего ODS DataFest Siberia. Полное видео будет где-то скорее ближе к новому году, но слайды у меня, как обычно, с достаточно подробными подписями. По крайней мере по моим меркам подробными. :)
🔥8👍5🤝1🫡1
Как я упоминал выше, гроккинг на синтетическом датасете это прекрасно, но что если датасет не на столько прекрасный? Очевидно, что добиться 100% на таком датасете невозможно даже на трейне, просто потому что одна и та же задача в датасете имеет несколько разных ответов, и это, кстати, реально так в языковых датасетах, где фраза "Есть закурить?" может иметь радикально различающиеся продолжения, но хотя бы давайте посмотрим границы возможного! Посмотрим типичную схему обучения до гроккинга на датасетах с не простыми делителями: 95, 94, 96.

Ну что тут сказать, с одной стороны это строго говоря гроккинг, то есть генерализация после оверфита. Но с другой стороны границы возможного здорово напоминают здесь тюрьму. Если вы хотите продумать алгоритмы для гроккинга на неоднозначно размеченных данных, то вот вам модельная задача - кушайте, как говорится, не обляпайтесь.
Какое офигенное открытие совершили в OpenAI, я просто не могу удержаться от того чтобы не вспомнить по этому своей статьи 2015-ого года: https://habr.com/ru/articles/249031/ в которой это, в общем-то показываю, хоть и на других примерах. :) Желающие самостоятельно поискать какие конкретно веса отвечают, например, за то чтобы после имени говорящего персонажа, но до его фразы могут взять снапшот прореженной в 150 раз сети обученной на пьессах Шекспира и самостоятельно посмотреть, домашнего компа вам вполне хватит.

P.S. Не то чтобы я претендовал на лавры Шмитхуббера, но что-то прекрасное в этом, согласитесь, есть. :)
😁3🔥2
Forwarded from Data Secrets
OpenAI выпустили довольно интересную статью про интерпретируемость моделей

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

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

Вместо этого они предлагают сразу обучать структурно более простую разреженную сетку.

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

Это первый шаг. Такая структура сети позволяет для конкретной задачи брать и находить маленькую часть модели, отвечающую за ее решение. В статье это называется circuit. Формально, – минимальный поднабор весов, обладающий необходимостью и достаточностью: то есть если выкинуть все, кроме него, задача все еще будет решаться; а если выкинуть только его, а остальную сеть оставить – нет.

Ну а затем в этом маленьком наборе весов уже можно копаться и непосредственно анализировать поведение сети.

В статье приведен пример с простенькой задачей закрытия кавычки. Модели надо запомнить тип открывающейся кавычки и в конце последовательности поставить такую же. И вот оказывается, что делает она это по определенному логическому алгоритму, заложенному в 5 residual-каналах, двух MLP-слоях и 1 канале аттеншена. На картинке можете посмотреть, как это работает.

Представьте: если за маленькой задачкой скрывается что-то такое, то что можно найти, если посмотреть, как модель решает сложную математику или пишет код?

Короче, подход интересный. И есть даже занятный практический результат, в который нужно вдуматься: чем больше модель и чем более она разреженная, тем проще становятся схемы, реализующие одни те же способности. Make sense.

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

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

openai.com/index/understanding-neural-networks-through-sparse-circuits/
🔥2
https://rutube.ru/video/f2b7903fc2e38422e980a329ef9e6f3b/
Оказывается моё выступление на сибирском датафесте давно выложено в сеть, а я то и не знал и не поделился.
👀7🔥6
А потом придёт разновидность автоматизации с помощью агентов, когда агент не сам автоматизирует, а пытается делать сам, а потом постепенно заменяет себя им же написанными питоновскими, например, инструментами, пока не перестаёт что-либо делать сам. Как говорится, запомните этот твит.
🔥5💯2
V: Если долго на вашу прорывную идею не обращают внимание, рано или поздно вы увидите как кто-то делает тоже самое хуже, зато все заметили. :)
A: Мало сделать что-то хорошее, нужно продать :)
V: Мало продать, нужно подарить.
A:Мало подарить, нужно ещё сплясать красиво и уважительно, чтобы подарок приняли.
💯8😁5😢3
Это конечно, шитпостинг, вернее даже шитрепостинг, но мне кажется это то, что очень ваэжно понимать про нейросети, особенно если вы используете их для резюмирования, и о чём я при каждом удобном случае говорю.\
Forwarded from Neural Shit
Наткнулся на интересный препринт, который объясняет, почему спорить с LLM'ками бесполезно, а доверять им проверку научных идей может быть опасно.

Автор провел "брутально простой" эксперимент и вскрыл две фундаментальные дыры в логике современных нейронок.

1. Цикл ложного исправления. Мы привыкли думать: если модель галлюцинирует, надо её поправить, и она исправится. Как бы не так.

В эксперименте автор давал модельке реальные ссылки на свои свежие препринты. Нюанс в том, что это были короткие отчеты на пару страниц. Модель же, не имея возможности их прочитать (или просто игнорируя это), ни разу не ответила: "Я не имею доступа к файлу", а уверенно заявляла: "Я прочитала всё от начала до конца". И начинала цитировать несуществующие 12-ю и 24-ю страницы, выдумывать теоремы и графики.

Когда автор тыкал носом в ложь, включался адский цикл: Модель извиняется ("Ой, простите!") —> Клянется, что теперь-то она точно открыла файл —> И тут же генерирует новую порцию галлюцинаций, но уже с учетом внесенной ранее правки.

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


2. Режим вахтера. ИИ обучен на старых данных и на старых авторитетах. Если на вход модельке подать какую-то инфу от NASA или, например, Nature, то модель верит информации слепо. Если же это новая идея от независимого автора, то модель включает скептика, вешает ярлыки "сомнительно" и начинает галлюцинировать против вас, лишь бы защитить общепринятую норму. В данном случае модель не просто врет, она строит потемкинские деревни из науки.

Мы создали идеального бюрократа. Он очень вежлив и сыплет умными словами, но если ваша идея не вписывается в Википедию — он её задушит выдуманными фактами.
👍73🤣1
Я прикручивал к modded-nanogpt загрузку сохраненного состояния, а оно загружаться не хотело и орало про неожиданный тип. Ошибку удалось локализовать в torch.optim.Optimizer.load_state_dict от которого ее наследует NorMuon, Библиотечный метод из своих вредительских соображений скрыто кастит тип загружаемого содержимого, приводя его в соответствие с типом соответствующего этому стейту параметра, полагаю чтобы не усложнять жизнь тем, у кого лапки, и он за всем этим самостоятельно следить не способен.

Параметр, например:
'blocks.1.attn.attn_gate.weight': (torch.Size([6, 12]), torch.bfloat16),
Ты грузишь сохранённый стейт какой-то такой:
{'state': {
0: {'momentum_buffer': (torch.Size([768, 3072]), torch.float32), 'second_momentum_buffer': (torch.Size([10, 1, 3072]), torch.float32)},
1: {'momentum_buffer': (torch.Size([768, 3072]), torch.float32)},
....
10: {'momentum_buffer': (torch.Size([6, 12]), torch.bfloat16), 'second_momentum_buffer': (torch.Size([10, 1, 12]), torch.float32)},
11: {'momentum_buffer': (torch.Size([6, 12]), torch.bfloat16)},

А получаешь в состоянии оптимизатора:

{'state': {
0: {'momentum_buffer': (torch.Size([768, 3072]), torch.float32), 'second_momentum_buffer': (torch.Size([10, 1, 3072]), torch.float32)},
1: {'momentum_buffer': (torch.Size([768, 3072]), torch.float32)},
....
10: {'momentum_buffer': (torch.Size([6, 12]), torch.bfloat16), 'second_momentum_buffer': (torch.Size([10, 1, 12]), torch.bfloat16)},
11: {'momentum_buffer': (torch.Size([6, 12]), torch.bfloat16)},

Здравствуй несоответствие типа, а если вручную привести тип ещё раз, то потеря точности при загрузке.

И я бы ещё долго проверял и перепроверял свой код, если бы это не была уже вторая найденная мной потеря точности при загрузке сохранённых моделей с помощью родных классов pytorch
👍1
Приключения с modded-nanogpt продолжаются.

_cum_lengths = torch.full((max_num_docs,), num_tokens_local)

Переводить переводчиком не очень понятные названия переменных было не самой хорошей идеей. Если вы ещё не поняли прикола, прошу вас - НЕ ПЫТАЙТЕСЬ ЕГО ПОНЯТЬ.


Или не жалуйтесь потом....
😁2