本文介绍了如何在Google Colab中提供机器学习项目,
如果想开始使用免费的星际争霸2机器学习环境,请先完善GPU硬件。可以看看我的Google Colab笔记本:https://Colab . research . Google . com/drive/1 azc kv 98 uaqz 2 ajiegwlexcxbrpgksiv。
最近我和几个朋友开始了星际争霸2的机器学习项目。我认为快速训练神经网络的能力对于研究人员的成功非常重要。为了给全世界的星际争霸2的研究人员提供一个可复制的、高效的、简单的代码共享环境,我想看看能不能让StrCraft II运行在Google Colab(Google提供免费GPU的机器学习环境)上。
但是,下载星际争霸2并安装必要的库后,你会面临以下问题:
I 0331 08:30:17.832181 139972195997568 sc _ process . py:148]连接尝试0(正在运行:无)* * * * * * *忽略的重新连接尝试* * * * * * I 0331 08:32:17.048350 139972195997568 sc _ process . py:148]连接尝试119(正在运行:-11)I 0331 08:32:14I 0331 08:32:18.050344 139972195997568 sc _ process . py:166]关闭并返回代码:-11未能创建套接字I 0331 08:32:18.056085 139972195997568 sc2 _ env . py:327]环境关闭建筑附加塔也不能解决此问题。
了解返回代码
我做的第一件事是弄清楚返回代码的含义。
看了PySC2的源代码(3359 github . com/deep mind/pysc 2/blob/39 f 84 b 01d 662 EB 58 B3 d 95791 f 59208 c 210 afd4e 7/pysc 2/lib/sc _ process . py)后,找到了设置返回代码的代码段:
@ propertydef running (self):返回self。_ proc.poll () if self。_ proc else false poll()来自Python的子进程模块。深入挖掘后发现,11是导致星际争霸中断的信号。
信号11就是臭名昭著的段落错误,给C语言程序员带来无尽的噩梦。
为了证实,我发现SC2是可执行的和自我执行的。
!~/starcraft ii/versions/base 59877/sc2 _ x64分段故障(核心转储)在硬模式下调试
正常情况下,我会启动我最喜欢的调试工具,所以这篇文章就变成了如何使用GDB的过程。
但是,我们使用Google Colab来处理它,我们唯一拥有的是一个Jupyter笔记本网页。这意味着:
1.没有调试器
没有根权限
3.有限的工具,如无strace
RIP调试
当你只有一个网页时.
第一步是在服务器上尝试不同版本的星际争霸2。暴雪提供了三个版本的星际争霸2:4 . 0 . 2,3.17,3.16.1。可惜没有一个能成功。
然后我决定在本地Linux机器上运行星际争霸2,我可以在其中控制和调试。这也让我可以检验我的假设。
我的第一个猜测:我没有找到所需的库。
我的初步猜测是,星际争霸2作为一款游戏,可能需要一些OpenGL函数和库,而我使用的Google Colab环境中并没有这些函数和库。
为了测试这个猜想,我在一台本地机器上运行了星际争霸2,这次使用了strace tool,它允许我跟踪系统让星际争霸2做了什么。因为所有的库都是通过操作系统加载的,所以我可以跟踪任何缺失的依赖项,或者看看是否有什么奇怪的事情发生。
有关完整的跟踪日志,请参阅:https://gist.github.com/frozenxZeus/53a85f58856cb346b 90313110 ce 89 bcc。下面是一小段:
exec ve(\’ 0.05 \’)/SC2 x64 \’,[\’ ./SC2_x64\’],0x 7 fffc 19 e 08 b 0/* 49 vars */)=0 brk(NULL)=0x 95 BD 000 access(\’/etc/LD。所以。preload \’,R_OK)=-1 ENOENT(无此类文件或目录)openat(AT_FDCWD,\’/etc/ld.so.cache \’,O _ r only | O _ clo exec)=3.openat(AT_FDCWD,\’/lib64/libdl.so.2 \’,O_RDONLY|O_CLOEXEC)=3.openat(AT_FDCWD,\’/lib64/libpthread.so.0 \’,O_RDONLY|O_CLOEXEC)=3.openat(AT_FDCWD,\’/lib64/libstdc .so.6 \’,O_RDONLY|O_CLOEXEC)=3.openat(AT_FDCWD,\’/lib64/libm.so.6 \’,O_RDONLY|O_CLOEXEC)=3.openat(AT_FDCWD,\’/lib64/libgcc_s.so.1 \’,O_RDONLY|O_CLOEXEC)=3.openat(AT_FDCWD,\’/lib64/libc.so.6 \’,O_RDONLY|O_CLOEXEC)=3.看一下这个结果,除了动态链接C/C库之外,星际争霸二没有做任何事情,这否定了我的假设。
那为什么会出现段错误呢?
因为同样的程序在我的本地机器上运行的时候没有崩溃,这也否定了暴雪的代码有问题的假设。
快速搜索如何调试段错误使我想起了Valgrind(http://valgrind.org/),令我惊讶的是,该工具竟然可以在Google Colab上使用。
瓦尔格兰的一段输出如下:
==354==进程以信号11(西格夫)的默认动作终止:转储内核==354==不在地址0x8的映射区域内访问==354==在0x6B3DF0:(in/content/starcraft ii/Versions/base 56787/SC2 _ x64)==354==by0x 65 ff 97:(in/content/starcraft ii/Versions/base 56787/SC2 _ x64)==354==by0x 89 cd5c 6:malloc extension:Initialize()(in/usr/lib/x86 _ 64-Linux-GNU/libtcmalloc。所以。4 .3 .0)==354==by0x 89 b7d 29:(在/usr/lib/x86 _ 64-Linux-GNU/libtcmalloc中。所以。4 .3 .0)==354==by 0 x7b 79 ad 9:call _ init。部分。0(dl-init。c:72)==354==by 0 x7b 79 bea:call _ init(dl-init。c:30)==354==by 0 x7b 79 bea:_ dl _ init(dl-init。c:120)==354==乘0 x7?(在/lib/x86 _ 64-Linux-GNU/LD-2.26中。所以)==354==如果您认为这是由于程序主线程中的stack==354==溢出造成的(不太可能,但==354==可能),您可以尝试使用- main-stacksize=标志增加==354==主线程堆栈的大小。==354==本次运行中使用的主线程堆栈大小为8388608。==354====354==堆摘要:==354==退出时正在使用:0个块中的0个字节==354==总堆使用量:4个分配、4个释放、72,710个分配的字节==354===354==所有堆块都已释放-没有泄漏可能==354===354==对于检测到的和隐藏的错误计数,请使用:-v==354==错误摘要:来自2个上下文的2个错误(隐藏:0那么,唯一一个可以识别的函数就是libtcmalloc.so中的MallocExtension : Initialize()。
对于不了解TCMalloc的人而言,它是谷歌的定制化内存分配器,用于谷歌浏览器等产品中。
等等.
回到我追踪星际争霸二的时候,我记得只看到C/C库被加载了。这似乎不正确,TCMalloc是从哪里来的呢?
结果证明,有一种方式能够让TCMalloc在没有使用TCMalloc编译的程序上强制执行。通过在Linux操作系统操作系统上设置LD _预载环境变量,你可以加TCMalloc共享库到程序中,强制让程序使用TCMalloc。
它在Google Colab上会是什么样子呢.
解决方案
不幸的是,设置LD _预载环境变量并不能传播到环境的其他部分中。
通过执行以下命令:
!容易得到卸载libtcmalloc*我成功地卸载了TCMalloc,然后尽管还有错误信息,但是星际争霸2已经开始运行了,星际争霸2机器学习项目的大门也随之开启了。
我已经在Google Colab上提出了这个bug(https://github。com/Google colab/colab tools/issues/106),因此我们以后不必为此大费周折了。
基于STARCRARFT II进行的机器学习项目。