Автор написал токенизатор, RoPE и SwiGLU руками и обучил модель на бытовой видеокарте
Развернуть Unsloth и дообучить Llama 3 за вечер несложно. Автор захотел посмотреть, что будет, если так не делать, и написал всё сам: BPE-токенизатор, RoPE, блоки SwiGLU и цикл обучения на чистом PyTorch.
Получилась EmsyAI версии 4 на 196,7 млн активных параметров: около 180 млн в блоках трансформера, остальное в эмбеддингах словаря примерно на 16 тысяч токенов. Обучение прошло на 1,96 млрд токенов и на потребительской видеокарте.
Ценность тут не в качестве модели, а в том, что каждый слой написан руками и его видно. Если вы читали про RoPE и SwiGLU, но не собирали их сами, это готовый маршрут.
Развернуть Unsloth и дообучить Llama 3 за вечер несложно. Автор захотел посмотреть, что будет, если так не делать, и написал всё сам: BPE-токенизатор, RoPE, блоки SwiGLU и цикл обучения на чистом PyTorch.
Получилась EmsyAI версии 4 на 196,7 млн активных параметров: около 180 млн в блоках трансформера, остальное в эмбеддингах словаря примерно на 16 тысяч токенов. Обучение прошло на 1,96 млрд токенов и на потребительской видеокарте.
Ценность тут не в качестве модели, а в том, что каждый слой написан руками и его видно. Если вы читали про RoPE и SwiGLU, но не собирали их сами, это готовый маршрут.
DEV Community
Building a 200M parameter LLM from scratch in PyTorch
It's really easy to spin up Unsloth and fine-tune Llama 3 in an afternoon. I wanted to see what...
❤1
В Python шесть предобъявленных констант, и каждая ведёт себя по-своему
Первая тройка это вообще не идентификаторы, а собственные лексические токены: разрешаются в лексере, а не при обычном разрешении имён. Побочный эффект в том, что выражение
Отдельный случай
True, False, None, __debug__, Ellipsis и NotImplemented. Автор разбирает, чем они отличаются, и различий больше, чем ожидаешь.Первая тройка это вообще не идентификаторы, а собственные лексические токены: разрешаются в лексере, а не при обычном разрешении имён. Побочный эффект в том, что выражение
x.True даёт SyntaxError, и больше в языке так не ведёт себя ничего.Отдельный случай
__debug__: обычный идентификатор, но единственный, которому нельзя присвоить значение, причём даже как атрибуту. При этом x.__debug__ даёт уже AttributeError, потому что синтаксически это законно. Хорошая заметка на вечер, если любите тёмные углы языка.✍1
EPUB это ZIP с XHTML внутри, и собрать его обратно после правки труднее, чем разобрать
Сервис LectuLibre переводит книги через модели: пользователь загружает EPUB, бэкенд достаёт текст, отправляет его в Claude или DeepSeek и кладёт перевод обратно в тот же файл. Автор пишет, что именно последний шаг оказался самым тяжёлым.
EPUB это ZIP-архив с документами XHTML, стилями, картинками, шрифтами и служебными файлами вроде
В разборе есть выбор библиотек и компромиссы, на которые пришлось пойти. Пригодится, если строите любой конвейер обработки электронных книг.
Сервис LectuLibre переводит книги через модели: пользователь загружает EPUB, бэкенд достаёт текст, отправляет его в Claude или DeepSeek и кладёт перевод обратно в тот же файл. Автор пишет, что именно последний шаг оказался самым тяжёлым.
EPUB это ZIP-архив с документами XHTML, стилями, картинками, шрифтами и служебными файлами вроде
container.xml и content.opf. Вернуть переведённый текст на место, сохранив форматирование, изображения, стили и метаданные, значит собрать валидный контейнер заново.В разборе есть выбор библиотек и компромиссы, на которые пришлось пойти. Пригодится, если строите любой конвейер обработки электронных книг.
DEV Community
Parsing and Rebuilding EPUB Files in Python: Lessons Learned from Building an AI Translation Service
How we handle complex EPUB structures, preserve metadata, and rebuild valid files after AI...
❤1
Что выбрать под неизменяемые объекты: обычный класс или dataclass
Обычный класс порождает изменяемые экземпляры, пока вы явно не запретите менять атрибуты. Отсюда и вопрос, который разбирает автор: где для неизменяемых данных проходит граница между ручным классом и
В разборе три части: как сделать неизменяемость на голом классе, что даёт
Тема из тех, где каждый однажды принимает решение по привычке и живёт с ним годами. Хороший повод пересмотреть привычку на конкретных примерах.
Обычный класс порождает изменяемые экземпляры, пока вы явно не запретите менять атрибуты. Отсюда и вопрос, который разбирает автор: где для неизменяемых данных проходит граница между ручным классом и
dataclass.В разборе три части: как сделать неизменяемость на голом классе, что даёт
__slots__ для памяти и контроля атрибутов, и что из этого закрывает dataclass(frozen=True) без ручной работы.Тема из тех, где каждый однажды принимает решение по привычке и живёт с ним годами. Хороший повод пересмотреть привычку на конкретных примерах.
DEV Community
🐍 Python classes vs dataclasses for immutable objects — which one should you use?
💡 Fundamentals — Understanding immutability A plain class is a blueprint that creates...
🔥3
EVE Online начала переезд на Python 3 после двух десятилетий на второй ветке
Под каждым прыжком через гейт, каждым ордером на рынке и каждым флитфайтом в EVE лежит очень много Python. Он держит New Eden больше двадцати лет, и теперь CCP объявила о начале перехода на третью ветку.
Формулировка успеха у команды показательная: миграция должна пройти совершенно незаметно, если не считать моментов, когда что-то начнёт работать глаже. Первые шаги уже выкачены на тестовый сервер Singularity.
Это редкий публичный кейс переезда живого продакшена такого возраста. Обещают в итоге более быстрый поиск багов, место под новые фичи и общее ускорение, но дорога, по их же словам, длинная.
Под каждым прыжком через гейт, каждым ордером на рынке и каждым флитфайтом в EVE лежит очень много Python. Он держит New Eden больше двадцати лет, и теперь CCP объявила о начале перехода на третью ветку.
Формулировка успеха у команды показательная: миграция должна пройти совершенно незаметно, если не считать моментов, когда что-то начнёт работать глаже. Первые шаги уже выкачены на тестовый сервер Singularity.
Это редкий публичный кейс переезда живого продакшена такого возраста. Обещают в итоге более быстрый поиск багов, место под новые фичи и общее ускорение, но дорога, по их же словам, длинная.
EVE Online
The Move to Python 3 Begins! | EVE Online
How do you migrate 2.4 million lines of code?
🤯5
Forwarded from Точка входа в программирование
Соберите первую нейросеть на Python без матана и видеокарты
Слово «нейросеть» звучит так, будто нужен продвинутый матанализ, мощная машина и тысячи строк кода. Ничего из этого не нужно.
На базовом уровне нейросеть это математическая модель, которая берёт на вход числа, что-то с ними считает, выдаёт предсказание, сравнивает его с правильным ответом и подправляет себя, чтобы в следующий раз ошибиться меньше. Этот цикл и есть обучение, всё остальное надстраивается сверху.
В туториале такую сеть строят руками на Python и NumPy, без фреймворков, чтобы был виден каждый шаг. Хороший следующий шаг после основ языка: слова «слой», «веса» и «обучение» перестанут быть заклинаниями и станут строчками кода, которые вы написали сами.
#python
Слово «нейросеть» звучит так, будто нужен продвинутый матанализ, мощная машина и тысячи строк кода. Ничего из этого не нужно.
На базовом уровне нейросеть это математическая модель, которая берёт на вход числа, что-то с ними считает, выдаёт предсказание, сравнивает его с правильным ответом и подправляет себя, чтобы в следующий раз ошибиться меньше. Этот цикл и есть обучение, всё остальное надстраивается сверху.
В туториале такую сеть строят руками на Python и NumPy, без фреймворков, чтобы был виден каждый шаг. Хороший следующий шаг после основ языка: слова «слой», «веса» и «обучение» перестанут быть заклинаниями и станут строчками кода, которые вы написали сами.
#python
freeCodeCamp.org
Neural Networks Explained: What They Are and How to Build One in Python
Have you ever wondered how a computer can recognize a handwritten number, predict whether an email is spam, recommend a video, or understand a sentence? A lot of modern AI systems rely on something ca
✍4
Forwarded from Сохранёнки программиста
Четыре джойна в SQL против одного запроса в графе: справочник по Neo4j и Python
Рамка задана вопросом, который легко произнести и тяжело написать: у каких инженеров есть свежий контекст по сервисам, задетым ночным инцидентом. В SQL это четыре или пять джойнов, каждый строит промежуточный результат шире нужного ответа и тут же выбрасывает большую часть. Запрос замедляется по мере роста таблиц и хуже читается с каждым возвращением к нему.
Справочник ведёт от пустой базы до работающего графа знаний: загрузка настоящих данных из Python и запросы, на которых идея становится понятной.
Разобраны части, которые туториалы пропускают: как решить, что становится узлом, почему первая модель данных почти наверняка неверна, как ускорить загрузку и как читать план запроса, когда что-то тормозит.
Рамка задана вопросом, который легко произнести и тяжело написать: у каких инженеров есть свежий контекст по сервисам, задетым ночным инцидентом. В SQL это четыре или пять джойнов, каждый строит промежуточный результат шире нужного ответа и тут же выбрасывает большую часть. Запрос замедляется по мере роста таблиц и хуже читается с каждым возвращением к нему.
Справочник ведёт от пустой базы до работающего графа знаний: загрузка настоящих данных из Python и запросы, на которых идея становится понятной.
Разобраны части, которые туториалы пропускают: как решить, что становится узлом, почему первая модель данных почти наверняка неверна, как ускорить загрузку и как читать план запроса, когда что-то тормозит.
freeCodeCamp.org
How to Build a Knowledge Graph with Python and Neo4j [Full Handbook]
Most of the data you work with is really about relationships. A customer belongs to an account. An incident affects a service. An engineer owns a repository. You store all of that in tables, and for a
Forwarded from Точка входа в программирование
Соберите Discord-бота на Python и заодно разберитесь с асинхронностью
Со стороны бот выглядит сложно: отвечает на сообщения, помнит куски разговора, живёт круглосуточно. На деле это программа на Python, которая подключается к Discord, ждёт событие и решает, как на него ответить.
Как учебный проект он хорош тем, что за одного бота вы трогаете сразу несколько тем: команды, события, асинхронный Python, хранение состояния пользователя, переменные окружения и простейший деплой. Обычно это учат по отдельности и не видят, как оно соединяется.
Туториал начинает с совсем маленького бота и наращивает по одной функции. Каждый шаг можно запустить и увидеть результат, а не ждать финала.
#python
Со стороны бот выглядит сложно: отвечает на сообщения, помнит куски разговора, живёт круглосуточно. На деле это программа на Python, которая подключается к Discord, ждёт событие и решает, как на него ответить.
Как учебный проект он хорош тем, что за одного бота вы трогаете сразу несколько тем: команды, события, асинхронный Python, хранение состояния пользователя, переменные окружения и простейший деплой. Обычно это учат по отдельности и не видят, как оно соединяется.
Туториал начинает с совсем маленького бота и наращивает по одной функции. Каждый шаг можно запустить и увидеть результат, а не ждать финала.
#python
freeCodeCamp.org
How to Build a Basic Discord Storytelling, Chat, and Mental Wellness Bot with Python
Discord bots can look surprisingly complicated when you see them in action. A bot can respond to messages, tell stories, remember parts of conversations, and stay online around the clock. When I first
JIT в CPython перестанет быть экспериментом, если обгонит free-threaded интерпретатор на 20%
JIT лежит в main с 3.13, и включать его до сих пор незачем. В 3.15 он даёт 4–12% ускорения (среднее геометрическое по платформам Tier 1), отдаёт кадры, которые нативные отладчики разматывают в нормальный стек, и занимает меньше памяти под сгенерированный код, чем в 3.14.
PEP 836 называет цену выхода из статуса «экспериментальный»: к первой бете сборка с JIT и free-threading должна обойти free-threaded интерпретатор без JIT минимум на 20% по среднему геометрическому на pyperformance. Плюс совместимость, инструменты, дистрибуция и модель поддержки.
То есть JIT и free-threading перестают быть двумя отдельными экспериментами, их сводят в одну цель. Прогнать свои бенчмарки на сборке с JIT стоит сейчас, пока цифры в PEP обсуждаются.
#cpython
JIT лежит в main с 3.13, и включать его до сих пор незачем. В 3.15 он даёт 4–12% ускорения (среднее геометрическое по платформам Tier 1), отдаёт кадры, которые нативные отладчики разматывают в нормальный стек, и занимает меньше памяти под сгенерированный код, чем в 3.14.
PEP 836 называет цену выхода из статуса «экспериментальный»: к первой бете сборка с JIT и free-threading должна обойти free-threaded интерпретатор без JIT минимум на 20% по среднему геометрическому на pyperformance. Плюс совместимость, инструменты, дистрибуция и модель поддержки.
То есть JIT и free-threading перестают быть двумя отдельными экспериментами, их сводят в одну цель. Прогнать свои бенчмарки на сборке с JIT стоит сейчас, пока цифры в PEP обсуждаются.
#cpython
❤1😁1
Как выбрать между threading, asyncio и процессами, не переписывая код четыре раза
Модель конкурентности обычно берут ту, что уже стоит в соседнем модуле, а не ту, что подходит нагрузке. Пока задача упирается в сеть, ошибиться сложно: ждёт всё равно не процессор. На счётной задаче цена решения видна сразу.
В руководстве Real Python одна и та же задача написана в четырёх версиях: синхронной, на потоках, на asyncio и на процессах. И так дважды: сначала для нагрузки, где программа ждёт ответа по сети, потом для той, где она считает. Восемь реализаций одной задачи.
В статье остаётся разбор: чем заканчивается тот же прогон на счётной нагрузке, где процессы дают настоящий параллелизм, а где хватает управления ожиданием на одном ядре, и по какому признаку выбирать модель до того, как писать код.
#python
Модель конкурентности обычно берут ту, что уже стоит в соседнем модуле, а не ту, что подходит нагрузке. Пока задача упирается в сеть, ошибиться сложно: ждёт всё равно не процессор. На счётной задаче цена решения видна сразу.
В руководстве Real Python одна и та же задача написана в четырёх версиях: синхронной, на потоках, на asyncio и на процессах. И так дважды: сначала для нагрузки, где программа ждёт ответа по сети, потом для той, где она считает. Восемь реализаций одной задачи.
В статье остаётся разбор: чем заканчивается тот же прогон на счётной нагрузке, где процессы дают настоящий параллелизм, а где хватает управления ожиданием на одном ядре, и по какому признаку выбирать модель до того, как писать код.
#python
❤4
Питонисту советуют TypeScript ради типов, которые у него уже есть
У питониста в CI давно стоит mypy, а аргументы за TypeScript ему перечисляют те же: типы ловят ошибки до запуска, интерфейсы фиксируют форму объекта, вывод типов экономит аннотации. Из этого набора собран и гайд для питонистов на dev.to.
Разница начинается дальше, в судьбе самих типов. В TypeScript они стираются при компиляции, и входящий JSON всё равно приходится проверять руками или через zod. В Python аннотации остаются в объекте: их читает pydantic, на них держится валидация в FastAPI, один и тот же тип работает и в проверке схемы, и в разборе запроса.
Одни считают, что после mypy в TypeScript идти незачем: тот же контракт, только с npm. Другие говорят, что tsc дисциплинирует сильнее mypy, который на чужом коде молча сдаётся на Any.
А по вашему опыту?
#python
У питониста в CI давно стоит mypy, а аргументы за TypeScript ему перечисляют те же: типы ловят ошибки до запуска, интерфейсы фиксируют форму объекта, вывод типов экономит аннотации. Из этого набора собран и гайд для питонистов на dev.to.
Разница начинается дальше, в судьбе самих типов. В TypeScript они стираются при компиляции, и входящий JSON всё равно приходится проверять руками или через zod. В Python аннотации остаются в объекте: их читает pydantic, на них держится валидация в FastAPI, один и тот же тип работает и в проверке схемы, и в разборе запроса.
Одни считают, что после mypy в TypeScript идти незачем: тот же контракт, только с npm. Другие говорят, что tsc дисциплинирует сильнее mypy, который на чужом коде молча сдаётся на Any.
А по вашему опыту?
#python
ffmpeg вернул нулевой код возврата, а видео на выходе оказалось битым
Внешние утилиты из Python проверяют обычно одинаково: subprocess.run(..., check=True), и раз исключения нет, значит всё получилось. С ffmpeg этого мало: он спокойно отрабатывает с нулевым кодом и отдаёт файл, собранный не из тех фрагментов, которые вы просили, а заметить это можно, только досмотрев результат до конца.
В ReelCraft, CLI на Python для сборки ролика из папки с фото и видео, такое случилось трижды: Gemini 3.7 Flash разбирает ассеты и предлагает список нарезки, ffmpeg режет по нему, оба этапа отчитываются об успехе. Что именно разъехалось в склейке и субтитрах, разбирает дев-лог автора.
Приём оттуда полезен и без видео: между выводом модели и вызовом ffmpeg лежит edl.yaml, который человек читает и подтверждает руками. И проверять после subprocess стоит артефакт, тем же ffprobe, а не код возврата.
#python
Внешние утилиты из Python проверяют обычно одинаково: subprocess.run(..., check=True), и раз исключения нет, значит всё получилось. С ffmpeg этого мало: он спокойно отрабатывает с нулевым кодом и отдаёт файл, собранный не из тех фрагментов, которые вы просили, а заметить это можно, только досмотрев результат до конца.
В ReelCraft, CLI на Python для сборки ролика из папки с фото и видео, такое случилось трижды: Gemini 3.7 Flash разбирает ассеты и предлагает список нарезки, ffmpeg режет по нему, оба этапа отчитываются об успехе. Что именно разъехалось в склейке и субтитрах, разбирает дев-лог автора.
Приём оттуда полезен и без видео: между выводом модели и вызовом ffmpeg лежит edl.yaml, который человек читает и подтверждает руками. И проверять после subprocess стоит артефакт, тем же ffprobe, а не код возврата.
#python