[TOOLS] 11 分鐘閱讀OraCore 編輯部

SCALE 讓 CUDA 變可攜 GPU 編譯

我拆 Spectral Compute 的 SCALE 編譯器,講它怎麼把 CUDA 專案拉出單一 GPU 綁定,還順手給你一份可直接套用的評估模板。

分享 LinkedIn
SCALE 讓 CUDA 變可攜 GPU 編譯

以前 CUDA 卡死在 Nvidia,現在 SCALE 想把同一份程式帶去別家 GPU

我在 CUDA 裡泡很久了,真的很久。程式能跑、kernel 也調過、團隊也把一堆血汗塞進去,然後總有人丟一句:這套能不能也跑 AMD?每次聽到我都想翻白眼,因為那通常不是一個技術問題,是一整包預算、時程、相容性債一起冒出來。我看過太多團隊一路繳 Nvidia 稅,因為「搬家」聽起來像第二個專案,沒人想付。

所以我看到 Spectral Compute 時,第一反應不是「哇好棒」,我對 GPU 工具鏈的宣傳早就有免疫力了。真正讓我停下來的是它打的位置很準:編譯器。原始拆解文在 TechPlanet,它把 SCALE 描成 NVCC 的 drop-in replacement,這句話如果是真的,影響的就不只是一個工具,而是整個 CUDA 綁定的思考方式。

CUDA 綁定先傷到預算,不是先傷到技術

訂閱 AI 趨勢週報

每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。

不會寄垃圾信,隨時可取消。

Nvidia's CUDA programming language has become the de facto standard for GPU computing, commanding approximately 80% of the market for parallel computing development tools.

白話一點就是:當一套工具變成預設值,硬體廠就開始有議價權。你如果把 codebase 綁死在 CUDA,上線時你買的不只是編譯器,你還一起買了 Nvidia 的定價、路線圖和供貨節奏。

SCALE 讓 CUDA 變可攜 GPU 編譯

我看過研究團隊和新創都踩過這坑。他們一開始根本不是想做 vendor lock-in,只是想先把結果做出來。CUDA 通常就是最快的路。問題是三年後,老闆想分散硬體風險,工程團隊才發現程式和手感都已經焊死在同一邊。

TechPlanet 提到 CUDA 大概吃下平行運算開發工具市場的 80%。我不會把這數字當天條,但方向很清楚:CUDA 是預設,預設會黏人,黏人最後就變成廠商手上的槓桿。

實操上,我會直接把可攜性拉進成本表。你在算雲端費用、模型品質、GPU 數量時,就該一起算能不能搬。如果搬不走,你其實沒有採購選項。

  • 先盤點哪些 kernel、library、build step 是 CUDA 專屬。
  • 標出一旦重寫會很痛的區塊。
  • 把「繼續綁死」和「做可攜化」的成本放同一張表。

SCALE 會被注意,是因為它碰的是 NVCC,不是表面語法

Spectral Compute 成立於 2018 年,做出 SCALE 這套編譯器,底層用了 ClangLLVM,目標是變成 NVCC 的替代品。這點很重要。它不是只翻幾個 API 就說自己支援 CUDA,而是直接重做編譯路徑。

也就是說,它不是站在外面做轉接頭,而是直接進到 compile time,去碰那些真正決定效能的地方。這比 source-to-source converter 難很多,但也比較像真的在解問題。因為 GPU 程式最貴的從來不是語法長什麼樣,是你能不能保住原本的優化結果。

我以前踩過一堆「看起來很美」的工具。簡報很順,demo 很穩,結果一碰到 template、device code,或是那種被資深工程師調到骨子裡的 kernel,整個就露餡。SCALE 如果真能把實際 CUDA code 編過去,而且行為夠接近 NVCC,那不是小修小補,是工作流直接換軌。

實操寫法很簡單:評估可攜工具時,不要問它懂不懂 CUDA。你要問的是,它能不能真的插進 build pipeline,能不能保 correctness,效能有沒有維持在可接受範圍。碰不到 build 的工具,基本就是 demo。

  • 先看能不能接進你現有 CI。
  • 確認它吃不吃你現在的 compiler flags 和 build system。
  • 不要只看 runtime,compile output 也要驗。

LLVM 路線比翻譯戲法更像正解

TechPlanet 把 SCALE 描成 clean-room re-implementation,而不是 translation layer。這個差別很大。翻譯層通常只是把原本的抽象包一層,再祈禱相容性不要炸。重做編譯器,才有機會針對目標硬體重新安排最佳化,不用硬扛 CUDA 原本的包袱。

SCALE 讓 CUDA 變可攜 GPU 編譯

翻成白話就是:SCALE 想少背一點 CUDA 的歷史債。文章也順手比了 HIPIFYSYCLomaticZLUDA,這些工具各自解一塊,但很少有人能把整條路都處理好。翻譯可以讓你先動起來,卻不保證你落地後還跑得漂亮。

我對「幾乎可攜」這種東西一直很警覺,因為最後 10% 通常才是工程本體。那裡面藏著奇怪的 data layout、手調 kernel、沒人寫文件的 library call、只有某一家硬體才成立的假設。這也是我比較願意相信 compiler-based approach 的原因,至少它有機會真的碰到執行模型本身。

實操寫法:你在比 GPU 可攜策略時,直接排一個順序,看它保留了多少原始執行模型、又重編了多少東西。越依賴 runtime patching 或 binary trickery 的方案,後面通常越容易補票。

正確性先過,漂亮 benchmark 沒什麼用

文章提到 Spectral 會在重新編譯後做數值驗證,只有輸出跟 NVCC 版本對得上,才算成功。這做法我喜歡,因為它很無聊,而無聊在 compiler 工作裡通常是好事。速度再快,答案錯了也白搭。

翻譯一下就是:SCALE 不只是在追 benchmark 截圖,它是在證明程式算出來的東西還是一樣。這聽起來理所當然,但你真的被「優化」工具陰過一次,就知道 edge case 被偷偷改掉有多煩。我看過團隊花好幾週 debug,最後發現不是演算法有問題,是 portability layer 在搞鬼。

GPU code 還有一個麻煩:很多錯誤不容易第一時間看出來。模型還能訓、模擬還能跑、數字看起來也合理。這種「錯但看起來對」最陰。比起一個只會喊快的工具,我寧可它保守一點,至少別讓我懷疑人生。

實操寫法:先做驗證 harness,再談遷移。把 NVCC 的已知正確輸出存起來,拿替代工具鏈去比,測代表性輸入,不要只測 happy path。

  • 先抓幾個真實 workload 當 baseline。
  • 比數值容忍度,不要只比字串是否一模一樣。
  • 邊界案例要測,別只看 benchmark dataset。

CUDA 生態不是只有編譯器,還有一整堆庫

CUDA 不是一門語言而已,它是一整包工具鏈和假設。文章點到 cuDNNcuTENSORcuDF,這才是最麻煩的地方。編譯器可以先幫你進門,但裡面還有一堆 CUDA 專屬依賴等著你拆。

也就是說,可攜性是分層的。第一層是能不能編過。第二層是 library 有沒有覆蓋。第三層才是換到別家硬體後,效能會不會直接塌掉。很多人講「我們支援 CUDA」的時候,根本沒說清楚到底支援到哪一層。

我之前做過一個案子,kernel 轉移其實不算最痛,真正拖死進度的是 library migration。團隊可以接受換編譯器,但很難接受一串缺功能的替代庫,尤其那些庫就在訓練或推論路徑中間。SCALE 的價值要成立,不能只看 compiler,還要看周邊能吃下多少。

實操寫法:先盤點你 runtime 路徑上用了哪些 CUDA library,再碰編譯器。若風險大多卡在 cuDNN 這類東西,光換 compiler 沒用,你需要的是整張遷移地圖。

  • 列出 runtime path 裡所有 CUDA library。
  • 把核心 compute 和 helper library 分開看。
  • 確認目標硬體上有哪些可用替代品。

中立工具會改變買硬體的方式

文章提到 Spectral 一邊進 Nvidia Inception,一邊又想對 AMD 保持友善。聽起來怪,但你想想買家怎麼決定就懂了。能讓 CUDA 變可攜的工具,不會把 CUDA 搞死,它只是把「我一旦選了就不能回頭」這種恐懼削掉。

白話就是:開發者會更敢用 CUDA,因為他知道自己不是永遠被鎖住。這很微妙,但真的有差。vendor neutrality 不只是態度問題,它會影響整個生態的成交速度。語言變可攜,語言本身就更容易被採用。

我在其他基礎設施也看過一樣的事。團隊一旦知道有退出路線,採用速度就會快很多。也許他們最後根本不會走,但「可以走」這件事本身就會改變討論方式。採購比較好談,架構審查也沒那麼像在打仗。

實操寫法:如果你是平台團隊,把可攜性納入 vendor 評估。目標不是反 Nvidia,也不是反 AMD,而是讓硬體選擇回到效能和成本,而不是被單一廠商綁架。

編譯器控制權,就是控制權本身

我最後一直卡在這點。Spectral Compute 沒有去包一層更花俏的抽象,而是直接打編譯器。因為性能、相容性、控制權,最後都會在這裡交會。就算你根本不打算直接用 SCALE,這種思路也值得抄。

翻成白話就是:誰掌握編譯路徑,誰就掌握很多使用者體驗。編譯器如果能乾淨地對多種加速器輸出,硬體廠最強的 lock-in 點就會鬆一點。反過來說,如果編譯器不行,那所有「替代方案」都只是在旁邊多收一筆稅。

我不會裝作這件事已經被解完。文章自己也講得很清楚:CUDA 生態很大,採用很黏,library 支援還在補。但我寧可看到一條認真的 compiler 路線,也不要再看一個碰到 production code 就倒的 portability layer。

實操寫法:你在看 GPU 基礎設施時,直接問三件事:誰管編譯器、誰管 library、誰管效能調校。這三個如果都在同一家手上,你買的不是平台,你是在租使用權。

可抄的模板

# GPU 可攜性評估模板

## 目標
我想降低 CUDA 綁定,但不想整個 codebase 重寫。

## 現況
- 主要加速器廠商:
- CUDA 版本:
- Build system:
- 關鍵 kernels:
- 目前用到的 CUDA libraries:
  - cuDNN
  - cuTENSOR
  - cuDF
  - 其他:

## 目標平台
- 目標硬體:
- 目標 compiler / toolchain:
- 效能目標:
- 正確性容忍度:

## 評估清單
### Compiler 相容性
- 能不能在 CI 裡直接替換 NVCC?
- 能不能吃我現在的 flags 和 build layout?
- 能不能編過真實 production kernels,不只是 toy example?

### 正確性
- 輸出能不能在容忍範圍內對上 NVCC baseline?
- 邊界案例有沒有測?
- 失敗能不能重現?

### 效能
- 在目標硬體上 runtime 是否可接受?
- 有沒有 kernel-level regression?
- 還保不保有 tuning 空間?

### 生態覆蓋
- 哪些 CUDA libraries 有支援?
- 哪些缺?
- 需要哪些 workaround?

### 商業面
- 遷移成本多少?
- 會打開哪些硬體選項?
- 會拿掉哪些 vendor 風險?

## 決策規則
只有在以下條件都成立時才導入:
1. 能編過代表性的 production code,
2. 正確性測試過關,
3. 效能低於門檻的幅度可接受,
4. 我實際依賴的 libraries 有覆蓋,
5. 能讓財務和採購看懂 vendor 風險有下降。

## 推進方式
- Phase 1:先 benchmark 一個 kernel
- Phase 2:先搬一個小服務
- Phase 3:再擴到完整 workload
- Phase 4:把不同 vendor 放到同一張表比

這段就是我會真的丟給團隊的版本。不是口號,也不是保證,只是一個判斷可攜性到底是真還是假、是不是在唬人的方法。SCALE 或其他工具如果真能進你的 stack,就用這份模板先把自己騙不過去。

原始拆解來源是 Kelly 的 TechPlanet 文章 Breaking Nvidia's CUDA Moat: How Spectral Compute is Democratizing GPU Computing。我這篇的解讀、結構和可抄模板是我自己整理的;事實點和引用觀點主要來自這篇文章,以及文中連到的官方網站與 repo。