當前位置:
首頁 > 新聞 > 教程|如何利用Google Colab免費訓練星際爭霸II

教程|如何利用Google Colab免費訓練星際爭霸II

本文介紹了如何在Google Colab中提供的機器學習項目,

如果你想開始使用免費的StarCraft II機器學習環境,請先完善GPU硬體,您可以看一下我的Google Colab筆記本:https://colab.research.google.com/drive/1AzCKV98UaQQz2aJIeGWlExcxBrpgKsIV

教程|如何利用Google Colab免費訓練星際爭霸II

最近,我和幾位朋友開始了星際爭霸II的機器學習項目。我覺得快速訓練神經網路的能力對於研究者的成功是很重要的。為了向全球的星際爭霸II研究者提供一個可復現,高效,並容易分享代碼的環境,我想看看我們能否讓StrCraft II在Google Colab(Google提供免費GPU的機器學習環境)上運行起來。

然而,在下載了StarCraft II,並安裝完必需的庫之後,你會面臨以下問題:

I0331 08:30:17.832181 139972195997568 sc_process.py:148] Connection attempt 0 (running: None)****** omitted reconnection attempts ******I0331 08:32:17.048350 139972195997568 sc_process.py:148] Connection attempt 119 (running: -11)I0331 08:32:18.050124 139972195997568 sc_process.py:180] Shutdown gracefully.I0331 08:32:18.050344 139972195997568 sc_process.py:166] Shutdown with return code: -11Failed to create the socket.I0331 08:32:18.056085 139972195997568 sc2_env.py:327] Environment Close

構建額外的Pylons也無法修復這個問題。

理解返回代碼

我所做的第一件事就是弄清楚返回代碼的含義。

讀了PySC2的源碼(https://github.com/deepmind/pysc2/blob/39f84b01d662eb58b3d95791f59208c210afd4e7/pysc2/lib/sc_process.py)之後,我找到了設置返回代碼的代碼段:

@propertydef running(self):
return self._proc.poll() if self._proc else False

poll()來自Python的subprocess模塊,深入挖掘後發現11就是導致StarCraft中斷的信號。

信號11就是臭名昭著的段錯誤,這個信號給C語言編程者帶來了無窮無盡的噩夢。

為了確認,我發現SC2是可執行的,而且是自行執行的。

> !~/StarCraftII/Versions/Base59877/SC2_x64
Segmentation Fault (Core Dumped)

在硬模式下調試

正常情況下,我會啟動最喜歡的調試工具,那本文就變成了如何使用GDB的過程。

不過,我們是使用Google Colab來處理的,我們唯一擁有的就是一個Jupyter Notebook網頁。這意味著:

1.沒有調試器

沒有根特權

3.工具有限,比如沒有strace

教程|如何利用Google Colab免費訓練星際爭霸II

RIP調試

當你只有一個網頁的時候......

第一步就是在伺服器上嘗試不同版本的星際爭霸II,暴雪公司提供了星際爭霸II的4.0.2,3.17和3.16.1三個版本。不幸的是,沒有一個能夠成功。

然後我決定在本地Linux機器上運行星際爭霸II,這個環境我可以控制並在其中進行調試。它還允許我測試我的假設。

第一個猜想:沒有找到需要的庫

我最初的猜測是,StarCraft II作為一個遊戲,可能需要某些OpenGL函數和庫,而這些並不包含在我所用的Google Colab環境中。

為了驗證這個猜想,我在本地機器上運行星際爭霸II,這次是有strace工具的,這使得我可以跟蹤系統讓星際爭霸II做了什麼。由於所有的庫都通過操作系統載入了,這樣一來,我就能夠跟蹤任何一個缺失的依賴項,或者查看是否有什麼奇怪的事情發生。

完整的trace日誌參見:https://gist.github.com/FrozenXZeus/53a85f58856cb346b90313110ce89bcc,下面展示了一小段:

execve("./SC2_x64", ["./SC2_x64"], 0x7fffc19e08b0 /* 49 vars */) = 0brk(NULL) = 0x95bd000access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 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 ++庫之外,星際爭霸II沒有做任何事情,這否定了我的假設。

那為什麼會出現段錯誤呢?

因為同樣的程序在我的本地機器上運行的時候沒有崩潰,這也否定了暴雪的代碼有問題的假設。

快速搜索如何調試段錯誤使我想起了Valgrind(http://valgrind.org/),令我驚訝的是,該工具竟然可以在Google Colab上使用。

Valgrind的一段輸出如下:

==354== Process terminating with default action of signal 11 (SIGSEGV): dumping core==354== Access not within mapped region at address 0x8==354== at 0x6B3DF0: ??? (in /content/StarCraftII/Versions/Base56787/SC2_x64)==354== by 0x65FF97: ??? (in /content/StarCraftII/Versions/Base56787/SC2_x64)==354== by 0x89CD5C6: MallocExtension::Initialize() (in /usr/lib/x86_64-linux-gnu/libtcmalloc.so.4.3.0)==354== by 0x89B7D29: ??? (in /usr/lib/x86_64-linux-gnu/libtcmalloc.so.4.3.0)==354== by 0x7B79AD9: call_init.part.0 (dl-init.c:72)==354== by 0x7B79BEA: call_init (dl-init.c:30)==354== by 0x7B79BEA: _dl_init (dl-init.c:120)==354== by 0x7B69ED9: ??? (in /lib/x86_64-linux-gnu/ld-2.26.so)==354== If you believe this happened as a result of a stack==354== overflow in your program"s main thread (unlikely but==354== possible), you can try to increase the size of the==354== main thread stack using the --main-stacksize= flag.==354== The main thread stack size used in this run was 8388608.==354====354== HEAP SUMMARY:==354== in use at exit: 0 bytes in 0 blocks==354== total heap usage: 4 allocs, 4 frees, 72,710 bytes allocated==354====354== All heap blocks were freed -- no leaks are possible==354====354== For counts of detected and suppressed errors, rerun with: -v==354== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)Segmentation fault (core dumped)

那麼,唯一一個可以識別的函數就是libtcmalloc.so.4.3.0中的MallocExtension :: Initialize()。

對於不了解TCMalloc的人而言,它是谷歌的定製化內存分配器,用於Google Chrome等產品中。

等等......

回到我追蹤星際爭霸II的時候,我記得只看到C / C ++庫被載入了。這似乎不正確,TCMalloc是從哪裡來的呢?

結果證明,有一種方式能夠讓TCMalloc在沒有使用TCMalloc編譯的程序上強制執行。通過在Linux上設置LD_PRELOAD環境變數,你可以加TCMalloc共享庫到程序中,強制讓程序使用TCMalloc。

它在Google Colab上會是什麼樣子呢......

教程|如何利用Google Colab免費訓練星際爭霸II

解決方案

不幸的是,設置LD_PRELOAD環境變數並不能傳播到環境的其他部分中。

通過執行以下命令:

!apt-get uninstall libtcmalloc*

我成功地卸載了TCMalloc,然後儘管還有錯誤信息,但是StarCraft II已經開始運行了,StarCraft II機器學習項目的大門也隨之開啟了。

我已經在Google Colab上提出了這個bug(https://github.com/googlecolab/colabtools/issues/106),因此我們以後不必為此大費周折了。

基於STARCRARFT II進行的機器學習項目。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器之心 的精彩文章:

Michael Jordan熱文:人工智慧革命尚未開啟
如何使用Docker、TensorFlow目標檢測API和OpenCV實現實時目標檢測和視頻處理

TAG:機器之心 |