![v2-7dc2af2bd5f724082594047905eb58c0_1440w.jpg?source=172ae18b](http://img-01.proxy.5ce.com/view/image?&type=2&guid=3d04c94d-1d30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-7dc2af2bd5f724082594047905eb58c0_1440w.jpg?source=172ae18b)
上篇简要介绍了FATE在MAC环境下如何快速跑通
花京华:联邦学习开源框架FATE研究--MAC环境下的安装和运行zhuanlan.zhihu.com![v2-7dc2af2bd5f724082594047905eb58c0_180x120.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=3d04c94d-1d30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-7dc2af2bd5f724082594047905eb58c0_180x120.jpg)
对于急需上手的开发者来讲,跑通是前提,debug才是根本,没有debug环节,很多代码的运行细节我们并不清楚,给我们阅读代码也会带来障碍。因此,本篇主要讲解如何在Pycharm里对Fate进行Debug
要了解如何进行Debug,首先要知道Fate在进行联邦学习任务的基本运行过程,通过上一篇文章,我们可以看到,Fate里面在跑一个任务时,主要依赖的环境和步骤为
- fate-flow-server: 用于对任务进行提交、队列管理、任务配置依赖解析等
- 编写任务的两个基本配置文件:dsl和runtime_conf
- 客户端提交任务
所以,我们在debug的时候,必须启动fate-flow-server。然而我们开发或者调试联邦学习算法的时候,需要进入细节研究的是我们的每个任务模块(fate中称为component),比如(intersect,featurebinning,hetero_lr等),所以我们若果想debug,必须找到fate-flow-server执行每个模块的启动代码(或者说执行入口)
- 找出任务的启动入口
分析源代码可以发现,在fate-flow-server中任务管理的具体模块在fate_flow/driver 中,
![v2-8f8d45e8ce6a00664d292d23a8e2da2b_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=3d04c94d-1d30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-8f8d45e8ce6a00664d292d23a8e2da2b_b.jpg)
与具体每个component的执行入口最相关的两个文件 task_scheduler.py 和task_executor.py
看文件名我们就很清楚知道,第一个是task(这里起名为task,是需要和job区分,job主要是指我们整体的作业,而task是根据job配置文件拆分后得到的每个子任务)调度相关代码,第二个是task执行相关的代码
具体到tasks_cheduler.py ,我们暂时只关心调度模块如何启动任务,在286行,我们可以看到start_task函数
![v2-9b387e09e9ba11f5cf652c69d1e2f33d_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=3d04c94d-1d30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-9b387e09e9ba11f5cf652c69d1e2f33d_b.jpg)
简单分析代码,可以看到,fate-flow目前支持两种执行后端,一个是eggroll,一个是spark。为开发方便,我们一般直接在standalone模式下,用现成的eggroll作为执行后端,然后我们可以看到关键代码:
![v2-869b09279357197b6e8868872345418d_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=3d04c94d-1d30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-869b09279357197b6e8868872345418d_b.jpg)
![v2-4a0aae4f608208cfb845191516cc7481_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=3d04c94d-1d30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-4a0aae4f608208cfb845191516cc7481_b.jpg)
这里,给出了启动任务的方法:拼接命令行,然后启动子进程交给os去处理!然而,在Pycharm中对子进程进行debug是非常麻烦的,为了我们方便调试,在 job_utils.run_subprocess前面,我们手动添加一行代码,打印具体的拼接命令:
print("run subprocess command:" + " ".join(process_cmd))
这样,scheduler在启动任何task的时候,我们都知道具体的执行命令,然后我们就可以将子进程找到入口文件后,在pycharm中作为主进程去debug
- 调试子任务
其实,敏锐的你应该发现了,执行子进程的入口就是task_executor.py文件中,我们在pycharm中按照上面的process_cmd 取出所有参数后,然后对task_executor进行debug,一切不就ok了?如下:
![v2-47b11befb82d4384f8bd5c34f9fec72c_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=3d04c94d-1d30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-47b11befb82d4384f8bd5c34f9fec72c_b.jpg)
这是我在Pycharm中的几个主要配置,因为涉及到多方计算,在debug时通常需要多个task一起启动,我们分别添加了 host,geust,arbitor的debug配置,如图中1所示;另外三方计算的时候,其实task执行的脚本都是一样的,就是driver/task_executor.py 如图中2所示,最后我们具体的process_cmd中的参数,在Parameters中设置,如图中3所示
我们重新跑一下quick_run.py,并修改下配置文件
DSL_PATH = 'hetero_logistic_regression/test_hetero_lr_train_job_dsl.json'
SUBMIT_CONF_PATH = 'hetero_logistic_regression/test_hetero_lr_train_job_conf.json'
用纵向逻辑回归场景进行测试,我们在fate-flow-server的控制台可以看到输出几个类似如下的命令:
run subprocess command:python3 /xxx/python/FATE/fate_flow/driver/task_executor.py -j 2020020822271098076518 -n dataio_0 -t 2020020822271098076518_dataio_0 -r guest -p 10000 -c /xxx/python/FATE/jobs/2020020822271098076518/guest/10000/dataio_0/task_config.json --job_server 192.168.31.58:9380
并在fateboard(后面会讲如何启动)中可以看到任务执行信息:
![v2-c816d51ae515a81b474cefb5a49a04dc_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=3d04c94d-1d30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-c816d51ae515a81b474cefb5a49a04dc_b.jpg)
可以看到 -j 2020020822271098076518 -n dataio_0 -t 2020020822271098076518_dataio_0 -r guest -p 10000 -c /xxx/python/FATE/jobs/2020020822271098076518/guest/10000/dataio_0/task_config.json --job_server 192.168.31.58:9380
主要参数解释:
-j: job_id,我们的作业id
-n:component
-t:task_id
-r:role task执行时的角色
就是我们需要在pycharm中debug时设置的参数,我们将这个参数填入Paramaters中,然后就可以开始我们愉快的debug之旅了
- 开始DEBUG
当我们完成debug参数,启动后会发现,怎么程序就直接退出了?
其实,由于我们刚才已经跑过了jobid=2020020822271098076518的dataio_0这个模块,这个时候系统会生成一系列jobs相关配置,配置文件里面有个kill文件,代表这个任务直接结束,所以我们启动的时候程序直接退出了,我们只需要将这个kill文件删除,就可以正常debug了
![v2-2ae341fd75b4dec5e5d655f00c0c3a92_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=3d04c94d-1d30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-2ae341fd75b4dec5e5d655f00c0c3a92_b.jpg)
我们找到federatedml/util/dataio.py 文件,并在_init_model中加入断点,pycharm就会自动进入到这里了
![v2-7b0f7ee7f1da6ac6893edb187b8ef85b_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=3d04c94d-1d30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-7b0f7ee7f1da6ac6893edb187b8ef85b_b.jpg)
- PS--补坑
在我们启动fate-flow-server时候,如果我们在debug模式启动,需要进行如下配置:
![v2-bd39f5c04cb84b896b761f1f293e62db_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=3d04c94d-1d30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-bd39f5c04cb84b896b761f1f293e62db_b.jpg)
在Python Debugger中不要勾选Attach to subprocess automatically while debugging
如果勾选了这个,那么start_task启动子任务过程中,会被pycharm注入一些模块路径信息,可能导致某些task运行错误。切记!