PaddlePaddle(中文名:飛槳,PArallel Distributed Deep LEarning 並行分佈式深度學習)是一個深度學習平臺,具備易用、高效、靈活和可伸縮等特色,它是中國第一個開源深度學習開發框架。前端
飛槳框架的核心技術,主要包括前端語言、組網編程範式、核心架構、算子庫以及高效率計算核心五部分。下邊分別分析這幾部分。算法
飛槳核心架構採用分層設計,以下圖所示,前端應用層考慮靈活性,採用Python實現,包括了組網 API、IO API、OptimizerAPI和執行 API等完備的開發接口;框架底層充分考慮性能,採用C++來實現。編程
框架內核部分,主要包含執行器、存儲管理和中間表達優化;內部表示方面,包含網絡表示(ProgramDesc)、數據表示(Variable)和計算表示(Operator)幾個層面。框架向下對接各類芯片架構,能夠支持深度學習模型在不一樣異構設備上的高效運行。網絡
爲了方便用戶使用,飛槳選擇Python做爲模型開發和執行調用的主要前端語言,並提供了豐富的編程接口API。Python做爲一種解釋型編程語言,代碼修改不須要從新編譯就能夠直接運行,使用和調試很是方便,而且擁有豐富的第三方庫和語法糖,擁有衆多的用戶羣體。架構
同時爲了保證框架的執行效率,飛槳底層實現採用C++。對於預測推理,爲方便部署應用,則同時提供了C++和Java API。框架
飛槳中同時兼容命令式編程(動態圖)與聲明式編程(靜態圖)兩種編程範式,以程序化「Program」的形式動態描述神經網絡模型計算過程,並提供對順序、分支和循環三種執行結構的支持,能夠組合描述任意複雜的模型,並可在內部自動轉化爲中間表示的描述語言。編程語言
「Program」的定義過程就像在寫一段通用程序,使用聲明式編程時,至關於將「Program」先編譯再執行,可類比靜態圖模式。分佈式
首先根據網絡定義代碼構造「Program」,而後將「Program」編譯優化,最後經過執行器執行「Program」,具有高效性能;同時因爲存在靜態的網絡結構信息,可以方便地完成模型的部署上線。模塊化
而命令式編程,至關於將「Program」解釋執行,可視爲動態圖模式,更加符合用戶的編程習慣,代碼編寫和調試也更加方便。函數
飛槳後面會加強靜態圖模式下的調試功能,方便開發調試;同時提高動態圖模式的運行效率,增強動態圖自動轉靜態圖的能力,快速完成部署上線;同時更加完善接口的設計和功能,總體提高框架易用性。
飛槳爲用戶提供簡單易用、兼顧顯存回收與複用的顯存優化策略,在不少模型上的表現優異。
顯存分配機制
原生的CUDA系統調用(cudaMalloc)和釋放(cudaFree)均是同步操做,很是耗時。爲了加速顯存分配,飛槳實現了顯存預分配的策略,具體方式以下圖所示。
設置一個顯存池chunk,定義其大小爲chunk_size。若分配需求requested_size不超過chunk_size,則框架會預先分配chunk_size大小的顯存池chunk,並從中分出requested_size大小的塊返回。
以後每次申請顯存都會從chunk中分配。若requested_size大於chunk_size,則框架會調用cudaMalloc分配requested_size大小的顯存。chunk_size通常依據初始可用顯存大小按比例肯定。
同時飛槳也支持按實際顯存佔用大小的動態自增加的顯存分配方式,能夠更精準地控制顯存使用,以節省對顯存佔用量,方便多任務同時運行。
顯存垃圾及時回收機制
顯存垃圾及時回收機制GC(Garbage Collection)的原理是在網絡運行階段釋放無用變量的顯存空間,達到節省顯存的目的。
GC策略會積攢必定大小的顯存垃圾後再統一釋放。GC內部會根據變量佔用的顯存大小,對變量進行降序排列,且僅回收前面知足佔用大小閾值以上的變量顯存。GC策略默認生效於使用Executor或Parallel Executor作模型訓練預測時。
Operator內部顯存複用機制
Operator內部顯存複用機制(Inplace)的原理是Operator的輸出複用Operator輸入的顯存空間。例如,數據整形(reshape)操做的輸出和輸入可複用同一片顯存空間。
Inplace策略可經過構建策略(BuildStrategy)設置生效於Parallel Executor的執行過程當中。
飛槳算子庫目前提供了500餘個算子,並在持續增長,可以有效支持天然語言處理、計算機視覺、語音等各個方向模型的快速構建。同時提供了高質量的中英文文檔,更方便國內外開發者學習使用。文檔中對每一個算子都進行了詳細描述,包括原理介紹、計算公式、論文出處,詳細的參數說明和完整的代碼調用示例。
飛槳的算子庫覆蓋了深度學習相關的普遍的計算單元類型。好比提供了多種循環神經網絡(Recurrent Neural Network,RNN),多種卷積神經網絡(Convolutional Neural Networks, CNN)及相關操做,如深度可分離卷積(Depthwise Deparable Convolution)、空洞卷積(Dilated Convolution)、可變形卷積(Deformable Convolution)、池化興趣區域池化及其各類擴展、分組歸一化、多設備同步的批歸一化。
另外涵蓋多種損失函數和數值優化算法,能夠很好地支持天然語言處理的語言模型、閱讀理解、對話模型、視覺的分類、檢測、分割、生成、光學字符識別(Optical Character Recognition,OCR)、OCR檢測、姿態估計、度量學習、人臉識別、人臉檢測等各種模型。
飛槳的算子庫除了在數量上進行擴充以外,還在功能性、易用性、便捷開發上持續加強。
例如針對圖像生成任務,支持生成算法中的梯度懲罰功能,即支持算子的二次反向能力;而對於複雜網絡的搭建,將會提供更高級的模塊化算子,使模型構建更加簡單的同時也能得到更好的性能;對於創新型網絡結構的需求,將會進一步簡化算子的自定義實現方式,支持Python算子實現,對性能要求高的算子提供更方便的、與框架解耦的C++實現方式,可以使得開發者快速實現自定義的算子,驗證算法。
飛槳對核心計算的優化,主要體如今如下兩個層面。
Operator粒度層面
飛槳提供了大量不一樣粒度的Operator(Op)實現。細粒度的Op可以提供更好的靈活性,而粗粒度的Op則能提供更好的計算性能。
飛槳提供了諸如softmax_with_cross_entropy等組合功能Op,也提供了像fusion_conv_inception、fused_elemwise_activation等融合類Operator。
其中大部分普通Op,用戶能夠直接經過Python API配置使用,而不少融合的Op,執行器在計算圖優化的時候將會自動進行子圖匹配和替換。
核函數實現層面
飛槳主要經過兩種方式來實現對不一樣硬件的支持:人工調優的核函數實現和集成供應商優化庫。
針對CPU平臺,飛槳一方面提供了使用指令Intrinsic函數和藉助於xbyak JIT彙編器實現的原生Operator,深刻挖掘編譯時和運行時性能。
另外一方面,飛槳經過引入OpenBLAS、Intel® MKL、Intel® MKL-DNN 和nGraph,對Intel CXL等新型芯片提供了性能保證。
針對GPU平臺,飛槳既爲大部分Operator用CUDA C實現了通過人工精心優化的核函數,也集成了cuBLAS、cuDNN等供應商庫的新接口、新特性。