在機器學習中,經(jīng)常遇到稀疏向量,稀疏矩陣。如何高效處理這些稀疏對象,決定了一些模型能否在線落地應用。目前正在專攻這方面,自己瞎琢磨,走了不少彎路,也有一點心得。這里記錄下來,不斷總結。
當遇到計算瓶頸時:
-
算法層面改進
這是最直接,收益也最大的。
比如在千萬級以上的向量空間中搜索最近鄰居,暴力的兩兩計算代碼層面無論如何加速計算量依然太大了。
faiss通過預訓練聚類和向量壓縮大大減少搜索時的計算量。上億級別搜索也能在毫秒級完成。例外情況是計算量本身不是特別大,而且在代碼層面很方便加速,改進對CPU負載的也不是特別大。比如利用avx和openmp,這時直接代碼加速也是可行的。
-
第三方庫
當要在代碼層面加速時,首先考慮已有的第三方庫。選擇庫時第一原則輕量,穩(wěn)定,而不是花哨,功能強大。
BLAS實現(xiàn)中openblas最好用,但是只支持稠密矩陣。MKL支持稀疏矩陣,性能也最好,但是編譯鏈接很麻煩。
-
手動優(yōu)化
BLAS庫適用場景是超大矩陣和超大向量,一次計算結果寫回內存。如果計算步驟過多,中間結果讀寫內存會有很大開銷,這時比較適合手動優(yōu)化。
手動優(yōu)化需要充分利用寄存器和緩存,盡量讓中間結果在寄存器和緩存中保存。其實挺難的,而且現(xiàn)代硬件已經(jīng)特別復雜,自己臆想的一些手段不一定就符合硬件的喜好。所以驗證很重要。
并行計算
當并行數(shù)不大時,可以直接使用cpu并行。但是cpu核心畢竟比較少,大規(guī)模并行GPU更有優(yōu)勢,這是目前正在嘗試的方向。
心得:
- 工程實現(xiàn)常常要對公式做變換,利于向量計算或并行計算。因此理解核心算法才能做出取舍和變換。
- 多多學習第三方庫的優(yōu)秀算法,第三方庫的實現(xiàn)通常為了考慮通用性優(yōu)化沒有做到極致。而為了適應手頭的需求可以各種魔改,優(yōu)化就是特化。