MindSpore Windows 編譯系列(一):如何在Windows下編譯MindSpore CPU版本

當前MindSpore對于Windows平臺的支持仍有欠缺,比如不支持GPU粱坤,編譯工具鏈導致的無法編譯debug版本而影響問題定位效率等。今年MindSpore將嘗試通過社區(qū)如易用性sig協(xié)作的方式瓷产,共同把這些問題解決站玄,為MindSpore的Windows用戶提供更好的使用體驗。

個人以前也沒有Windows以及MindSpore框架開發(fā)的經(jīng)驗濒旦,在網(wǎng)絡(luò)搜索關(guān)于MindSpore的資料時株旷,找到的更多是關(guān)于如何使用MindSpore進行網(wǎng)絡(luò)實現(xiàn)和訓練、推理,沒有從框架貢獻者的角度介紹如何參與或者給MindSpore貢獻代碼的內(nèi)容晾剖。所以锉矢,想借這個機會記錄好Windows下這些問題解決的過程,既能聯(lián)合社區(qū)的朋友們解決MindSpore在Windows下的問題齿尽,也能提升自己對于Windows下開發(fā)沽损、對于MindSpore在架構(gòu)和代碼層面的理解,還可以為想給MindSpore貢獻代碼的同學提供一些參考循头。

在開始解決實際的問題前绵估,我想第一步應(yīng)該是參考MindSpore官網(wǎng)的安裝指南來完成Windows下CPU版本的編譯,本文就是記錄下我編譯安裝的過程以及發(fā)現(xiàn)的問題卡骂。

Windows下編譯MindSpore CPU版本

1. 安裝依賴軟件

MindSpore的CPU版本在編譯時依賴軟件及安裝方式如下表:

軟件 版本要求 用途 安裝方法
Windows 10,64位 操作系統(tǒng)平臺
python 3.9.0/3.7.5 Python語言解釋器 3.9.0 下載地址国裳,直接安裝即可
mingw 7.3.0 編譯工具鏈 下載地址,解壓后將目錄加入到Path環(huán)境變量下
git 2.29.0 版本管理工具 下載地址全跨,下載直接安裝即可
cmake >3.18.3 構(gòu)建工具 下載地址缝左,下載64位MSI版本直接安裝即可
strawberry perl 5.28.1.2801 perl編譯器 下載地址,解壓后將Perl的bin目錄加到Path環(huán)境變量中
wheel >0.32.0 Python打包工具 執(zhí)行pip install wheel即可

官網(wǎng)的Windows編譯安裝指南中推薦使用ActivePerl浓若,但其下載過程中還需要注冊渺杉,體驗并不好,所以我使用了strawberry perl挪钓,而且最好是zip包少办,因為MSI的安裝會將額外的gcc編譯工具鏈添加到Path中,影響編譯中g(shù)cc編譯器的選擇诵原;

對于以上需要安裝的工具,exe以及msi格式的軟件包都可以自動配置bin目錄到Path環(huán)境變量中(有些需要在安裝過程中指定挽放,如cmake)绍赛,而壓縮包版本則需要在解壓后,手動在Windows的環(huán)境變量Path中添加新的路徑辑畦。如下圖吗蚌,如果strawberry-perl-5.28.2.1-64bit.zip被解壓到D盤的根目錄,可以在系統(tǒng)變量Path或者用戶變量Path中增加D:\Strawberry\perl\bin的項目纯出,同理蚯妇,也需要增加mingw bin的路徑,如圖中的D:\mingw64\bin暂筝。

perl.png

另一個需要配置的是pip的鏡像源箩言,可以考慮使用華為云Python鏡像,在C:\Users\<UserName>\pip\pip.ini中添加如下內(nèi)容即可:

[global]
index-url = https://repo.huaweicloud.com/repository/pypi/simple
trusted-host = repo.huaweicloud.com
timeout = 120

2. 下載MindSpore源碼編譯

首先通過git clone --depth=1 https://gitee.com/mindspore/mindspore.git -b r1.6 下載框架的源碼焕襟,這里指定了1.6版本的tag陨收,原因當前的master分支編譯會出錯……。

然后啟動Windows的CMD,然后切換到代碼倉庫的目錄务漩,正式開始編譯前可以設(shè)置下patch的環(huán)境變量MS_PATCH_PATH拄衰,以防止在三方庫打patch時因為git安裝路徑的問題找不到patch命令,方式和第一部分中添加Path環(huán)境變量類似饵骨。首先在cmd中通過where git找到git的安裝目錄翘悉,如D:\Program Files\Git\cmd\git.exe,然后創(chuàng)建一個新的用戶環(huán)境變量MS_PATCH_PATH,賦值為D:\Program Files\Git\usr\bin居触。最后在cmd 輸入 refreshenv完成環(huán)境變量刷新妖混。

MindSpore代碼倉根目錄下的build.bat是啟動編譯的批處理腳本,腳本中有兩處變量會影響到編譯的效率:

  • SET threads=8:設(shè)置并行編譯的線程數(shù)饼煞,默認為8源葫。如果你的處理器支持的線程數(shù)更高,可以修改為更大的數(shù)字砖瞧,比如我的CPU是8核16線程息堂,這個地方我就改成了16;
  • SET ENABLE_GITEE=ON:是否通過gitee下載三方庫的壓縮包,默認從github下載块促。如果網(wǎng)絡(luò)訪問外網(wǎng)環(huán)境不太好荣堰,可以選擇修改為ON,加快下載速度竭翠;

這些準備完成后振坚,就可以在cmd中執(zhí)行call build.bat開始編譯,正常大約1小時左右就可以完成編譯斋扰,生成mindspore的whl包渡八。

3. 安裝編譯版本并檢查

MindSpore的編譯好的whl包路徑在build\package\下,切換到該目錄下传货,使用pip install mindspore-1.6.1-cp39-cp39-win_amd64.whl 屎鳍,執(zhí)行運行檢查:

D:\Workspace\mindspore\build\package>python -c "import mindspore;mindspore.run_check()"
MindSpore version:  1.6.1
The result of multiplication calculation is correct, MindSpore has been installed successfully!

可以運行,表明編譯成功。

發(fā)現(xiàn)的問題/改進點

如果一切順利,整個的編譯時間大概在一小時多一點挺智,但實際上我花了大約1天的時間钦奋,原因是在過程中碰到了一些列的問題。

  1. 使用conda的Python環(huán)境,編譯Protobuf失敗。如果你的Python環(huán)境是通過conda去做管理的,在編譯Protobuf三方庫會遇到這樣的錯誤:
-- 3.13.0.0
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Found ZLIB: C:/Users/lenovo/.conda/envs/py39/Library/lib/z.lib (found version "1.2.11")
-- Performing Test protobuf_HAVE_BUILTIN_ATOMICS
-- Performing Test protobuf_HAVE_BUILTIN_ATOMICS - Success
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Workspace/mindspore/build/mindspore/_deps/protobuf-src/_build
Scanning dependencies of target libprotobuf-lite
In file included from D:\Workspace\mindspore\build\mindspore\_deps\protobuf-src\src\google\protobuf\arena.cc:37:0:
C:/Users/lenovo/.conda/envs/py39/Library/include/google/protobuf/stubs/mutex.h: In constructor 'constexpr google::protobuf::internal::WrappedMutex::WrappedMutex()':
C:/Users/lenovo/.conda/envs/py39/Library/include/google/protobuf/stubs/mutex.h:124:29: error: temporary of non-literal type 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' in a constant expression
   constexpr WrappedMutex() {}
                             ^
……                             

protobuf.cmake中用-Dprotobuf_WITH_ZLIB=OFF屏蔽zlib后可以完成編譯忧饭,但具體影響的功能不祥。

mindspore_add_pkg(protobuf
        VER 3.13.0
        LIBS protobuf
        EXE protoc
        URL ${REQ_URL}
        MD5 ${MD5}
        CMAKE_PATH cmake/
        CMAKE_OPTION -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -Dprotobuf_WITH_ZLIB=OFF
        PATCHES ${PROTOBUF_PATCH_ROOT}/CVE-2021-22570.patch)

通過上面的日志發(fā)現(xiàn)編譯時用到了conda的zlib秉氧、protobuf頭文件眷昆,并非框架下載zlib和protobuf,推測根源的問題在這里。檢查系統(tǒng)環(huán)境變量亚斋,發(fā)現(xiàn)miniconda在安裝時自動的在Path環(huán)境變量中添加了mingw的類庫路徑作媚,而這個路徑下包含了編譯框架需要的zlib、protobuf的一些頭文件帅刊,版本不一致導致了protobuf的編譯錯誤纸泡。將下圖中包含Library路徑從Path變量中去掉后,在不修改protobuf.cmake的情況下也可以正常編譯赖瞒。

conda.png
  1. master分支編譯完成安裝后出現(xiàn)導入錯誤女揭。具體的錯誤信息如下:
(py39) D:\Workspace\mindspore\build\package>python -c "import mindspore;mindspore.run_check()"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "D:\Workspace\mindspore\build\package\mindspore\__init__.py", line 29, in <module>
    from .rewrite import *
ModuleNotFoundError: No module named 'mindspore.rewrite'
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "D:\Workspace\mindspore\build\package\mindspore\__init__.py", line 29, in <module>
    from .rewrite import *
ModuleNotFoundError: No module named 'mindspore.rewrite'

屏蔽對應(yīng)的代碼行可以正常運行,但這個錯誤不應(yīng)該出現(xiàn)栏饮,master上合入的代碼應(yīng)該保證基本的功能吧兔,這里的自動化測試環(huán)節(jié)沒有能照顧到這個基礎(chǔ)的健康檢查。這也是為什么上面的編譯使用了1.6版本的分支而非master的原因袍嬉。

  1. 是否有必要引入perl這個依賴境蔼。我檢查了MindSpore代碼倉中對于perl的使用,結(jié)果發(fā)現(xiàn)Windows下只有protobuf的cmake有使用伺通,
        if(WIN32)
            add_custom_command(
                    OUTPUT "${CMAKE_BINARY_DIR}/proto/${file_name}.pb.cc"
                    "${CMAKE_BINARY_DIR}/proto/${file_name}.pb.h"
                    "${CMAKE_BINARY_DIR}/proto/${file_name}_pb2.py"
                    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
                    ...
                    COMMAND perl -pi.bak -e "s/import (.+_pb2.*)/from . import \\1/"
                            "${CMAKE_BINARY_DIR}/proto/${file_name}_pb2.py"
                    ...
                    COMMENT "Running C++ protocol buffer compiler on ${file}" VERBATIM)

這里perl命令的作用是把所有*_pb2.py的python文件中的import xxx as xxx 替換為 from . import xxx as xxx箍土。如果沒有其它的庫依賴perl,這里可以考慮用inline的python命令罐监、cmd命令行工具或者sed(for windows)來替換吴藻,最優(yōu)的情況下可以在安裝和編譯的過程中減少一個依賴,提升使用體驗弓柱。

總結(jié)

本次的MindSpore CPU版本編譯過程中發(fā)現(xiàn)了3個問題:conda管理的python環(huán)境編譯沟堡、master編譯后的執(zhí)行錯誤以及編譯依賴perl的問題,針對這幾個問題矢空,我在gitee的代碼倉中創(chuàng)建了issue并添加kind/bugcomp/build-install標簽弦叶,方便負責相應(yīng)領(lǐng)域的開發(fā)人員進行分析和解決問題。

編譯的過程中出現(xiàn)了大量的三方庫以及模塊的編譯過程妇多,要理解MindSpore的編譯,首先得理清楚過程中都依賴了什么燕侠,編譯了那些模塊者祖,功能和作用是什么,這也是下一步需要分析和完成的內(nèi)容绢彤。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末七问,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子茫舶,更是在濱河造成了極大的恐慌械巡,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異讥耗,居然都是意外死亡有勾,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門古程,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔼卡,“玉大人,你說我怎么就攤上這事挣磨」统眩” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵茁裙,是天一觀的道長塘砸。 經(jīng)常有香客問我,道長晤锥,這世上最難降的妖魔是什么掉蔬? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮查近,結(jié)果婚禮上眉踱,老公的妹妹穿的比我還像新娘。我一直安慰自己霜威,他們只是感情好谈喳,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著戈泼,像睡著了一般婿禽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上大猛,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天扭倾,我揣著相機與錄音,去河邊找鬼挽绩。 笑死膛壹,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的唉堪。 我是一名探鬼主播模聋,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼唠亚!你這毒婦竟也來了链方?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤灶搜,失蹤者是張志新(化名)和其女友劉穎祟蚀,沒想到半個月后工窍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡前酿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年患雏,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片薪者。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡纵苛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出言津,到底是詐尸還是另有隱情攻人,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布悬槽,位于F島的核電站怀吻,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏初婆。R本人自食惡果不足惜蓬坡,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望磅叛。 院中可真熱鬧屑咳,春花似錦、人聲如沸弊琴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽敲董。三九已至紫皇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間腋寨,已是汗流浹背聪铺。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留萄窜,地道東北人铃剔。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像查刻,于是被迫代替她去往敵國和親番宁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容