Соглашения
Ветки и pull request
Заголовок раздела «Ветки и pull request»- Работа ведётся в ветках от
master, одна задача — одна ветка и один PR. Префикс ветки — тип изменения:fix/,feat/,refactor/,perf/,test/,docs/,chore/(например,fix/pad-in-loss,feat/gemma-hf-parity). - PR вливается merge-коммитом (не squash): история веток сохраняется, на неё ссылается бэклог.
- Перед PR:
uv run pytestиз корня проходит; для изменений вdocs/илиsite/— сайт собирается. - Описание PR — на русском, разделы: «Проблема» (что было не так и чем это проявлялось), «Что сделано», «Несовместимость» (или «Нет»), «Проверка» (какие тесты, на старом коде падают ли, итог прогона). Если PR закрывает пункт бэклога — ссылка на него в первой строке.
Коммиты
Заголовок раздела «Коммиты»Сообщения — на английском, в стиле Conventional Commits: type(scope): summary, где type — fix, feat, refactor, perf, test, docs, chore, а scope — модуль или модель (tokenizer, training, gemma, datasets). Тело объясняет почему: что было не так, как проявлялось, что изменилось, чем проверено, — так, чтобы коммит читался без PR.
- Зависимости
llm— толькоtorchиnumpy. Всё про HuggingFace — вhf-proxyили в тестах черезpytest.importorskip. - Докстринги и комментарии — на русском, как во всём проекте. Комментарий объясняет, зачем код такой, а не пересказывает его.
- Формулы в докстрингах — в сырых строках (
r"""…"""): иначе\betaпревращается в управляющий символ. Это проверяетtests/test_source.py. - Поведение по умолчанию сохраняет совместимость. Новый ключ конфига, меняющий форму весов или результат, по умолчанию оставляет прежнее поведение; оригинальная конфигурация включается ключом.
- Ошибки — рано и явно. Неверный конфиг —
ValueErrorв конструкторе; неподдерживаемый вход — исключение с объяснением, а не молча неверный результат. - Форматирование —
black, линтер —ruff(uv sync --extra dev).
Старый PyTorch. Библиотека требует torch>=2.3 и поддержку torch < 1.2 не заявляет (бэклог, пункт 32). Код для внешнего стенда со старым torch переносится отдельно и использует float-маски (masked_fill(mask == 0, ...)) вместо .bool() и ~.
Документация
Заголовок раздела «Документация»Изменение кода, которое видно пользователю, сопровождается документацией в том же PR:
| Что изменилось | Где описать |
|---|---|
| как пользоваться (API, ключ конфига, поведение) | Руководство пользователя, таблица ключей в llm/README.md |
| как устроен механизм, формулы, соответствие статье | глава Учебного пособия |
| старый код, конфиги или чекпоинты ведут себя иначе | CHANGELOG — с ссылкой на PR |
| найдено расхождение со статьёй или ошибка | бэклог |
Учебное пособие описывает текущее поведение. История («раньше было так, исправлено в PR …») — в CHANGELOG и бэклоге, а не в главах: читателю пособия она не нужна. Исключение — поучительные ошибки: их описывают в «Типичных ошибках и тонкостях» как ошибку, которую легко сделать, без номеров PR и пунктов бэклога.
Числа в документации (loss, точность сверки, размеры) должны быть получены запуском, а не оценены; примеры кода — запускаться.
Бэклог — журнал найденных расхождений кода со статьями и эталонами. Запись: где, что, как воспроизведено, как исправить, приоритет (P1 — неверный результат или падение, P2 — расхождение со статьёй или документацией, P3 — качество кода). Исправленный пункт получает строку «Статус»: в какой ветке исправлено, как и чем проверено. Номера пунктов не перенумеровываются — на них ссылаются.