Skip to content

Commit

Permalink
📝 docs: refine xdoctest project
Browse files Browse the repository at this point in the history
  • Loading branch information
SigureMo committed Jan 7, 2024
1 parent 90f281c commit 41d8943
Showing 1 changed file with 70 additions and 63 deletions.
133 changes: 70 additions & 63 deletions src/posts/xdoctest-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ figcaption {
}
</style>

[将 xdoctest 引入飞桨工作流](https://github.com/PaddlePaddle/Paddle/issues/54705)】 是第六届“中国软件开源创新大赛”开源任务挑战赛赛道——[飞桨框架任务挑战赛](https://github.com/PaddlePaddle/Paddle/issues/53172)的赛题之一(赛题五),由社区开发者**顺师傅**主导,是 Paddle 社区迄今为止影响范围最大的开源活动 🎊。该项目规模极其庞大,涉及一千多个 API 示例的整合和数十万行代码的优化,由超过 20 名社区开发者共同参与完成。
[将 xdoctest 引入飞桨工作流](https://github.com/PaddlePaddle/Paddle/issues/54705)】 是第六届“中国软件开源创新大赛”开源任务挑战赛赛道——[飞桨框架任务挑战赛](https://github.com/PaddlePaddle/Paddle/issues/53172)的赛题之一(赛题五),由社区开发者**顺师傅**[@megemini](https://github.com/megemini)主导,是 Paddle 社区迄今为止影响范围最大的开源活动 🎊。该项目规模极其庞大,涉及一千多个 API 示例的整合和数十万行代码的优化,由超过 20 名社区开发者共同参与完成。

- 想知道顺师傅的故事 👉 [【开源江湖闲聊录】社区掌舵人:顺师傅的 Paddle 之旅](./shun-story.md)
- 想了解“中国软件开源创新大赛” 👉 [活动详情](https://aistudio.baidu.com/competition/detail/911/0/introduction)[活动剪影](./xian-event.md)
Expand All @@ -43,16 +43,20 @@ figcaption {

### 01 - 关于任务

`Python`源代码与官方文档中的`Example`,也就是示例代码,是学习与使用 Paddle 框架非常重要的学习与参考依据。赛题要求将 xdoctest 引入到飞桨框架的工作流中,利用 xdoctest 来自动检查示例代码运行正确,且与输出结果匹配,以确保示例代码输出的一致性,进一步提高飞桨框架示例代码的质量。
文档是用户了解项目最主要的方式,而 API 文档更是承担了用户了解每个 API 使用方式的重要入口。Paddle 为上千个公开 API 提供了详尽的 API 文档,每个 API 都有对应的示例代码,以便用户能够最直观的了解 API 的使用方式。

但由于历史原因,Paddle 的 API 文档中的示例代码是直接使用 Python 代码块形式编写的,这使得我们无法对示例代码的输出进行自动化检查,从而无法保证展示给用户的示例代码的有效性,导致经常出现用户发现文档中的输出与实际运行结果不一致的情况。

<!-- 示例代码 -->
<div style="display: flex; justify-content: center">
<figure style="width: 80%;">
<img src="../images/xdoctest-project/xdoctest-1.jpg"/>
<figcaption>Python 源码的示例代码的部分</figcaption>
<figcaption>过去 API 文档示例代码格式</figcaption>
</figure>
</div>

而本任务,则是要求将 xdoctest 工具引入到 Paddle CI 检查流水线中,利用 xdoctest 能够自动执行示例代码,并对示例代码的输出进行检查的特性,对 Paddle API 文档中的示例代码进行检查,确保示例代码的输出结果与实际运行结果一致,从而提高 Paddle API 文档的质量。

#### >>> print(why_do_it) 为什么做这个事情?

文档是开发者接触 Paddle 的第一手学习资料,需要保证用户能够 **快速、正确** 地上手 Paddle 框架,代码示例的重要程度也就不言而喻。
Expand All @@ -73,24 +77,27 @@ figcaption {

![xdoctest-02](../images/xdoctest-project/xdoctest-2.jpg)

- 代码和注释混用的方式。
- 需要用户自己区分普通注释与代码输出。
- 不符合 Python 开源项目里对可交互示例的实践和习惯。
- 代码检查不严格,只保证运行,**不保证正确**
- 需要用户自己区分普通注释与代码输出
- 不符合 Python 开源项目里对可交互示例的实践和习惯
- 代码检查不严格,只保证运行,**不保证正确**

#### >>> print(solutions) 都有哪些现成的解决方案?

[xdoctest](https://xdoctest.readthedocs.io/en/latest/) 是一个示例代码自动执行和检查工具,可以自动执行 Python docstring 中的示例代码,并对示例代码输出进行检查。

![xdoctest-03](../images/xdoctest-project/xdoctest-3.jpg)

Python 标准库中内置了 [doctest](https://docs.python.org/3/library/doctest.html) 可用于示例代码的自动执行和检查。但 doctest 是使用正则表达式来解析示例代码部分的,这使得示例代码的编写必须遵循严格的格式要求。

[xdoctest](https://xdoctest.readthedocs.io/en/latest/) 是一个基于 AST 的 Python 示例代码自动执行和检查工具,相比 doctest,xdoctest 的示例代码格式要求更加宽松,xdoctest 作者在博客 [Extending Python Doctests – xdoctest](https://erotemic.wordpress.com/2018/06/12/extending-python-doctests-xdoctest/) 详细阐述了这一点。

显然后者是更适合 Paddle 的需求的,因此我们选择将 xdoctest 作为引入 Paddle CI 检查流水线的基础工具。这里为什么说是基础工具呢?是因为在后期迭代开发过程中发现 xdoctest 本身也有很多不足,因此我们在 xdoctest 的基础上进行了大量的二次开发,以满足 Paddle 的需求。

### 03 - 挑战

#### >>> 可以预见的挑战

- 有 800 万开发者每天都在学习、使用 Paddle 框架,xdoctest 的引入**需要无缝切换**
- Paddle 框架包含 1400+ API,还涉及到版本更迭、API 迭代,**框架庞大复杂**
- 由于深度学习特殊性,同一示例代码在不同设备环境(CPU、GPU)会有差异性,**需要区别验证**
- 有 800 万开发者每天都在学习、使用 Paddle 框架,xdoctest 的引入**需要无缝切换**
- Paddle 框架包含 1400+ API,还涉及到版本更迭、API 迭代,**框架庞大复杂**
- 由于深度学习特殊性,同一示例代码在不同设备环境(CPU、GPU)会有差异性,**需要区别验证**

#### >>> 项目的三个大坑

Expand Down Expand Up @@ -118,14 +125,14 @@ figcaption {

##### 设计文档(抛开可以预见的那些挑战不说)

- Paddle 代码和 docs 都有代码检查逻辑
- 代码检查逻辑还不尽相同
- Paddle 与 PyTorch 很多实现方式不一样
- PyTorch 的检查方式并不完整
- Paddle 代码和 docs 都有代码检查逻辑
- 代码检查逻辑还不尽相同
- Paddle 与 PyTorch 很多实现方式不一样
- PyTorch 的检查方式并不完整

##### 后知后觉

- 文档中的示例代码未及时随着框架的演进和接口的的变化更新
- 文档中的示例代码未及时随着框架的演进和接口的的变化更新
- 接口变动、逻辑变动
- 与单元测试关注点不同,测试方案不同

Expand All @@ -150,43 +157,43 @@ figcaption {
</figure>
</div>

#### >>> print(just_use_it) 直接用 Xdoctest 不行吗?
#### >>> print(just_use_it) 直接用 xdoctest 不行吗?

Xdoctest 并不适用如 Paddle 此类庞大复杂的框架。
xdoctest 并不适用如 Paddle 此类庞大复杂的框架。

- **【接口遍历不全】** 对于全局命名等情况无能为力
- **【检查环境混用】** 不能隔离多个示例检查的逻辑
- **【无数据类型检查】** 不能比对浮点数、复数等情况
- **【无法进行全局控制】** 如 timeout,错误语句等
- **【接口遍历不全】** 对于全局命名等情况无能为力
- **【检查环境混用】** 不能隔离多个示例检查的逻辑
- **【无数据类型检查】** 不能比对浮点数、复数等情况
- **【无法进行全局控制】** 如 timeout,错误语句等

#### >>> print(technique_solutions) 主要的技术解决方案

- **针对【接口遍历不全】** 此次任务沿用飞桨原有的接口遍历逻辑,将原有的 xdoctest 的检查逻辑进行拆分
- **针对【检查环境混用】** 此次任务利用多进程技术对执行环境进行隔离,进而防止环境污染等情况
- **针对【无数据类型检查】** 此次任务对 xdoctest 的检查逻辑进行 patch,从而可以比对整数、浮点数、复数等情况
- **针对【无法进行全局控制】** 引入全局指令、全局语句检查机制
- **针对【接口遍历不全】** 此次任务沿用飞桨原有的接口遍历逻辑,将原有的 xdoctest 的检查逻辑进行拆分
- **针对【检查环境混用】** 此次任务利用多进程技术对执行环境进行隔离,进而防止环境污染等情况
- **针对【无数据类型检查】** 此次任务对 xdoctest 的检查逻辑进行 patch,从而可以比对整数、浮点数、复数等情况
- **针对【无法进行全局控制】** 引入全局指令、全局语句检查机制

#### >>> print(technique_solutions.\_\_more\_\_)

进行重构,优化迁移环境

- 全局指令转换
- 抽象示例检查类
- 解耦示例检查流程与检查类
- 解耦示例检查结果
- 日志级别分离
- 全局指令转换
- 抽象示例检查类
- 解耦示例检查流程与检查类
- 解耦示例检查结果
- 日志级别分离

#### >>> print(workload) 工作量有多大?

由于 Paddle 的公开 API 数量众多,且需要全量的优化对应文档的示例代码,所以在该阶段遇到第三个大坑——**工程量巨大**

因此,我们选择**相信开源的力量**,号召 Paddle 社区的伙伴一起参与进来!

- 代码到文档全流程
- 数千个 API
- 数百个源文件
- 数十万行代码
- 已有 24 位开发者近 3 个月的贡献
- 代码到文档全流程
- 上千个 API
- 数百个源文件
- 数十万行代码
- 已有 24 位开发者近 3 个月的贡献

### 02 - 里程碑

Expand Down Expand Up @@ -214,7 +221,7 @@ Xdoctest 并不适用如 Paddle 此类庞大复杂的框架。

#### >>> print(missions_1) 开源任务二 : 修改旧的示例代码

[xdoctest] 分批次修改已有代码的示例 [#55629](https://github.com/PaddlePaddle/Paddle/issues/55629)
\[xdoctest\] 分批次修改已有代码的示例 [#55629](https://github.com/PaddlePaddle/Paddle/issues/55629)

<!-- xdoctest -->
<div style="display: flex; justify-content: center">
Expand All @@ -228,21 +235,21 @@ Xdoctest 并不适用如 Paddle 此类庞大复杂的框架。

##### >>> print(reviewer)

- 更关注用户的体验
- 更关注代码的质量
- 更清楚开发者的诉求
- 更关注用户的体验
- 更关注代码的质量
- 更清楚开发者的诉求

##### >>> print(reviewer.\_\_task\_\_)

- 熟悉 review 工作流
- 熟悉 review 工作流
- 任务拆解
- 第一批:简单,开发者熟悉环境与流程
- 第二批:复杂,涉及 CPU/GPU 环境等情况
- 第三批:困难,涉及 C++、并行、静态图等
- 阶段总结,问题反馈
- 开发、打磨工具 `convert_doctest`
- 第一批:简单,开发者熟悉环境与流程
- 第二批:复杂,涉及 CPU/GPU 环境等情况
- 第三批:困难,涉及 C++、并行、静态图等
- 阶段总结,问题反馈
- 开发、打磨工具 `convert_doctest`

##### >>> print(convert_doctest.**doc**) 辅助工具
##### >>> print(convert_doctest.\_\_doc\_\_) 辅助工具

为了方便社区开发者完成示例代码的修改,顺师傅开发了 [convert_doctest](https://github.com/megemini/convert_doctest) 辅助工具,能够实现:

Expand Down Expand Up @@ -294,35 +301,35 @@ Xdoctest 并不适用如 Paddle 此类庞大复杂的框架。
- 涉及 PR:**23 个**
- 涉及文件:**82 个**
- 开源贡献者:**7 人**
- 开源社区任务二:[xdoctest] 分批次修改已有代码的示例:
- 开源社区任务二:xdoctest 分批次修改已有代码的示例:
- 涉及 PR:**123 个**
- 涉及文件:**364 个**
- 开源贡献者:**19 人**

#### >>> 个人贡献

- 调研分析、任务拆解、项目开发、代码 review。
- RFC《将 xdoctest 引入到飞桨框架工作流中》
- 完成飞桨框架使用 xdoctest 进行示例代码检查的切换
- 退场飞桨文档原有的示例代码检查
- 完成飞桨文档《开发 API Python 端》与《API 文档书写规范》的更新
- 提交 PR:**20 个**
- 开源社区 Review PR:**59 个**
- 开发辅助工具 **convert_doctest**
- RFC《将 xdoctest 引入到飞桨框架工作流中》
- 完成飞桨框架使用 xdoctest 进行示例代码检查的切换
- 退场飞桨文档原有的示例代码检查
- 完成飞桨文档《开发 API Python 端》与《API 文档书写规范》的更新
- 提交 PR:**20 个**
- 开源社区 Review PR:**59 个**
- 开发辅助工具 **convert_doctest**

#### >>> 个人收获

- 开源协作,开发者 与 Reviewer 身份的转换
- 学习飞桨,更全面、更深入的学习;学习的越多,需要学习的更多
- 编程能力,更直接的需求反馈与实现
- 开拓视野,开源参与者之广,人外有人
- 开源协作,开发者 与 Reviewer 身份的转换
- 学习飞桨,更全面、更深入的学习;学习的越多,需要学习的更多
- 编程能力,更直接的需求反馈与实现
- 开拓视野,开源参与者之广,人外有人

### 02 - 未来规划

#### >>> CONVERT_DOCTEST

- 合入 Paddle、发布到 PyPI,回馈开源社区
- 思考是否有工具可以取代 xdoctest ?是否单独开发 doctest 工具?
- 合入 Paddle、发布到 PyPI,回馈开源社区
- 思考是否有工具可以取代 xdoctest?是否单独开发 doctest 工具?

### 03 - 开源贡献

Expand Down Expand Up @@ -360,7 +367,7 @@ Xdoctest 并不适用如 Paddle 此类庞大复杂的框架。
[@yoyoIcy](https://github.com/yoyoIcy)
[@yuchen202](https://github.com/yuchen202)

#0### >>> 飞桨人员
#### >>> 飞桨工作人员

[@SigureMo](https://github.com/SigureMo)
[@sunzhongkai588](https://github.com/sunzhongkai588)
Expand Down

0 comments on commit 41d8943

Please sign in to comment.