print无法输出到.out文件中 用 -u

故事背景: 做BraTS项目,快要交论文初稿了,模型还不合格,心情急躁,无奈遇到了从来没见过的长相奇特的bug,又卡了好几天,内心是崩溃的…

bug描述: 在服务器上跑.py模型训练脚本,之前好好的可以跑通的代码突然什么都不输出(.out文件中没有内容),连已经运行到的print语句也没有输出内容,如下图;
print无法输出到.out文件中 用 -u
只有当程序出现报错时,之前的print内容才会和报错信息一起显示到.out文件中,如下图。
print无法输出到.out文件中 用 -u
解决过程:

  1. 起初看到多个任务的进度条都是 0/n 以为是学校服务器又大姨妈了(虽然学校的服务器老有各种各样的问题,但这是我debug是很忌讳的一点,第一反应是甩锅)

  2. 但等待几日之后发现服务器正常,于是开始反思是否代码中出现死循环;用print大法判断程序执行到哪一步,却发现.out文件中除了卡在0的进度条什么都不输出;

  3. 由于.out中只有进度条,让我怀疑是tqdm的问题,于是我注释掉import tqdm这行,这下.out文件中连进度条都没了… 此刻我以陷入深深的自我怀疑中。

  4. 突破点在于:当代码中出错的时候(比如cuda OOM或者文件名出错),.out文件中就会出现先前print出来的内容。 这表明代码已经运行过了那些print的位置,卡在了其他地方。

  5. 终于我开始搜索“linux,print无法输出到.out文件”相关的内容,此刻我才走在了正确的道路上。在我了解到 python的输出有缓冲机制,print的内容是先输出到缓冲区,导致out在文件中并不能够马上看到输出 。解决办法是 运行时用 -u 参数禁用缓冲区 (这也解释了在先前成功训练完的模型.out文件中,为什么print的内容在tqdm进度条之后才统一打印出)print无法输出到.out文件中 用 -u

  6. 在调用脚本时加了 -u 参数,终于看到正常的print输出,虽然进度条仍然卡在0,但我至少可以知道程序卡在了哪一步。
    print无法输出到.out文件中 用 -u

  7. 最后发现我在util.py中写了两个名为combine_labels的函数,一个用于计算dice,一个用在predict之后, 两个函数名字是一样的。 调用 combine_labels 函数时,我本地的python解释器选择了较后定义的那个,而linux服务器上的python解释器可能傻了,于是卡在此处 (也不报错,令人头秃;或许哪位读者大神能纠正一下我的理解) 给两者之一改名后,bug终于解决。

总结: 遇到奇怪的bug别甩锅,也别在自我怀疑中浪费太多时间。如果一时三刻解决不了就先做点别的事。 尝试了几种可能性行不通也别焦躁和气馁,做好记录工作,慢慢将每种可能性都排除了问题就有可能迎刃而解。 关键还有多google。