CV CUDA在微博多媒體內容理解的應用
一、微博多媒體內容理解的背景介紹
首先和大家分享多媒體內容理解的背景,多媒體內容主要包含視頻,音頻,圖像和文本的理解。在視頻的理解里邊,有很多非常重要也非常基礎的一些工作,比如視頻的 embedding 標簽,視頻的質量,視頻的摘要、封面等等。圖片的理解同樣,圖片的理解也是非常重要的,因為在微博的場景里面,圖片是占比較大的一類數據。主要的工作包含 embedding 標簽,圖片 OCR 了,人臉識別。在這一系列的算法層上面,支持了公司非常多的業務。最基本的,比如個性化推薦內容的審核,物料標簽版權,視頻的指紋,視頻拆條等等一系列的業務。
以上就是微博多媒體內容理解的總體的一個結構。
下面會分 4 塊的技術的內容做詳細說明。
二、視頻摘要(Video Summarization)
1、技術背景
視頻摘要的主要目的是對于一段相對比較長的視頻,采用算法抽取一部分幀,或者一部分連續的幀,也可以是單獨的一幀去表達視頻。使觀看者在看完摘要后能夠大致理解視頻所要表達的主要內容,一般有兩種摘要的方式。
第一種是靜態的摘要。這項技術很早之前就有了,最常見的一個應用就是視頻的靜態封面怎么去抽取,其實就只抽取一幀,這一幀可能會包含了比較豐富的信息。使用戶看了這一幀就能大體知道這個視頻的內容。比如講的打籃球還是踢足球。第二種摘要是動態摘要,從視頻里邊選取一段或者多段連續時間的視頻幀作為摘要,這種可以作為物料的審核或者物料的打標。還有個應用是視頻的動態封面,比如有一些 APP,它的視頻是有這種動態封面的。物料審核主要針對某些涉及政治或者色情的視頻,以及版權侵犯的場景等,可能是需要人工去審核。這種場景人工在審核的時候,如果對于原始的視頻去簡單看一遍,是非常耗時的。先對視頻進行一定程度的濃縮,是可以極大的節省人力的。
2、業界做法
(1)dppLSTM(ECCV 2016)
業界之前比較普遍地做法,第一個是 ECCV 2016 的一個方法,這個方法其實它比較早,但是它特別有代表性。這是一個有監督的方式。首先人工去標注這一幀,是不是比較關鍵的一個幀,以及這一段是不是比較關鍵的一段。
這個模型的輸入是從一個預訓練的模型去抽取每一幀的特征向量,然后供兩個 LSTM 模型在時間維度上建模,它會算一下當前幀與其他幀的關系。再接一層 MLP,這一層主要會預測當前這一幀它的重要程度,當前這一幀它跟其它幀的相似度。最后再有個模塊,基于這兩個分數值,去判斷當前視頻幀的集合里邊哪一些是比較重要,哪一些是適合的。
這個方法比較常規的一種做法,需要人工標注,但人工標注其實非常的難,不同的人去標,可能標準很難去統一。第二就是非常耗人力了,對于視頻,需要一幀一幀的標注。
(2)SUM-GAN(CVPR’ 2017)
右邊這個圖是 2017 年的一個方法,它是一種無監督的方式,非常類似于現在比較火的對比學習的技術。
首先這個模型它分成了四大塊,sLSTM 模塊會給輸入的幀打一個重要性分數。這樣相當于有了每一幀的向量和重要程度。然后,這個模塊會根據重用性的程度把向量去做加權,重新去算向量。生成模塊會根據重用性程度加權之后的向量,再去恢復視頻的原始向量,然后把恢復的向量跟原始的向量做對比,看恢復得好不好,如果恢復得好,就可以說明幀的重要性算對了。反之就沒算對。所以整個過程是一個無監督的過程,因為它是個已知的原始向量去對比的過程。
(3)CSNet(AAAI’ 2018)
視頻處理的時候,對于長視頻這種以遠程的關系建立時間建模,是比較難的一個問題。上面左圖是 AAAI’18 年的論文,它的一個側重點是解決當時間跨度比較長的情況下,怎么去建立幀與幀之間的關系。
首先每一幀向量進來通過 CNN 以后會分成兩塊,第一塊按照它原有的時間順序切成一個一個的段。第二塊在時間維度上,會跳著挑一些幀,比如挑第一幀,第四幀,第八幀,它把 148 放在一塊,相當于把不同時間跨度的幀放在一塊,這有利于對遠程幀的向量的一個感知特性的感知。另外,是類似于 attention 的一個方式。比如這一幀跟第四幀去比一下,跟第八幀去比一下,根據差異性來判斷這一幀的重要性,差異大說明重要,類似的話說明不重要。最后就根據 tension 和原始上傳的向量去做一個融合,最后再去預測分數。這種方法它主要是解決了長視頻的一種建模的方式。
(4)DR-DSN(AAAI’ 2018)
右邊這個圖也是 2018 年的一篇論文,首先它在原來的基礎上能做到無監督。第二個,當時來講,它的效果是比較好的。
跟前面的方法一樣。首先把每一幀都向量化,再做雙向的 LSTM 網絡。它的不同點在于,把整個訓練建模的目標變成了兩個。這樣做有兩個目的,第一個是去度量多樣性,最后摘要出來的這一段必須是比較豐富的內容。第二個是選出來這些關鍵的片段和尾幀是具有代表性的,能夠代表原始的視頻。這樣從比較長的視頻,選出來的片段會具有多樣性,相互之間重復度是比較低的。其次還能代表原來整個長視頻的內容。整個過程不需要任何的監督的信號,所以它是一個無監督方式。
3、微博的工作
前沿的這些做法其實各有各的優點,也各有各的缺點。微博結合我們自己的業務場景,做了我們自己的模型。當然有監督的這種方式我們基本上就不用考慮了,因為太費人力了。無監督的這種方式相對來講,相對于有監督來講,它在效果上會有一些差異,會有所降低。但我們在探索怎么樣可以在不需要人工標注的情況下,還能做到一個比較好的效果。
下面是微博特定場景里面做模型的一些動機。
在微博多媒體的場景里,事先有視頻分類這么一個模型,這個模型它其實抽出的特征是有一定的語義信息的,訓練視頻分類的時候,標簽是一致的。因為微博場景里面有大量的這種數據,所以這個模型是比較容易得到的。當時基于這一點想去虛擬一個弱監督或者無監督的模型。弱監督是因為用視頻分類模型去做監督,所以稱它為弱監督。這個圖就是整個的算法結構。當然這個方法的論文是在 2021 發表的,如果大家感興趣,可以去仔細地去閱讀一下論文。
首先視頻會抽成幀,然后每一幀都會去抽到一個向量。之后會使用一個比較常規的算法。比如用一個鏡頭切割的算法,把視頻切割成 5 個鏡頭或者是 5 個片段,每一段把這一段里的向量做一個平均,得到的向量就代表了這一個片段的特征,這一個代表片段的特征會被放到視頻分類的模型里面去,這個模型的作用就是,輸入是一串向量,輸出是一個向量,并且因為后接一個分類。可以拿分類層的前面特征作為最后的視頻的一個表達向量,這樣多個鏡頭通過上面的分類網絡,就可以得到唯一的向量。
然后 Summary Generation Sub-network 的部分會根據輸入的鏡頭的向量去做選擇,選擇一些鏡頭作為最后的摘要的片段。當然也是采用了潛量的一些做法,用 LSTM 去建立鏡頭與鏡頭之間的關系,同時每一個鏡頭會預測到一個分數,再根據分數去選擇一些片段。
那么最后這個片段選得好不好,用一種什么樣的方式去衡量呢?這里設計了四種的監督方式。
第一種就是選出來這個片段,仍然送到視頻分類網絡里面去,這個時候多個鏡頭向量,最后可以得到一個向量。如果選了這個片段是比較好得到的向量,那么就和所有的片段進去之后,視頻分類網絡得到的向量是一樣的了,或者至少是高度相同的。所以可以把它作為一個基因多信號,在語義層次上,選出的這些片段,能夠跟原來整體視頻的語義層次是相同的。那么選出來的這些片段,它本身需要一些什么樣的約束呢?
第一個,選出來的片段必須有多樣性,這一段與另外一段肯定是不同的。如果是相同的,就不需要去重復地選。第二個,它是具有代表性的,原來視頻的某一段,可以在選出的片段里面找到一段在語義層次上比較相似的。最后一點就是選出的這些片段在時間上應該是有個約束,不應該讓模型在極端的情況下,比如把原來所有的片段都選上,不就是涵蓋了所有的語義嗎?這樣肯定是不需要的,所以加個時間長度的一個約束。最后所有的約束項一共有 4 項,4 項里面后面的三項都是無監督的。第一項是根據視頻分類網絡的監督信號算出來的,所以總體上不需要去額外的標注一些信息。當然視頻分類網絡是有監督的,所以這個方法稱為一個弱監督的方式。
這種方法在做前向推理的時候,上面視頻的分類網絡就可以扔掉了,因為那個只是作為訓練時候的一個監督信號的來源。來了新的視頻之后,就走下面流程,每一幀去抽向量,做鏡頭的切割,再算鏡頭向量,再過我們的摘要網絡。最后可以得到每一個片段的分數,這一個片段里邊我們認為每一幀的分數都是一樣的。
上圖展示了我們跟有監督和無監督的一些方法去做對比,我們作為一個弱監督的方式,但是跟有監督對比也還是有優勢的。跟現有的一些無監督的方式,我們的這種方式性能相對來講會更好一些。圖上下面部分展示了我們當時的方法,跟業界最好的方法做了一個具體的,在視頻上做了一個對比。我們看了抽出來的摘要信息,其實更符合,至少更符合我們微博場景對于摘要的一些需求。同時在開源的數據里面,摘出來的片段其實哪怕跟當時最好的方法相比,也是很有優勢的。圖片最下面是我們論文的地址。
4、具體應用
下面介紹視頻摘要在微博的應用,以及在什么樣的場景下面去使用。第一個是靜態的封面,對于一個長視頻,一般會選擇比較重要的一幀去作為視頻,在沒有播放的時候作為一個封面展示在前面。第二個是動態的方面,作為封面,可能在時間的長度上面是有一個約束,比如不能超過 3 秒或者 5 秒,所以動態方面會從整個視頻里邊去抽,連續一段持續 3 秒的得分數最高的一段去作為動態的封面。第三個應用場景是物料的打標,打一些標簽和物料的審核,這樣人只要一看摘要,就基本上能夠知道這個物料怎么去打標,或者審核過不過。如果有疑慮,再去看原始視頻,這樣能夠大大的提升人工的效率。
三、視頻質量
1、技術背景
視頻質量的主要目的是通過使用深度學習產生統一量化的質量指標,從而可以根據質量對視頻進行推薦或者打壓限流。
幾個圖展示的是一些具體的例子。什么樣的是質量不好的,比如拍得比較模糊,或者是拍攝的時候焦距不夠好,或者是這種運動模糊。
2、業界做法
首先看看業界以前是怎么去解決視頻質量這個問題的。這個大致架構比較常規,大部分論文都采用的這么一種結構,可能有些在這個結構上會做一些小小變動。
每一幀進來之后,首先過一個 CNN 網絡拿到 feature map,然后在 feature map 做 global pulling 得到向量。向量再通過一個 GRU 從而建立時序的關系,然后可以得到每一幀的質量分。再根據每一幀的分數通過 pulling 或者其他一些方式計算視頻的總體質量得分。
3、微博的做法
在微博的場景怎么去解決這個問題?能否用現有模型呢?經過實驗,發現現有模型不是特別適合微博的場景。因為像視頻質量,一般沒有一個唯一的標準,是一個相對比較主觀的評價。開發的視頻質量評價模型需要符合微博的業務場景。那么從微博為什么需要視頻質量評估這個問題本源出發,之前其實一直有人工持續的在標注數據,通過與標注人員的溝通,了解他們是怎么理解視頻質量標準的,我們再從中總結一些經驗,設計出符合我們視頻質量評價的算法架構。
我們采用的是遞進式的處理方式,也可以說是層次的一種結構。我們先從幀級別去判斷,從幀級別再上升到鏡頭或者片段的級別,再從片段級別上升到整體視頻的級別。
上圖是這個算法模型的整體的架構。首先輸入的是視頻幀,每一幀都一個位置編碼和一個事先算好的能夠代表這一幀質量的 embedding。那么這個 embedding 怎么算呢?先分析完這個總體結構之后再詳細介紹。視頻幀輸入之后過 Transformer 結構。就 Transformer 我們針對視頻質量場景做了特殊的設計。過 Transformer 之后,就可以把第 0 個第 1 個位置作為最后預測視頻質量分數的輸出。上圖左邊就是設計的 Transformer 結構的,輸出有兩塊,一塊是幀的向量,第二塊是代表初始的視頻的質量。這是一個需要學習的量。我們會把視頻幀切斷,每一段在內部去過一個 Transformer 結構,這里的兩段 Transformer 結構也是有兩個輸出,每一幀會輸出一個 embedding。這個 embedding 的含義會描述這一幀的質量,同時還有一部分是代表了這一個片段的質量。這樣的話,多個片段,每一段它都會有 embedding 代表這一段的質量。最后再把段的質量做一個融合,通過 Transformer 結構做一個融合,把它 pulling 起來,然后因為是從段級別進行融合,就能夠代表視頻整體的質量的情況。這里幀的向量也會作為輸出。因為下一個還是一個完整的 Transformer 結構,也是作為一個輸出,這樣輸入輸出可以使我們堆疊多次 Transformer 的架構。
那么初始的幀向量是怎么來的?因為我們有大量的這種基于圖片的質量評估的數據,所以可以從通過圖片質量數據訓練出來的一個模型中抽取向量,最后得到一個 128 位的向量作為視頻幀里邊的向量。
上圖是我們的方法和業界的方法在開源數據上的一些對比的結果。從結果上看我們的方法還是有一些優勢的。因為我們會從幀級別,段級別多個維度去考量視頻的質量。
4、具體應用
在做推薦的時候,首先有一個物料池,給某一個人推什么物料肯定都是來自于這個池子的。通過一些策略或者一些模型去做召回,完了之后再做一個排序,最后再推給最終的內容的消費端。所以我們應用點有兩個。
第一個是判斷視頻是否放到物料池,需要對質量分數做一個閾值,作為其中一個條件,協同其他條件或者模型最后做綜合判斷。第二個應用的地方是精排和粗排,排序的時候會優先推薦視頻質量好的物料。
四、文字識別
1、技術背景
文字識別其實是很早就有的一個算法,經歷了一系列的發展。最初的時候是要求圖片的背景需要比較干凈,這樣檢測起來比較容易,分割也比較容易。
到了現在,因為圖片是各種各樣的,比如有自然場景的圖片,比如路邊的招牌或者店的招牌這種信息。場景里面這種圖片,它的字體以及大小是各種各樣的,是非常復雜的。第二種是網絡圖片,比如網絡的截圖或者廣告上面的圖,微信的截圖之類的網絡的圖片。第三種是文檔圖,比如一些掃描件。第四種是手寫體,手寫體是非常難的。
2、業界做法
文字的識別基本上有兩個大塊的內容,第一個是文字的檢測,第二個是文字的識別。文字的檢測就是輸入的是一個圖片,算法要去確定這個圖片的哪個位置有文字,然后用框給框出來。文字識別就是輸入前面這個框把圖像給摳出來之后,過文字識別模型,然后就能夠輸出這一塊圖像里邊包含的是什么字。最后輸出的其實就是文本。
文字識別的發展大概可以分為從兩階段模型到現在的端到端模型這么一個過程。兩階段模型是指把文字檢測作為一個單獨的模型,檢測完了之后再做文字識別,它又是一個單獨的模型。這種方式計算成本是比較高的,因為需要過兩個網絡。發展到最近幾年變成了一個模型,這一個模型它既能做檢測,又能做識別,這樣效率就是非常高的。
文字識別,尤其是中文的識別,難度是比較大的。第一個是中文不管是字符還是整行,做檢測的時候比較難。第二個是中文的字符特別的多,常見的漢字就超過 3000,還有很多不常見的,這么一算估計得上萬。另外,現在很多論文,一些開源的算法,基本上都是在英文場景下去做的,直接搬到中文的場景下,效果會打一個折扣。
檢測文字的檢測,早期的時候基本上是當成普通的目標檢測的方式,比如用 Fast-CRNN 或者 Yolo 模型去檢測。對于水平的文字,用這些模型檢測一般是沒問題的。然而隨著發展,對傾斜的文本需求也越來越大,所以大概在 2017/2018 年的時候,就有一些論文去做傾斜的文本檢測。這些檢測的方法除了預測框的坐標以外,還要預測一個角度的信息,所以就能夠檢測傾斜的文本。最近幾年,因為算法越做越復雜,需求也越來越復雜。有很多文字的邊不是直的,可能是彎的。最近的一些論文想去攻克這個問題,怎么樣去檢測不是一條直線的文本。它的大概思路基本上是不一次性就把整個文本的位置給預測出來,而是分塊的。比如以 TextSnake (ECCV2018)為例,它通過預測一個圓參數。比并以它為中心去預測一個圓的半徑,從而畫出一個圓,通過圓邊把文本區域檢測出來。
上圖是最近 5 年比較有代表性的論文。在 4 種不同場景下,最近 5 年的論文的數據表現除了文檔類的指標比較高以外,其他三種場景其實指標都不是特別高。尤其是在手寫體上,其實提升是非常非常難的。
普遍方法還是做完文字檢測之后,比如用 CNN 抽特征,在特征的基礎上去建立序列之間的關系。一般有做 LSTM 的,或者 Attention 來做的,大部分思路都是這樣子。最后再做一個 CTT 的這種解碼。
前面主要是把檢測和識別是分開的,這里介紹的是端到端的模型,就是它就能做到既檢測又識別。這種方式最早的一篇非常有代表性的論文是 FOTS(CVPR2018),它在當時是效果非常好的。上圖下部列舉了端到端模型的主要流程結構,首先輸入圖片,然后是一個特征抽取的網絡,一般來說都是使用 CNN 來抽取特征,然后通過金字塔方式去用多層次特征或者用 U-Net。最后這一塊 Text Spotting 的部分回去探測文本的位置,然后識別。
3、我們的做法
具體在微博的場景下,早期的時候也是采用 2 階段模型,因為當時 1 階段模型還沒有,或者不是太成熟,現在也改到使用端到端模型。采用的基礎架構是 FOTS 這種方式,因為在微博的文字識別場景里面,它能夠節省大量的集團資源。當原封不動地去采用它的結構,上圖上面部分是 FOTS 原始的結構設計,有個主干模型和特征金字塔。它會用主干模型里邊不同層的 feature map 去構建金字塔結構。相當于能夠產生檢測和識別的特征了。特征再給到檢測模塊,它可以輸出文本的位置。檢測模塊的輸出是一個矩形框,這個矩形框它有可能是傾斜的,所以識別的時候,需要做旋轉,再用得到的坐標去特征金字塔里邊把特征拿出來,然后再給到分支模型去給識別模型做最終的識別,識別出最終的結果。
但是原始 FOTS 檢測和分支是共用的一個特征金字塔,經過測試了之后發現,在微博的場景里面,如果共用,尤其是識別中文的情況下,它的效果不是特別好,因為它的原始論文是在英文場景下做的,畢竟英文的識別比中文要簡單一些。我們做的唯一的改動就是把特征拆開,檢測是檢測的特征,識別是識別的特征,就是這么一個簡單的改動就非常大地提升了我們在中文字符識別的效果。當然,由于共用了主干模型,我們的計算還是非常高效的。因為特征金字塔,它的計算復雜度也不是特別高。這里就看看在微博場景里面,文字識別在什么樣的場景去用。
4、具體應用
第一個是視頻里的文字識別。有一些視頻在上傳的時候,它就會配一些比較重要的文字,一般這幾個文字基本上就能夠代表了整個視頻的內容。所以我們把它識別出來之后,第一個是作為文字,可以跟我們的博文拼到一起,去做一些內容的理解。第二個就是在做視頻打標的時候,它也是可以把文本和視頻畫面結合起來,作為一個模態的輸入做視頻打表。
第二個是圖片文字的識別,在微博場景里面有很多產品的介紹,比如上圖右側,這些文字一般對于理解這張圖片來講是非常有意義的。所以我們把文字識別了之后,再根據圖像的特征去對這張圖片去做一些理解,不管是抽 embedding 還是分類,都是可以用上的。
第三個是頭像文字的識別,在比較特殊的一些場景里面,比如色情的場景,頭像里邊有一些特殊的字,就是為了吸引別人的。我們也對頭像會用 OCR 去識別。
第四種場景是證件文字的識別,有一些用戶,他是需要認證的,比如企業需要拿營業執照做認證,所以營業執照上面信息,我們也是通過 OCR 去抽取,如果純粹靠人工去的敲字,第一方面是容易犯錯,第二個是人力成本。所以我們也是通過算法的方式來做識別。
五、視頻embedding
1、背景介紹
視頻 embedding 在微博場景里面,很多業務都有需求,但是不同的業務對 embedding 的要求是不一樣的。比如版權保護,它對 embedding 的要求是比較細致的。為什么?因為版權保護沒法完全用算法來確定視頻是不是侵權了。因為版權的確權是沒法用算法完全確定的,肯定是需要人工去審核的。人工審核的時候,他就需要明確地知道這兩個視頻從第幾秒開始到第幾秒結束,他是侵權的,需要精確的時間節點。如果整個視頻單獨的一個向量,肯定刻畫不了這個信息。所以對于這種場景,視頻會按每秒去抽一幀,每一幀都會有個相應的向量,這樣能夠算出時間的信息。
第二種比較典型的需求就是視頻的去重。視頻的去重大部分應用在推薦的場景,對于具體是在第幾秒發生重復它不是特別的關心,它只需要知道這兩個視頻有多長時間,它重復的大概位置就行。有一點點偏差是可以的。這個時候抽取的時候我們會把視頻給它分成段,每一段有個向量,這個時候我們是能夠判斷出兩個視頻它有多長是重復的,同時可以節省很多存儲的資源,因為每一段一個向量數明顯會少很多。再一個應用是視頻廣告的檢測,廣告通常也是一段一段的,所以可以按段來做匹配。
第三種是推薦場景,可能有時候需要從整體上、從語義層次上理解視頻。他希望的是一個視頻就一個向量或者一個 ID,這樣可以嵌到推薦的精排算法里邊去做具體的推薦。不同的業務有不同的需求,那怎么樣去用一個統一的算法架構去滿足不同業務需求?
上圖展示了我們整體的視頻 embedding 的架構。輸入有兩種信息,一種是視頻的畫面,另一種是視頻的音頻畫面。按每秒去抽幀,每一幀會訓練一個網絡去抽幀的向量。網絡的訓練方式是通過對比學習的方式去訓練的,是一個無監督的任務。下面的音頻也是一樣,會把音頻按照每秒切成一段,每一段抽出一個向量,訓練的方式也是比較相同的。這個時候我們每秒都有一個向量,這個向量是可以解決版權這種要求比較高的業務。我們把向量稱為幀的向量。
第二種向量,我們把它稱為段的向量,段的向量是把幀的向量融合成的一個向量。會單獨用一個模型去做這種融合,這樣就可以滿足視頻去重的要求。那么為什么視頻去重不直接用幀向量去做去重呢?就是考慮到資源的問題,去重會對過去幾個月的數據進行去重,每當有個新的視頻來了之后,要去看過去幾個月里有沒有視頻重復。如果過去幾個月的視頻量是非常非常大的,可能會超過 1 億或者 2 億。那每一個視頻去抽 200 幀,這個庫里面可能有幾百億個向量。如果要這樣子去檢索恐怕是不太現實的。所以必須把向量的數量降低,所以才會按照段來抽取向量。
在這個項目的基礎上,還會對整體視頻的描述會抽一個唯一的向量,這也是從通過一個模型來算最終的視頻級的向量。這個向量就可以用到具體的視頻推薦業務里面去,也可以用來做視頻的聚類。當然還有很多其他應用方式。
2、具體應用
以上介紹了視頻 embedding 的一些典型的應用場景。當然應用場景非常多,我主要是列了一些比較重要的。比如第一個版權保護的,我們庫里邊存的是幀的向量,這個時候其實庫不是特別大,因為具有版權的視頻,它量不會特別多,所以可以用更加精細的 embedding。第二種是視頻去重的功能,我們用的是段向量,可以相對于幀向量來比,去重庫所占的資源是比較小的。第三個是標簽的復用。標簽復用它的場景是這樣,我們有好些個物料都是人工標注的,這些標注的信息是高度準確的,所以把這些向量和對應的標簽放到一個庫里邊。來了新的視頻之后,先看看有沒有跟他高度相同的視頻,曾經人工是標過的,如果已經標過了,直接給他打標簽就可以了。第四個應用是視頻的聚類,也是應用到推薦里面去的。為什么會有視頻聚類這么一個特征?通常來講,視頻的理想化刻畫有分類的方式,但是分類有一個限制,一個模型訓練了幾個分類,就只能支持幾個視頻類別的分類,通過聚類的方式,可以是作為分類的一種補充,可以是不同層次的聚類。比如可以根據向量去聚 1 萬個類,這個時候相當于有 1 萬個標簽,甚至聚 10 萬個類都可以。這樣相當于標簽就有不同的層次,比如是 1 萬類,10 萬類。并且這個時候是不需要監督信號的。在推薦的場景,也是取得了比較好的推薦的效果。
六、CV-CUDA在微博場景的應用
一般來說視頻處理的傳統做法是先把幀在 CPU 的環境里邊解碼,把原始的字節流解碼成 BGR 數據,再做一些常規的操作,比如 resize 的、crop 之類的,再把數據上傳到 GPU 去做具體的模型的運算。
而應用 CV-CUDA 之后,處理方式是 CPU 解碼之后,在內存里會有 JPG 的字節流,再把字節流上傳到 GPU 上做解碼。當然這個解碼也有可能不完全在 GPU 上,這跟 CUDA 的內部屬性有關。假定它就在 GPU 上,這個時候所有的預處理都是在 GPU 上,所以就可以跟具體的模型無縫的銜接,而不需要顯存到內存的拷貝,或者內存都顯存的拷貝。
從算法層面和 OpenCV 做對比。即使是使用 OpenCV,也可以調用 CUDA 的解碼函數在來解碼 JPG 數據。所以上圖 OpenCV 部分會劃兩個流程。第一個流程是解碼在 GPU 上,然后把 GPU 上解碼之后的圖像數據拷貝到 CPU,再走 OpenCV 的預處理,處理完之后傳到 GPU,再次過模型。第二種方式是 OpenCV 自己的函數在 CPU 上去解碼,再走后面的流程。CV-CUDA 的部分,圖像先傳到 GPU,然后解碼預處理再次過模型這三個步驟都是在 GPU 環境。
在算子層面是分開來對比的。OpenCV 用 CPU 的方式來解碼,CV-CUDA 用 GPU 的方式來解碼,都加上預處理。途中藍色部分是模型的消耗時間,橘黃色部分是解碼消耗的時間。可以看到在微博視頻處理的測試場景里邊,解碼是非常耗時間。因為處理的是視頻,每一個視頻它有非常多的幀,每一幀都要去做解碼,所以它耗時相對會比較長。
綠色部分是預處理的耗時。基本上 CV-CUDA 的預處理耗時可以忽略不計,可能也跟我們的預處理不是特別復雜有關系。可能在你的環境里面測,如果預處理的復雜度特別高,可能會有不太一樣。
上圖是 OpenCV 使用 GPU 去做解碼的情況下,去對比這個效果。最下面還是模型的運算時間,中間是解碼的時間,因為都是 GPU 解碼,所以耗時是差不多的。在預處理這一塊,CV CUDA 已經做得非常好了,預處理時間是非常非常短的,整個 pipeline 的對比也是有提升的,大概 50% 左右。
最后一塊的內容,具體在微博線上具體的業務中,在線上去做的測試,我們的目標是在限定的硬件場景里邊,怎么樣去充分利用硬件資源,做到單位時間處理更多的數據。上圖可以看到用 OpenCV 去做預處理的時候,整體的 CPU 的利用率基本上已經已經漲滿,達到 300%-350% 。但此時它 GPU 的利用率它是偏低的,低于 10% 了。整體 pipeline 的 QPS 是零點八六,指一秒鐘處理零點八六個視頻。上傳 gpu 的意思是用 OpenCV 需要 GPU 上傳的數據量。
再看 CV-CUDA 的一些性能數據,相對來講,它的顯存會占比較多一些。因為它把原始數據在 GPU上做解碼,相當于做了展開。這樣原始的圖片在 GPU 上顯存上,它肯定會占得多一些,內存的占用會少一點。這個時候它的 CPU 利用率降低了,同時 GPU 的利用率提升了,整體的 QPS 提升了 70%,同時上傳的數據量減少了非常多。從資源的利用來看,通過兩個方面來討論,第一個是考慮 CPU 的利用率,要把 GPU 打滿,在 GPU的利用率只有 10% 的情況下,需要十倍的 CPU 才能把 GPU 打滿利用率。而對于使用 CV-CUDA 來說,CPU 和 GPU 的總體利用率會比較均衡。能夠使用更少的 CPU 資源把 GPU 的利用率拉到最大。
七、問答環節
Q1:請問有總結如何排查預處理瓶頸嗎?
A1:預處理瓶頸在你的整個 pipeline 里面,你先得知道你的預處理在你整個 pipeline 里面占的時間占比是多少。比如你占比多,肯定預處理是有提升空間的。如果它整體占比少,那基本上的耗時都在你的模型上。預處理做得再好,也不會對整個 pipeline 的提升也不大。
Q2:沒太弄明白剛才您的 10% 是怎么算出來的,可以再講一下嗎?
A2:這個會跟測試的環境有一定的關系,這個地方可以初步地去算一下,如果 GPU 利用率是 10%。能把 GPU 打滿的情況下,Open CV 需要多少個 CPU 和 CUDA 需要多少個 CPU 這樣子去算的。
Q3:您說訓練框架用的是 Python 是嗎?有 demo 可以參考一下嗎?
A3:我的分享主要是 CV-CUDA 在我們推理的環節里邊去做的。訓練框架我們都是用的PyTorch,Demo 因為涉及到我們具體的業務場景,涉及到我們業線上的代碼。不是特別確定能不能分享。
Q4:您介紹的 Open CV 與 CV CUDA的效率對比,那里圖表可以看到預處理速度有很大的提升。這里對比的預處理里面包含了 resize,包含了是如何打 batch 的。表中 batch 的 128 如何對比的細節可以再介紹一下嗎?
A4:預處理是包含 resize 的,如何打 batch 的話,CV-CUDA 本身就支持 batch。如何對比,這個是在一個限定了資源的情況下,我們通過多線程或者多進程的方式,把資源用到最大的情況之下去做的對比。對于 OpenCV,我們會采用多線程的方式,CV-CUDA 會打 batch。
Q5:業務 pipeline 總共是多少個算法?是剛才講的所有算法都包括了嗎?
A5:我這里講的只是其中的四個比較有代表性的。因為時間有限,我沒法把所有的都介紹一遍,所以就從這里面挑選了 4 個比較有代表性,同時也是挑使用了 CV CUDA 做了測試的場景的算法進行了介紹。
Q6:鏡頭分割時,有的非常短,有的有很長,是怎么控制的?
A6:其實長短對于我們的理解來講,影響不是特別大,可能有一些極端的情況。鏡頭的切換比較頻繁,這個時候可能會產生一些比較短的鏡頭。但是我們鏡頭的切割它只是第一步,后面還有模型去做這種預測和融合,所以它即使切得比較短,也不會太影響最終的結果。可能后面的模型里邊會根據前后卷的關系以及一些語義的信息做一些融合。
Q7:推理或者訓練的時候從遠程拉圖片數據比較慢,微博是怎么解決的?可以介紹一下嗎?
A7:拉數據,訓練或者推理拉數據。我們因為我們公司內部的集群都是萬兆的帶寬,目前拉數據。可能我理解你是不是你把數據拉到本地,又要下載純實盤。通常我們的做法是我們拉取圖片數據的時候是不會落到磁盤的。如果只是作為推理或者訓練,直接拿到內存,直接根據 jpg 字節碼去做解碼了。包含 OpenCV,它也有這個功能,不需要存磁盤的。如果你去存磁盤,因為受到磁盤的性能的影響,可能會有影響速度。我們的做法是在內存去解碼 jpg 數據。另外一點是,把圖片數據下載,解碼,預處理,模型計算進行并行化,各個模塊間通過隊列進行通信。
Q8:請問 embedding 向量是多久更新一次?
A8:embedding 向量的更新,更新的頻次是根據業務上的需求來定的,我們通常在確定了更新之后導致的效果差異,在一個可以接受的范圍之內,我們才去做更新。如果業務上認為我們 embedding 不好的時候,我們才會去更新的。
Q9:詳細介紹一下視頻分段 embedding?
A9:其實這個圖我是畫了一個統一的結構圖。在訓練的時候,它可以用 3 個 loss 來訓練。但是具體在我們做的時候,其實是分開來訓的,當然你要做成統一的訓練也是可以的。所以這個地方訓練每幀的向量,它是有一個對比學習的。這個時候是通過數據增強的方式,包含語音也是一樣,也是通過數據增強的方式來做對比的訓練。有了幀向量之后,再去訓練段向量的時候,這個時候也是包含語音和視頻的片段,也是做一些增強,這個地方去做了一個對比學習。
至于向量對比學習,我們會做一些不僅僅是通過增強的方式,因為增強的方式很難去把視頻增強得非常的豐富。在我們的場景里面,還是有一些比如話題,比如標簽之類的帶有標注性的信息,有時候會使用增強,有時候會比如從同一個話題里邊抽取,通過一些規則去篩,基本上基于這個規則之下,我知道這兩個視頻它有一定相同的語義含義。數據擴展這一塊,第一個方面是有正向,第二個方面是通過規則篩出來的,它是一對正樣本的數據去做對比學習。