Diffusers 文档
如何为 Diffusers 做出贡献 🧨
并获得增强的文档体验
开始使用
如何为 Diffusers 做出贡献 🧨
我们 ❤️ 来自开源社区的贡献!我们欢迎所有人,并且所有类型的参与——不仅仅是代码——都受到重视和赞赏。回答问题、帮助他人、联系沟通以及改进文档对社区都非常有价值,所以如果你愿意,请不要害怕并参与进来!
我们鼓励大家先在我们的公共 Discord 频道中说声 👋。我们讨论扩散模型的最新趋势、提问、展示个人项目、在贡献方面互相帮助,或者只是闲逛 ☕。
无论你选择哪种方式贡献,我们都努力成为一个开放、热情和友善的社区的一份子。请阅读我们的行为准则,并在互动中注意遵守。我们还建议你熟悉指导我们项目的道德准则,并请你遵守同样的透明和负责任原则。
我们非常重视来自社区的反馈,所以如果你认为你有宝贵的反馈可以帮助改进这个库,请不要害怕说出来——每一条消息、评论、问题和拉取请求(PR)都会被阅读和考虑。
概述
你可以通过多种方式做出贡献,从在 issue 和 discussion 中回答问题,到向核心库添加新的扩散模型。
下面,我们概述了不同的贡献方式,按难度升序排列。所有这些对社区都很有价值。
- 在 Diffusers 讨论区或 Discord 上提问和回答问题。
- 在 GitHub Issues 标签页上开启新的 issue 或在 GitHub Discussions 标签页上开启新的 discussion。
- 在 GitHub Issues 标签页上回答 issue 或在 GitHub Discussions 标签页上回答 discussion。
- 修复一个简单的 issue,标记为“Good first issue”,请见此处。
- 为文档做贡献。
- 贡献一个社区 Pipeline。
- 为示例做贡献。
- 修复一个更难的 issue,标记为“Good second issue”,请见此处。
- 添加一个新的 pipeline、模型或调度器,请见“新 Pipeline/模型”和“新调度器”的 issue。对于此贡献,请查看设计理念。
如前所述,所有贡献对社区都很有价值。下面,我们将更详细地解释每种贡献。
对于所有 4 - 9 的贡献,你都需要开启一个 PR。在开启一个拉取请求中有详细说明。
1. 在 Diffusers 讨论区或 Diffusers Discord 上提问和回答问题
任何与 Diffusers 库相关的问题或评论都可以在讨论区或 Discord 上提问。这类问题和评论包括(但不限于):
- 分享知识的训练或推理实验报告
- 个人项目展示
- 关于非官方训练示例的问题
- 项目提案
- 一般反馈
- 论文摘要
- 在基于 Diffusers 库构建的个人项目中寻求帮助
- 一般性问题
- 关于扩散模型的伦理问题
- ...
在论坛或 Discord 上提出的每个问题都积极鼓励社区公开分享知识,并且很可能在未来帮助到有同样问题的初学者。请随时提出你可能有的任何问题。本着同样的精神,通过回答这些问题,你对社区的帮助是巨大的,因为这样你就在为每个人公开记录知识,供大家学习。
请记住,你在提问或回答问题上投入的精力越多,公开记录的知识质量就越高。同样,提问得好、回答得好的问题会创建一个高质量的知识库,供所有人访问,而提问得差或回答得差的问题会降低公共知识库的整体质量。简而言之,一个高质量的问题或回答是*精确*、*简洁*、*相关*、*易于理解*、*易于访问*和*格式/提问良好*的。更多信息,请查看如何写一个好的 issue部分。
关于渠道的说明:论坛更容易被搜索引擎(如谷歌)索引。帖子按受欢迎程度而非时间顺序排名。因此,查找我们前段时间发布的问题和答案更容易。此外,论坛上发布的问题和答案可以轻松链接。相比之下,Discord 具有类似聊天的格式,适合快速的来回交流。虽然在 Discord 上你的问题很可能更快得到答案,但随着时间的推移,你的问题将不再可见。而且,在 Discord 上找到很久以前发布的信息要困难得多。因此,我们强烈建议使用论坛进行高质量的提问和回答,以期为社区创造持久的知识。如果 Discord 上的讨论产生了非常有趣的答案和结论,我们建议将结果发布在论坛上,以便未来的读者更容易获取这些信息。
2. 在 GitHub issues 标签页上开启新的 issue
🧨 Diffusers 库的稳健和可靠得益于用户们告知我们他们遇到的问题。所以感谢你报告一个 issue。
请记住,GitHub issues 是为直接与 Diffusers 库相关的技术问题、错误报告、功能请求或对库设计的反馈而设的。
简而言之,这意味着所有与 Diffusers 库的代码(包括文档)无关 的事情都不应该在 GitHub 上提问,而应该在论坛或 Discord 上提问。
在开启新的 issue 时,请考虑以下准则::
- 确保你已经搜索过你的问题是否已经被提出过(使用 GitHub Issues 下的搜索栏)。
- 请永远不要在另一个(相关的)issue 上报告一个新的 issue。如果另一个 issue 高度相关,请仍然开启一个新的 issue,并链接到相关的 issue。
- 确保你的 issue 是用英文写的。如果你对英语不自信,请使用像 DeepL 这样优秀的免费在线翻译服务,将你的母语翻译成英语。
- 检查你的问题是否可以通过更新到最新的 Diffusers 版本来解决。在发布你的 issue 之前,请确保 `python -c "import diffusers; print(diffusers.__version__)"` 的版本高于或匹配最新的 Diffusers 版本。
- 请记住,你在开启新 issue 时投入的精力越多,你的答案质量就会越高,Diffusers issues 的整体质量也会更好。
新的 issue 通常包括以下内容。
2.1. 可复现的、最小化的错误报告
错误报告应该总是包含一个可复现的代码片段,并且尽可能地最小化和简洁。具体来说:
- 尽可能地缩小错误的范围,不要只是把你整个代码文件都扔上来。
- 格式化你的代码。
- 除了 Diffusers 依赖的外部库之外,不要包含任何其他外部库。
- 总是提供关于你环境的所有必要信息;为此,你可以在你的 shell 中运行:`diffusers-cli env`,然后将显示的信息复制粘贴到 issue 中。
- 解释问题。如果读者不知道问题是什么,以及为什么这是一个问题,他(她)就无法解决它。
- 总是确保读者能以最少的努力复现你的问题。如果你的代码片段因为缺少库或未定义的变量而无法运行,读者就无法帮助你。确保你的可复现代码片段尽可能地最小化,并且可以被复制粘贴到一个简单的 Python shell 中运行。
- 如果为了复现你的问题需要一个模型和/或数据集,确保读者能够访问那个模型或数据集。你总是可以把你的模型或数据集上传到 Hub,以便于下载。尽量保持你的模型和数据集尽可能小,以便复现你的问题尽可能地轻松。
更多信息,请查看如何写一个好的 issue部分。
你可以在这里开启一个错误报告。
2.2. 功能请求
一个世界级的功能请求应该解决以下几点:
- 动机优先
- 它是否与库中的问题/困扰有关?如果是,请解释原因。提供一个展示问题的代码片段是最好的。
- 它是否与你项目需要的东西有关?我们很乐意了解!
- 这是你做过的并且认为可以造福社区的东西吗?太棒了!告诉我们它为你解决了什么问题。
- 写一个*完整的段落*来描述这个功能;
- 提供一个展示其未来用法的**代码片段**;
- 如果这与一篇论文有关,请附上链接;
- 附上你认为有帮助的任何额外信息(图纸、截图等)。
你可以在这里开启一个功能请求。
2.3 反馈
关于库设计的反馈,以及它好或不好的原因,极大地帮助核心维护者构建一个用户友好的库。要理解当前设计理念背后的哲学,请查看这里。如果你觉得某个设计选择不符合当前的设计理念,请解释为什么以及应该如何改变。如果某个设计选择过于遵循设计理念,从而限制了使用场景,请解释为什么以及应该如何改变。如果某个设计选择对你非常有用,也请留言,因为这是对未来设计决策的极好反馈。
你可以在这里开启一个关于反馈的 issue。
2.4 技术问题
技术问题主要关于库的某些代码为何以某种方式编写,或者某部分代码的作用。请确保链接到相关的代码,并详细说明为什么这部分代码难以理解。
你可以在这里开启一个关于技术问题的 issue。
2.5 提议添加新模型、调度器或 pipeline
如果扩散模型社区发布了你希望在 Diffusers 库中看到的新模型、pipeline 或调度器,请提供以下信息:
- 扩散 pipeline、模型或调度器的简要描述,并附上论文或公开发布的链接。
- 其任何开源实现的链接。
- 如果模型权重可用,请提供链接。
如果你愿意自己为模型做贡献,请告诉我们,以便我们能最好地指导你。另外,如果能找到,请不要忘记在 GitHub 上标记组件(模型、调度器、pipeline 等)的原始作者。
你可以在这里开启一个模型/pipeline/调度器的请求。
3. 在 GitHub issues 标签页上回答 issue
在 GitHub 上回答 issue 可能需要一些关于 Diffusers 的技术知识,但我们鼓励每个人都尝试一下,即使你不是 100% 确定你的答案是正确的。给出高质量 issue 回答的一些技巧:
- 尽可能简洁和最小化。
- 保持主题。对 issue 的回答应该只关注该 issue。
- 提供指向代码、论文或其他来源的链接,以证明或支持你的观点。
- 用代码回答。如果一个简单的代码片段是 issue 的答案或展示了如何解决问题,请提供一个完全可复现的代码片段。
此外,许多 issue 往往是跑题、与其他 issue 重复或无关的。如果你能回答这类 issue,鼓励 issue 的作者更精确、提供重复 issue 的链接或将他们引导到论坛或 Discord,这对维护者来说是极大的帮助。
如果你已经验证了发布的错误报告是正确的,并且需要在源代码中进行修正,请查看接下来的部分。
对于以下所有贡献,你都需要开启一个 PR。在开启一个拉取请求部分有详细说明。
4. 修复一个“Good first issue”
Good first issues 由 Good first issue 标签标记。通常,issue 已经解释了一个潜在的解决方案应该是什么样子,以便更容易修复。如果 issue 尚未关闭,并且你想尝试修复此 issue,你可以留言说“我想尝试这个 issue。” 通常有三种情况:
- a.) issue 描述已经提出了一个修复方案。在这种情况下,如果解决方案对你来说有意义,你可以开启一个 PR 或草稿 PR 来修复它。
- b.) issue 描述没有提出修复方案。在这种情况下,你可以询问一个提议的修复方案可能是什么样子,Diffusers 团队的某个人应该会很快回答。如果你对如何修复它有很好的想法,可以直接开启一个 PR。
- c.) 已经有一个开放的 PR 来修复该 issue,但该 issue 尚未关闭。如果该 PR 已经过时,你可以简单地开启一个新的 PR 并链接到过时的 PR。如果最初想修复 issue 的贡献者突然没有时间继续,PR 往往会过时。这在开源中经常发生,非常正常。在这种情况下,如果你能重新尝试并利用现有 PR 的知识,社区会非常高兴。如果已经有一个 PR 并且是活跃的,你可以通过给出建议、审查 PR 甚至询问是否可以为该 PR 做出贡献来帮助作者。
5. 为文档做贡献
一个好的库**总是**有好的文档!官方文档通常是库的新用户的第一个接触点,因此为文档做贡献是**非常有价值的贡献**。
为库做贡献可以有多种形式:
- 纠正拼写或语法错误。
- 纠正文档字符串的错误格式。如果你看到官方文档显示奇怪或链接损坏,我们非常高兴你花时间纠正它。
- 纠正文档字符串输入或输出张量的形状或维度。
- 澄清难以理解或不正确的文档。
- 更新过时的代码示例。
- 将文档翻译成另一种语言。
在官方 Diffusers 文档页面上显示的任何内容都是官方文档的一部分,可以在相应的文档源中进行更正、调整。
请查看此页面,了解如何在本地验证对文档所做的更改。
6. 贡献一个社区 pipeline
阅读社区 pipeline指南,了解 GitHub 和 Hugging Face Hub 社区 pipeline 之间的区别。如果你对我们为什么有社区 pipeline 感兴趣,可以看看 GitHub Issue #841(基本上,我们无法维护扩散模型可用于推理的所有可能方式,但我们也不想阻止社区构建它们)。
贡献一个社区 pipeline 是与社区分享你的创造力和工作的好方法。它让你可以在 DiffusionPipeline 的基础上构建,这样任何人都可以通过设置 `custom_pipeline` 参数来加载和使用它。本节将引导你创建一个简单的 pipeline,其中 UNet 只进行一次前向传播并调用调度器一次(一个“一步式” pipeline)。
为你的社区 pipeline 创建一个 one_step_unet.py 文件。这个文件可以包含你想要使用的任何包,只要用户安装了它。确保你只有一个继承自 DiffusionPipeline 的 pipeline 类,以便从 Hub 加载模型权重和调度器配置。在 `__init__` 函数中添加一个 UNet 和调度器。
你还应该添加 `register_modules` 函数,以确保你的 pipeline 及其组件可以使用 save_pretrained() 保存。
from diffusers import DiffusionPipeline
import torch
class UnetSchedulerOneForwardPipeline(DiffusionPipeline):
def __init__(self, unet, scheduler):
super().__init__()
self.register_modules(unet=unet, scheduler=scheduler)
- 在前向传播(我们建议定义为 `__call__`)中,你可以添加任何你想要的功能。对于“一步式” pipeline,创建一个随机图像,并通过设置 `timestep=1` 来调用 UNet 和调度器一次。
from diffusers import DiffusionPipeline
import torch
class UnetSchedulerOneForwardPipeline(DiffusionPipeline):
def __init__(self, unet, scheduler):
super().__init__()
self.register_modules(unet=unet, scheduler=scheduler)
def __call__(self):
image = torch.randn(
(1, self.unet.config.in_channels, self.unet.config.sample_size, self.unet.config.sample_size),
)
timestep = 1
model_output = self.unet(image, timestep).sample
scheduler_output = self.scheduler.step(model_output, timestep, image).prev_sample
return scheduler_output
现在,你可以通过向其传递一个 UNet 和调度器来运行 pipeline,或者如果 pipeline 结构相同,则加载预训练权重。
from diffusers import DDPMScheduler, UNet2DModel
scheduler = DDPMScheduler()
unet = UNet2DModel()
pipeline = UnetSchedulerOneForwardPipeline(unet=unet, scheduler=scheduler)
output = pipeline()
# load pretrained weights
pipeline = UnetSchedulerOneForwardPipeline.from_pretrained("google/ddpm-cifar10-32", use_safetensors=True)
output = pipeline()
你可以将你的 pipeline 作为 GitHub 社区 pipeline 或 Hub 社区 pipeline 分享。
通过在 Diffusers 仓库上开启一个拉取请求,并将 one_step_unet.py 文件添加到 examples/community 子文件夹中,来分享你的 GitHub pipeline。
7. 为训练示例做贡献
Diffusers 示例是位于 examples 中的一系列训练脚本。
我们支持两种类型的训练示例:
- 官方训练示例
- 研究性训练示例
研究性训练示例位于 examples/research_projects,而官方训练示例包括 examples 下的所有文件夹,除了 `research_projects` 和 `community` 文件夹。官方训练示例由 Diffusers 的核心维护者维护,而研究性训练示例由社区维护。这是出于与6. 贡献一个社区 pipeline中提出的官方 pipeline 与社区 pipeline 相同的原因:核心维护者不可能维护扩散模型的所有可能的训练方法。如果 Diffusers 核心维护者和社区认为某个训练范式过于实验性或不够流行,相应的训练代码应该放在 `research_projects` 文件夹中,并由作者维护。
官方训练和研究示例都包含一个目录,该目录包含一个或多个训练脚本、一个 `requirements.txt` 文件和一个 `README.md` 文件。为了让用户能够使用训练示例,需要克隆仓库:
git clone https://github.com/huggingface/diffusers
以及安装训练所需的所有额外依赖项:
cd diffusers
pip install -r examples/<your-example-folder>/requirements.txt
因此,在添加示例时,`requirements.txt` 文件应定义你的训练示例所需的所有 pip 依赖项,以便一旦安装了所有这些依赖项,用户就可以运行示例的训练脚本。例如,请参见 DreamBooth 的 `requirements.txt` 文件。
Diffusers 库的训练示例应遵循以下理念:
- 运行示例所需的所有代码都应在一个 Python 文件中找到。
- 应该能够通过命令行 `python <your-example>.py --args` 来运行示例。
- 示例应保持简单,并作为如何使用 Diffusers 进行训练的**一个示例**。示例脚本的目的**不是**创建最先进的扩散模型,而是复现已知的训练方案,而不添加过多的自定义逻辑。作为这一点的副产品,我们的示例也力求成为好的教育材料。
要贡献一个示例,强烈建议查看已有的示例,如 dreambooth,以了解它们应该是什么样子。我们强烈建议贡献者使用 Accelerate 库,因为它与 Diffusers 紧密集成。一旦示例脚本可以工作,请确保添加一个全面的 `README.md`,说明如何准确使用该示例。这个 README 应该包括:
- 一个如何运行示例脚本的示例命令,如这里所示。
- 一些训练结果(日志、模型等)的链接,展示用户可以期待的结果,如这里所示。
- 如果你正在添加一个非官方/研究性训练示例,**请不要忘记**添加一句话,说明你正在维护这个训练示例,并包括你的 git 句柄,如这里所示。
如果你正在为官方训练示例做贡献,请确保也为其文件夹添加一个测试,例如 examples/dreambooth/test_dreambooth.py。对于非官方训练示例,这不是必需的。
8. 修复一个“Good second issue”
Good second issues 由 Good second issue 标签标记。Good second issues 通常比 Good first issues 更复杂。issue 描述通常对如何修复问题提供的指导较少,并且需要感兴趣的贡献者对库有相当的理解。如果你有兴趣解决一个 good second issue,可以直接开启一个 PR 来修复它,并将 PR 链接到该 issue。如果你看到已经为该 issue 开启了一个 PR 但尚未合并,请查看原因并尝试开启一个改进的 PR。Good second issues 通常比 good first issues 更难合并,所以不要犹豫向核心维护者寻求帮助。如果你的 PR 差不多完成了,核心维护者也可以加入你的 PR 并提交代码,以使其合并。
9. 添加 pipelines、模型、调度器
Pipelines、模型和调度器是 Diffusers 库中最重要的部分。它们提供了对最先进的扩散技术的便捷访问,从而使社区能够构建强大的生成式 AI 应用。
通过添加一个新的模型、pipeline 或调度器,你可能会为依赖 Diffusers 的任何用户界面启用一个新的强大用例,这对于整个生成式 AI 生态系统来说都具有巨大的价值。
Diffusers 对所有这三个组件都有一些开放的功能请求——如果你还不知道想添加哪个特定组件,可以浏览一下:
在添加任何这三个组件之前,强烈建议你阅读理念指南,以更好地理解这三个组件的设计。请注意,我们不能合并与我们的设计理念严重偏离的模型、调度器或 pipeline 添加,因为这会导致 API 不一致。如果你根本不同意某个设计选择,请开启一个反馈 issue,以便可以讨论某个设计模式/设计选择是否应在整个库中更改,以及我们是否应更新我们的设计理念。整个库的一致性对我们非常重要。
请确保在 PR 中添加指向原始代码库/论文的链接,并最好直接在 PR 上 ping 原始作者,以便他们可以跟进进度并可能帮助解决问题。
如果你在 PR 中不确定或卡住了,不要犹豫留言寻求第一次审查或帮助。
Copied from 机制
在添加任何 pipeline、模型或调度器代码时,一个独特而重要的要理解的特性是 `# Copied from` 机制。你会在 Diffusers 代码库中到处看到这个,我们使用它的原因是为了保持代码库易于理解和维护。用 `# Copied from` 机制标记的代码强制与它所复制的代码相同。这使得在运行 `make fix-copies` 时,可以轻松地更新和传播更改到多个文件。
例如,在下面的代码示例中,StableDiffusionPipelineOutput 是原始代码,而 `AltDiffusionPipelineOutput` 使用 `# Copied from` 机制来复制它。唯一的区别是将类前缀从 `Stable` 更改为 `Alt`。
# Copied from diffusers.pipelines.stable_diffusion.pipeline_output.StableDiffusionPipelineOutput with Stable->Alt
class AltDiffusionPipelineOutput(BaseOutput):
"""
Output class for Alt Diffusion pipelines.
Args:
images (`List[PIL.Image.Image]` or `np.ndarray`)
List of denoised PIL images of length `batch_size` or NumPy array of shape `(batch_size, height, width,
num_channels)`.
nsfw_content_detected (`List[bool]`)
List indicating whether the corresponding generated image contains "not-safe-for-work" (nsfw) content or
`None` if safety checking could not be performed.
"""
要了解更多,请阅读这篇博客文章的 `~不要~ 重复你自己*` 部分。
如何写一个好的 issue
你的 issue 写得越好,它被迅速解决的机会就越大。
- 确保你为你的 issue 使用了正确的模板。你可以选择*错误报告*、*功能请求*、*关于 API 设计的反馈*、*新模型/pipeline/调度器添加*、*论坛*或一个空白 issue。在开启一个新 issue时,请确保选择正确的模板。
- 要精确:给你的 issue 一个合适的标题。尽量以最简单的方式阐述你的 issue 描述。你提交 issue 时越精确,理解和可能解决问题所需的时间就越少。确保一个 issue 只针对一个问题,而不是多个问题。如果你发现了多个问题,只需开启多个 issue。如果你的 issue 是一个 bug,尽量精确地说明是什么 bug——你不应该只写“diffusers 中的错误”。
- 可复现性:没有可复现的代码片段 == 没有解决方案。如果你遇到了一个 bug,维护者**必须能够复现**它。确保你包含一个可以复制粘贴到 Python 解释器中以复现问题的代码片段。确保你的代码片段可以工作,*即*没有缺失的导入或缺失的图像链接等。你的 issue 应该包含一个错误消息**和**一个可以无需任何更改即可复制粘贴以复现完全相同的错误消息的代码片段。如果你的 issue 使用了读者无法访问的本地模型权重或本地数据,那么问题就无法解决。如果你不能分享你的数据或模型,请尝试制作一个虚拟模型或虚拟数据。
- 简约:尽量帮助读者尽快理解问题,保持尽可能的简洁。移除所有与问题无关的代码/信息。如果你发现了一个 bug,试着创建一个最简单的代码示例来演示你的问题,不要一发现 bug 就把你的整个工作流程都扔到 issue 里。例如,如果你训练一个模型并在训练过程中的某个点出现错误,你应该首先尝试理解是训练代码的哪一部分导致了错误,并尝试用几行代码复现它。尽量使用虚拟数据而不是完整的数据集。
- 添加链接。如果你提到某个命名、方法或模型,请确保提供一个链接,以便读者能更好地理解你的意思。如果你提到某个特定的 PR 或 issue,请确保将其链接到你的 issue 中。不要假设读者知道你在说什么。你在 issue 中添加的链接越多越好。
- 格式化。确保通过将代码格式化为 Python 代码语法,将错误消息格式化为普通代码语法,来美化你的 issue。更多信息,请参阅官方 GitHub 格式化文档。
- 请不要将您的问题看作是一个需要解决的工单,而应将其视为一本优秀百科全书中的一个优美条目。每一个新增的问题都是对公开知识库的贡献。通过提交一个撰写精良的问题,您不仅能让维护者更容易解决您的问题,还能帮助整个社区更好地理解该库的某个方面。
如何编写一个好的 PR
- 要像变色龙一样。理解现有的设计模式和语法,并确保您添加的代码能够无缝地融入现有代码库。与现有设计模式或用户界面有显著差异的拉取请求将不会被合并。
- 要高度专注。一个拉取请求应该只解决一个问题。确保不要陷入“顺便修复另一个问题”的陷阱。审查一次性解决多个不相关问题的拉取请求要困难得多。
- 如果可行,请尝试添加一个代码片段,展示您所添加功能的使用示例。
- 您的拉取请求的标题应该是对其贡献内容的总结。
- 如果您的拉取请求解决了某个 issue,请在拉取请求的描述中提及该 issue 的编号,以确保它们被关联起来(这样查阅该 issue 的人就会知道您正在处理它);
- 要表明工作正在进行中,请在标题前加上
[WIP]
前缀。这有助于避免重复工作,并将其与准备合并的 PR 区分开; - 请尝试按照如何编写一个好的 issue 中说明的方式来组织和格式化您的文本。
- 确保现有测试能够通过;
- 添加高覆盖率的测试。没有高质量的测试 = 不合并。
- 如果您正在添加新的
@slow
测试,请确保它们能通过RUN_SLOW=1 python -m pytest tests/test_my_new_model.py
命令。CircleCI 不会运行慢速测试,但 GitHub Actions 每晚都会运行!
- 所有公共方法都必须有信息丰富的文档字符串(docstrings),并且能与 markdown 很好地协同工作。请参阅
pipeline_latent_diffusion.py
作为示例。 - 由于代码库的快速增长,确保不添加会显著增加仓库大小的文件非常重要。这包括图像、视频和其他非文本文件。我们倾向于利用 hf.co 上托管的
dataset
,例如hf-internal-testing
或 huggingface/documentation-images 来存放这些文件。如果是外部贡献,您可以随意将图像添加到您的 PR 中,并请求 Hugging Face 成员将您的图像迁移到此数据集中。
如何提交 PR
在编写代码之前,我们强烈建议您搜索现有的 PR 或 issue,以确保没有其他人已经在做同样的事情。如果您不确定,最好先开一个 issue 来获取一些反馈。
您需要具备基本的 git
技能才能为 🧨 Diffusers 做出贡献。git
不是最容易使用的工具,但它有最好的手册。在 shell 中输入 git --help
并享受吧。如果您更喜欢书籍,Pro Git 是一个非常好的参考资料。
请按照以下步骤开始贡献 (支持的 Python 版本)
通过点击仓库页面上的 ‘Fork’ 按钮来复刻(fork)该仓库。这会在您的 GitHub 用户账户下创建一个代码副本。
将您的复刻克隆到本地磁盘,并将基础仓库添加为远程仓库
$ git clone git@github.com:<your GitHub handle>/diffusers.git $ cd diffusers $ git remote add upstream https://github.com/huggingface/diffusers.git
创建一个新分支来存放您的开发更改
$ git checkout -b a-descriptive-name-for-my-changes
不要 在 main
分支上工作。
在虚拟环境中运行以下命令来设置开发环境
$ pip install -e ".[dev]"
如果您已经克隆了仓库,您可能需要执行 git pull
来获取库的最新更改。
- 在您的分支上开发新功能。
在您开发功能时,应确保测试套件能够通过。您应像这样运行受您更改影响的测试
$ pytest tests/<TEST_TO_RUN>.py
在运行测试之前,请确保您安装了测试所需的依赖项。您可以通过此命令进行安装
$ pip install -e ".[test]"
您也可以使用以下命令运行完整的测试套件,但随着 Diffusers 的不断壮大,这需要一台性能强劲的机器才能在合理的时间内得出结果。以下是相应的命令
$ make test
🧨 Diffusers 依赖 black
和 isort
来统一格式化其源代码。在您做出更改后,使用以下命令一次性应用自动样式修正和无法自动化的代码验证
$ make style
🧨 Diffusers 还使用 ruff
和一些自定义脚本来检查编码错误。质量控制会在 CI 中运行,但您也可以使用以下命令运行相同的检查
$ make quality
一旦您对自己的更改感到满意,使用 git add
添加已更改的文件,并使用 git commit
在本地记录您的更改
$ git add modified_file.py
$ git commit -m "A descriptive message about your changes."
定期将您的代码副本与原始仓库同步是一个好主意。这样您可以快速处理变更
$ git pull upstream main
使用以下命令将更改推送到您的账户
$ git push -u origin a-descriptive-name-for-my-changes
当您满意后,请转到您在 GitHub 上的复刻仓库网页。点击‘Pull request’,将您的更改发送给项目维护者进行审查。
如果维护者要求您进行修改,这很正常。核心贡献者也会遇到这种情况!为了让每个人都能在拉取请求中看到更改,请在您的本地分支上工作,并将更改推送到您的复刻仓库。它们会自动显示在拉取请求中。
测试
我们提供了一个广泛的测试套件来测试库的行为和一些示例。库的测试可以在 tests 文件夹 中找到。
我们喜欢使用 pytest
和 pytest-xdist
,因为它们速度更快。在仓库的根目录下,可以这样使用 pytest
来运行库的测试
$ python -m pytest -n auto --dist=loadfile -s -v ./tests/
实际上,make test
就是这样实现的!
您可以指定一个较小的测试集,以便只测试您正在开发的功能。
默认情况下,慢速测试会被跳过。将 RUN_SLOW
环境变量设置为 yes
来运行它们。这将下载数 GB 的模型——请确保您有足够的磁盘空间和良好的网络连接,或者有足够的耐心!
$ RUN_SLOW=yes python -m pytest -n auto --dist=loadfile -s -v ./tests/
unittest
也完全支持,以下是如何使用它来运行测试
$ python -m unittest discover -s tests -t . -v $ python -m unittest discover -s examples -t examples -v
将复刻的 main 分支与上游(HuggingFace)的 main 分支同步
为了避免 ping 上游仓库(这会给每个上游 PR 添加引用注释,并给相关开发人员发送不必要的通知),在同步复刻仓库的 main 分支时,请遵循以下步骤
- 如果可能,请避免使用复刻仓库上的分支和 PR 与上游同步。相反,直接合并到复刻的 main 分支。
- 如果绝对需要一个 PR,请在检出您的分支后使用以下步骤
$ git checkout -b your-branch-for-syncing
$ git pull --squash --no-commit upstream main
$ git commit -m '<your message without GitHub references>'
$ git push --set-upstream origin your-branch-for-syncing
风格指南
对于文档字符串,🧨 Diffusers 遵循 Google 风格。
< > 在 GitHub 上更新