近日,昆侖芯科技應邀出席百度技術沙龍第99期“智能芯片”專場:昆侖芯一周年——構筑國產數智基石,AI算力賦能千行百業。四位專家首次同臺,揭秘十年磨一劍的中國芯的神秘技術面紗,并系統介紹昆侖芯兩代產品賦能千行百業的最新成果及應用實踐。
本篇以下內容整理于沙龍第三位演講嘉賓——昆侖芯科技基礎工具鏈開發負責人張釗題為 “強大易用的昆侖芯軟件棧助力生態發展”直播分享。
昆侖芯科技基礎工具鏈開發負責人張釗
我是昆侖芯科技基礎工具鏈開發負責人張釗,今天分享昆侖芯軟件棧的相關內容,主要包含以下四個部分:
1)昆侖芯的硬件架構,包括最新一代昆侖芯XPU-R架構以及其中的計算部分和存儲部分。
2)昆侖芯的軟件棧,包括運行時環境、開發套件、高性能加速庫、通信庫和圖編譯加速庫。
3)昆侖芯的編程模型,包括編程模型、內存層級和算子開發的方法。
4)昆侖芯和上層框架的合作,主要包括適配的方法和當前支持推理和訓練的場景情況。
昆侖芯的硬件架構
第一部分,再次強調我們的新一代昆侖芯XPU-R架構,主要是為了更好地了解軟件棧。
昆侖芯XPU-R架構,大體分為計算、存儲、互聯和接口四個部分。
計算部分主要有SDNN和Cluster。這里面的SDNN就是軟件定義的神經網絡引擎,是自研核心張量計算單元,加速卷積和矩陣乘法的計算。Cluster主要負責除了卷積和矩陣乘法之外的通用計算部分。
存儲部分主要包括GDDR6和Shared Memory,GDDR6是高速內存,提供了512 GB/s的存儲帶寬,具有較高的能效比和性價比。Shared Memory是片上的共享內存,保證所有計算單元高并發、低延時的訪問。
片間互聯提供了高速的芯片間互聯,有效地支持大規模、分布式的訓練,減少通信的延遲。
接口支持PCIe4.0,同時也兼容PCIe3.0,可以靈活適配業界已經上市的一些AI的服務器。
這一代的架構XPU-R是采用SDNN加Cluster的融合架構,既有通用性,也兼顧了高性能。作為第二代架構持續優化,進一步提升了計算性能,同時也增強了靈活的編程能力和通用性。
接下來看一下芯片架構的計算部分。XPU-R主要包含有8個Cluster單元和6個SDNN單元。Cluster單元主要承擔通用計算任務,支持SIMD指令,提供通用和靈活的編程能力。SDNN主要承擔MAC類計算和EW類計算,提供 128 TFLOPS@ FP16的算力。當然,SDNN也具有靈活的可編程性,能夠輕松實現卷積、矩陣乘法、向量計算等功能。
架構中的存儲部分,重點看片上高速存儲和外存GDDR6。L3 SRAM作為片上高速共享存儲,容量為64MB,能夠被Cluster和SDNN共享訪問。它能夠提供比片外GDDR6更低的延時和更高的帶寬。在我們軟件編程過程中,用好L3 SRAM是提高性能非常重要的手段之一。GDDR6不同的產品形態有不同的容量,比如16GB版本、32GB版本,能夠被Cluster和SDNN共享訪問。GDDR6作為主要的存儲單元,與L3 SRAM的管理基本一致。
昆侖芯的軟件棧
接下來進入核心的第二部分——昆侖芯的軟件棧。下圖是昆侖芯軟件棧架構圖。
在應用層,我們支持深度學習模型的訓練和推理,也支持視頻智能分析以及一些科學計算。
在框架層,我們深度適配PaddlePaddle(百度飛槳),同時也支持常見的開源框架,如PyTorch、TensorFlow、ONNX等。
中間部分是昆侖芯的SDK——從下到上包括昆侖芯的驅動、虛擬化模塊,還有昆侖芯的運行時庫,再往上是昆侖芯的一個以編譯器為核心的開發者套件、圖編譯引擎、高性能算子庫和高性能通信庫的部分。
之下的硬件部分是昆侖芯AI加速卡。
部署環境方面,支持公有云、計算中心和邊緣設備等。
接下來圍繞SDK中的各個模塊展開,分別介紹各個模塊的功能和作用。
昆侖芯的運行時環境這個模塊主要包括昆侖芯AI芯片的底層驅動,這是一個內核態的程序;也提供了方便易用的Runtime API,這個是用戶態的程序;同時昆侖芯運行時環境包含了大量的管理工具,包括監控、測試、debugger和profiler,這樣能更好提升昆侖芯板卡的可操控性,也為上層提供靈活的應用接口。昆侖芯運行時環境主要的特性包括支持多stream、支持SR-IOV虛擬化,也支持event的同步。昆侖芯的運行時環境支持多個平臺,如常見的x86-64平臺、Arm64平臺,也適配國產主流平臺。
昆侖芯的模擬器實現了對昆侖芯AI芯片的完全模擬,使用上是由上層的昆侖芯運行時根據上層的配置進行AI加速卡和模擬器之間的控制切換,主要包括了對計算和存儲單元的模擬、昆侖芯芯片運行時環境的完全模擬。同時,昆侖芯的模擬器可以提供豐富的工具,包括debugger、profiler和測試工具,既實現了功能級模擬,做到了比特級的精確對齊,也提供了相應的性能模擬,做到計算模塊的性能cycle級對齊的水準。同時它支持多個應用場景,包括一些軟件棧的功能驗證、Kernel的開發和調試,以及Kernel性能的評估和優化。同時,昆侖芯模擬器可以做到和芯片無縫切換。
昆侖芯開發套件是以編譯器為核心的一組開發套件,作為昆侖芯的基礎工具鏈,它是基于LLVM開發的,實現了定制化的Clang前端并適配了昆侖芯XPU后端。它是一套完整的工具鏈,包括編譯器、匯編器、linker、compiler-rt(libs)和一些常用的編程工具;同時它支持AOT編譯和JIT的方式編譯,支持device和host文件的分割和混合編譯,向開發者提供一些debugger和profiler工具。
昆侖芯深度神經網絡高性能加速庫,專門為深度學習設計,是一套高效靈活的軟件庫,易于集成到機器學習框架中。我們目前集成的框架包括百度飛槳、TensorFlow,還有PyTorch等框架。這套加速庫提供了基于Context的一套API,支持多線程和多stream的應用。同時它也支持DNN的一些常用算子,例如矩陣乘法、卷積前向和卷積反向、池化前向和池化反向、激活前向和激活反向等。
昆侖芯通信庫,提供了芯片之間的數據傳輸能力,實現了broadcast、reduce等一系列的通信接口。主要特性包括數據壓縮、拓撲檢測、多機多卡、跨代兼容的支持,還有異常檢測和恢復等。
昆侖芯的圖編譯加速庫是根據昆侖芯硬件相關的設計,做圖層的分析和優化,它是基于TVM進行開發的,提供了大量的C++和Python的接口,方便易用。作為一個昆侖芯的推理引擎,可以對接主流的Deep Learning框架導出的模型,也可以直接導入百度飛槳模型、TensorFlow模型、PyTorch模型等。提供了一套編譯優化器和運行時分離的工作流程。如下圖可以看到一個AI的模型如何進入我們這套圖編譯加速庫,最終進行上線部署的一套過程。
昆侖芯的編程模型
講完了軟件棧的各個模塊,接下來第三部分主要介紹昆侖芯XPU的編程模型。昆侖芯XPU編程模型是在典型的異構計算場景中的一個多核并行計算的模型。其中有幾個概念。Kernel是描述昆侖芯XPU上的一個計算程序,比較常見;host端是通過設置Kernel函數的執行參數,并發送給昆侖芯device端進行執行。其中一種最簡單的CPU和XPU混合編程的流程,可以從這個圖中看出,主機端也就是host端執行一段串行的程序,然后通過調用內核函數讓設備端并行執行這些程序,如此交錯進行。CPU端和昆侖芯XPU端的內存是相互獨立的,因此在運行內核函數之前,主機端需要調用內存拷貝的函數,將數據通過PCIe拷貝到設備端內核,運行結束之后,需要通過CPU再次調用內存拷貝函數,將數據拷回到主機端。這是比較常見的一個編程方式。
同時我們也支持event和stream的一些工作方式,讓CPU和昆侖芯XPU并行工作起來,提升整體的效率。我們這套編程模型可以高效地處理數據。我們采用的是一種類似于CUDA的編程語法,對開發者來說相對友好一些,學習和遷移的成本更低。
為了更好了解昆侖芯XPU的編程和開發,我們必須要掌握其中兩個硬件的相關設計和架構。其中第一個是我們的Cluster的架構,這個Cluster向外提供靈活的可編程能力。如圖所示,每個Cluster有64個core,每個core內部有8KB的Local Memory,每個Cluster共享256KB的Shared Memory,支持SIMD指令,當然也支持一些特殊的指令,例如內存搬運、同步和原子操作等。
另外一個需要我們掌握是內存層級,了解內存層級才能進行有效的昆侖芯XPU編程開發。從這個圖中可以看到,從內部到外部主要分為Local Memory、Shared Memory、L3 SRAM和Global Memory,依次向外分布,越靠內性能越高。我們可以簡單地解釋為,從L0到L1、L2、L3、L4這些層級相應的一些映射關系,如下表所示。
接下來講一下如何在昆侖芯XPU上開發一段程序。主要分為兩個部分:第一部分,在host端即CPU端上開發的代碼;另一部分,在device端開發的一段Kernel的代碼。在host端,實現一個調用Kernel的流程,大體上需要使用類似于CUDA的這種三個尖括號的語法。
舉一個簡單的例子。比如一個relu的操作,實現的代碼大致是這樣:
第一步,我們要在設備端——昆侖芯XPU端分配空間,利用昆侖芯的運行時接口,比如xpu_malloc來實現。
第二步,將左圖的這種data輸入數據拷貝到設備端。
第三步,讓我們的Kernel在設備上運行,relu這個Kernel。這里面有幾個參數,比如說啟動了8個Cluster,然后用到了每個Cluster里面的64個core,這樣我們的 Kernel函數就在device端運行起來,也就是我們左下角的這個relu.xpu的一個程序。
最后,在Kernel運行完之后,我們需要主動地去獲取輸出。拿到輸出之后也要釋放設備的空間。
在host的代碼大體流程是這個樣子。
接下來講一下我們在device端如何開發一個Kernel程序。
我們在device端實現的Kernel代碼,支持類似于CUDA的語法,是C++語言的一種擴展。我們提供了core之間的同步機制,也提供了一些專有的NN的指令擴展。還是以我們這個relu文件為例:我們實現了relu.xpu的一個Device Kernel。
首先,將讀入的數據進行分塊——基于我們的Cluster_id 和core_id計算出相應的tid,根據這個tid把輸入的數據進行分塊,相應的數據分給不同的core進行計算;
第二步,每個core會把顯示的數據搬運到Local Memory上。
接下來,每個core啟動計算,這是一個典型的relu的計算。
之后,會把結果顯示的寫回到Global Memory之上。
這就是我們一段完整的昆侖芯XPU的Device Kernel的程序。可以看得出來,它和普通的C++的程序比較相似。
昆侖芯和上層框架的合作
講完了昆侖芯軟件棧的功能模塊,也講了如何開發一段算子,接下來講一下昆侖芯和上層框架的一些合作。
昆侖芯AI加速卡支持各種不同的開源框架,比如PyTorch 、TensorFlow等。這里我們重點講一下昆侖芯和百度飛槳的合作。
2018年,啟動昆侖芯AI芯片和飛槳的合作,從飛槳的1.2版本開啟合作;
2019年之后,昆侖芯的代碼進入了PaddlePaddle的社區,當時主要集中在Paddle Lite,也就是推理部分;
2020年,昆侖芯和百度飛槳進行了一個小流量的上線。在2020年12月份發布的飛槳2.0版本完全支持昆侖芯的訓練。
2021年1月,我們共同實現了實時在線推理服務、超大規模部署。
2022年5月,飛槳2.3發布并全面支持昆侖芯2代的產品。
昆侖芯和飛槳的深度合作形成了一個全棧式的AI技術生態。昆侖芯和百度飛槳是以PaddleCV、PaddleNLP這些產品向外提供知識和服務的,已經完成了主流模型的適配性能優化和精度對齊。
百度飛槳和昆侖芯的適配主要圍繞PaddlePaddle框架完成,我們共同完成了框架層面的適配,支持XPU Device和大部分算子,同時也支持分布式訓練。昆侖芯的軟件棧已經完全集成到了PaddlePaddle的框架里面,完成了適當的對接和支持工作,最終我們可以在一些國產CPU和OS上共同完成生態建設。
重點講一下昆侖芯和飛槳在推理和訓練部分的適配方式。
先看一下Paddle Lite和XPU的推理部分,我們在三個層面上進行了適配:接口層、計算圖層、算子層。
接口層,基本實現修改三行代碼即可切換到昆侖芯的后端,實現了昆侖芯+CPU自動混合推理。
計算圖層,實現了通用圖優化,也做了基于XPU的一些圖優化,例如融合、緩存優化和權重預處理優化等。
算子層面,我們做了深度學習算子優化、自動代碼生成。(上圖右)可以看到,通過我們的高性能算子庫和paddle進行對接,也可以通過我們的圖優化的引擎和paddle進行對接。(昆侖芯支持的一些具體的模型列表可以參見百度飛槳官網。)
昆侖芯與飛槳合作的訓練部分主要是昆侖芯XPU和PaddlePaddle框架的適配。這個我們基本上做到了只切換一行代碼便可指定到昆侖芯XPU的后端,低成本地從GPU切換到昆侖芯,滿足絕大部分用戶的需求。同時,支持分布式訓練。(具體的昆侖芯訓練支持的模型介紹可以參見百度飛槳的官網。)
接下來講一下昆侖芯和飛槳現在的生態建設。
從上圖表中可以看出,從底層的AI算力組件到AI服務器,到國產的操作系統,再到昆侖芯SDK之上,是端到端的AI開發平臺解決方案等。這是我們完成的一套端到端的國產AI計算系統的解決方案。昆侖芯原生支持百度飛槳框架、百度的機器學習BML平臺,并且訓練與飛槳社區進行協同生態建設,已經開源,在國內處于第一份額。昆侖芯加百度飛槳是百度人工智能生態端到端軟硬件一體解決方案的獨特產品組合,實現了國產AI計算生態的解決方案。
案例分享
分享一個昆侖芯與飛槳合作在工業質檢方向的一個具體案例。客戶主要做手機上微小零件的質量檢測,一開始采用的是用人工檢測的辦法——用肉眼來檢查零部件缺陷。但目視檢測不僅速度非常慢,新老員工的檢測標準也非常不一致。中期,客戶升級到了PyTorch + GPU的方案,成本高且并非國產化方案。后期,通過百度飛槳和昆侖芯的合作和支持,完成了全部切換成百度飛槳加昆侖芯的方案。這是中國自研AI芯片在工業領域首次大規模應用,實現成本降低65%、性能提升9%的效果。
總結
昆侖芯XPU誕生于AI場景,能夠滿足多樣的AI模型和場景需求,提供了較高的性能和能耗效率,給開發者提供了一個相對靈活、易用的編程模型。我們有大規模部署,超過兩萬片的落地,在技術上能達到100%自主研發,已與多款通用處理器、操作系統和AI框架完成端到端的適配。靈活易用方面,昆侖芯的SDK為開發者提供了全方位的軟件工具包,使開發者在轉換已有模型、開發新模型以及定義和使用定制化模型時,能夠最大化地提高開發效率。