歡迎大家前往雲+社群,獲取更多騰訊海量技術實踐乾貨哦~
作者:Gophery
本文由 騰訊技術工程官方號 釋出在雲+社群
影象已經發展成人類溝通的視覺語言。無論傳統網際網路還是移動網際網路,影象一直佔據著很大部分的流量。如何在保證視覺體驗的情況下減少資料流量消耗,一直是影象處理領域研究的熱點。也誕生了許多種類的影象格式JPEG、PNG 、GIF、WEBP、HEVC,以及騰訊公司自研的WXAM和SHARPP格式。
騰訊TEG - 架構平臺部圖片儲存系統TPS 作為超大規模的圖片平臺,圖片數萬億張儲存量百P,下載頻寬數T,一直需要嚴重關注影象壓縮技術的發展。本文就近幾年影象壓縮技術的發展、新格式的出爐,和圖片儲存系統TPS在實際業務上的落地實踐做個簡單的介紹。以及在不斷出現的新格式被逐步應用之後,相容性最好的傳統老格式JPEG依然地位高居不下佔據大幅頻寬,如何在老格式上也繼續挖掘優化點,是本文重點介紹的內容。在開始介紹之前先大概總結下各個格式在相容性、影象大小以及編解碼效能上的優勢和劣勢。
Webp和HEVC的面世
JPEG、PNG、GIF在網際網路暢行了多年後,2010年Google提出了一種新的圖片壓縮格式 — webp,給圖片壓縮優化提供了一個新方向。Webp相比JPEG多了一個預測模式,在相同ssim得分下,有損WebP相比可減少25%~34%的大小,有損WebP也支援透明通道,大小通常約為對應PNG的1/3。
藉助Webp的開放性和平臺相容性,網際網路的推廣應用變得很暢順,這是webp相比JPEG2000和JPEGXR能取得成功的關鍵原因。Chrome和opera瀏覽器都支援webp,它們佔據了一半的瀏覽器市場份額,另外Android系統 4.0以上版本也預設支援webp格式。
在這個背景下,TEG架構平臺部圖片儲存系統TPS,快速推出了webp解決方案,如下圖所示。並在QQ相簿、微信朋友圈、微信公眾號、QQ看點、騰訊新聞、騰訊視訊等公司絕大多數的圖片業務開啟使用。總共節省了超過500G的頻寬,每年成本節省額度大幾千萬元。
很快,HEVC/H265到來了,它是當前最新一代的視訊編碼技術,基於該標準壓縮出來的圖片大小可降到JPEG的46%,動圖相對gif甚至可以降低到原來的20%大小,這相比webp又有了極大的提升,這個節省量可以說是相當可觀了。但相應的,它的編解碼速度相比jpg要差非常多,處理延時大同時裝置資源消耗量也非常巨大。於是騰訊微信團隊和SNG音視訊團隊經過大量研究和開發工作,分別推出了自研的效能業界領先的高效圖片壓縮核心WXAM和SHARP,不犧牲壓縮的情況下,編解碼速度數倍於知名開源工程x265,甚至超過了webp。
為了進一步提升處理速度,我們甚至對它們的編碼在FPGA硬體卡進行實現,進一步降延時降低到了cpu的1/4以內。
雖然WXAM/SHARP並沒有外界的瀏覽器支援,但公司內的各大手機app都推動進行了解碼庫封裝來支援解析,圖片儲存系統進行適配輸出後,又一次優化掉了將近500G的頻寬,年化收益大幾千萬。
JPEG優化之路
WEBP/WXAM/SHARP紛紛落地之後,統計公司業務的圖片頻寬,JPEG頻寬佔比仍然超過1/3。原因主要有,各類不相容這些格式的瀏覽器、不便進行改造的app、其他不可控的第三方過來的訪問。再統計騰訊雲的永珍優圖產品的頻寬,外部業務的JPEG甚至超過了90%,終端相容門檻始終是個很大的障礙。
那在JPEG頻寬上我們還能做些什麼呢?
通常影象處理服務在編碼JPEG影象時會調整影象量化表,以減少影象的大小,即通過降低圖片質量值的方式。我們根據不同業務要求設定不同的質量引數,還對特定圖片做降級處理,比如二維碼為主體的圖片,降低更多質量並不影響檢視體驗。但這些畢竟還是容易肉眼可見的有損調整,於是就有了基於人眼視覺特性來對JPEG做進一步壓縮的guetzli,它可以讓JPEG圖片平均減少30%的大小。壓縮效果不比webp差,卻沒有webp的解碼端相容性問題。
採用傳統方法處理影象調整影象質量為85,得到處理後影象大小為48403位元組。
Libjpeg編碼影象:進行心理視覺編碼得到影象大小為32449位元組
guetzli編碼的影象:採用心理視覺方法編碼出的影象,肉眼無法感知其差異,其大小是libjpeg編碼影象的67%
基於心理視覺的方法
1. 編碼原理
年初google發表了關於使用心理視覺來進行影象處理的guetzli論文,在該文中描述了相關優化的主要依據:
- 人眼錐細胞敏感光譜的重疊,RGB三個通道之間是有聯絡的,黃色光會降低藍色光的敏感度,因此黃色區域附近的藍色可以使用低精度編碼
- 人眼的藍色空間解析度低於在紅色和綠色,並在高解析度旁邊沒有藍色的受體因此藍色的高頻變化可以使用低精度編碼
- 視覺影象中的精細結構依賴於附近視覺變化的量級,因此可以在有大量視覺噪音的地方使用低精度編碼
下圖展示了人眼對黃色區域附近的藍色不敏感(影象引用自guetzli論文)
黃色背景上的hello world!文字不易被觀察,將上圖分別採用libjpeg和guetzli編碼後,將藍色通道轉換為灰度圖如下圖所示:
上半部分jpeg編碼針對黑色背景和黃色背景,藍色通道均採用相同的精度儲存,而下半部分guetzli編碼藍色在黃色背景下儲存時採用低精度的編碼。
guetzli編碼影象處理過程主要分為以下三個大的迭代過程:
- 第一次迭代,取得最優的全域性量化表
- 第二次迭代,計算每個塊中的哪些係數可供消零(低解析度部分),且消零後視覺評價體系上影象無差別
- 第三次迭代,將第二次迭代的消零序列,進行消零嘗試,先進行大幅度消零計算其得分和檔案大小,然後根據檔案大小適當回撥消零的係數
因為有了這些消零的部分,使得影象相對於原圖在編碼時產生更多的連續的0,這樣在進行遊程編碼時能夠減少資料量。
原始處理過程:
2. 效能優化
Guetzli處理過程有非常多次的大小迭代,計算量極大, 加上google官方的版本未進行太多的優化,存在大量重複計算以及流程冗餘。Guetzli單圖計算消耗,相比jpeg編碼高出兩個數量級,呈百倍關係。處理延時遠遠超出線上使用的可承受範圍,更關鍵的是,裝置消耗過大。按解析度500x500的圖片來看,平均處理一張延時10秒以上,單圖必須被下載1000次節省下頻寬成本才能抵消一次的處理裝置成本消耗。隨著圖片解析度增大,延時上升到分鐘級甚至小時級別,非常驚人。
為了能夠在現網應用,需要對演算法進行移植改造提升其處理速度。影象處理的過程中的很多計算是可以並行的,那麼利用GPU來並行化加速處理,很自然的成為了我們的解決思路。和SNG增值產品部開發運維團隊組成公司圖片業務的Guetzli落地推廣的聯合專案:實現了演算法優化改造,併線下進行了千萬級別的圖片測試驗證,確定了機器選型和資源排程上線。這裡的主要優化和效果如下:
- Jpeg影象取樣方式較多,而官方版本僅支援420與444取樣格式,為支援所有的取樣,我們在應用中擴充套件了影象編解碼函式,採用libjpeg-turbo進行影象資料解碼,完整支援所有jpeg取樣,同時ibjpeg-turbo相對於libjpeg在編解碼上做了一定的優化,能夠提升解碼過程的效能。
- 由於視覺評價體系中大量計算是分別針對影象三個通道進行處理,同時也會將影象按照不同的塊進行分割計算以及影象卷積操作,單個塊或者通道計算量大,所有塊或通道需要重複上百萬次計算,計算過程完全相同且塊與塊之間的計算相對獨立不會有相互的影響。那麼這些計算過程能夠並行,我們擴充套件了butteraugli視覺評價體系,將這些繁複可並行的計算全部移植到GPU上能大幅減少計算延遲。
- 在第二次迭代計算可供消零的係數過程中,當消零後的影象誤差超過了允許的全域性誤差之後,後續的可供消零序列將變得不再有意義,我們將計算過程提前終止掉,這樣去除了後續大量的無效冗餘運算,從計算流程上減少了編碼延遲。
- 演算法實現中大量採用雙精度進行計算,我們支援將雙精度調整為單精度加速計算過程,減少雙精度帶來的大量效能消耗,不過由於精度上的損失會使得輸出結果與官方工具有些差異,但是精度的損失反映到影象上的影響微乎其微。
- 由於影象大小在一定的範圍內波動,影象資料通常在數百KB內波動,影象需要連續的記憶體、視訊記憶體空間,那麼優化記憶體、視訊記憶體使實體記憶體空間上連續能夠提高記憶體讀寫速度。利用tcmalloc替換glibc的記憶體管理,提升主機端記憶體訪問效能。應用內池化視訊記憶體能夠減少裝置驅動的呼叫,提升影象大資料塊的分配和釋放效能。這樣優化後能夠減少記憶體和視訊記憶體的碎片、由於記憶體連續也提高了訪問效能。
- 在計算處理過程中有許多冗餘函式來生成固定的引數序列,將這些函式合併或預處理展開後減少計算流程上的函式呼叫冗餘。
- 從主機記憶體到裝置視訊記憶體的資料拷貝是需要經過PCIE匯流排,資料拷貝頻寬受到GPU物理佈局方式以及PCIE匯流排頻寬兩方面的影響,那麼針對一些較小解析度的影象,為了平衡傳輸延遲和計算延遲,我們按影象解析度將計算拆分,影象大於某一分別率之後計算延遲遠遠超過傳輸延遲時,這部分計算轉移至GPU上進行,否則在CPU上完成計算。
- 現網實際應用中,在GPU上提供異構計算服務時同樣有一些需要注意的地方,為了避免GPU空閒時驅動程式釋放裝置導致新應用啟動時長過長,我們需要將裝置持久化保持在驅動程式中。
- 為了避免在GPU上部署應用時建立GPU Context的效能開銷,應用應該僅在啟動時建立GPU Context後續所有計算均在同一Context上使用不同的流來完成。合理的使用流能夠有效提升GPU吞吐。
- 影象處理過程對GPU裝置的利用是一個波動的狀態,而單個程式通常不能完全有效的利用GPU,為了提升GPU利用率,提升編碼叢集的吞吐量,需要部署多個應用程式繫結到同一GPU,具體繫結數量需要考慮視訊記憶體大小與實際應用的GPU利用率。
改造後的平均處理延時下降到原來的10%以內,下圖GI1和G6代表改造的庫跑在GPU裝置上的延時,M10表示改造前的官方庫的延時。
3. 業務落地
經過上述改造後,已經有望上線服務業務了。我們對當前圖片平臺架構做了部分調整:採用非同步壓縮,持久化儲存,控制CDN快取時間的方式來貼合業務使用。基本架構如下圖所示:
guetzli下載架構
1. 源站需要根據當前影象的格式以及快取時間靈活的設定CDN快取時間
2. 編碼叢集要根據其處理能力和請求時間合理的處理請求
下載流程如下:
guetzli下載流程
1. 當快取命中後,需要判斷快取影象是否已經編碼過,若在編碼週期內,則向CDN前端返回臨時快取。否則返回持久快取
2. 若快取沒有命中,則從儲存系統中查詢落地的編碼影象,若落地影象不存在,則將原圖返回給CDN設定臨時快取,同時非同步發起影象編碼。若已存在則直接將影象返回給CDN且持久快取
4. 業務落地現狀
針對當前webp/wxam/sharpp無法覆蓋的場景,採用心理視覺的影象處理方法,能夠在保證影象質量的前提下,大幅減少影象大小,節省使用者流量並提升下載體驗。上述方案已經在QQ增值業務、騰訊視訊、QQ音樂、QQ看點、LOL視訊官網中心等業務上進行了應用,騰訊視訊、微信公眾號、頭像等適合落地的圖片業務也在測試中。騰訊雲的永珍優圖產品,也可以在控制檯一鍵開啟。
這些優化紛紛落地後,總共節省上T的頻寬,使用者下載延時減少20%以上。未來還會有更多的發展。2017下半年IPhone又新推出了HEIF格式,並對iphone7以上支援硬編解,讓IOS對hevc的相容提供了重大便利,隨著ios11的普及,預計未來眾多圖片業務會朝著heif格式收攏。圍繞節省使用者和伺服器頻寬,以及提升使用者下載體驗的目標,我們會繼續前行,讓頻寬壓到最小,讓圖片越來越清晰。
相關閱讀
此文已由作者授權雲加社群釋出,轉載請註明原文出處