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