PyMC 开源贡献完整指南:从个人提交到机构合作的全流程实践
2026/9/16 21:51:38 网站建设 项目流程

PyMC 开源贡献完整指南:从个人提交到机构合作的全流程实践

【免费下载链接】pymcBayesian Modeling and Probabilistic Programming in Python项目地址: https://gitcode.com/GitHub_Trending/py/pymc

PyMC 是一个以 Python 编写的开源贝叶斯统计建模与概率编程框架,其官方贡献指南(docs/source/contributing/index.md)明确了这是一个"集体努力"的项目:任何人都可以以自己擅长的方式参与建设。本文以该指南为核心骨架,完整梳理 PyMC 的贡献方式、Pull Request 全流程、代码礼仪、质量检查、测试运行、文档构建、开发环境搭建以及机构合作路径,并结合仓库内真实源码与配置逐一佐证,帮助你从"想贡献"到"会贡献"走通每一步。

一、贡献方式的总体图景:PyMC 是集体努力的开源项目

PyMC 的贡献指南开宗明义地指出:PyMC 是一个开源、集体努力的项目("PyMC is an open source, collective effort"),有非常多的方式可以让它变得更好,且所有方式都受到欢迎。编码(coding)和文档(documentation)是最常见的贡献类型,但绝非全部——指南明确列出以下同样重要的非代码贡献方向:

  • 报告 Bug 或提出改进建议:通过 GitHub 的 issue 新建入口提交问题报告或改进提案;
  • 在社区论坛回答问题:帮助其他用户在 Discourse 论坛上解答疑问;
  • 教学与传播最佳实践:通过写博客或做演讲,推广 PyMC 的正确用法;
  • 参与 PyMCon 的策划:PyMCon 是 PyMC 社区主办的科学会议;
  • 推广与外联:包括联系潜在的赞助公司、向可能在工作与学术研究中用得上 PyMC 的人介绍它,以及确保使用 PyMC 的学者在论文中正确引用;
  • 协助筹款工作
  • 为 PyMCon 的视频添加时间戳

指南特别提示:如果还不确定自己能贡献什么、如何开始,可以通过 Discourse 论坛联系团队,也可以订阅office-hours标签参与定期举办的"office hours",获得面向贡献者的专门支持。对于刚接触开源的新手,指南还推荐参考 sprint 材料——即使不参加 sprint 活动,这套材料也是目前可用的最详细贡献入门指导。

二、通过 Pull Request 贡献:完整的分步教程

代码与文档贡献都需要通过 GitHub 向 pymc-devs 组织下的仓库提交 Pull Request(PR)。仓库中保存了完整的步骤化教程 docs/source/contributing/pr_tutorial.md,推荐的工作流是fork 主仓库 → 克隆到本地 → 在 feature 分支上开发。其完整步骤如下:

  1. 先阅读代码贡献礼仪(见下文第三节);

  2. Fork 主仓库:点击主仓库页面右上角的 "Fork" 按钮,在你的 GitHub 账户下生成一份代码副本;

  3. 克隆并配置远程仓库

    git clone git@github.com:<your GitHub handle>/pymc.git cd pymc git remote add upstream git@github.com:pymc-devs/pymc.git

    其中upstream指向 pymc-devs 官方主仓库,origin指向你自己的 fork;

  4. 创建 feature 分支

    git checkout -b my-feature

    注意:始终使用 feature 分支。在任何仓库中,都不应养成直接在main分支上工作的习惯;

  5. 搭建开发环境:项目运行依赖在requirements.txt,开发依赖在requirements-dev.txt。指南推荐使用 miniconda 通过 conda 环境文件一键创建:

    • Linux/MacOS:

      conda env create -f conda-envs/environment-dev.yml
    • Windows 与 Windows(Git Bash):

      conda env create -f conda-envs/windows-environment-dev.yml

    创建完成后激活环境并以可编辑模式安装本地包:

    conda activate pymc-dev pip install -e .

    另一种等价方式是在虚拟环境中执行pip install -e .后再pip install -r requirements-dev.txt。从仓库结构看,conda-envs/environment-dev.yml 与 conda-envs/windows-environment-dev.yml 分别覆盖了 Unix 与 Windows 平台,Windows 版本单独维护正是为了处理平台差异(例如 docs/source/contributing/python_style.md 中提到的 Windows 上 pre-commit 钩子对 YAML 文件的空白改动问题);

  6. 在 feature 分支上开发功能git checkout my-feature,分支已存在时无需-b标志);

  7. 提交前运行 pre-commit 检查

    pip install pre-commit pre-commit run --all # 手动运行全部检查 pre-commit install # 安装钩子,让每次 commit 前自动运行
  8. 暂存并提交git add modified_files后执行git commit记录本地改动;

  9. 同步上游并推送:提交后建议与主仓库同步,避免分叉:

    git fetch upstream git rebase upstream/main git push -u origin my-feature

    若是首次贡献,部分 CI 任务的启动需要维护者批准;

  10. 发起 PR:进入你 fork 后的仓库网页,点击 "Pull request" 按钮把改动提交给维护者审查。PR 就绪后,建议对照 docs/source/contributing/pr_checklist.md 逐项自检。

三、代码贡献礼仪:让协作更顺畅的约定

指南在pr_etiquette一节中专门规定了代码贡献的行为准则,这些约定直接决定了 PR 能否被高效地审查与合入:

  • 尽早打开 Draft PR:开始处理一个 issue 时,在完成第一次提交后就立即以Draft(草稿)状态打开 PR(详见 PR 教程),以便尽早获得实现细节或 API/功能层面的反馈,同时避免重复劳动;
  • 新功能先提案:提交新功能 PR 之前,先通过 issue 或 Discussion 与维护者讨论提案。根据提案内容,维护者可能会将你引导到其他仓库,例如pymc-experimentalpymc-examples
  • issue 认领规则:任何没有对应开放 PR 的 issue 都可认领。反之,一个开放的 PR 就是认领该 issue 的方式——请不要在 issue 中做出不切实际的承诺;
  • PR 的"最近活跃"判定:若 PR 长时间没有动静,可能会被关闭或由他人接手。"长时间"没有硬性标准,通常一个无阻塞的正常 PR 每几天会有一次活动,最终由核心开发者根据贡献者、改动性质与上下文因素综合判断;
  • 中断时请留言:如果你被耽搁或需要暂停,请在 PR 中留言说明无法推进到可合入状态。核心开发者会根据改动性质(紧急 Bug 修复 vs. 新功能)决定是否重新指派。

代码类贡献的具体方式是参与开放 issue 的讨论或提交解决方案;文档类贡献则可以从带有docs标签的开放 issue 入手。

四、提交 PR 前的检查清单

docs/source/contributing/pr_checklist.md 是合入前的"体检表",逐项对照可以显著提高 PR 被接受的概率:

  • 关联 issue:若 PR 解决某个 issue,应在 PR 标题中描述该问题,并在 PR描述中提及 issue 编号,从而自动生成指向原 issue 的链接。不要把 issue 编号写进标题——标题中的编号不会生成链接,且读者无法凭编号判断含义;
  • docstring 规范:所有公共方法必须有信息充分的 docstring,并在合适时给出示例用法;docstring 遵循 numpydoc 风格;
  • 使用 Draft PR:打开 PR 时在下拉菜单中选择 "Create draft pull request" 以标识工作仍在进行中;
  • 文档与高覆盖率测试:增强功能(enhancement)要获得接受,配套的文档与高覆盖率测试是必要条件;
  • 补充示例 notebook:添加新功能时,考虑在pymc-examples仓库中新增一个示例 notebook,并先在示例仓库打开一个提案 issue 讨论 notebook 的具体范围;
  • 回归检查:运行pymc-examples中会受到改动影响的分析示例,这不仅可能暴露单元测试发现不了的 Bug,也能展示你的贡献对最终用户的改进;
  • 无 pre-commit 报错:参考 docs/source/contributing/python_style.md 与 docs/source/contributing/jupyter_style.md 安装并运行;
  • 全部测试通过:所有测试需从零重建后全部通过,参见 docs/source/contributing/running_the_test_suite.md。

五、代码质量保障:pre-commit 与 Python 风格指南

docs/source/contributing/python_style.md 说明了如何利用 pre-commit 在本地复现 CI 中的代码质量检查:

  1. 在虚拟环境中安装:pip install pre-commit
  2. 启用钩子:pre-commit install

启用后,每次git commit都会按仓库根目录的.pre-commit-config.yaml定义运行检查,任一钩子失败即阻断提交。你需要修复问题(必要时)、重新git add,再重新 commit。其他常用操作包括:

  • 跳过全部检查git commit -m "wip lol" --no-verify
  • 跳过单个钩子(Linux 示例):SKIP=ruff git commit -m "<descriptive message>"
  • 手动运行全部钩子pre-commit run --all-files
  • 对指定文件运行pre-commit run --files <file_1> <file_2> ... <file_n>

常见问题排查

  • pre-commit 只检查已暂存文件:若既有 staged 又有 unstaged 改动,钩子只作用于 staged 部分;若反复报同样的格式化问题,先检查是否有未暂存的改动;
  • Windows 上 environment YAML 的空白改动:pre-commit 钩子的已知 Bug 可能改动部分环境 YAML 文件,上游修复前应忽略这些改动。要完成提交,可先pre-commit uninstall停用自动钩子,确保手动运行pre-commit run --all后再提交;
  • mypy 步骤失败:仓库通过 mypy 持续改进类型安全,但目前仍有大量文件存在未解决的类型问题,因此允许部分文件在 mypy 检查中失败。若 mypy 钩子报错,可能是你的改动引入了类型问题(应修复),也可能是修复了类型问题(值得庆祝)。无论哪种情况,都要仔细阅读 mypy 钩子的日志输出,其中包含处理指引。也可以手动运行python scripts/run_mypy.py [--verbose]复现检查——仓库中保存了该脚本 scripts/run_mypy.py。

Jupyter 笔记本的风格要求

文档与示例中的 notebook 还需遵循 docs/source/contributing/jupyter_style.md 的约定,要点包括:首个单元格需包含 MyST 目标((notebook_name)=)、一级标题与 post 指令(含日期、tags、category、author);markdown 必须是合法 MyST,且绝不使用 url 链接引用其他 notebook 或文档,而应使用{ref}交叉引用以保证版本化文档中的自引用不失效;变量命名要语义化并标注维度;采样结果统一用idata命名 InferenceData 变量;notebook 末尾需要## Authors章节与## Watermark章节(输出 Python 与依赖版本,watermark库已包含在requirements-dev.txt中);最后一个单元格是固定的页脚 include 指令。pre-commit 同样对这些 notebook 运行检查,可用pre-commit run --files notebook1.ipynb notebook2.ipynb手动验证。

六、运行测试套件

docs/source/contributing/running_the_test_suite.md 说明 PyMC 的测试基于 pytest。首先安装测试依赖:

pip install -r requirements-dev.txt

重要提醒:完整测试套件需要运行数小时,因此建议只运行与你改动相关的具体测试。

常用测试命令:

  • 运行单个测试文件

    pytest -v tests/model/test_core.py

    -v--verbose)会打印当前正在运行的测试用例名称;

  • 按名称过滤用例:用-k匹配模式,例如运行test_core.py中名称含 "coord" 的全部用例:

    pytest -v tests/model/test_core.py -k coord
  • 生成覆盖率报告

    pytest -v --cov=pymc --cov-report term-missing tests/<name of test>.py

    --cov=pymc统计pymc包的覆盖率,--cov-report term-missing打印被测试代码访问到的行号。由于只跑了局部测试,覆盖率数字会很低,但你可以借此关注自己改动的具体代码行是否被覆盖。

当你对改动有足够信心后即可推送并打开 PR,GitHub Actions 流水线会运行完整测试套件;若有失败,可回到本地复现并修复。仓库的测试代码按模块组织在 tests/ 目录下,与pymc/包结构一一对应,例如 tests/model/test_core.py 对应 pymc/model/core.py 的核心模型逻辑。

七、本地构建文档

docs/source/contributing/build_docs.md 给出了文档构建流程。注意文档构建不支持 Windows,Windows 用户应在 Docker 容器内构建。

首先安装文档依赖(在仓库根目录执行):

conda env create -f conda-envs/environment-docs.yml pip install -e .

仓库根目录的 Makefile 封装了构建流程:

  • make html:使用 sphinx-build 构建文档;
  • make clean:删除缓存与中间文件(仅在重构内容或编辑 toctree 时必要;只改单页时可跳过以加快构建。若页面显示异常,再依次执行make cleanmake html排查);
  • make rtd:链式执行make clean并附加额外选项与环境变量,尽量模拟 readthedocs 构建。注意:它不会像真正的 readthedocs 那样在干净环境中重装依赖,但会执行core_notebooks文件夹内的全部 notebook(默认不执行),这会把构建时间延长数分钟(6 个 notebook 各需约 20 秒到 5 分钟);
  • make view:使用 Python 的webbrowser模块在浏览器中打开生成的静态站点,无需启动服务器即可预览。

八、开发环境的多重选择:Docker 与 Gitpod

使用 Docker 隔离开发环境

docs/source/contributing/docker_container.md 说明仓库提供了 Dockerfile,用于隔离构建问题与支持本地开发。安装 Docker、克隆仓库后,通过脚本 scripts/docker_container.sh 构建镜像并启动容器:

cd pymc bash scripts/docker_container.sh build # 构建 pymc 镜像 bash scripts/docker_container.sh bash # 以 bash 进入容器 bash scripts/docker_container.sh jupyter # 以 jupyter notebook(端口 8888)进入容器

仓库中的 scripts/Dockerfile 与 scripts/dev.Dockerfile 共同支撑了该构建流程。

使用 Gitpod 零配置开发

docs/source/contributing/using_gitpod.md 介绍了浏览器端开发环境 Gitpod 的优势:绕开本地机器配置问题、省时、省磁盘空间。工作流如下:

  1. 先 fork 主仓库;
  2. 创建 Gitpod 账户并通过 GitHub 登录授权;
  3. 在 Gitpod 的集成设置中为 GitHub 授予user:emailpublic_reporepoworkflow权限:

  1. 创建 "New Workspace",选择 fork 后的仓库;若列表中没有,可在 "Context URL" 粘贴https://github.com/yourusername/pymc后创建。Gitpod 会拉取容器并构建环境,约需数分钟:

  1. 环境就绪后,终端会出现类似(base) gitpod@reshamas-pymc-0ygu5rf74md:/workspace/pymc$的提示符。该环境使用 micromamba 引导完整的 conda 环境,安装过程约需 5~10 分钟;
  2. git remote -v核对远程仓库:origin指向你的 fork,upstream指向官方仓库;
  3. pip list | grep pymcpython3 --version确认 pymc 与 Python 版本;
  4. 同步仓库:git checkout main,再git pull upstream main --tags拉取代码与版本标签,最后pip install -e .更新可编辑安装,并用python -c "import pymc; print(pymc.__version__)"验证版本。

开始工作前记得创建 feature 分支(git checkout -b feature-branch),并按git addgit commitgit push origin feature-branch的流程操作。Gitpod 免费计划每月提供 500 额度(约 50 小时标准工作区);需要注意其工作区生命周期策略:默认在无操作 30 分钟后停止(最长可调至 24 小时),工作区 14 天后删除,但固定(pin)的工作区不会被自动删除

九、深入核心开发:实现新分布与开发者指南

对希望深度参与核心开发的贡献者,仓库还提供了两份进阶文档。

实现一个新的 RandomVariable 分布

docs/source/contributing/implementing_distribution.md 面向希望向库中新增分布(Distribution)的开发者,给出了五步清单:

  1. 创建新的RandomVariableOp
  2. 实现对应的Distribution类;
  3. 为新RandomVariable添加测试;
  4. logp/logcdf/icdf/support_point方法添加测试;
  5. 编写新Distribution的文档。

其核心思想是:PyMC 的Distribution构建在 PyTensor 的RandomVariable之上,并实现logplogcdficdfsupport_point方法以及初始化与校验辅助逻辑,最引人注目的是shape/dims/observed关键字、替代参数化方式与默认transform。创建新的RandomVariable前,先确认该分布是否已存在于 NumPy 库——若是,应先加入 PyTensor 库再导入 PyMC;同时并非所有新分布都需要新的RandomVariable,例如OrderedLogisticOrderedProbit只是Categorical分布的特殊参数化。文档提供了完整的RandomVariable实现骨架,包括signature(NumPy 风格签名,标明各输入输出的核心维度)、dtype(离散变量标准为"int64",连续变量为"floatX")、_print_name(文本与 LaTeX 表示)以及rng_fn(接收 NumPyRandomState、分布参数与size,返回样本的采样实现)。普通用户不需要接触这些复杂性,直接使用pm.CustomDist之类的辅助方法即可。

PyMC 开发者指南

docs/source/contributing/developer_guide.md 从实现层面解释了 PyMC 的设计:概率分布类继承自ContinuousDiscrete,二者又继承定义高层 API 的Distribution。在pm.Model()上下文内调用pm.Normal("z", 0, 5)会返回一个 PyTensorTensorVariable,其背后经由Distribution.distAPI 调用对应的RandomVariableOp;模型上下文相当于一台"磁带机",记录 named_vars、free_RVs、observed_RVs、deterministics、potentials、missing_values 等信息。文档还深入讲解了logp的求值机制、pm.Model编译的logp/dlogp系列函数、MCMC 中CompoundStep(Metropolis-within-Gibbs 概念的实现,见 pymc/step_methods/compound.py)、NUTS 动态 HMC、变分推断(pymc/variational/inference.py 与 pymc/variational/opvi.py)以及前向采样等内部机制,并坦诚讨论了实现中踩过的坑(shape 处理、numpy 随机方法、Python 实现的采样器带来的性能开销等)。

十、版本发布流程

docs/source/contributing/release_checklist.md 描述了维护者侧的发布工作流:

  • 通过版本专属的 milestone跟踪所有相关 issue 与 PR;
  • 确认没有不应随版本发布的重大已知 Bug;
  • 提交一个 PR提升版本号__init__.py)并编辑RELEASE-NOTES.md:在顶部新建 "vNext" 小节、把标题改为发布版本与日期、按以往格式添加一行致谢发布经理。PR 名称不要与版本同名,并像普通贡献者一样推送到自己的 fork;
  • 合并 PR 后确认 master 分支的 CI 流水线全部通过;
  • v1.2.3格式创建 Tag 并配有人性化标题的 Release;此后 GitHub Actionrelease-pipeline会自动构建并把新版本发布到 PyPI。

排错提示:若需"撤销发布",可在 PyPI 与 GitHub 上手动删除,但PyPI 不接受相同版本号的再次发布release-pipelinetest-install-job可能因 PyPI 索引更新不及时而失败。发布后还需把 Zenodo 生成的版本专属 DOI 徽章复制进发布说明、关闭并重命名已发布 milestone 并新建 "vNext" milestone、关注 conda-forge 的pymc-feedstock自动更新 PR(可能需手动干预)、用新版本重跑示例 notebook,并确认文档站点稳定版已指向新版本。

十一、机构贡献:成为 Institutional Partner 或 Sponsor

除了个人贡献,PyMC 也接受机构层面的支持。指南明确指出机构可以通过两种方式参与:

  • 成为机构合作伙伴(Institutional Partners)
  • 成为赞助商(Sponsors)

这两类身份的详细说明与资金相关条款记录在仓库根目录的 GOVERNANCE.md 中(其Institutional Partners and FundingSponsors小节),有合作意向的机构可通过指南中给出的邮箱pymc.devs@gmail.com联系项目组。此外,docs/logos/sponsors/目录下存放了 numfocus、odsc、pymc-labs 等现有赞助方的标识素材,可见机构赞助已是 PyMC 生态的现实组成部分。

十二、贡献者文档导航总览

贡献指南的索引页通过隐藏 toctree 把整套贡献文档组织为四个层次,方便按需查阅(以下均以仓库根目录为基准):

层次文档适用场景
Tutorialsdocs/source/contributing/pr_tutorial.md第一次提交 PR 的完整步骤
How-to guidesdocs/source/contributing/build_docs.md、docs/source/contributing/docker_container.md、docs/source/contributing/running_the_test_suite.md、docs/source/contributing/review_pr_pymc_examples.md、docs/source/contributing/using_gitpod.md、docs/source/contributing/implementing_distribution.md构建文档、容器开发、跑测试、审查示例 PR、Gitpod 环境、实现新分布
Reference contentdocs/source/contributing/python_style.md、docs/source/contributing/jupyter_style.md、docs/source/contributing/pr_checklist.md、docs/source/contributing/release_checklist.md风格规范、检查清单、发布流程
In depth explanationsdocs/source/contributing/versioning_schemes_explanation.md版本管理方案背后的原理

仓库根目录的 CONTRIBUTING.md 则是一份精简入口,将外部访问者快速引导至上述贡献文档站点。整套体系从"想贡献"的动机出发,一路覆盖到合入、发布与机构合作,构成了一条完整的开源参与闭环——无论你是第一次提交 PR 的新手,还是准备实现新分布的资深开发者,都可以在这套文档与仓库源码中找到对应的路线图。

【免费下载链接】pymcBayesian Modeling and Probabilistic Programming in Python项目地址: https://gitcode.com/GitHub_Trending/py/pymc

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询