最近釋出的 go-attention(一個純 Go 實現的注意力機制和 transformer 層)在開發者社群引發了關於 Go 語言在機器學習等計算密集型任務中效能侷限性的重大爭論。
雖然該庫旨在提供一個沒有外部依賴的簡潔實現,但社群反饋表明,與那些更好地支援硬體加速的語言相比,它可能面臨嚴重的效能挑戰。
效能問題成為討論焦點
社群開發者對在純 Go 中實現注意力機制的效能影響提出了嚴重擔憂。多位評論者指出,Go 缺乏原生的 SIMD(單指令多資料)支援,而這對於構成 transformer 模型核心的向量和矩陣運算至關重要。一位開發者指出,在數學計算方面,Go 的速度慢得令人無法接受,如果沒有 SIMD CPU 指令,其實現可能比 C、C++、Rust 甚至 Python 和 Java(它們通常呼叫最佳化的 C/C++ 庫)慢幾個數量級。
該庫缺乏 GPU/CUDA 支援也被指出是一個顯著的限制,因為現代 transformer 實現在實際應用中嚴重依賴 GPU 加速來獲得實用效能。一些開發者建議,對於生產用例,使用 Go 繫結已建立的庫(如 llama.cpp)可能是更為務實的方法。
社群強調的效能侷限性:
- 缺乏原生 SIMD(單指令多資料)支援
- 無 GPU/CUDA 加速
- 標量程式碼僅操作單個 fp64 值
- 可能比 C/C++/Rust 實現"慢幾個數量級"
建議的替代方案:
- 使用 Go 繫結 llama.cpp
- 在 Go 彙編(Goasm)中實現關鍵部分
- 使用專門的包如 viterin/vek 或 kelindar/simd
- 使用 Go 作為帶有 cgo 的 JIT 程式碼生成器
替代方法和解決方案
幾位開發者提出瞭解決效能瓶頸的潛在方案。一種建議是利用 Go 的彙編支援(Goasm)來實現關鍵的數學運算。其他人則提到了現有的 Go 包,如 viterin/vek 或 kelindar/simd,這些可以透過更好地利用 SIMD 來提高效能。
一位開發者提出了一個有趣的替代方法,描述瞭如何使用 Go 作為 JIT 程式碼生成器,動態連結結果,然後透過 cgo 跳入其中以獲得更好的效能,這種方法可以輕鬆飽和 CPU 向量數學單元。這突顯了開發者正在探索的創造性解決方案,以克服 Go 在數學運算方面的原生效能限制。
儘管存在效能問題,但具有教育價值
儘管存在效能問題,一些社群成員仍然讚賞該實現的教育價值。一位評論者指出,該庫提供了一個機會,可以在實現層面而不是僅透過閱讀部落格來研究注意力機制。這表明,即使該庫不適合生產工作負載,它在使這些演算法對 Go 開發者更容易理解和訪問方面仍然發揮著重要作用。
當使用 Ghidra 等工具分析程式碼時,開發者確認該實現編譯為操作單個 fp64 值的標量程式碼,這進一步證實了效能方面的擔憂。共識似乎是,雖然該庫可能對學習和原型設計有用,但生產應用可能需要能夠利用硬體加速的替代方法。
圍繞 go-attention 的討論反映了 Go 生態系統中更廣泛的張力,即語言對簡單性和可讀性的強調與機器學習等計算密集型領域的效能需求之間的矛盾。正如一位開發者所說:
「如果不使用 SIMD CPU 指令,計算成本將會非常高。」
這場辯論也觸及了在 Python 之外的語言中實現機器學習原語的日益增長的興趣,因為開發者希望將這些功能整合到他們現有的技術棧中,而不需要跨語言互操作的開銷。
參考:go-attention: A full attention mechanism and transformer in pure go