如何贡献#

每个人都可以为 Flax 做出贡献,Flax 开发团队重视每个人的贡献!你可以通过多种方式做出贡献,而不仅仅是编写代码。在 Flax GitHub 讨论页面上回答问题、互相帮助以及改进 Flax 文档对 Flax 生态系统都非常有价值。

如果你能宣传 Flax,例如为 Flax GitHub 存储库加星标,或在使用了 Flax 的项目的博客文章中引用 Flax,我们也会非常感谢。

本项目遵循 谷歌的开源社区准则

贡献方式#

我们欢迎拉取请求 (PR),特别是对于那些 标记为 PR 就绪的问题。对于其他提议,你应该首先打开一个 GitHub Issue 或 GitHub Discussion,开始讨论你计划的贡献。

使用拉取请求贡献代码#

Flax 开发团队使用 Git 进行所有开发。要做出贡献,你应该具备 GitGitHub 的基本知识。(你可以通过 Git 的官方 入门 - 首次 Git 设置 和 GitHub 的 设置 Git 指南学习如何设置 Git。)

要在 GitHub 上为 Flax 贡献代码,请按照以下步骤操作

从 fork 创建拉取请求#

  1. 使用 GitHub 的 Web UI,通过单击 github.com/google/flax 存储库页面上的“Fork”按钮来 fork Flax 存储库。这会在你自己的 GitHub 中创建一个 Flax 存储库的 fork(副本)。

    参考:从 fork 创建拉取请求

  2. 安装 Python >=3.7

  3. (可选)创建虚拟环境或 Docker 容器。有关如何设置 Docker 容器的详细信息,请参阅 dev/README.md。要设置虚拟环境,请运行以下命令

    python3 -m virtualenv env
    . env/bin/activate
    

    这确保你的所有依赖项都安装在此环境中。

  4. 使用 git clone 克隆你本地 fork 的 Flax 存储库。然后,使用 PyPi 安装所需的软件包。这使你能够在修改代码后立即测试它

    git clone https://github.com/YOUR_USERNAME/flax
    cd flax
    pip install -e ".[all,testing,docs]"
    

    你还可以使用 uv 来设置开发环境

    uv sync --all-extras
    
  5. 设置 pre-commit 钩子,这将在每次 git 提交期间运行一些自动检查,并可能更新一些需要更改的文件。

    pip install pre-commit
    pre-commit install
    
  6. 将 Google Flax 存储库(不是你的 fork)添加为上游远程,以便你可以使用它来同步你的更改。

    git remote add upstream http://www.github.com/google/flax
    
  7. 创建一个分支,例如 my_development_branch,你将从该分支进行开发

    git checkout -b my_development_branch
    
  8. 使用你喜欢的编辑器(我们推荐 Visual Studio Code)实现你的更改。

    通过从存储库顶部运行以下命令来确保测试通过

    ./tests/run_all_tests.sh
    
  9. 完成更改后,不要忘记创建提交(了解如何编写提交消息

    git add file1.py file2.py ...
    # or use `git add .` to add all changed files
    git commit -m "Your commit message"
    

    然后将你的代码与主存储库同步

    git fetch upstream
    git rebase upstream/main
    
  10. 最后,将你的提交推送到你的 my_development_branch,并在你的 fork 中创建一个远程分支,你可以使用该分支来创建拉取请求

git push --set-upstream origin my_development_branch

运行命令后,你应在你的 (VS Code) 终端输出中获得一个用于创建拉取请求的 GitHub 链接。如果你在 git push 之后没有收到链接,请使用 GitHub Web UI 来创建拉取请求。

  1. 确保你的拉取请求通过了 Flax PR 清单。如果通过,请从 Flax 存储库创建一个拉取请求并发送以供审查。有关使用拉取请求的更多信息,请参阅 GitHub 帮助

你可以在 GitHub 的 从 fork 创建拉取请求 文档中了解更多信息。

添加或更新依赖项#

要添加或更新依赖项,你必须在更新 pyproject.toml 文件后使用 uv,以确保 uv.lock 文件是最新的。

uv sync --all-extras

或者,你可以使用 uv add 来自动添加或更新依赖项,例如

uv add 'some-package>=1.2.3'

更新 Jupyter Notebooks#

我们使用 jupytext 来维护 docs/notebooks 中文档的两个同步副本:一个采用 Jupyter Notebook (.ipynb) 格式,另一个采用 Markdown (.md) 格式。

前者可以直接在 Google Colab 中打开和执行。Markdown 使跟踪版本控制中的更改/差异更容易,例如,GitHub Web UI,因为 .ipynb 文件基于 JSON。

编辑 Jupyter Notebooks (.ipynb)#

对于进行实质性修改代码和输出的较大更改,建议在 JupyterColab 中编辑笔记本。

如果您选择在 Colab 中工作,请转到文件并点击上传笔记本,然后选择您的文件。将其加载到 Colab 并进行编辑后,请确保您运行了单元格,并且没有任何错误。点击运行时,然后选择全部运行。完成后,点击文件 > 下载 > 下载 ipynb。您可能还需要使用 sphinx-build 来测试文件是否正确执行,如上所述。

在 Jupyter Notebook 中进行更改后,请按照下面的同步笔记本步骤操作。

编辑 Markdown 文件 (.md)#

对于对笔记本的文本内容进行较小的更改,最简单的方法是使用文本编辑器编辑 .md 版本。

在 Markdown 文件中进行更改后,请按照下面的同步笔记本步骤操作。

同步笔记本#

在编辑了文档的 .ipynb.md 版本后,请使用 jupytext 通过在更新的笔记本上运行 jupytext --sync 来同步这两个版本。

首先,请确保您已安装 jupytext。jupytext 版本应与 .pre-commit-config.yaml 中指定的版本匹配(目前为 v1.13.8)。

pip install jupytext==1.13.8

然后,在 Jupyter Notebook 中进行更改后,通过运行以下命令将其内容与 Markdown 等效文件同步

jupytext --sync path/to/the/file.ipynb

同样,要将 Markdown 文件与其 Jupyter Notebook 版本同步,请运行

jupytext --sync path/to/the/file.md

请注意,如果您收到错误,并且这是您第一次在 Jupyter Notebook 中工作,您可能需要(重新)创建该文档的同步副本(这将在下面的创建新笔记本部分中详细说明)

jupytext --set-formats ipynb,md:myst path/to/the/notebook.ipynb

完成 .md.ipynb 文件的同步后,您可以使用 pre-commit 框架来执行 Flax GitHub CI 中使用的相同检查,以检查它们是否已正确同步

git add docs -u  # pre-commit runs on files in git staging.
pre-commit run jupytext

创建新笔记本#

如果您要向文档添加新的 Jupyter Notebook,可以使用 jupytext --set-formats。它可以设置文件的 Jupyter Notebook (.ipynb) 和 Markdown (.md) 版本

jupytext --set-formats ipynb,md:myst path/to/the/notebook.ipynb

它的工作原理是在笔记本文件中添加一个 "jupytext" 元数据字段,该字段指定所需的格式。调用 jupytext --sync 命令时,它可以识别这些格式。

在您更改文件后,请按照上面同步笔记本部分的步骤操作,以保持 Markdown 和 Jupyter Notebook 文件内容的同步。

Sphinx 构建中的笔记本#

一些笔记本会自动构建,作为预提交检查和 Read the Docs 构建的一部分。如果单元格引发错误,构建将失败。如果这些错误是有意的,您可以捕获它们,或者使用 raises-exceptions 元数据标记单元格(示例 PR)。您必须在 .ipynb 文件中手动添加此元数据。当其他人重新保存笔记本时,它将被保留。

我们从构建中排除了一些笔记本,例如,因为它们包含长时间的计算。请参阅 conf.py 中的 exclude_patterns

更新拉取请求内容#

每个拉取请求最好仅限于一个提交,因此如果您有多个提交,请将它们合并。

假设您的拉取请求中现在只有一个提交,并且想要添加在审查期间请求的更改

  1. 在编辑器中本地进行更改。

  2. 运行 git commit -a --amend。这将更新提交内容并允许您编辑提交消息。

  3. 此时,单独使用 git push 将导致错误。请改用 git push --force

  4. 检查是否完成:您提交的更改应立即反映在 Github Web UI 中。

故障排除#

拉取请求中的提交过多#

如果您的 PR 有过多的提交与之关联(例如,超过五个),您需要将它们合并。否则,Flax 文档构建过程可能会失败并显示错误消息。这是因为以下原因

  • 您的拉取请求中有超过五个提交;并且

  • 当提交树太大时,Flax 源同步过程会失败。

要合并您的提交,您可以将您的分支变基到 main 并创建一个包含您所有更改的新提交,请运行以下命令

git rebase main && git reset --soft main && git commit

这将把您的所有更改应用到主分支。请注意,如果您在处理更改时必须解决任何冲突(例如,您执行了 pull upstream main 导致冲突),那么您将不得不再次解决这些冲突。

成功变基您的分支后,您应该推送您的更改。并且由于您更改了提交历史记录,您可能必须使用 git push --force

贡献者许可协议#

对此项目的贡献必须附带贡献者许可协议。您(或您的雇主)保留您的贡献的版权;这仅仅是允许我们使用和重新分发您的贡献,作为项目的一部分。请访问 https://cla.developers.google.com/ 查看您当前的文件协议或签署新的协议。

您通常只需要提交一次 CLA,因此如果您已经提交过一次(即使是为了不同的项目),您可能不需要再次提交。