在我們之前的文章《從零到 GPU》中,我們介紹了 🤗 Kernels 專案,其目標是標準化客製化核心的封裝、分發和使用方式。我們希望這個專案能夠流暢、安全,同時盡可能地與 Hub 整合。
在過去幾個月中,我們一直朝著這個目標努力,並在此過程中幾乎完全重新設計了該專案。這篇文章將總結我們已發布的主要更新以及未來的規劃。
我們在 Hub 上引入了一種新的儲存庫類型,稱為「核心」(kernel)。這使我們能夠滿足具有特定運算需求的使用者。例如,使用者可以了解特定核心支援哪些加速器、作業系統和後端版本。
您可以在這裡瀏覽 Hub 上所有可用的核心:https://huggingface.co/kernels。將這些核心視為 Hub 的一等公民,也對整個 AI 生態系統有所助益。使用者現在可以觀察核心、模型以及使用它們的應用程式之間的趨勢,讓核心更容易被使用者發現。
核心執行原生程式碼,其權限與載入它們的 Python 程序相同,因此惡意核心可能造成實質損害。因此,安全性一直是 Kernels 專案的首要考量。
這就是為什麼我們早期就專注於可重現性:您應該能夠自行重新編譯核心,並驗證它與公開來源碼相符。我們使用 Nix 來實現這一點,因為它透過建構配方的密封評估和強隔離沙盒來保持建構的純粹性。我們還透過將來源 Git SHA1 嵌入核心本身來進一步改善來源證明。
近幾個月來,我們增加了額外的防禦層:信任的核心發布者和程式碼簽章。
隨著新的儲存庫類型,我們也引入了「信任發布者」。由於核心在機器上執行的程式碼權限與其所使用的 Python 程序相同,攻擊者可能會透過上傳惡意核心並誘騙您使用該核心來危害機器。為了幫助您避免此類惡意核心,Kernels 套件現在預設只會載入來自信任發布者的核心。信任發布者是社群信任會善意行事的組織。
我們仍然支援載入來自非信任發布者組織或使用者的核心,但您必須在從 Hub 載入核心時,明確使用 trust_remote_code 參數選擇啟用。預設情況下,使用者無法在 Hub 上發布核心儲存庫,他們必須申請成為核心發布者。使用者和組織可以從其帳戶設定中請求存取權限,這讓我們有時間逐案處理這些請求。
我們新增的另一層安全性是程式碼簽章。程式碼簽章可以防範攻擊者將惡意核心上傳到來自受信任發布者的核心儲存庫,而該發布者的 Hub 憑證可能已被洩漏。在程式碼簽章中,核心會使用只有核心開發者知道的私鑰進行簽署,並使用公開可用的公鑰進行驗證。在 Hub 憑證洩漏的情況下,攻擊者無法簽署惡意核心,因為他們不擁有簽署所需的私鑰。
為了進一步提高安全性,我們使用 Sigstore 的 cosign 來透過短暫私鑰進行簽署。由於這些簽署金鑰僅在有限時間內有效,即使金鑰洩漏,攻擊者通常也無法使用該私鑰。我們還會驗證核心是否由來自受信任 GitHub 儲存庫的受信任 GitHub 工作流程簽署。
kernel-builder 已支援核心簽章,我們也提供了 kernels verify-signature 來驗證核心。Kernels 尚未在載入核心時驗證簽章,因為我們希望在全面推出此新功能之前進行更多測試。有關為您自己的核心設定程式碼簽章的初步說明,可以在 kernels 0.16.0 發布說明中找到。
以前,許多實用工具在 kernels 和 kernel-builder 之間相互交織。我們現在在 kernels 和 kernel-builder 的命令列介面(CLI)之間建立了更好的職責分離。這裡的思維模型是,kernels 是一個用於載入和準備核心以供使用的函式庫,因此它不應包含任何與「建構」核心相關的功能。
因此,kernels 和 kernel-builder 現在都更加精簡和專用。請參閱文件以了解更多資訊。
我們擴展了對框架的支援,最顯著的變化包括:我們為 kernels 和 kernel-builder 增加了對 Torch Stable ABI 的支援。Torch Stable ABI 允許核心開發者針對特定的 Torch 版本或其之後大約兩年內發布的任何版本。例如,針對 Torch 2.9 Stable ABI 的核心將支援 Torch >= 2.9。
Apache TVM FFI 是除了 Torch 之外第一個受支援的框架。TVM FFI 是一個標準化的核心 ABI,可與 PyTorch、Jax 和 CuPy 等其他框架互通。這使得核心開發者能夠建立跨框架運行的核心。
kernel-builder 和 kernels 補充了代理式核心開發的興起,其中代理(agent)被用來從頭開始設計出(最佳化的)核心。它們共同支援一個工作流程,讓代理能夠建構骨架、編譯、基準測試並迭代最佳化核心。
代理式核心開發仍處於萌芽階段,正確的開發循環將持續演進。這使得簡單、清晰的基礎變得尤為重要,工具應該易於組合成人們選擇使用的任何代理工作流程或框架。
kernel-builder 有助於強制規範核心原始碼的建構方式,並用於執行可重現的編譯。這為代理提供了可預測的專案佈局和可重複的工作流程。其命令列介面(CLI)也旨在為代理進行最佳化,例如,這可能意味著非互動式命令和易於代理以程式方式解釋的輸出。為此,我們還具備後端特定的技能,以幫助代理處理不同後端的特殊性。這些技能可以涵蓋後端特定的工具鏈、編譯路徑和效能考量。
成功建構核心並非唯一目標,我們需要確保它在目標硬體上確實比基準線提供實際的速度提升。因此,成功的編譯僅是第一個驗證步驟。通常,目標硬體可能包括許多不同的加速器,甚至是相同加速器的不同系列。
這使得在相關情況下,評估跨硬體供應商和世代的結果變得重要。我們與 HF Jobs 的緊密整合可以使基準測試過程變得容易。代理可以使用此整合來執行基準測試套件、收集效能結果,並將其與定義的基準線進行比較。
透過這種方式,代理可以在不同的硬體配置上運行測試,以獲得關於生成核心效能的可靠回饋,並確定需要改進的地方。這些回饋隨後可以指導下一次最佳化迭代。
以下是一些代理增強型核心的範例,這些範例展示了可以透過此工作流程開發和評估的核心類型。
使用 kernel-builder 建構核心的環境設定可能令人望而卻步。為了讓使用者更容易上手,我們現在提供了一個安裝腳本,可以一鍵設定環境。如果您偏好使用短暫實例,我們的 Terraform 設定指南值得參考。
核心建構完成後,我們會為每個核心建立一個系統卡,以公開有用的資訊,包括如何使用它及其公開的介面。當核心被推送到 Hub 時,這個系統卡就成為核心的「前言」。
「我的系統是否相容這個核心?」這是人們為了更好地規劃事情會多次提出的問題。為此,請使用 has_kernel() 方法。它會回傳一個布林值。如果您想了解為什麼特定核心不受支援的更多解釋,請使用 get_kernel_variants()。
它應該會印出類似以下的結果(取決於您使用的機器):
torch212-cxx11-cu130-aarch64-linux: compatible
torch210-cu128-x86_64-windows: rejected (CPU (x86_64) does not match system CPU (aarch64))
torch211-cu128-x86_64-windows: rejected (CPU (x86_64) does not match system CPU (aarch64))
torch212-metal-aarch64-darwin: rejected (OS (darwin) does not match system OS (linux))
torch211-metal-aarch64-darwin: rejected (OS (darwin) does not match system OS (linux))
torch210-metal-aarch64-darwin: rejected (OS (darwin) does not match system OS (linux))
torch29-metal-aarch64-darwin: rejected (OS (darwin) does not match system OS (linux))
…
kernel-builder 從一開始就幾乎以 manylinux_2_28 為目標。我們過去透過使用以 glibc 2.28 編譯的現代 gcc 工具鏈來針對 manylinux。為了避免與舊版 libstdc++ 的相容性問題,我們靜態連結了 libstdc++。
然而,這種方法最近導致了一些問題。某些 libstdc++ 功能使用全域初始化。當多個 libstdc++ 版本同時存在時,例如 PyTorch 動態連結的 libstdc++ 和核心靜態連結的 libstdc++,這可能導致資料損壞。一些最近的核心使用會觸發全域初始化的功能(例如 C++ 正規表達式),導致此類資料損壞,進而引起記憶體區段錯誤和其他問題。
為了解決這個問題,kernels 現在動態連結 libstdc++。為了確保與舊版 libstdc++ 的相容性,我們現在使用官方的 manylinux_2_28 工具鏈來編譯核心。
Kernels 專案的目標是服務核心開發者和客製化核心的使用者。我們一直熱切期待收到社群關於如何改進專案的回饋。請不要猶豫,踴躍貢獻!



