Pytorch编译maskRCNN问题:cpp_extension.py:189: UserWarning: Error checking compiler version for cl...
先给出两个报错的内容:
d:\Anaconda3\envs\torch\lib\site-packages\torch\utils\cpp_extension.py:189: UserWarning: Error checking compiler version for cl: [WinError 2] 系统找不到指定的文件。
d:\Anaconda3\envs\torch\lib\site-packages\torch\utils\cpp_extension.py:189: UserWarning: Error checking compiler version for cl: 'utf-8' codec can't decode byte 0xd3 in position 0: invalid continuation byte
解决方案:
打开cpp_extension.py,把编码改成' gbk',下面我注释掉了原来的一行(match...),添加了两个print用来追踪。
try:
if sys.platform.startswith('linux'):
minimum_required_version = MINIMUM_GCC_VERSION
version = subprocess.check_output([compiler, '-dumpfullversion', '-dumpversion'])
version = version.decode().strip().split('.')
else:
print("----windows operation system")
minimum_required_version = MINIMUM_MSVC_VERSION
compiler_info = subprocess.check_output(compiler, stderr=subprocess.STDOUT)
# the default decode is 'utf8', since cl.exe will return Chinese, so ' gbk'
#match = re.search(r'(\d+)\.(\d+)\.(\d+)', compiler_info.decode().strip())
print("----compiler_info: ", compiler_info.decode(' gbk'))
match = re.search(r'(\d+)\.(\d+)\.(\d+)', compiler_info.decode(' gbk').strip())
print("----match: ", match)
version = (0, 0, 0) if match is None else match.groups()
except Exception:
_, error, _ = sys.exc_info()
warnings.warn('Error checking compiler version for {}: {}'.format(compiler, error))
return False
问题的起源与解决过程:
原来的maskRCNN太久远,已经忘记是什么时候的事了,这次更新了pytorch,要重新编译。本来是想升级到pytorch1.2,但报错了。于是再回到pytorch1.0.1。还是原来的facebook/maskrcnn-benchmark,该项目原来就成功编译过,再编译应该是不会出问题的,命令很简单,
(torch) D:\maskrcnn-benchmark>python setup.py build develop
#结果报错
d:\Anaconda3\envs\torch\lib\site-packages\torch\utils\cpp_extension.py:189: UserWarning: Error checking compiler version for cl: [WinError 2] 系统找不到指定的文件。
warnings.warn('Error checking compiler version for {}: {}'.format(compiler, error))
OK,找不到cl.exe是吧,那我call一个,预设一下环境
(torch) D:\maskrcnn-benchmark>call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.9.6
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
补充说明:如果你用vs2019,那就用下面这条:
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat",通常检查一下,如果输出的不是中文,你就不会有gbk和utf-8冲突的问题了。
再来一次python setup.py build develop,就会出现第二条报错(注意我这里已经添加了两条追踪命令print("----windows operation system"),print("----compiler_info: ", compiler_info)),
(torch10) E:\AMaskRCNN\maskrcnn-benchmark>python setup.py build develop
running build
running build_py
running build_ext
----windows operation system
----compiler_info: b'\xd3\xc3\xd3\xda x64 \xb5\xc4 Microsoft (R) C/C++ \xd3\xc5\xbb\xaf\xb1\xe0\xd2\xeb\xc6\xf7 19.16.27026.1 \xb0\xe6\r\n\xb0\xe6\xc8\xa8\xcb\xf9\xd3\xd0(C) Microsoft Corporation\xa1\xa3\xb1\xa3\xc1\xf4\xcb\xf9\xd3\xd0\xc8\xa8\xc0\xfb\xa1\xa3\r\n\r\n\xd3\xc3\xb7\xa8: cl [ \xd1\xa1\xcf\xee... ] \xce\xc4\xbc\xfe\xc3\xfb... [ /link \xc1\xb4\xbd\xd3\xd1\xa1\xcf\xee... ]\r\n'
d:\Anaconda3\envs\torch10\lib\site-packages\torch\utils\cpp_extension.py:188: UserWarning: Error checking compiler version for cl: 'utf-8' codec can't decode byte 0xd3 in position 0: invalid continuation byte
warnings.warn('Error checking compiler version for {}: {}'.format(compiler, error))
看着这些乱码就头皮发麻,注意compiler_info得到的是compiler的输出结果,subprocess.check_output只不过对compiler进行了一次空的执行(参考python源码:如,Python-3.7.4\Lib\subprocess.py第351行),
compiler_info = subprocess.check_output(compiler, stderr=subprocess.STDOUT)
于是我直接运行了一下cl.exe,看看这个输出结果到底是什么玩意,
(torch10) E:\AMaskRCNN\maskrcnn-benchmark>cl
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.16.27026.1 版
版权所有(C) Microsoft Corporation。保留所有权利。
用法: cl [ 选项... ] 文件名... [ /link 链接选项... ]
那么现在一目了然,这些中文就是上面对应的字符串,使用utf-8编码时是认不出来的,而python默认的情况下使用的正是utf-8。搞不懂微软啥时把这个cl.exe的运行输出也中文化了,唉,悲催。
b'\xd3\xc3\xd3\xda x64 \xb5\xc4 Microsoft (R) C/C++ \xd3\xc5\xbb\xaf\xb1\xe0\xd2\xeb\xc6\xf7 19.16.27026.1 \xb0\xe6\r\n\xb0\xe6\xc8\xa8\xcb\xf9\xd3\xd0(C) Microsoft Corporation\xa1\xa3\xb1\xa3\xc1\xf4\xcb\xf9\xd3\xd0\xc8\xa8\xc0\xfb\xa1\xa3\r\n\r\n\xd3\xc3\xb7\xa8: cl [ \xd1\xa1\xcf\xee... ] \xce\xc4\xbc\xfe\xc3\xfb... [ /link \xc1\xb4\xbd\xd3\xd1\xa1\xcf\xee... ]\r\n'
现在问题明白了,要正确识别compiler,就必须使用' gbk'编码,也就是我前面给出的解决方案。
当然,如果你换系统了,在采用utf8的情况下,别忘记改回来。
关于pytorch1.2的额外问题
上面的内容即适用于pytorch1.0.1也适用于pytorch1.20,不过新版本的pytorch1.20有更多的麻烦,最主要的是,老的配置文件不能用了(当然如果你够熟悉,直接改),要用新的配置文件,同时你会发现新版本的maskRCNN有不少函数也已经发生了变化。
还有一处要格外注意,
File "e:\maskrcnn-benchmark\maskrcnn_benchmark\layers\nms.py", line 5, in <module>
from apex import amp
ModuleNotFoundError: No module named 'apex'
需要安装apex,注意在windows下要到这里去下载,
https://github.com/ptrblck/apex/tree/apex_no_distributed
linux则要到这里下载,
https://github.com/NVIDIA/apex
安装完成后,顺利的话就可以正常运行了。
后记:
VS编译器换成中文版的以后,可以想像这个问题会成为python们的常态,所以要点只有两点,
1。首先是要
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
2。然后,修改你的D:\Anaconda3\envs\torch36\Lib\site-packages\torch\utils\cpp_extension.py,大概从第183行左右(取决于你的版本)开始,try-else 中那段,我加了print(".......blabla....")的那段,不会的话你copy-paste就行。gbk前面有个空格,你少打了可运行不通的。
# First check if the compiler is one of the expected ones for the particular platform.
if not check_compiler_ok_for_platform(compiler):
warnings.warn(WRONG_COMPILER_WARNING.format(
user_compiler=compiler,
pytorch_compiler=_accepted_compilers_for_platform()[0],
platform=sys.platform))
return False
if sys.platform.startswith('darwin'):
# There is no particular minimum version we need for clang, so we're good here.
return True
try:
if sys.platform.startswith('linux'):
minimum_required_version = MINIMUM_GCC_VERSION
version = subprocess.check_output([compiler, '-dumpfullversion', '-dumpversion'])
version = version.decode().strip().split('.')
else:
print("________________windows operation system ______________________")
minimum_required_version = MINIMUM_MSVC_VERSION
compiler_info = subprocess.check_output(compiler, stderr=subprocess.STDOUT)
print("________________compiler info:", compiler_info)
#match = re.search(r'(\d+)\.(\d+)\.(\d+)', compiler_info.decode().strip())
match = re.search(r'(\d+)\.(\d+)\.(\d+)', compiler_info.decode(' gbk').strip())
version = (0, 0, 0) if match is None else match.groups()
except Exception:
_, error, _ = sys.exc_info()
warnings.warn('Error checking compiler version for {}: {}'.format(compiler, error))
return False