Обновить
62
Василий Писарев@Pand5461

Пользователь

15
Подписчики
Отправить сообщение

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

С одной стороны да, поскольку так уже было с выходом Python 3 - что-то так до сих пор и работает на Python 2, потому что переписать дороже, чем поддерживать. С другой стороны, если вдруг весь FAANG начнёт от питона избавляться, остальные тоже, скорее всего, будут смотреть в ту же сторону.

В языке, кроме синтаксиса, есть и семантика. Язык определяет, что программа знает о данных, с которыми работает, и какие преобразования допустимо делать. В Python программа довольно мало знает о данных и мало что имеет право делать в плане “срезания углов”. Видя, например, запись a + b, компилятор C++ имеет право ругнуться, если обнаруживает, что для типов переменных a и b не определён operator+. Python же не знает, что там за типы. Не знает, определено для них суммирование как встроенная функция, или нужно будет вызвать a.__add__(b), или b.__radd__(a). Более того, в Python объекты одного и того же типа не обязаны иметь одинаковые атрибуты. По сути, объект - это словарь, из которого по имени достаются атрибуты. Поэтому на любой чих там поиск по хэш-таблице, несколько переходов по указателям и динамический диспатч. Сгенерировать эффективный машинный код заранее не представляется возможным. Если убрать такой беспредельный динамизм - получится что-то типа Julia, где, действительно, всё компилируется +/- в такой же код, что и в Си. Но, как заметил автор, там пока что не просматривается надежда на помощь крупных корпораций в создании ИИ-стека, поэтому там возможности очень неоднородные, может всё работать идеально и быстро, а можно оказаться перед необходимостью с нуля писать движок. Отдельно надо сказать, что когда появлялся Python, компиляторы не очень умели автоматически выводить типы, когда они явно не указаны. Поэтому вопрос пригодности скриптового языка для компиляции в принципе на повестке не стоял - всё, что без явной типизации, рассматривалось как неизбежно медленное.

Если удобно прототипировать на питоне, то можно солвер перенести на Julia. По опыту, пока не лезешь в совсем низкоуровневые оптимизации типа SIMD производительность будет на уровне 90% от плюсов.

А assert (и вообще выбрасывание исключений) не считается препятствием для разыменовывания, получается?

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

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

То, о чём вы говорите, - это в стандарте имеет отдельные названия неуточнённое поведение (unspecified behavior) и поведение, определяемое реализацией (implementation-defined behavior). К этим вещам обычно претензий не возникает.

Предложение хорошее, но поезд компиляторостроения, похоже, слишком далеко уже ушёл.

Вот именно для случая с целыми, что вы описали, недавно была статья: https://habr.com/ru/companies/pvs-studio/articles/276657/

С учётом UB при переполнении знаковых целых компилятор имеет полное право для операций с короткими целыми использовать полноширинные регистры, поэтому +32767 + 1 может быть по факту +32768, потому что под капотом операция выполнилась в 32 или 64 битах. И, если судить по вышеуказанной статье, такое поведение компиляторов можно на деле встретить.

На 24 ГБ RAM + VRAM? Если бы RAM хватало, то там можно было бы 15-35 ток/с ожидать. А тут модель в Q4 (18-20 ГБ) едва влазит, браузер запустил - и уже часть весов будет на диск сгружаться. Я так пробовал на 8 + 64 ГБ запустить 60 ГБ модель, очень медленно. На 16+64 ГБ уже остается запас RAM, 10 ток/с даёт стабильно.

В теории, возможно, но скорость будет упираться в SSD. Скорее всего, 2-5 ток/с. Смотрите флаги -cmoe и --mmap.

Есть ещё синхронная параллельность в виде SIMD и ILP, например. Или стрельба через винт как механическая аналогия.

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

Смешно. А что тогда в фортране 1e37 / 1e38 = 0?

https://fortran-lang.discourse.group/t/ifort-ifort-2021-8-0-1-0e-37-1-0e-38-0/4936?u=zaikunzhang

Ах да, ieee - это для педантов, а ФОРТРАН - ЭТО СКОРОСТЬ!!1 Если нужна правильная арифметика, так указывайте флагом компилятора, что нужно правильно, а не быстро.

На llama.cpp запустится, но нужно самостоятельно скомпилировать его. Но скорость будет низкая с 31b, т.к. плотная модель. 35b-a3b или 26b-a4b будет норм работать, около 20ток/с генерация у меня с rtx 4060, если тензоры экспертов сгружать на cpu.

У меня почти не прошёл, но в последнем предложении сделал ремарку.

Walk.

At 50 meters (about 164 feet), it will take you roughly 30–45 seconds on foot. Driving would actually take longer just to start the engine, maneuver out of parking, and park again at the car wash. It’s also unnecessary fuel consumption, added wear on your car, and overkill for such a short distance.

One quick clarification: If you need to bring the car to the wash, you’ll obviously have to drive it. But if you’re just heading over to check in, pay, grab supplies, or see if there’s a line, walking is the fastest, simplest choice.

А 122b-a10b не работает с экспертами в RAM? Должна быть чуток поумнее с такой же примерно скоростью, если RAM хватает.

Ну, можно всё упростить. Если p - это перестановка, то r = argsort(p) - это обратная к ней перестановка, то есть p[r] == arange(len(p)). То есть x[p[r]] == x, если длины x и p совпадают. Далее можно заметить, что x[p] - это умножение на перестановочную матрицу P: x[p] == P @ x. То есть x[p[r]] == (R @ P) @ x. Из ассоциативности матричного умножения x == (R @ P) @ x == R @ (P @ x), т.е. x == (x[p])[r]. Т.е. r - это массив индексов элементов исходного массива в отсортированном, ЧТД.

Видимо, непонятно написал - имеется в виду, что -O3 и -Ofast не отличаются по производительности.
В Julia ещё проверял, там есть эффект в 10-15% от отключения проверок границ массива (fastmath, как и в Си, на скорость не повлиял). Если для numba есть такой флажок, то он, скорее всего, тоже с 200 до 170 мс время скинет.

Намеряны какие-то очень не те времена. У меня получается с numpy примерно 20 секунд на 10М уравнений, с numba примерно 200 мс, на Си с -Ofast и -O3 130 мс (AMD Ryzen 5 3500U). И объяснений, почему вдруг Numba быстрее Си, уже не требуется.

А я вот так и узнал, что в LAPACK алгоритм чуть сложнее стандартной прогонки, как в первой ссылке - обнаружил, что своя реализация по учебнику быстрее библиотечной процентов на 10-20. Но в реальных задачах часто гарантируется, например, диагональное преобладание - а этого достаточно для устойчивости даже без выбора главного элемента.
С параллелизмом есть вопросы. Не так часто возникают задачи, где в основе будет гигантская трёхдиагональная система. По ссылке, впрочем, говорится также про оптимизированный солвер для большого числа трёхдиагональных систем, это как раз реально.

или уж действительно выжимать все соки из своей имплементации (например, не аллоцировать рабочие массивы каждый раз, как в статье)

Тут полностью согласен. В Julia тут была бы стандартная идиома - функция thomas_solver!(rhp, ld, d, ud), которая перезаписывает d и ud, а в rhp записывает решение, и thomas_solver(rhp, ld, d, ud), которая создаёт временные массивы и с ними запускает предыдущую.

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

1
23 ...

Информация

В рейтинге
5 324-й
Откуда
Москва, Москва и Московская обл., Россия
Зарегистрирован
Активность