Перейти к содержимому
Ступень 1111.4 Расти дальше

Вклад в open source

Как сделать первый вклад в большой открытый проект: выбрать проект и проверить, живой ли он, прочитать CONTRIBUTING, найти посильную задачу (от документации до исправления бага с тестом), пройти путь форк → ветка → коммит с подписью → pull request → ревью и соблюсти правила проектов, в том числе об ИИ-помощниках. На примерах transformers, vLLM, llama.cpp, verl, LlamaFactory и MiniMind.

УРОКstage-11/11-4-growth/02-open-source.mdx2 чУрок 2 из 5
После урока вы сможете
  • Выбрать проект по своим интересам и за 15 минут оценить, живой ли он и есть ли шанс на ревью
  • Прочитать CONTRIBUTING и перевести его в чек-лист — сборка, тесты, стиль, подпись DCO или CLA, правила об ИИ
  • Найти посильную первую задачу — перевод, воспроизведение бага, тест, исправление — в том числе среди своих находок из курса
  • Пройти полный цикл — форк, ветка, коммит, pull request, ответ на ревью, синхронизация с upstream

В уроке 11.1.2 вы учились читать чужой код и чинить его через ветку и pull requestpull request (запрос на слияние)EN pull request, merge requestПредложение влить ветку с изменениями в основную; место, где идёт код-ревью и прогоняются автотесты. В GitLab называется merge request.. Открытый проект — тот же чужой код, только больше, и с тремя бонусами, которых нет у учебных задач:

  • Большой живой код. В transformers сотни моделей, в vLLM планировщик, ядра и десятки бэкендов. Чтобы поправить одну строку, вы научитесь находить её среди сотен тысяч — тот самый навык, который нужен в первую неделю на работе.
  • Ревью от сильных инженеров. Мейнтейнер vLLM или llama.cpp прочитает ваш diff и объяснит, почему так нельзя. Это код-ревьюкод-ревьюEN code reviewПроверка изменений кода другим инженером до слияния в основную ветку — на корректность, читаемость, тесты и производительность., за которое не нужно платить и которое не дадут ни курс, ни ИИ-помощник.
  • Видимое портфолио. Слитый PR в известный проект проверяется за минуту: ссылка, diff, обсуждение. Как вписать его в резюме — в уроке 11.3.6.

Честная оговорка: в 2026 году большие проекты получают много PR, написанных код-агентами (transformers прямо пишет, что не успевает их разбирать). Правила ужесточились, и мейнтейнеры объясняют, что ценят. В CONTRIBUTING transformers перечислено то, чего агент сам не сделает: точно найти причину бага (в том числе через git bisect), воспроизвести проблему, а не поверить описанию в issue, сделать diff минимальным, сравнить исправление с соседними моделями. Ровно этому и учил курс. Значит, у вас есть что предложить.

Начинайте с проекта, которым вы уже пользовались в курсе: вы знаете, как он работает снаружи, и, возможно, уже натыкались на его шероховатости.

ПроектЧто этоГде в курсеЯзыкПорог входа
transformersмодели, токенизаторы, обучениеступени 4–7Pythonсредний: огромный код, строгие правила
vLLMдвижок инференса7.1.2, 8.4Python, CUDA/C++высокий: многие тесты требуют GPU
llama.cppинференс на CPU и GPU, GGUF7.2C/C++высокий: строгий стиль, много бэкендов
verlRL-пост-трейнинг (PPO, GRPO)6.4.5, раздел «Переводы»Pythonвысокий: Ray, FSDP, движки инференса
LlamaFactorySFT, LoRA, DPO из конфига6.2.2Pythonсредний
MiniMindсвоя LLM на 64M с нуля5.6Pythonнизкий: код читается за вечер

Два адреса поменялись, и в старых материалах встречаются оба варианта. verl раньше жил в volcengine/verl, а llama.cpp — в ggerganov/llama.cpp; файлы CONTRIBUTING по старым адресам совпадают с новыми, а ссылки в них ведут уже на verl-project/verl и ggml-org/llama.cpp. LLaMA-Factory теперь называется hiyouga/LlamaFactory. Клонируйте по новым адресам.

Проект может быть знаменитым и при этом не отвечать внешним авторам месяцами. Вот срез, снятый поиском GitHub 6 октября 2026 года (звёзды округлены, «слито» — PR, влитые с 6 сентября по 5 октября):

ПроектЗвёздСлито за 30 днейОткрытых PRОчередь, месяцев
transformers≈ 167 тыс.3221643≈ 5
vLLM≈ 93 тыс.15995927≈ 3.7
llama.cpp≈ 130 тыс.6101665≈ 2.7
verl≈ 24 тыс.93706≈ 7.6
LlamaFactory≈ 75 тыс.8171≈ 21
MiniMind≈ 63 тыс.1433≈ 2.4

«Очередь» — грубая оценка: открытые PR, делённые на слитые за месяц. Среди открытых есть черновики и брошенные PR, поэтому это не срок ожидания, а сигнал. Звёзды почти ничего не говорят: у LlamaFactory их втрое больше, чем у verl, а PR в месяц сливается в одиннадцать раз меньше.

Пять проверок перед тем, как вкладывать вечер:

  1. Слияния за последний месяц. Поиск на GitHub: repo:jingyaogong/minimind is:pr is:merged merged:>=2026-09-06.
  2. Есть ли среди них внешние авторы. У MiniMind с 1 июня по 6 октября 2026 года слито 17 PR от внешних участников — и с английскими заголовками, и с китайскими.
  3. Сколько ждут ответа. Откройте пять последних PR от новичков и посмотрите дату первого комментария мейнтейнера. У тех же 17 PR MiniMind путь от открытия до слияния занял от 9 часов (#868) до четырёх месяцев (#769).
  4. Есть ли CONTRIBUTING и метки для новичков (good first issue, help wanted).
  5. Как разговаривают с новичками. Прочитайте два-три закрытых без слияния PR: вежливо ли объяснили причину?
Окно терминала
# слитые PR последних недель: кто автор, сколько шло от открытия до слияния
gh pr list --repo jingyaogong/minimind --state merged --limit 20 --json number,title,author,createdAt,mergedAt
# открытые задачи для новичков
gh issue list --repo vllm-project/vllm --label "good first issue" --state open

Эти проверки вы закодируете в задании в конце урока.

CONTRIBUTING.mdруководство для участников (CONTRIBUTING)EN contributing guide, CONTRIBUTING.mdФайл с правилами для внешних авторов: как собрать проект, какие проверки стиля и тесты запустить, формат заголовка PR, подпись DCO или CLA, правила об ИИ-помощниках. Лежит в корне репозитория или в папке .github. — главный документ для внешнего автора. Его пишут мейнтейнерымейнтейнер (сопровождающий проекта)EN maintainerЧеловек с правом сливать изменения в проект; ревьюит PR, отвечает на issue и потом годами поддерживает принятый код., и всё, что в нём сказано, — условия, при которых ваш PR вообще прочитают. Лежит он в корне (transformers, llama.cpp, verl) или в .github/ (LlamaFactory). У vLLM файл в .github/ только отсылает на сайт документации, а сам текст лежит в docs/contributing/README.md. У MiniMind отдельного CONTRIBUTING нет: правила — в README.

Вот что в них написано на 6 октября 2026 года. Перед своим PR перечитайте оригинал: правила меняются.

ПроектУстановка для разработкиСтиль и проверкиТестыПодпись
transformerspip install -e ".[dev]"make fix-repopython utils/tests_fetcher.py покажет тесты, задетые вашими файлами; запустить их до PR, потом дождаться зелёного CIне упомянута
vLLMтолько Python: VLLM_USE_PRECOMPILED=1 uv pip install -e .pre-commit installpytest; не все тесты проходят на CPU — без GPU полагайтесь на CIDCO: Signed-off-by в каждом коммите
llama.cppсборка CMakeclang-format по образцу кодаполный CI локально: bash ./ci/run.sh ./tmp/results ./tmp/mnt; для исправления бага — регрессионный тестне упомянута
verlpip install -e .[test,vllm]pre-commit installтесты в CI-воркфлоу; новую функцию — с тестом в CI или объяснением, почему его нетне упомянута
LlamaFactorypip install -e ".[dev]"Google Python Style, make style && make qualitymake testне упомянута
MiniMind————

Ещё четыре правила, которые легко пропустить:

  • Заголовок PR по формату. vLLM: теги в квадратных скобках, затем описание — [Bugfix][Scheduler] Fix priority handling. verl: [модули] тип: описание, например [trainer] fix: ..., и это проверяет CI скриптом tests/special_sanity/check_pr_title.py.
  • Новичкам — один PR. llama.cpp просит новых авторов держать открытым не больше одного PR. У vLLM для авторов без прав записи лимит — 6 открытых PR.
  • Функции начинаются с issue. llama.cpp: «Features must begin with an issue, not a PR». vLLM для крупных архитектурных изменений (больше 500 строк без учёта ядер, данных, конфигов и тестов) ждёт сначала issue с обсуждением дизайна (RFC).
  • Сначала поиск. Дубли в llama.cpp «скорее всего закроют без вопросов». Шаблон PR verl требует вставить ссылку на поисковый запрос, которым вы проверили, что похожего PR нет.

Отдавая код, вы подтверждаете, что имеете на это право. Есть два способа.

DCO (Developer Certificate of Origin, версия 1.1 от Linux Foundation) — короткий текст: «вклад создан мной или основан на открытой работе, и я вправе отдать его под лицензией проекта». Согласие ставится в каждом коммите строкой Signed-off-by: Имя <почта>. Её добавляет флаг git commit -s. vLLM требует DCO; если подпись забыта в последнем коммите, исправьте её командой git commit --amend -s --no-edit и отправьте ветку заново с --force-with-lease.

CLAлицензионное соглашение участника (CLA)EN Contributor License Agreement (CLA)Договор между автором вклада и владельцем проекта о правах на код; подписывают один раз, обычно через бота в первом PR. Другой вариант — DCO: строка Signed-off-by в каждом коммите (git commit -s). (Contributor License Agreement) — отдельный договор между вами и владельцем проекта, обычно компанией. Подписывают один раз, как правило через бота, который приходит в первый PR. В CONTRIBUTING шести проектов из таблицы CLA не упомянут. Зато, например, в CONTRIBUTING.md PyTorch среди служебных проверок PR названа проверка CLA. Если работаете по найму, прочитайте трудовой договор: права на код, написанный в рабочее время, могут принадлежать работодателю.

flowchart LR
A["Документация<br/>неточность, устаревшая команда"] --> B["Перевод<br/>глава учебника, раздел документации"]
B --> C["Воспроизведение бага<br/>минимальный пример в issue"]
C --> D["Тест<br/>падает до правки"]
D --> E["Исправление бага<br/>минимальный diff и тест"]
E --> F["Небольшая функция<br/>сначала issue и согласие"]
От простого к сложному: каждая ступень учит тому, что нужно на следующей

1. Документация. Вы шли по README и наткнулись на команду, которая не работает, или на параметр, которого уже нет. Это лучший первый вклад: вы — тот самый пользователь, для которого пишут документацию. Важная поправка 2026 года: разовые PR с одной опечаткой большие проекты присылать не советуют. В transformers больше не принимают мелкие правки стиля и опечатки в комментариях, хотя исправления документации — недостающее, неверное, непонятное — по-прежнему приветствуют. Правила об ИИ-помощи vLLM и AGENTS.md verl называют «busywork» разовый PR с одной опечаткой и просят собирать механические правки в осмысленный пакет. llama.cpp прямо просит новых авторов не присылать тривиальные правки — опечатки и форматирование. В маленьких проектах вроде MiniMind такие правки по-прежнему уместны: в его README сказано, что документация длинная, в ней неизбежны упущения, и предлагается сообщать о них через issue или PR.

2. Перевод. В курсе Hugging Face по LLM русский перевод помечен как незавершённый: на 6 октября 2026 года в его оглавлении нет глав 10 (разметка данных в Argilla), 11 (дообучение LLM: SFT и LoRA) и 12 (рассуждающие модели, GRPO в TRL) и нескольких отдельных разделов. Главы 11 и 12 — ровно темы ваших 6.1–6.2 и 6.4, то есть переводить вы будете то, что понимаете. Процесс описан в README репозитория huggingface/course: проверить, нет ли issue для вашего языка, открыть issue по шаблону Translation, перевести сначала оглавление _toctree.yml, потом сами MDX-файлы, проверить форматирование make style и в PR отметить ревьюеров. В документации transformers русского раздела нет совсем; как начать новый язык, описано в docs/TRANSLATING.md. Это большой проект: начинайте с одного раздела и issue.

3. Воспроизведение бага. Найдите открытый issue, где автор пишет «у меня падает», но без кода. Соберите минимальный воспроизводимый примерминимальный воспроизводимый примерEN minimal reproducible example (MRE)Самый короткий код (обычно 10–20 строк), который воспроизводит ошибку без ваших файлов и данных, плюс версии библиотек и полный traceback. Главное содержимое хорошего issue и вопроса на форуме.: 10–20 строк, без ваших файлов и данных, с версиями (transformers env печатает их для issue transformers) и полным traceback. Комментарий «воспроизвёл на версии X, вот пример, падает здесь, на версии Y — нет» экономит мейнтейнеру час. CONTRIBUTING transformers прямо пишет, что часто проблема оказывается в окружении пользователя или в неверном диагнозе, поэтому самостоятельное воспроизведение ценно. Как писать такой пример — в главе 8.5 курса Hugging Face (она переведена на русский).

4. Тест. Тест, который падает до исправления и проходит после, — регрессионный тестрегрессионный тестEN regression testТест, написанный на уже исправленный баг, чтобы он не вернулся незаметно. из урока 11.1.2. В llama.cpp без него PR с исправлением бага «может быть закрыт без ревью». Тест можно прислать и без исправления: отмеченный как ожидаемо падающий (в pytest — @pytest.mark.xfail), он фиксирует баг и облегчает работу тому, кто будет чинить. Спросите в issue, удобно ли это мейнтейнерам.

5. Исправление бага. Причина, а не симптом. Ищите первый плохой коммит через git bisect (урок 11.1.2), делайте diff минимальным: transformers просит «если исправление в одну строку — пусть будет в одну строку» и проверять, нет ли того же бага в соседних моделях. В описании PR — три вопроса из урока 11.1.2: что сломано, почему, как проверено.

6. Небольшая функция. Сначала issue: зачем, как будет выглядеть API, готовы ли вы поддерживать. В llama.cpp напоминают: большая часть работы над функцией начинается после слияния, и кто-то должен её сопровождать.

Метки. good first issue есть у vLLM, llama.cpp и verl, у transformers — Good First Issue и Good Second Issue, у verl ещё call for contribution. Реальность 2026 года: 6 октября у transformers открытых задач с меткой Good First Issue не было ни одной (всего с этой меткой за историю — 209), а у открытых good first issue vLLM по 10–29 комментариев. Такие задачи разбирают быстро. Прочитайте комментарии: если кто-то уже взялся, найдите другую или предложите помощь с тестом. Не пишите «можно я возьму?» без плана — напишите, как собираетесь чинить.

Свои находки из курса — лучший источник: вы уже знаете контекст.

Где в курсеЧто искатьКакой вклад
5.6 MiniMindчто упало или вело себя странно на ваших картахissue с примером или PR. Похожие внешние PR слиты в сентябре 2026: недостающие fastapi и uvicorn в requirements.txt (#865), маска внимания -1e9, которая во float16 переполняется в -inf и даёт NaN (#863, вспомните предел 65 504 из 5.4.1), токенизатор, который молча обучался на нуле текстов (#860)
раздел «Переводы»: verl, Qwen, ModelScopeкоманда из документации не сработала на вашей версииисправление документации в репозитории проекта
каталог тихих багов 11.1.2softmax не по той оси, сдвиг меток, забытый model.eval() в коде, которым вы пользуетесьвоспроизведение и тест, потом исправление
токенизация 4.2.3краевые случаи на русском и китайском: пробелы, эмодзи, смешанный тексттест на краевой случай
ДЗ курсарасхождение документации библиотеки и её поведенияминимальный пример в issue
курс Hugging Faceглавы 11–12 без русского переводаперевод раздела

Порядок для любой находки: сначала поиск по issue и PR (не нашли — значит, можно), потом минимальный пример, потом issue, и только после ответа мейнтейнера — PR.

flowchart LR
U["upstream<br/>github.com/проект"] -- "Fork" --> O["origin<br/>ваш форк на GitHub"]
O -- "git clone" --> L["локальная копия"]
U -- "git fetch upstream" --> L
L -- "git push origin ветка" --> O
O -- "pull request" --> U
Три копии репозитория: из upstream забираем свежий код, в форк отправляем ветку, PR открываем из форка в upstream

Форкфорк (копия репозитория)EN forkВаша копия чужого репозитория на GitHub: в оригинал писать нельзя, в форк — можно. Из форка открывают pull request в исходный репозиторий. В китайской речи часто говорят просто «fork». — ваша копия проекта на GitHub: писать в оригинал вам нельзя, в форк — можно. Upstreamupstream (исходный репозиторий)EN upstream repositoryОригинальный репозиторий проекта, от которого сделан форк. В локальной копии его обычно добавляют вторым remote с именем upstream (origin указывает на ваш форк) и забирают оттуда свежий main. — оригинал. Команды ниже — на примере transformers (так же устроен его CONTRIBUTING); для другого проекта поменяйте адрес и команды проверок по таблице выше. Основы Git — в уроке 0.1.1.

Окно терминала
# 0. Форк: кнопка Fork на странице проекта (или: gh repo fork huggingface/transformers --clone)
git clone git@github.com:<ваш-логин>/transformers.git
cd transformers
git remote add upstream https://github.com/huggingface/transformers.git
git remote -v # origin — ваш форк, upstream — оригинал
# 1. Свежий main и отдельная ветка под одну задачу
git checkout main
git pull upstream main
git switch -c fix-zh-tokenizer-docs
# 2. Окружение и установка из исходников (editable: правки в коде видны сразу)
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
# 3. Тесты ДО правки: убедиться, что они проходят (или падают так же, как в CI)
python utils/tests_fetcher.py # какие тесты задевают изменённые файлы
pytest tests/models/bert/test_tokenization_bert.py -q # пример: запуск одного файла тестов
# 4. Правка + тест, затем автоисправление стиля
make fix-repo
git diff # перечитать свой diff: ни отладочных print, ни лишних файлов
# 5. Коммит (-s добавляет строку Signed-off-by, нужна для DCO) и отправка в форк
git add -p # добавлять по кускам, глядя на каждый
git commit -s -m "Fix tokenizer docs example for Chinese text"
git push -u origin fix-zh-tokenizer-docs
# 6. PR из форка в upstream (или кнопка Compare & pull request на GitHub)
gh pr create --repo huggingface/transformers --base main \
--title "Fix tokenizer docs example for Chinese text" --body-file pr.md

Описание PR заполняйте по шаблону проекта (его GitHub подставит сам): что меняется, ссылка на issue (Fixes #номер закроет issue при слиянии), как проверено. Если пользовались ИИ — скажите, как именно (правила ниже).

Ревью и обновление ветки. На замечания отвечайте новыми коммитами в ту же ветку: PR обновится сам. Если main ушёл вперёд и появились конфликты, перенесите ветку на свежий upstream:

Окно терминала
git fetch upstream
git rebase upstream/main # конфликты — поправить, git add, git rebase --continue
git push --force-with-lease # перезапись ветки, но только если в форке нет чужих новых коммитов

--force-with-lease безопаснее обычного --force: он откажется перезаписывать ветку, если в ней появились коммиты, которых у вас нет (например, мейнтейнер дописал что-то сам — llama.cpp советует разрешать это для ускорения ревью).

  • Ждите разумно. vLLM обещает обновления статуса раз в 2–3 дня и разрешает напомнить, если ревью нет 7 дней. Шаблон PR transformers советует через неделю тишины упомянуть тех же людей. Напоминание — одно вежливое сообщение, а не ежедневные «ап».
  • Отвечайте на каждое замечание — исправлением или аргументом. Не согласны — объясните почему; vLLM пишет, что если договориться с ревьюером не получается, решить поможет коммиттер.
  • Не дублируйте. Перед issue и PR — поиск. Нашли похожий PR — помогите его автору в комментариях вместо своего.
  • Дождитесь зелёного CI до просьбы о ревью: transformers прямо просит не звать ревьюеров, пока CI красный.
  • Маленький PR — одна задача. llama.cpp: отдельный PR на каждую функцию или исправление.
  • Пишите сами и коротко. Мейнтейнер читает десятки PR в день. Три предложения по существу лучше страницы.

ИИ-помощники: что написано в правилах проектов

Заголовок раздела «ИИ-помощники: что написано в правилах проектов»

Курс сам построен на правиле «ИИ объясняет, решаете вы» (файл homework/AGENTS.md). Большие проекты пришли к тому же. Ниже — только то, что написано в их CONTRIBUTING, AGENTS.md и шаблонах PR на 6 октября 2026 года.

ПроектЧто сказано про ИИ
transformersновичкам не использовать код-агентов для issue и PR; похожие на написанные агентом PR, скорее всего, закроют без ревью, а за повторы могут заблокировать; в шаблоне PR — галочка «описание и код написаны не LLM» для тех, кто вносит вклад впервые. Остальным ИИ-помощь можно, но без PR «целиком от агента» и с указанием в описании
vLLMникаких PR «целиком от агента»: человек проверяет каждую строку и запускает тесты; использование ИИ указать в описании PR и отметить в коммите строкой вроде Co-authored-by:; в чек-листе PR — галочка «AI assistance was used»
llama.cppсгенерированный код разрешён, но за каждую строку отвечаете вы и должны объяснить её без ИИ; ручное ревью — порядка часа на 200–400 строк; запрещено писать ИИ сообщения об ошибках, описания PR и ответы людям; нераскрытое использование ИИ — вплоть до бессрочного бана
verlAGENTS.md: PR «целиком от агента» не принимают; в описании — почему это не дубль, какие тесты запущены и с каким результатом, явное указание на помощь ИИ; нарушение может кончиться автоматическим баном
LlamaFactory, MiniMindотдельных правил в CONTRIBUTING и README нет — действуют общие правила вежливости и ответственности

Общий знаменатель: ИИ не может быть автором вашего вклада. Им можно разбираться в коде, искать места вызова, спрашивать, почему тест падает. Но issue, описание PR и ответы ревьюерам — ваши слова, а каждую строку diff вы должны уметь защитить сами. Как настроить ИИ-ментора так, чтобы он учил, а не решал, — в уроке 11.4.4.

Задание в браузере: предполётная проверка PR

Заголовок раздела «Задание в браузере: предполётная проверка PR»

Правила из CONTRIBUTING можно проверять кодом — verl так и делает в CI. Напишите четыре проверки: заголовок по правилу verl (повторяет скрипт check_pr_title.py), заголовок по правилу vLLM, подпись DCO в сообщении коммита и «пульс» проекта по выборке PR: медиана дней до первого ответа, доля старых PR без ответа, число слияний за месяц.

Предполётная проверка pull request6 тестов
"""Предполётная проверка pull request: заголовки по правилам verl и vLLM, подпись DCO и «пульс» проекта."""
import re
import statistics
from datetime import date

# Списки из tests/special_sanity/check_pr_title.py в verl-project/verl (на 6 октября 2026 года). Готово.
ALLOWED_MODULES = [
    "fsdp", "megatron", "veomni", "sglang", "vllm", "trtllm", "rollout", "trainer",
    "tests", "training_utils", "recipe", "hardware", "deployment",
    "ray", "worker", "single_controller", "misc", "docker", "ci",
    "perf", "model", "algo", "env", "tool", "ckpt", "doc", "data", "cfg", "reward",
    "fully_async", "one_step_off",
]
ALLOWED_TYPES = ["feat", "fix", "refactor", "chore", "test"]


def verl_title_ok(title):
    """Заголовок PR по правилу CI verl: «[BREAKING][модули] тип: описание».

    - в начале может стоять префикс прогресса: одна цифра, косая черта, цифра или N — «[1/3]», «[2/N]»;
    - затем может стоять «[BREAKING]» (регистр не важен);
    - дальше обязательны квадратные скобки с одним или несколькими модулями через запятую
      (каждый — из ALLOWED_MODULES, регистр не важен);
    - пробел(ы), тип из ALLOWED_TYPES, двоеточие, пробел(ы) и непустое описание.
    Вернуть True или False.
    """
    # TODO
    ...


def vllm_title_ok(title):
    """Заголовок PR по правилу vLLM: один или несколько тегов в квадратных скобках подряд, без пробелов
    между ними (внутри тега пробелы можно: «[KV Offload]»), затем один пробел и описание.
    Пример: «[Bugfix][Scheduler] Fix priority handling». Вернуть True или False.
    """
    # TODO
    ...


def has_signoff(message, email):
    """DCO: есть ли в сообщении коммита отдельная строка «Signed-off-by: Имя <почта>» с непустым именем
    и именно этой почтой (без учёта регистра). Такую строку добавляет git commit -s. Вернуть True или False.
    """
    # TODO
    ...


def project_pulse(prs, today):
    """«Пульс» проекта по выборке внешних PR.

    prs — список словарей с датами в виде строк 'YYYY-MM-DD':
      'opened'      — когда открыт PR;
      'first_reply' — первый ответ мейнтейнера (None — ответа не было);
      'merged'      — когда слит (None — не слит).
    today — строка 'YYYY-MM-DD'. Вернуть словарь:
      'median_reply_days' — медиана дней от opened до first_reply среди PR с ответом (None, если таких нет);
      'unanswered_share'  — среди PR, открытых больше 14 дней назад, доля оставшихся без ответа (0.0, если таких нет);
      'merged_30d'        — сколько PR слито за последние 30 дней (0 ≤ today − merged ≤ 30 дней).
    """
    # TODO
    ...


if __name__ == "__main__":
    print(verl_title_ok("[trainer, fsdp] fix: keep grad norm finite"))
    print(vllm_title_ok("[Doc] Fix typo in quickstart"))
    print(has_signoff("Fix mask\n\nSigned-off-by: Ivan Petrov <ivan@example.com>", "ivan@example.com"))
  1. Неделя 1. Выберите проект из таблицы, снимите его «пульс», прочитайте CONTRIBUTING целиком и выпишите чек-лист на полстраницы. Соберите проект из исходников и прогоните тесты одного модуля. Уже здесь бывает первый вклад: инструкция по установке устарела.
  2. Неделя 2. Найдите issue без минимального примера или собственную находку из курса. Воспроизведите, сократите до 10–20 строк, напишите комментарий или новый issue.
  3. Неделя 3. Тест, затем исправление. PR по шаблону, с подписью, если нужна, с честной строкой о помощи ИИ.
  4. Неделя 4. Ревью: ответы на замечания, обновление ветки. Запишите в журнал, чему научило ревью, — это готовая история для собеседования (урок 11.3.6).
Проверь себя6 вопросов
1 Вы клонировали свой форк, а оригинал проекта ушёл вперёд на 40 коммитов. Какая пара команд обновит вашу ветку поверх свежего кода проекта?
2 В issue vLLM пишут: «у меня падает генерация, помогите». Какой ваш вклад полезнее всего на первой неделе?
3 Что верно про DCO и CLA? Выберите все верные.Можно выбрать несколько ответов
4 Вы впервые вносите вклад в llama.cpp и нашли две опечатки в комментариях. Как поступить по их CONTRIBUTING?
5 У проекта 171 открытый PR, а за последние 30 дней слито 8. Чему примерно равна «очередь» в месяцах (открытые / слитые за месяц)? Округлите до целого.
6 Какой текст можно доверить ИИ, не нарушая правил llama.cpp?
  • Вклад в open source — это работа с большим чужим кодом, бесплатное ревью от сильных инженеров и портфолио, которое проверяется по ссылке. Начинайте с проекта, которым пользовались в курсе.
  • Живость проекта видна по слияниям за месяц, очереди открытых PR, времени до первого ответа и тому, как отвечают новичкам. Звёзды почти ничего не говорят.
  • CONTRIBUTING — условия, при которых ваш PR прочитают: установка, стиль, тесты, формат заголовка, DCO или CLA, правила об ИИ. Перечитывайте его перед каждым PR.
  • Лестница: документация → перевод → воспроизведение бага → тест → исправление → функция. Одиночные опечатки большие проекты в 2026 году не принимают; минимальный пример и регрессионный тест ценят всегда.
  • ИИ может помогать разбираться, но автор вклада — вы: каждую строку нужно уметь объяснить, а помощь ИИ — раскрыть.

Дальше: «Соревнования: Kaggle и другие» — другой способ получить внешнюю проверку своих навыков: метрика, лидерборд и тысячи соперников с теми же данными.