如何为 Diffusers 贡献力量 🧨
我们 ❤️ 开源社区的贡献!欢迎所有人参与,我们重视并感谢各种形式的参与——不仅仅是代码。回答问题、帮助他人、积极参与以及改进文档对社区都至关重要,所以如果您愿意,请不要犹豫,积极参与进来!
我们鼓励每个人首先在我们的公共 Discord 频道中 👋 打个招呼。我们在这里讨论扩散模型的最新趋势,提问、展示个人项目、互相帮助贡献代码,或者只是简单地聊聊天 ☕。
无论您选择哪种方式进行贡献,我们都力求成为一个开放、友好和善意的社区。请阅读我们的行为准则,并在互动中牢记并遵守。我们也建议您熟悉指导我们项目的伦理指南,并遵循同样的透明度和责任原则。
我们非常重视来自社区的反馈,因此,如果您认为自己有宝贵的反馈可以帮助改进库,请不要犹豫,大胆提出来——我们阅读并审视每一个消息、评论、问题和拉取请求 (PR)。
概览
您可以通过多种方式做出贡献,从回答问题和参与讨论到为核心库添加新的扩散模型。
在下文中,我们将概述不同的贡献方式,并按难度升序排列。所有这些贡献对社区都非常有价值。
- 在Diffusers 讨论论坛或Discord上提问和回答问题。
- 在GitHub Issues 选项卡上打开新的问题,或在GitHub Discussions 选项卡上发起新的讨论。
- 回答GitHub Issues 选项卡上的问题或GitHub Discussions 选项卡上的讨论。
- 修复一个简单的问题,这些问题通常带有“新手友好问题”标签,请查看此处。
- 为文档做出贡献。
- 贡献一个社区管道。
- 为示例做出贡献。
- 修复一个更困难的问题,这些问题通常带有“中等难度问题”标签,请查看此处。
如前所述,**所有贡献对社区都非常有价值**。在下文中,我们将更详细地解释每种贡献方式。
对于第 4 到第 9 种贡献方式,您需要创建一个 PR。如何在创建拉取请求中详细解释了操作步骤。
1. 在 Diffusers 讨论论坛或 Diffusers Discord 上提问和回答问题
任何与 Diffusers 库相关的问题或评论都可以在讨论论坛或Discord上提出。此类问题和评论包括(但不限于):
- 训练或推理实验报告,旨在分享知识
- 个人项目的展示
- 非官方训练示例的问题
- 项目提案
- 一般反馈
- 论文摘要
- 请求帮助,解决基于 Diffusers 库的个人项目
- 一般问题
- 关于扩散模型的伦理问题
- …
在论坛或 Discord 上提出的每一个问题都积极鼓励社区公开分享知识,并且很可能帮助将来遇到相同问题的初学者。请提出您可能遇到的任何问题。同样地,通过回答此类问题,您对社区有巨大的帮助,因为这样您就在公开地为每个人提供知识文档,供他们学习。
**请**记住,您在提问或回答问题时付出的努力越多,公开知识文档的质量就越高。同样,措辞清晰且答案完善的问题创建了高质量的知识库,供所有人访问,而问题或答案表达不清则会降低公共知识库的整体质量。简而言之,高质量的问题或答案是精确的、简洁的、相关的、易于理解的、可访问的,以及格式良好/表达清晰的。有关更多信息,请查看如何撰写高质量的问题部分。
**关于渠道的说明**:论坛更容易被搜索引擎(如 Google)索引。帖子按受欢迎程度而不是按时间顺序排列。因此,更容易查找我们之前发布的问题和答案。此外,论坛中发布的问题和答案可以轻松链接。相比之下,Discord 采用类似聊天的格式,鼓励快速双向沟通。虽然您在 Discord 上获得问题的答案可能需要更少的时间,但您的问题随着时间的推移将不再可见。此外,在 Discord 上查找之前发布的信息也更加困难。因此,我们强烈建议您将论坛用于高质量的问题和答案,以期为社区创建持久性的知识。如果 Discord 上的讨论产生了非常有趣的答案和结论,我们建议您将结果发布到论坛上,以便更多未来的读者可以访问这些信息。
2. 在 GitHub Issues 选项卡上打开新的问题
感谢用户的积极反馈,🧨 Diffusers 库才变得如此强大和可靠。感谢您报告问题。
请记住,GitHub Issues 专用于与 Diffusers 库直接相关的技术问题、错误报告、功能请求或对库设计的反馈。
简而言之,这意味着所有**不**与**Diffusers 库代码**(包括文档)相关的内容都**不**应该在 GitHub 上提问,而应该在论坛或Discord上提问。
在打开新问题时,请考虑以下指南:
- 确保您已搜索过之前是否有人提出过相同的问题(在 GitHub 的 Issues 下使用搜索栏)。
- 请勿在其他(相关)问题上报告新问题。如果另一个问题高度相关,请无论如何都打开一个新问题,并链接到相关问题。
- 请确保您的问题是用英文书写的。如果您不熟悉英语,请使用一些优秀的免费在线翻译服务,例如 DeepL 将您的母语翻译成英语。
- 检查您的问题是否可以通过更新到最新版本的 Diffusers 来解决。在发布您的问题之前,请确保
python -c "import diffusers; print(diffusers.__version__)"
的版本高于或与最新版本的 Diffusers 版本匹配。 - 请记住,您在提交新问题时付出的努力越多,您得到的答案质量就越高,Diffusers 问题的整体质量也越好。
新的问题通常包括以下内容。
2.1. 可复现的最小化错误报告
错误报告应始终包含可复现的代码片段,并尽可能简洁明了。这意味着更详细地
- 尽可能缩小错误范围,**不要只是直接粘贴整个代码文件**。
- 格式化您的代码。
- 除了 Diffusers 依赖的库之外,不要包含任何外部库。
- **始终**提供有关您的环境的所有必要信息;为此,您可以在 shell 中运行:
diffusers-cli env
并将显示的信息复制粘贴到问题中。 - 解释问题。如果读者不知道问题是什么以及为什么是问题,他/她将无法解决它。
- **始终**确保读者能够以尽可能少的努力复现您的问题。如果您的代码片段由于缺少库或未定义的变量而无法运行,读者将无法帮助您。确保您的可复现代码片段尽可能简洁,并且可以复制粘贴到简单的 Python shell 中。
- 如果为了复现您的问题需要模型和/或数据集,请确保读者可以访问该模型或数据集。您可以随时将您的模型或数据集上传到 Hub 以便轻松下载。尝试使您的模型和数据集尽可能小,以便尽可能轻松地复现您的问题。
有关更多信息,请查看 如何编写优质问题 部分。
您可以在 此处 打开错误报告。
2.2. 功能请求
一个世界一流的功能请求需要解决以下几点
- 首先是动机
- 它是否与库中的某个问题/困扰有关?如果是,请解释原因。最好提供一个演示问题的代码片段。
- 它是否与您项目中需要的东西有关?我们很乐意听到您的想法!
- 您是否已经完成了一些工作,并认为可以使社区受益?太棒了!告诉我们它为您解决了什么问题。
- 用完整的段落描述该功能;
- 提供一个代码片段来演示其未来用法;
- 如果这与论文有关,请附加链接;
- 附加您认为可能有所帮助的任何其他信息(图纸、屏幕截图等)。
您可以在 此处 打开功能请求。
2.3 反馈
关于库设计的反馈以及它为什么好或不好的反馈对核心维护者来说非常有帮助,可以帮助他们构建一个用户友好的库。要了解当前设计理念背后的理念,请查看 此处。如果您觉得某个设计选择与当前的设计理念不符,请解释原因以及应该如何更改。如果某个设计选择过于遵循设计理念,从而限制了用例,请解释原因以及应该如何更改。如果某个设计选择对您非常有用,请也留下注释,因为这对未来的设计决策来说是很好的反馈。
您可以在 此处 打开有关反馈的问题。
2.4 技术问题
技术问题主要关于库中的某些代码为什么以某种方式编写,或者代码的某一部分的作用是什么。请确保链接到相关的代码,并提供有关此代码部分难以理解的原因的详细信息。
您可以在 此处 打开有关技术问题的问题。
2.5 建议添加新的模型、调度器或管道
如果扩散模型社区发布了您希望在 Diffusers 库中看到的新的模型、管道或调度器,请提供以下信息
- 扩散管道、模型或调度器的简要描述,以及指向论文或公开发布的链接。
- 指向其任何开源实现的链接。
- 如果模型权重可用,请提供链接。
如果您愿意自己为模型做出贡献,请告知我们,以便我们能够更好地指导您。此外,如果您能找到组件(模型、调度器、管道等)的原始作者,请不要忘记通过 GitHub 句柄对其进行标记。
您可以在 此处 打开模型/管道/调度器的请求。
3. 在 GitHub 问题选项卡上回答问题
在 GitHub 上回答问题可能需要一些 Diffusers 的技术知识,但我们鼓励每个人都尝试一下,即使您不确定您的答案是否完全正确。一些提供高质量问题答案的技巧
- 尽可能简洁明了。
- 保持主题相关性。对问题的回答应该只关注问题本身。
- 提供指向代码、论文或其他来源的链接,以证明或支持您的观点。
- 用代码回答。如果一个简单的代码片段是问题的答案,或者展示了如何解决问题,请提供一个完全可复现的代码片段。
此外,许多问题往往是偏离主题、重复其他问题或不相关的。如果您能回答此类问题,将对维护人员有很大帮助,鼓励问题作者更加精确,提供重复问题的链接,或将其重定向到 论坛 或 Discord。
如果您已验证发布的错误报告是正确的,并且需要在源代码中进行更正,请查看下一节。
对于以下所有贡献,您都需要打开一个 PR。在 打开拉取请求 部分详细说明了如何操作。
4. 修复“新手友好问题”
标记为“**良好入门 Issue**” 的 Issue 可以通过 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. 贡献文档
一个优秀的库**始终**需要良好的文档!官方文档通常是库新用户接触的第一点,因此,贡献文档是**非常有价值的贡献**。
贡献库可以有多种形式
- 更正拼写或语法错误。
- 更正 docstring 的错误格式。如果您发现官方文档显示异常或链接已损坏,我们非常乐意您抽出时间进行更正。
- 更正 docstring 输入或输出张量的形状或维度。
- 阐明难以理解或不正确的文档。
- 更新过时的代码示例。
- 将文档翻译成其他语言。
显示在 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
现在,您可以通过向 Pipeline 传递 UNet 和调度器来运行它,或者如果 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 仓库 上打开一个 Pull Request 并将 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. 解决“中等难度问题”
中等难度问题 标记有 中等难度问题 标签。中等难度问题通常比 简单问题 更复杂。问题描述通常会提供较少的解决问题的指导,并且需要贡献者对库有较好的理解。如果您有兴趣解决中等难度问题,请随时提交 PR 来修复它,并将 PR 链接到问题。如果您看到此问题已提交 PR 但未合并,请查看了解未合并的原因,并尝试提交改进的 PR。与简单问题相比,中等难度问题通常更难合并,因此请不要犹豫,向核心维护者寻求帮助。如果您的 PR 即将完成,核心维护者也可以加入您的 PR 并提交,以便将其合并。
9. 添加管道、模型和调度器
管道、模型和调度器是 Diffusers 库中最重要的组成部分。它们提供了对最先进的扩散技术的轻松访问,从而允许社区构建强大的生成式 AI 应用程序。
通过添加新的模型、管道或调度器,您可以为任何依赖于 Diffusers 的用户界面启用新的强大用例,这对于整个生成式 AI 生态系统都具有巨大的价值。
Diffusers 针对所有三个组件提供了一些开放的功能请求 - 如果你还不知道你想添加哪个特定组件,可以随意浏览一下它们。
在添加任何三个组件之前,强烈建议您阅读 设计理念指南,以便更好地理解任何三个组件的设计。请注意,我们无法合并与我们的设计理念严重偏离的模型、调度器或管道添加,因为这会导致 API 不一致。如果您从根本上不同意某个设计选择,请提交 反馈问题,以便讨论是否应在库中的所有地方更改某些设计模式/设计选择,以及我们是否应该更新我们的设计理念。库的一致性对我们来说非常重要。
请确保将原始代码库/论文的链接添加到 PR 中,理想情况下,还应直接在 PR 上 ping 原始作者,以便他们能够跟踪进度并可能帮助解答问题。
如果您在 PR 中不确定或遇到困难,请不要犹豫,留下消息请求首次审查或帮助。
复制机制
在添加任何管道、模型或调度器代码时,需要理解的一个独特且重要的功能是 # 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.
"""
要了解更多信息,请阅读 ~不要~ 重复自己* 博客文章的此部分。
如何提交高质量的问题
您提交的问题越清晰,它被快速解决的可能性就越大。
- 确保您使用了正确的问题模板。您可以从错误报告、功能请求、关于 API 设计的反馈、新模型/管道/调度器添加、论坛或空白问题中选择。在提交 新问题 时,请确保选择了正确的模板。
- 准确性:为您的问题提供合适的标题。尝试尽可能简单地表达您的问题描述。您在提交问题时越准确,理解问题并最终解决问题所需的时间就越少。确保每个问题只针对一个问题,而不是多个问题。如果您发现了多个问题,只需提交多个问题即可。如果您的问题是错误,请尽可能精确地描述错误是什么 - 您不应该只写“Diffusers 中的错误”。
- 可复现性:没有可复现的代码片段 == 没有解决方案。如果您遇到错误,维护者**必须能够复现**它。确保您包含一个可以复制粘贴到 Python 解释器中以复现问题的代码片段。确保您的代码片段有效,例如,没有缺少导入或缺少图像链接等。您的问题应包含错误消息**和**一个可以复制粘贴而无需任何更改即可复现完全相同的错误消息的代码片段。如果您的问题使用了本地模型权重或读者无法访问的本地数据,则无法解决该问题。如果您无法共享您的数据或模型,请尝试创建一个虚拟模型或虚拟数据。
- 最小化:尝试通过尽可能简洁地表达,尽可能帮助读者快速理解问题。删除与问题无关的所有代码/所有信息。如果您发现了一个错误,请尝试创建您可以用来演示问题的最简单的代码示例,而不要在发现错误后立即将您的整个工作流程转储到问题中。例如,如果您训练了一个模型并在训练过程中某一点遇到了错误,您应该首先尝试理解训练代码的哪一部分导致了错误,并尝试用几行代码来复现它。尝试使用虚拟数据而不是完整数据集。
- 添加链接。如果您指的是某个名称、方法或模型,请确保提供链接,以便读者能够更好地理解您的意思。如果您指的是特定的 PR 或问题,请确保将其链接到您的问题。不要假设读者知道您在说什么。您添加到问题中的链接越多越好。
- 格式。通过将代码格式化为 Python 代码语法,并将错误消息格式化为普通代码语法,确保您的问题格式良好。有关更多信息,请参阅 官方 GitHub 格式化文档。
- 不要把您的问题当作一张需要解决的票据,而是将其视为一篇写得很好百科全书中的一个漂亮的条目。每个添加的问题都是对公开知识的贡献。通过添加一个写得好的问题,您不仅使维护者更容易解决您的问题,而且还有助于整个社区更好地理解库的某个方面。
如何提交高质量的 PR
- 成为变色龙。理解现有的设计模式和语法,并确保您的代码添加能够无缝地融入现有的代码库。与现有设计模式或用户界面显著不同的拉取请求将不会被合并。
- 专注于一点。一个拉取请求应该只解决一个问题。确保不要陷入“既然我们正在添加它,也修复另一个问题”的陷阱。一次审查解决多个不相关问题的拉取请求要困难得多。
- 如果适用,请尝试添加一个代码片段,演示如何使用您的添加。
- 您的拉取请求的标题应概括其贡献。
- 如果您的拉取请求解决了某个问题,请在拉取请求描述中提及问题编号,以确保它们链接在一起(并且查看问题的人知道您正在处理它);
- 若要指示一项正在进行的工作,请在标题前加上
[WIP]
。这有助于避免重复工作,并将其与准备合并的 PR 区分开来; - 请尝试按照如何撰写优质 Issue中说明的方式来表述和格式化您的文本。
- 确保现有的测试通过;
- 添加高覆盖率的测试。没有质量测试 = 无法合并。
- 如果您正在添加新的
@slow
测试,请确保它们可以使用RUN_SLOW=1 python -m pytest tests/test_my_new_model.py
通过。CircleCI 不会运行缓慢的测试,但 GitHub Actions 每天晚上都会运行!
- 所有公共方法都必须具有信息丰富的文档字符串,并且能够与 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”按钮来分叉存储库。这会在您的 GitHub 用户帐户下创建代码副本。
将您的分叉克隆到本地磁盘,并将基本存储库添加为远程
$ git clone [email protected]:<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”将您的更改发送给项目维护者以供审查。
如果维护者要求您进行更改,这没关系。这也会发生在核心贡献者身上!因此,每个人都可以看到 Pull request 中的更改,在您的本地分支中工作并将更改推送到您的分叉。它们将自动出现在 Pull request 中。
测试
包含一个广泛的测试套件来测试库行为和几个示例。库测试可以在tests 文件夹中找到。
我们喜欢pytest
和pytest-xdist
,因为它速度更快。从存储库的根目录开始,以下是如何使用pytest
运行库测试
$ python -m pytest -n auto --dist=loadfile -s -v ./tests/
事实上,这就是make test
的实现方式!
您可以指定更小的测试集,以便仅测试您正在处理的功能。
默认情况下,缓慢的测试会被跳过。将RUN_SLOW
环境变量设置为yes
以运行它们。这将下载许多千兆字节的模型——请确保您有足够的磁盘空间和良好的互联网连接,或者要有足够的耐心!
$ 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 添加参考注释并向参与这些 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 上的更新