张小白带你学习如何提交MindSpore Python API文档的issue和PR

MindSpore作为深度学习的开源框架,要靠广大开发者的共同参与才能蓬勃发展。想必华为昇腾团队的领导和运营也深知这一点,所以就跟华为云层出不穷的培训、直播、实验、跟帖等活动有丰富的礼物那样,MindSpore也常常开展各项活动。这点,作为开发者,张小白们一定是喜闻乐见的。

这不,张小白童鞋就发现了一个有奖品的活动 https://bbs.huaweicloud.com/forum/thread-111428-1-1.html   ,并且在参加这个活动的过程中,学会了如何向开源框架MindSpore的Python API文档提issue和PR。

先科普一下:

issue,简单的说,就是给一个仓库提问题。当我们发现了仓库中代码的一个bug,我们会提一个issue暴露出问题。如果仓库的负责人看到了,解决了这个问题,则会close这个issue。

PR呢?是Pull Request的缩写。提了issue之后,如何解决这个issue呢?一般情况下,我们会先把这个仓库fork到自己的仓库,然后在自己的仓库做更新和修改(commit),自己测试通过后,再将改好的内容提交到仓库——这一步就是Pull Request。仓库负责人看到PR后,也会进行一番审查和测试,发现没问题后,就会把我们提交的内容合并(Merge)到仓库中去。

就拿张小白刚提交的issue和PR为例吧。

(一)发现问题,提交issue

打开 https://www.mindspore.cn/doc/api_python/zh-CN/master/mindspore/mindspore.train.html    链接:

image.png

会发现 class mindspore.train.callback.LearningRateScheduler(learning_rate_function) 这个类的Note中,"This class are not supported on CPU." 存在一个语法错误,我们知道class作为类的名词,是单数。

那么正确的说法应该是:"This class is not supported on CPU.",中文含义应该是:这个类不支持CPU(环境)。

那么发现了这个问题,我们就该提issue了。

我们去mindspore在gitee的主仓。 https://gitee.com/mindspore/mindspore 

点击 代码右边的 Issues(如箭头所示),再点击右边的 “+新建 Issue”按钮。系统会弹出以下界面:

这里有一个提bug的模板,你可以用,也可以不用。

我们填入标题:Problems with the Python API mindspore.train

在输入标题之后,gitee会在下面友善的提示这个issue是不是已经有了答案。我们可以关注或者不关注这些内容。

我们将正文清空,填入以下内容

I found some problems in Python API documents:
URL: https://www.mindspore.cn/doc/api_python/zh-CN/master/mindspore/mindspore.train.html
API name: mindspore.train

classmindspore.train.callback.LearningRateScheduler(learning_rate_function)

输入图片说明

This class are not supported on CPU。

The correct usage is " This class is not supported on CPU ".

请注意,这里gitee是支持贴图的。张小白常常使用微信PC端的工具进行截图,简单又方便。

输入后的效果如下:

输入完毕后,点击“创建”。issue就会显示在Issues列表中,并且给你生成一串号,这个就是issue编号,后面提PR的时候会用到。

我们这次提交的issue编号为 #13BVAQ。(图中的issue状态为DONE其实是已经解决了,因为张小白截图迟了,正常刚提交时,这个状态 应该是橙色的“TODO”)

(拿个别的issue的例子示范一下)

(二)fork到个人仓库,下载个人仓库代码

下面我们开始PR前的一些准备工作。前面讲解PR概念的时候提到了,我们先要把MindSpore的仓库fork到自己的仓库:

https://gitee.com/mindspore/mindspore/ 主仓地址点击 右边的fork按钮(图中因张小白已经fork过了,所以显示的是forked,否则应该是fork)

点击后,系统会弹出这个菜单:

点击大大的“张”(这取决于你注册在gitee的名字),然后点击确认后,系统会将MindSpore的官方仓库复制到用户自己gitee的仓库下,并自动跳转到自己的gitee仓库页面:

等待页面刷新后,系统会显示以下内容:

那我们接着将自己在gitee的个人仓库的内容下载到本地:

mkdir mypr

cd mypr

git init

git remote add origin https://gitee.com/zhanghui_china/mindspore.git

上面这个链接可以通过点击个人仓库的“克隆/下载”按钮,再选择HTTPS,然后点击“复制”,将仓库的URL复制下来。

git pull origin master

(这里是pull master版本,如果需要pull其他版本可以将master改为对应的版本名称)

image.png

(三)本地修改问题代码

然后我们回头看我们发现问题的那个页面:

https://www.mindspore.cn/doc/api_python/zh-CN/master/mindspore/mindspore.train.html  ,函数右边有个“source”,标明了文档对应代码的位置,点击这个"source"

会弹出这个页面,告诉你该文档对应的源代码注释的位置:

mindspore.train.callback._lr_scheduler_callback

我们用Windows资源管理器,去刚才下载的仓库目录找到这个python代码:_lr_scheduler_callback.py

再用VSCode编辑这个文件:

将are改为is,然后保存。

(四)本地验证修改结果

怎么检验自己修改的内容对不对呢?

MindSpore的API文档都是用MindSpore Docs仓库的Sphinx工具生成。同样的,我们去MindSpore仓库找到docs仓库的位置:

点击MindSpore的“仓库” https://gitee.com/organizations/mindspore/projects 

显示出12个仓库,找到docs点进去:

点击“克隆/下载””,找到docs仓库的下载地址(HTTPS): https://gitee.com/mindspore/docs.git 

本地创建一个mindspore-doc目录

git clone https://gitee.com/mindspore/docs.git

将代码仓下载下来

image.png

进入api_python目录

cd docs/api_python

image.png

根据requirements.txt的内容安装一些依赖包:

pip install -r requirements.txt

image.png

此时,本地需要安装gcc(gcc里面自带了make)

(可以参照张小白的博客: https://bbs.huaweicloud.com/blogs/239829 完成Windows上gcc的安装)

并将原来MinGW上的 mingw32-make.exe复制一份叫做make.exe

image.png

执行make html试图生成本地文档:

image.png

注释掉仓库下docs\api_python\source_en\conf.py和docs\api_python\source_zh_cn\conf.py代码中的几个import,以便让编译通过(当然此时仅仅能生成mindspore的Python API文档,应该生成不了mindarmour,mindspore_hub或者mindspore_serving的API文档了。)

image.png

image.png

再重新make html

image.png

。。。

会报很多错,(红色部分),但是能走完。。

image.png

而且会告诉你, HTML文件生成了,在 build_zh_cn\html目录下。

打开这个目录下的index.html文件:

如果打开mindarmour,mindspore_hub,mindspore_serving,会发现右边都是空的:

说明前面说的是对的。

点击我们找到的issue对应的API mindspore.train

当然,目前生成的还是错的。为啥呢?

mindspore本地Python API文档的生成依赖于我们已经安装的mindspore的版本。正常的调试流程,应该是“编译mindspore源码,安装mindspore,然后生成api文档。”。但是一个比较快速的流程是:直接把自己改动后的python文件覆盖本地已经安装好的mindspore库。

张小白已经安装好的mindspore在  C:\Users\zhang\miniconda3\Lib\site-packages\mindspore\ 目录下。(可以通过搜索找 _lr_scheduler_callback.py 文件)

那将刚才改过的  _lr_scheduler_callback.py覆盖掉这个文件 

重新回到 mindspore-doc目录的相关目录 make html

...

再重新打开生成的文档:

可见修改确实生效了。

(五)提交本地修改代码到个人仓库

在本地测试通过之后,我们就可以将代码的变更提交个人仓库了。

git branch mypr

git checkout mypr

git branch

git add .

git commit -m "Fix Issue #I3BVAQ"

image.png

(上图仅用其他的issue示意)

git push --set-upstream origin mypr

image.png

去看看 远程仓库也可以看到这个变化。

image.png

(六)新建PR

到自己仓库,提PR。点击自己仓库的 “+Pull Request”按钮

image.png

会自动弹出以下页面:

image.png

好像就需要填这三个地方:标题,对应issue和标签(Mindspore的Python API文档修改可以增加 mindspore-contrib标签)

image.png

点击“创建”

image.png

(上图以别的PR为例)

PR好像就生成了。

(七)签署CLA

第一次在Mindspore仓库提交PR,i-robot会告诉你需要签署CLA。

image.png

点击 Please access here的here的链接,可以进入签署CLA的页面:

此时,需注意:在前面提交代码仓库的时候,会让你输入邮箱:

而你要确保这个邮箱跟  C:\Users\zhang\.gitconfig 的邮箱要保持一致。

张小白就因为这两个邮箱不一致,导致i-robot认为提交的我不是我。又需要重签cla。

具体签署的过程也很简单:

点击后,弹出以下窗口:

image.png

选择 sign individual CLA

image.png

输入gitee-id,邮箱,名字,然后提交即可.


image.png

正常应该是显示签署成功,上图只是张小白签过了,再签一次自然报已经签过。

签署完毕后,我们在PR的评论栏输入 /check_cla,得到肯定的答复,就说明签署成功。

(八)提交测试

在提交给审查人员之前,我们应该负责任地先把自己的代码在服务器上测试一遍。

尽管本次改动只有一个单词。但是测试还是不能少的。

我们在PR的评论区输入 /retest

mindspore-ci-bot这个小机器人会做jenkins测试环境的自动部署,并进行代码的测试,点击Link可以看到测试的过程:


从上面的过程可以看出,云端的测试包含 代码下载download-code,代码检查code-check,代码编译compile,ut-test,冒烟测试smoke-test等过程。虽然仅有一行代码的改动,但是mindspore-ci-bot 还是把各种环境都编译测试了一遍。所以这段测试时间历时也会比较长,一般在一小时左右。

测试完毕后,会在PR的评论区告诉你Build Result是SUCCESS还是FAIL。

一般情况下,如果SUCCESS,就可以做后续操作,否则,应该检查是什么问题,重新在本地修改代码,重新在本地测试完毕后,再重新提交PR的retest。

(九)等待审核

一般情况下,我们应该在此时,耐心等待MindSpore审核团队进行PR的审核就行了。

但是,我们也可以通过指定PR审核人的方式,迅速让审核团队进行操作。

MindSpore官方可能会在近期整理出模块对应的PR审核人的列表。这样方便开发者提交PR时,选择合适的审查人员。

比如可以在PR的编辑页面指定审查人员:

image.png

审核人员会进行 /lgtm。从本次实践的例子来看,有3个人参加了审核。

审核完之后,这个PR就会多了4个标签:approved和 3个lgtm-人名 

而且 bot机器人也会完成PR的合并。

而对应的issue,也会从TODO状态改为DONE状态。

再去看mindspore主仓的代码:

image.png

很高兴看到了自己的PR提交生效了。

至此,就完成了PR的全过程。

我们再去打开一下原来有bug的那个网页:https://www.mindspore.cn/doc/api_python/zh-CN/master/mindspore/mindspore.train.html 

可以看到,最终的API文档页面也得到了修正。(但是这个不是合并后马上生效,需耐心等待官方合并发布。)

有心人还可以看一下 r1.1版本的页面: https://www.mindspore.cn/doc/api_python/zh-CN/r1.1/mindspore/mindspore.train.html 

这个还是错误的。

当然,这里需要补充一句,如果我们发现了1.1分支的bug,那么就应该拉回1.1分支的代码进行修改;如果发现了master分支的bug,就应该拉回master分支的代码进行修改。我在论坛中看到有些童鞋发现了1.1分支的代码,但是又是从master拉回的分支进行了代码的修改,这样子操作还是有点危险的。因为有可能这个分支的bug已经被修复了。我们也可以在提交PR的时候注意一下:

比如这个是用自己个人仓库mypr的版本,往官方仓库mindspore/mindspore的master分支提交版本。

个人觉得以前的版本有bug,我们下最新的版本就行了。当然,也不反对有人就是喜欢给老版本提bug,但是记得一定要做到把PR提交到老版本才对。以免给其他开发人员造成困扰。。

好了,大家可以看到,尽管张小白只是改了一个单词,但是以上的操作应该都是不必可少的。希望大家能够通过本文了解具体的提issue和提PR的整个过程,也希望大家多为MindSpore社区做出贡献。

MindSpore BBS论坛的地址为:https://bbs.huaweicloud.com/forum/forum-1076-1.html    

欢迎大家到论坛找张小白,或者找MindSpore团队的专家咨询。

。。

。。

。。

别急,还有彩蛋:

大家有没有发现,MindSpore.cn网站生成的内容跟使用make html 生成的内容,在文档风格上并不一样。

比如对于同一块区域:

而make html生成的如下:

image.png

MindSpore.cn显示的如下:

image.png

如果想将本地渲染成跟官网mindspore.cn一样的效果,需要将 https://www.mindspore.cn/doc/api_python/zh-CN/master/_static/css/theme.css 这个样式文件下载到本地。覆盖掉make html已经生成的 docs\api_python\build_zh_cn\html\_static\css下的同名文件。

image.png

你会发现,居然出现了官方显示的效果了:

image.png

这里多谢 论坛中 @longvoyage 大大的指点。

在写本文的过程中,张小白发了多个问题贴,试验了多种方式,并在群里骚扰了多个MindSpore团队的专家(如 @琦玉、@TingWang等等),才形成此文,为此向几位表示衷心的感谢。

(全文完,谢谢阅读)

(完)