在機(jī)器學(xué)習(xí)中望伦,經(jīng)常遇到稀疏向量林说,稀疏矩陣。如何高效處理這些稀疏對象屯伞,決定了一些模型能否在線落地應(yīng)用腿箩。目前正在專攻這方面,自己瞎琢磨劣摇,走了不少彎路珠移,也有一點(diǎn)心得。這里記錄下來末融,不斷總結(jié)钧惧。
當(dāng)遇到計算瓶頸時:
-
算法層面改進(jìn)
這是最直接,收益也最大的勾习。
比如在千萬級以上的向量空間中搜索最近鄰居浓瞪,暴力的兩兩計算代碼層面無論如何加速計算量依然太大了。
faiss通過預(yù)訓(xùn)練聚類和向量壓縮大大減少搜索時的計算量巧婶。上億級別搜索也能在毫秒級完成乾颁。例外情況是計算量本身不是特別大,而且在代碼層面很方便加速艺栈,改進(jìn)對CPU負(fù)載的也不是特別大英岭。比如利用avx和openmp,這時直接代碼加速也是可行的湿右。
-
第三方庫
當(dāng)要在代碼層面加速時诅妹,首先考慮已有的第三方庫。選擇庫時第一原則輕量毅人,穩(wěn)定漾唉,而不是花哨,功能強(qiáng)大堰塌。
BLAS實(shí)現(xiàn)中openblas最好用,但是只支持稠密矩陣分衫。MKL支持稀疏矩陣场刑,性能也最好,但是編譯鏈接很麻煩。
-
手動優(yōu)化
BLAS庫適用場景是超大矩陣和超大向量牵现,一次計算結(jié)果寫回內(nèi)存铐懊。如果計算步驟過多,中間結(jié)果讀寫內(nèi)存會有很大開銷瞎疼,這時比較適合手動優(yōu)化科乎。
手動優(yōu)化需要充分利用寄存器和緩存,盡量讓中間結(jié)果在寄存器和緩存中保存贼急。其實(shí)挺難的茅茂,而且現(xiàn)代硬件已經(jīng)特別復(fù)雜,自己臆想的一些手段不一定就符合硬件的喜好太抓。所以驗(yàn)證很重要空闲。
并行計算
當(dāng)并行數(shù)不大時,可以直接使用cpu并行走敌。但是cpu核心畢竟比較少碴倾,大規(guī)模并行GPU更有優(yōu)勢,這是目前正在嘗試的方向掉丽。
心得:
- 工程實(shí)現(xiàn)常常要對公式做變換跌榔,利于向量計算或并行計算。因此理解核心算法才能做出取舍和變換捶障。
- 多多學(xué)習(xí)第三方庫的優(yōu)秀算法僧须,第三方庫的實(shí)現(xiàn)通常為了考慮通用性優(yōu)化沒有做到極致。而為了適應(yīng)手頭的需求可以各種魔改残邀,優(yōu)化就是特化皆辽。