CV CUDA在微博多媒體內(nèi)容理解的應(yīng)用

一、微博多媒體內(nèi)容理解的背景介紹

首先和大家分享多媒體內(nèi)容理解的背景,多媒體內(nèi)容主要包含視頻,音頻,圖像和文本的理解。在視頻的理解里邊,有很多非常重要也非?;A(chǔ)的一些工作,比如視頻的 embedding 標(biāo)簽,視頻的質(zhì)量,視頻的摘要、封面等等。圖片的理解同樣,圖片的理解也是非常重要的,因?yàn)樵谖⒉┑膱鼍袄锩?,圖片是占比較大的一類數(shù)據(jù)。主要的工作包含 embedding 標(biāo)簽,圖片 OCR 了,人臉識(shí)別。在這一系列的算法層上面,支持了公司非常多的業(yè)務(wù)。最基本的,比如個(gè)性化推薦內(nèi)容的審核,物料標(biāo)簽版權(quán),視頻的指紋,視頻拆條等等一系列的業(yè)務(wù)。
以上就是微博多媒體內(nèi)容理解的總體的一個(gè)結(jié)構(gòu)。
下面會(huì)分 4 塊的技術(shù)的內(nèi)容做詳細(xì)說明。
二、視頻摘要(Video Summarization)

1、技術(shù)背景
視頻摘要的主要目的是對(duì)于一段相對(duì)比較長的視頻,采用算法抽取一部分幀,或者一部分連續(xù)的幀,也可以是單獨(dú)的一幀去表達(dá)視頻。使觀看者在看完摘要后能夠大致理解視頻所要表達(dá)的主要內(nèi)容,一般有兩種摘要的方式。
第一種是靜態(tài)的摘要。這項(xiàng)技術(shù)很早之前就有了,最常見的一個(gè)應(yīng)用就是視頻的靜態(tài)封面怎么去抽取,其實(shí)就只抽取一幀,這一幀可能會(huì)包含了比較豐富的信息。使用戶看了這一幀就能大體知道這個(gè)視頻的內(nèi)容。比如講的打籃球還是踢足球。第二種摘要是動(dòng)態(tài)摘要,從視頻里邊選取一段或者多段連續(xù)時(shí)間的視頻幀作為摘要,這種可以作為物料的審核或者物料的打標(biāo)。還有個(gè)應(yīng)用是視頻的動(dòng)態(tài)封面,比如有一些 APP,它的視頻是有這種動(dòng)態(tài)封面的。物料審核主要針對(duì)某些涉及政治或者色情的視頻,以及版權(quán)侵犯的場景等,可能是需要人工去審核。這種場景人工在審核的時(shí)候,如果對(duì)于原始的視頻去簡單看一遍,是非常耗時(shí)的。先對(duì)視頻進(jìn)行一定程度的濃縮,是可以極大的節(jié)省人力的。
2、業(yè)界做法

(1)dppLSTM(ECCV 2016)
業(yè)界之前比較普遍地做法,第一個(gè)是 ECCV 2016 的一個(gè)方法,這個(gè)方法其實(shí)它比較早,但是它特別有代表性。這是一個(gè)有監(jiān)督的方式。首先人工去標(biāo)注這一幀,是不是比較關(guān)鍵的一個(gè)幀,以及這一段是不是比較關(guān)鍵的一段。
這個(gè)模型的輸入是從一個(gè)預(yù)訓(xùn)練的模型去抽取每一幀的特征向量,然后供兩個(gè) LSTM 模型在時(shí)間維度上建模,它會(huì)算一下當(dāng)前幀與其他幀的關(guān)系。再接一層 MLP,這一層主要會(huì)預(yù)測當(dāng)前這一幀它的重要程度,當(dāng)前這一幀它跟其它幀的相似度。最后再有個(gè)模塊,基于這兩個(gè)分?jǐn)?shù)值,去判斷當(dāng)前視頻幀的集合里邊哪一些是比較重要,哪一些是適合的。
這個(gè)方法比較常規(guī)的一種做法,需要人工標(biāo)注,但人工標(biāo)注其實(shí)非常的難,不同的人去標(biāo),可能標(biāo)準(zhǔn)很難去統(tǒng)一。第二就是非常耗人力了,對(duì)于視頻,需要一幀一幀的標(biāo)注。
(2)SUM-GAN(CVPR’ 2017)
右邊這個(gè)圖是 2017 年的一個(gè)方法,它是一種無監(jiān)督的方式,非常類似于現(xiàn)在比較火的對(duì)比學(xué)習(xí)的技術(shù)。
首先這個(gè)模型它分成了四大塊,sLSTM 模塊會(huì)給輸入的幀打一個(gè)重要性分?jǐn)?shù)。這樣相當(dāng)于有了每一幀的向量和重要程度。然后,這個(gè)模塊會(huì)根據(jù)重用性的程度把向量去做加權(quán),重新去算向量。生成模塊會(huì)根據(jù)重用性程度加權(quán)之后的向量,再去恢復(fù)視頻的原始向量,然后把恢復(fù)的向量跟原始的向量做對(duì)比,看恢復(fù)得好不好,如果恢復(fù)得好,就可以說明幀的重要性算對(duì)了。反之就沒算對(duì)。所以整個(gè)過程是一個(gè)無監(jiān)督的過程,因?yàn)樗莻€(gè)已知的原始向量去對(duì)比的過程。
(3)CSNet(AAAI’ 2018)

視頻處理的時(shí)候,對(duì)于長視頻這種以遠(yuǎn)程的關(guān)系建立時(shí)間建模,是比較難的一個(gè)問題。上面左圖是 AAAI’18 年的論文,它的一個(gè)側(cè)重點(diǎn)是解決當(dāng)時(shí)間跨度比較長的情況下,怎么去建立幀與幀之間的關(guān)系。
首先每一幀向量進(jìn)來通過 CNN 以后會(huì)分成兩塊,第一塊按照它原有的時(shí)間順序切成一個(gè)一個(gè)的段。第二塊在時(shí)間維度上,會(huì)跳著挑一些幀,比如挑第一幀,第四幀,第八幀,它把 148 放在一塊,相當(dāng)于把不同時(shí)間跨度的幀放在一塊,這有利于對(duì)遠(yuǎn)程幀的向量的一個(gè)感知特性的感知。另外,是類似于 attention 的一個(gè)方式。比如這一幀跟第四幀去比一下,跟第八幀去比一下,根據(jù)差異性來判斷這一幀的重要性,差異大說明重要,類似的話說明不重要。最后就根據(jù) tension 和原始上傳的向量去做一個(gè)融合,最后再去預(yù)測分?jǐn)?shù)。這種方法它主要是解決了長視頻的一種建模的方式。
(4)DR-DSN(AAAI’ 2018)
右邊這個(gè)圖也是 2018 年的一篇論文,首先它在原來的基礎(chǔ)上能做到無監(jiān)督。第二個(gè),當(dāng)時(shí)來講,它的效果是比較好的。
跟前面的方法一樣。首先把每一幀都向量化,再做雙向的 LSTM 網(wǎng)絡(luò)。它的不同點(diǎn)在于,把整個(gè)訓(xùn)練建模的目標(biāo)變成了兩個(gè)。這樣做有兩個(gè)目的,第一個(gè)是去度量多樣性,最后摘要出來的這一段必須是比較豐富的內(nèi)容。第二個(gè)是選出來這些關(guān)鍵的片段和尾幀是具有代表性的,能夠代表原始的視頻。這樣從比較長的視頻,選出來的片段會(huì)具有多樣性,相互之間重復(fù)度是比較低的。其次還能代表原來整個(gè)長視頻的內(nèi)容。整個(gè)過程不需要任何的監(jiān)督的信號(hào),所以它是一個(gè)無監(jiān)督方式。
3、微博的工作

前沿的這些做法其實(shí)各有各的優(yōu)點(diǎn),也各有各的缺點(diǎn)。微博結(jié)合我們自己的業(yè)務(wù)場景,做了我們自己的模型。當(dāng)然有監(jiān)督的這種方式我們基本上就不用考慮了,因?yàn)樘M(fèi)人力了。無監(jiān)督的這種方式相對(duì)來講,相對(duì)于有監(jiān)督來講,它在效果上會(huì)有一些差異,會(huì)有所降低。但我們在探索怎么樣可以在不需要人工標(biāo)注的情況下,還能做到一個(gè)比較好的效果。
下面是微博特定場景里面做模型的一些動(dòng)機(jī)。
在微博多媒體的場景里,事先有視頻分類這么一個(gè)模型,這個(gè)模型它其實(shí)抽出的特征是有一定的語義信息的,訓(xùn)練視頻分類的時(shí)候,標(biāo)簽是一致的。因?yàn)槲⒉﹫鼍袄锩嬗写罅康倪@種數(shù)據(jù),所以這個(gè)模型是比較容易得到的。當(dāng)時(shí)基于這一點(diǎn)想去虛擬一個(gè)弱監(jiān)督或者無監(jiān)督的模型。弱監(jiān)督是因?yàn)橛靡曨l分類模型去做監(jiān)督,所以稱它為弱監(jiān)督。這個(gè)圖就是整個(gè)的算法結(jié)構(gòu)。當(dāng)然這個(gè)方法的論文是在 2021 發(fā)表的,如果大家感興趣,可以去仔細(xì)地去閱讀一下論文。

首先視頻會(huì)抽成幀,然后每一幀都會(huì)去抽到一個(gè)向量。之后會(huì)使用一個(gè)比較常規(guī)的算法。比如用一個(gè)鏡頭切割的算法,把視頻切割成 5 個(gè)鏡頭或者是 5 個(gè)片段,每一段把這一段里的向量做一個(gè)平均,得到的向量就代表了這一個(gè)片段的特征,這一個(gè)代表片段的特征會(huì)被放到視頻分類的模型里面去,這個(gè)模型的作用就是,輸入是一串向量,輸出是一個(gè)向量,并且因?yàn)楹蠼右粋€(gè)分類。可以拿分類層的前面特征作為最后的視頻的一個(gè)表達(dá)向量,這樣多個(gè)鏡頭通過上面的分類網(wǎng)絡(luò),就可以得到唯一的向量。
然后 Summary Generation Sub-network 的部分會(huì)根據(jù)輸入的鏡頭的向量去做選擇,選擇一些鏡頭作為最后的摘要的片段。當(dāng)然也是采用了潛量的一些做法,用 LSTM 去建立鏡頭與鏡頭之間的關(guān)系,同時(shí)每一個(gè)鏡頭會(huì)預(yù)測到一個(gè)分?jǐn)?shù),再根據(jù)分?jǐn)?shù)去選擇一些片段。
那么最后這個(gè)片段選得好不好,用一種什么樣的方式去衡量呢?這里設(shè)計(jì)了四種的監(jiān)督方式。
第一種就是選出來這個(gè)片段,仍然送到視頻分類網(wǎng)絡(luò)里面去,這個(gè)時(shí)候多個(gè)鏡頭向量,最后可以得到一個(gè)向量。如果選了這個(gè)片段是比較好得到的向量,那么就和所有的片段進(jìn)去之后,視頻分類網(wǎng)絡(luò)得到的向量是一樣的了,或者至少是高度相同的。所以可以把它作為一個(gè)基因多信號(hào),在語義層次上,選出的這些片段,能夠跟原來整體視頻的語義層次是相同的。那么選出來的這些片段,它本身需要一些什么樣的約束呢?
第一個(gè),選出來的片段必須有多樣性,這一段與另外一段肯定是不同的。如果是相同的,就不需要去重復(fù)地選。第二個(gè),它是具有代表性的,原來視頻的某一段,可以在選出的片段里面找到一段在語義層次上比較相似的。最后一點(diǎn)就是選出的這些片段在時(shí)間上應(yīng)該是有個(gè)約束,不應(yīng)該讓模型在極端的情況下,比如把原來所有的片段都選上,不就是涵蓋了所有的語義嗎?這樣肯定是不需要的,所以加個(gè)時(shí)間長度的一個(gè)約束。最后所有的約束項(xiàng)一共有 4 項(xiàng),4 項(xiàng)里面后面的三項(xiàng)都是無監(jiān)督的。第一項(xiàng)是根據(jù)視頻分類網(wǎng)絡(luò)的監(jiān)督信號(hào)算出來的,所以總體上不需要去額外的標(biāo)注一些信息。當(dāng)然視頻分類網(wǎng)絡(luò)是有監(jiān)督的,所以這個(gè)方法稱為一個(gè)弱監(jiān)督的方式。

這種方法在做前向推理的時(shí)候,上面視頻的分類網(wǎng)絡(luò)就可以扔掉了,因?yàn)槟莻€(gè)只是作為訓(xùn)練時(shí)候的一個(gè)監(jiān)督信號(hào)的來源。來了新的視頻之后,就走下面流程,每一幀去抽向量,做鏡頭的切割,再算鏡頭向量,再過我們的摘要網(wǎng)絡(luò)。最后可以得到每一個(gè)片段的分?jǐn)?shù),這一個(gè)片段里邊我們認(rèn)為每一幀的分?jǐn)?shù)都是一樣的。

上圖展示了我們跟有監(jiān)督和無監(jiān)督的一些方法去做對(duì)比,我們作為一個(gè)弱監(jiān)督的方式,但是跟有監(jiān)督對(duì)比也還是有優(yōu)勢的。跟現(xiàn)有的一些無監(jiān)督的方式,我們的這種方式性能相對(duì)來講會(huì)更好一些。圖上下面部分展示了我們當(dāng)時(shí)的方法,跟業(yè)界最好的方法做了一個(gè)具體的,在視頻上做了一個(gè)對(duì)比。我們看了抽出來的摘要信息,其實(shí)更符合,至少更符合我們微博場景對(duì)于摘要的一些需求。同時(shí)在開源的數(shù)據(jù)里面,摘出來的片段其實(shí)哪怕跟當(dāng)時(shí)最好的方法相比,也是很有優(yōu)勢的。圖片最下面是我們論文的地址。
4、具體應(yīng)用

下面介紹視頻摘要在微博的應(yīng)用,以及在什么樣的場景下面去使用。第一個(gè)是靜態(tài)的封面,對(duì)于一個(gè)長視頻,一般會(huì)選擇比較重要的一幀去作為視頻,在沒有播放的時(shí)候作為一個(gè)封面展示在前面。第二個(gè)是動(dòng)態(tài)的方面,作為封面,可能在時(shí)間的長度上面是有一個(gè)約束,比如不能超過 3 秒或者 5 秒,所以動(dòng)態(tài)方面會(huì)從整個(gè)視頻里邊去抽,連續(xù)一段持續(xù) 3 秒的得分?jǐn)?shù)最高的一段去作為動(dòng)態(tài)的封面。第三個(gè)應(yīng)用場景是物料的打標(biāo),打一些標(biāo)簽和物料的審核,這樣人只要一看摘要,就基本上能夠知道這個(gè)物料怎么去打標(biāo),或者審核過不過。如果有疑慮,再去看原始視頻,這樣能夠大大的提升人工的效率。
三、視頻質(zhì)量

1、技術(shù)背景
視頻質(zhì)量的主要目的是通過使用深度學(xué)習(xí)產(chǎn)生統(tǒng)一量化的質(zhì)量指標(biāo),從而可以根據(jù)質(zhì)量對(duì)視頻進(jìn)行推薦或者打壓限流。
幾個(gè)圖展示的是一些具體的例子。什么樣的是質(zhì)量不好的,比如拍得比較模糊,或者是拍攝的時(shí)候焦距不夠好,或者是這種運(yùn)動(dòng)模糊。
2、業(yè)界做法

首先看看業(yè)界以前是怎么去解決視頻質(zhì)量這個(gè)問題的。這個(gè)大致架構(gòu)比較常規(guī),大部分論文都采用的這么一種結(jié)構(gòu),可能有些在這個(gè)結(jié)構(gòu)上會(huì)做一些小小變動(dòng)。
每一幀進(jìn)來之后,首先過一個(gè) CNN 網(wǎng)絡(luò)拿到 feature map,然后在 feature map 做 global pulling 得到向量。向量再通過一個(gè) GRU 從而建立時(shí)序的關(guān)系,然后可以得到每一幀的質(zhì)量分。再根據(jù)每一幀的分?jǐn)?shù)通過 pulling 或者其他一些方式計(jì)算視頻的總體質(zhì)量得分。
3、微博的做法
在微博的場景怎么去解決這個(gè)問題?能否用現(xiàn)有模型呢?經(jīng)過實(shí)驗(yàn),發(fā)現(xiàn)現(xiàn)有模型不是特別適合微博的場景。因?yàn)橄褚曨l質(zhì)量,一般沒有一個(gè)唯一的標(biāo)準(zhǔn),是一個(gè)相對(duì)比較主觀的評(píng)價(jià)。開發(fā)的視頻質(zhì)量評(píng)價(jià)模型需要符合微博的業(yè)務(wù)場景。那么從微博為什么需要視頻質(zhì)量評(píng)估這個(gè)問題本源出發(fā),之前其實(shí)一直有人工持續(xù)的在標(biāo)注數(shù)據(jù),通過與標(biāo)注人員的溝通,了解他們是怎么理解視頻質(zhì)量標(biāo)準(zhǔn)的,我們再從中總結(jié)一些經(jīng)驗(yàn),設(shè)計(jì)出符合我們視頻質(zhì)量評(píng)價(jià)的算法架構(gòu)。

我們采用的是遞進(jìn)式的處理方式,也可以說是層次的一種結(jié)構(gòu)。我們先從幀級(jí)別去判斷,從幀級(jí)別再上升到鏡頭或者片段的級(jí)別,再從片段級(jí)別上升到整體視頻的級(jí)別。
上圖是這個(gè)算法模型的整體的架構(gòu)。首先輸入的是視頻幀,每一幀都一個(gè)位置編碼和一個(gè)事先算好的能夠代表這一幀質(zhì)量的 embedding。那么這個(gè) embedding 怎么算呢?先分析完這個(gè)總體結(jié)構(gòu)之后再詳細(xì)介紹。視頻幀輸入之后過 Transformer 結(jié)構(gòu)。就 Transformer 我們針對(duì)視頻質(zhì)量場景做了特殊的設(shè)計(jì)。過 Transformer 之后,就可以把第 0 個(gè)第 1 個(gè)位置作為最后預(yù)測視頻質(zhì)量分?jǐn)?shù)的輸出。上圖左邊就是設(shè)計(jì)的 Transformer 結(jié)構(gòu)的,輸出有兩塊,一塊是幀的向量,第二塊是代表初始的視頻的質(zhì)量。這是一個(gè)需要學(xué)習(xí)的量。我們會(huì)把視頻幀切斷,每一段在內(nèi)部去過一個(gè) Transformer 結(jié)構(gòu),這里的兩段 Transformer 結(jié)構(gòu)也是有兩個(gè)輸出,每一幀會(huì)輸出一個(gè) embedding。這個(gè) embedding 的含義會(huì)描述這一幀的質(zhì)量,同時(shí)還有一部分是代表了這一個(gè)片段的質(zhì)量。這樣的話,多個(gè)片段,每一段它都會(huì)有 embedding 代表這一段的質(zhì)量。最后再把段的質(zhì)量做一個(gè)融合,通過 Transformer 結(jié)構(gòu)做一個(gè)融合,把它 pulling 起來,然后因?yàn)槭菑亩渭?jí)別進(jìn)行融合,就能夠代表視頻整體的質(zhì)量的情況。這里幀的向量也會(huì)作為輸出。因?yàn)橄乱粋€(gè)還是一個(gè)完整的 Transformer 結(jié)構(gòu),也是作為一個(gè)輸出,這樣輸入輸出可以使我們堆疊多次 Transformer 的架構(gòu)。

那么初始的幀向量是怎么來的?因?yàn)槲覀冇写罅康倪@種基于圖片的質(zhì)量評(píng)估的數(shù)據(jù),所以可以從通過圖片質(zhì)量數(shù)據(jù)訓(xùn)練出來的一個(gè)模型中抽取向量,最后得到一個(gè) 128 位的向量作為視頻幀里邊的向量。

上圖是我們的方法和業(yè)界的方法在開源數(shù)據(jù)上的一些對(duì)比的結(jié)果。從結(jié)果上看我們的方法還是有一些優(yōu)勢的。因?yàn)槲覀儠?huì)從幀級(jí)別,段級(jí)別多個(gè)維度去考量視頻的質(zhì)量。
4、具體應(yīng)用

在做推薦的時(shí)候,首先有一個(gè)物料池,給某一個(gè)人推什么物料肯定都是來自于這個(gè)池子的。通過一些策略或者一些模型去做召回,完了之后再做一個(gè)排序,最后再推給最終的內(nèi)容的消費(fèi)端。所以我們應(yīng)用點(diǎn)有兩個(gè)。
第一個(gè)是判斷視頻是否放到物料池,需要對(duì)質(zhì)量分?jǐn)?shù)做一個(gè)閾值,作為其中一個(gè)條件,協(xié)同其他條件或者模型最后做綜合判斷。第二個(gè)應(yīng)用的地方是精排和粗排,排序的時(shí)候會(huì)優(yōu)先推薦視頻質(zhì)量好的物料。
四、文字識(shí)別
1、技術(shù)背景

文字識(shí)別其實(shí)是很早就有的一個(gè)算法,經(jīng)歷了一系列的發(fā)展。最初的時(shí)候是要求圖片的背景需要比較干凈,這樣檢測起來比較容易,分割也比較容易。
到了現(xiàn)在,因?yàn)閳D片是各種各樣的,比如有自然場景的圖片,比如路邊的招牌或者店的招牌這種信息。場景里面這種圖片,它的字體以及大小是各種各樣的,是非常復(fù)雜的。第二種是網(wǎng)絡(luò)圖片,比如網(wǎng)絡(luò)的截圖或者廣告上面的圖,微信的截圖之類的網(wǎng)絡(luò)的圖片。第三種是文檔圖,比如一些掃描件。第四種是手寫體,手寫體是非常難的。
2、業(yè)界做法

文字的識(shí)別基本上有兩個(gè)大塊的內(nèi)容,第一個(gè)是文字的檢測,第二個(gè)是文字的識(shí)別。文字的檢測就是輸入的是一個(gè)圖片,算法要去確定這個(gè)圖片的哪個(gè)位置有文字,然后用框給框出來。文字識(shí)別就是輸入前面這個(gè)框把圖像給摳出來之后,過文字識(shí)別模型,然后就能夠輸出這一塊圖像里邊包含的是什么字。最后輸出的其實(shí)就是文本。
文字識(shí)別的發(fā)展大概可以分為從兩階段模型到現(xiàn)在的端到端模型這么一個(gè)過程。兩階段模型是指把文字檢測作為一個(gè)單獨(dú)的模型,檢測完了之后再做文字識(shí)別,它又是一個(gè)單獨(dú)的模型。這種方式計(jì)算成本是比較高的,因?yàn)樾枰^兩個(gè)網(wǎng)絡(luò)。發(fā)展到最近幾年變成了一個(gè)模型,這一個(gè)模型它既能做檢測,又能做識(shí)別,這樣效率就是非常高的。

文字識(shí)別,尤其是中文的識(shí)別,難度是比較大的。第一個(gè)是中文不管是字符還是整行,做檢測的時(shí)候比較難。第二個(gè)是中文的字符特別的多,常見的漢字就超過 3000,還有很多不常見的,這么一算估計(jì)得上萬。另外,現(xiàn)在很多論文,一些開源的算法,基本上都是在英文場景下去做的,直接搬到中文的場景下,效果會(huì)打一個(gè)折扣。

檢測文字的檢測,早期的時(shí)候基本上是當(dāng)成普通的目標(biāo)檢測的方式,比如用 Fast-CRNN 或者 Yolo 模型去檢測。對(duì)于水平的文字,用這些模型檢測一般是沒問題的。然而隨著發(fā)展,對(duì)傾斜的文本需求也越來越大,所以大概在 2017/2018 年的時(shí)候,就有一些論文去做傾斜的文本檢測。這些檢測的方法除了預(yù)測框的坐標(biāo)以外,還要預(yù)測一個(gè)角度的信息,所以就能夠檢測傾斜的文本。最近幾年,因?yàn)樗惴ㄔ阶鲈綇?fù)雜,需求也越來越復(fù)雜。有很多文字的邊不是直的,可能是彎的。最近的一些論文想去攻克這個(gè)問題,怎么樣去檢測不是一條直線的文本。它的大概思路基本上是不一次性就把整個(gè)文本的位置給預(yù)測出來,而是分塊的。比如以 TextSnake (ECCV2018)為例,它通過預(yù)測一個(gè)圓參數(shù)。比并以它為中心去預(yù)測一個(gè)圓的半徑,從而畫出一個(gè)圓,通過圓邊把文本區(qū)域檢測出來。

上圖是最近 5 年比較有代表性的論文。在 4 種不同場景下,最近 5 年的論文的數(shù)據(jù)表現(xiàn)除了文檔類的指標(biāo)比較高以外,其他三種場景其實(shí)指標(biāo)都不是特別高。尤其是在手寫體上,其實(shí)提升是非常非常難的。
普遍方法還是做完文字檢測之后,比如用 CNN 抽特征,在特征的基礎(chǔ)上去建立序列之間的關(guān)系。一般有做 LSTM 的,或者 Attention 來做的,大部分思路都是這樣子。最后再做一個(gè) CTT 的這種解碼。

前面主要是把檢測和識(shí)別是分開的,這里介紹的是端到端的模型,就是它就能做到既檢測又識(shí)別。這種方式最早的一篇非常有代表性的論文是 FOTS(CVPR2018),它在當(dāng)時(shí)是效果非常好的。上圖下部列舉了端到端模型的主要流程結(jié)構(gòu),首先輸入圖片,然后是一個(gè)特征抽取的網(wǎng)絡(luò),一般來說都是使用 CNN 來抽取特征,然后通過金字塔方式去用多層次特征或者用 U-Net。最后這一塊 Text Spotting 的部分回去探測文本的位置,然后識(shí)別。
3、我們的做法

具體在微博的場景下,早期的時(shí)候也是采用 2 階段模型,因?yàn)楫?dāng)時(shí) 1 階段模型還沒有,或者不是太成熟,現(xiàn)在也改到使用端到端模型。采用的基礎(chǔ)架構(gòu)是 FOTS 這種方式,因?yàn)樵谖⒉┑奈淖肿R(shí)別場景里面,它能夠節(jié)省大量的集團(tuán)資源。當(dāng)原封不動(dòng)地去采用它的結(jié)構(gòu),上圖上面部分是 FOTS 原始的結(jié)構(gòu)設(shè)計(jì),有個(gè)主干模型和特征金字塔。它會(huì)用主干模型里邊不同層的 feature map 去構(gòu)建金字塔結(jié)構(gòu)。相當(dāng)于能夠產(chǎn)生檢測和識(shí)別的特征了。特征再給到檢測模塊,它可以輸出文本的位置。檢測模塊的輸出是一個(gè)矩形框,這個(gè)矩形框它有可能是傾斜的,所以識(shí)別的時(shí)候,需要做旋轉(zhuǎn),再用得到的坐標(biāo)去特征金字塔里邊把特征拿出來,然后再給到分支模型去給識(shí)別模型做最終的識(shí)別,識(shí)別出最終的結(jié)果。
但是原始 FOTS 檢測和分支是共用的一個(gè)特征金字塔,經(jīng)過測試了之后發(fā)現(xiàn),在微博的場景里面,如果共用,尤其是識(shí)別中文的情況下,它的效果不是特別好,因?yàn)樗脑颊撐氖窃谟⑽膱鼍跋伦龅?,畢竟英文的識(shí)別比中文要簡單一些。我們做的唯一的改動(dòng)就是把特征拆開,檢測是檢測的特征,識(shí)別是識(shí)別的特征,就是這么一個(gè)簡單的改動(dòng)就非常大地提升了我們在中文字符識(shí)別的效果。當(dāng)然,由于共用了主干模型,我們的計(jì)算還是非常高效的。因?yàn)樘卣鹘鹱炙挠?jì)算復(fù)雜度也不是特別高。這里就看看在微博場景里面,文字識(shí)別在什么樣的場景去用。
4、具體應(yīng)用

第一個(gè)是視頻里的文字識(shí)別。有一些視頻在上傳的時(shí)候,它就會(huì)配一些比較重要的文字,一般這幾個(gè)文字基本上就能夠代表了整個(gè)視頻的內(nèi)容。所以我們把它識(shí)別出來之后,第一個(gè)是作為文字,可以跟我們的博文拼到一起,去做一些內(nèi)容的理解。第二個(gè)就是在做視頻打標(biāo)的時(shí)候,它也是可以把文本和視頻畫面結(jié)合起來,作為一個(gè)模態(tài)的輸入做視頻打表。
第二個(gè)是圖片文字的識(shí)別,在微博場景里面有很多產(chǎn)品的介紹,比如上圖右側(cè),這些文字一般對(duì)于理解這張圖片來講是非常有意義的。所以我們把文字識(shí)別了之后,再根據(jù)圖像的特征去對(duì)這張圖片去做一些理解,不管是抽 embedding 還是分類,都是可以用上的。
第三個(gè)是頭像文字的識(shí)別,在比較特殊的一些場景里面,比如色情的場景,頭像里邊有一些特殊的字,就是為了吸引別人的。我們也對(duì)頭像會(huì)用 OCR 去識(shí)別。
第四種場景是證件文字的識(shí)別,有一些用戶,他是需要認(rèn)證的,比如企業(yè)需要拿營業(yè)執(zhí)照做認(rèn)證,所以營業(yè)執(zhí)照上面信息,我們也是通過 OCR 去抽取,如果純粹靠人工去的敲字,第一方面是容易犯錯(cuò),第二個(gè)是人力成本。所以我們也是通過算法的方式來做識(shí)別。
五、視頻embedding
1、背景介紹

視頻 embedding 在微博場景里面,很多業(yè)務(wù)都有需求,但是不同的業(yè)務(wù)對(duì) embedding 的要求是不一樣的。比如版權(quán)保護(hù),它對(duì) embedding 的要求是比較細(xì)致的。為什么?因?yàn)榘鏅?quán)保護(hù)沒法完全用算法來確定視頻是不是侵權(quán)了。因?yàn)榘鏅?quán)的確權(quán)是沒法用算法完全確定的,肯定是需要人工去審核的。人工審核的時(shí)候,他就需要明確地知道這兩個(gè)視頻從第幾秒開始到第幾秒結(jié)束,他是侵權(quán)的,需要精確的時(shí)間節(jié)點(diǎn)。如果整個(gè)視頻單獨(dú)的一個(gè)向量,肯定刻畫不了這個(gè)信息。所以對(duì)于這種場景,視頻會(huì)按每秒去抽一幀,每一幀都會(huì)有個(gè)相應(yīng)的向量,這樣能夠算出時(shí)間的信息。
第二種比較典型的需求就是視頻的去重。視頻的去重大部分應(yīng)用在推薦的場景,對(duì)于具體是在第幾秒發(fā)生重復(fù)它不是特別的關(guān)心,它只需要知道這兩個(gè)視頻有多長時(shí)間,它重復(fù)的大概位置就行。有一點(diǎn)點(diǎn)偏差是可以的。這個(gè)時(shí)候抽取的時(shí)候我們會(huì)把視頻給它分成段,每一段有個(gè)向量,這個(gè)時(shí)候我們是能夠判斷出兩個(gè)視頻它有多長是重復(fù)的,同時(shí)可以節(jié)省很多存儲(chǔ)的資源,因?yàn)槊恳欢我粋€(gè)向量數(shù)明顯會(huì)少很多。再一個(gè)應(yīng)用是視頻廣告的檢測,廣告通常也是一段一段的,所以可以按段來做匹配。
第三種是推薦場景,可能有時(shí)候需要從整體上、從語義層次上理解視頻。他希望的是一個(gè)視頻就一個(gè)向量或者一個(gè) ID,這樣可以嵌到推薦的精排算法里邊去做具體的推薦。不同的業(yè)務(wù)有不同的需求,那怎么樣去用一個(gè)統(tǒng)一的算法架構(gòu)去滿足不同業(yè)務(wù)需求?

上圖展示了我們整體的視頻 embedding 的架構(gòu)。輸入有兩種信息,一種是視頻的畫面,另一種是視頻的音頻畫面。按每秒去抽幀,每一幀會(huì)訓(xùn)練一個(gè)網(wǎng)絡(luò)去抽幀的向量。網(wǎng)絡(luò)的訓(xùn)練方式是通過對(duì)比學(xué)習(xí)的方式去訓(xùn)練的,是一個(gè)無監(jiān)督的任務(wù)。下面的音頻也是一樣,會(huì)把音頻按照每秒切成一段,每一段抽出一個(gè)向量,訓(xùn)練的方式也是比較相同的。這個(gè)時(shí)候我們每秒都有一個(gè)向量,這個(gè)向量是可以解決版權(quán)這種要求比較高的業(yè)務(wù)。我們把向量稱為幀的向量。
第二種向量,我們把它稱為段的向量,段的向量是把幀的向量融合成的一個(gè)向量。會(huì)單獨(dú)用一個(gè)模型去做這種融合,這樣就可以滿足視頻去重的要求。那么為什么視頻去重不直接用幀向量去做去重呢?就是考慮到資源的問題,去重會(huì)對(duì)過去幾個(gè)月的數(shù)據(jù)進(jìn)行去重,每當(dāng)有個(gè)新的視頻來了之后,要去看過去幾個(gè)月里有沒有視頻重復(fù)。如果過去幾個(gè)月的視頻量是非常非常大的,可能會(huì)超過 1 億或者 2 億。那每一個(gè)視頻去抽 200 幀,這個(gè)庫里面可能有幾百億個(gè)向量。如果要這樣子去檢索恐怕是不太現(xiàn)實(shí)的。所以必須把向量的數(shù)量降低,所以才會(huì)按照段來抽取向量。
在這個(gè)項(xiàng)目的基礎(chǔ)上,還會(huì)對(duì)整體視頻的描述會(huì)抽一個(gè)唯一的向量,這也是從通過一個(gè)模型來算最終的視頻級(jí)的向量。這個(gè)向量就可以用到具體的視頻推薦業(yè)務(wù)里面去,也可以用來做視頻的聚類。當(dāng)然還有很多其他應(yīng)用方式。
2、具體應(yīng)用

以上介紹了視頻 embedding 的一些典型的應(yīng)用場景。當(dāng)然應(yīng)用場景非常多,我主要是列了一些比較重要的。比如第一個(gè)版權(quán)保護(hù)的,我們庫里邊存的是幀的向量,這個(gè)時(shí)候其實(shí)庫不是特別大,因?yàn)榫哂邪鏅?quán)的視頻,它量不會(huì)特別多,所以可以用更加精細(xì)的 embedding。第二種是視頻去重的功能,我們用的是段向量,可以相對(duì)于幀向量來比,去重庫所占的資源是比較小的。第三個(gè)是標(biāo)簽的復(fù)用。標(biāo)簽復(fù)用它的場景是這樣,我們有好些個(gè)物料都是人工標(biāo)注的,這些標(biāo)注的信息是高度準(zhǔn)確的,所以把這些向量和對(duì)應(yīng)的標(biāo)簽放到一個(gè)庫里邊。來了新的視頻之后,先看看有沒有跟他高度相同的視頻,曾經(jīng)人工是標(biāo)過的,如果已經(jīng)標(biāo)過了,直接給他打標(biāo)簽就可以了。第四個(gè)應(yīng)用是視頻的聚類,也是應(yīng)用到推薦里面去的。為什么會(huì)有視頻聚類這么一個(gè)特征?通常來講,視頻的理想化刻畫有分類的方式,但是分類有一個(gè)限制,一個(gè)模型訓(xùn)練了幾個(gè)分類,就只能支持幾個(gè)視頻類別的分類,通過聚類的方式,可以是作為分類的一種補(bǔ)充,可以是不同層次的聚類。比如可以根據(jù)向量去聚 1 萬個(gè)類,這個(gè)時(shí)候相當(dāng)于有 1 萬個(gè)標(biāo)簽,甚至聚 10 萬個(gè)類都可以。這樣相當(dāng)于標(biāo)簽就有不同的層次,比如是 1 萬類,10 萬類。并且這個(gè)時(shí)候是不需要監(jiān)督信號(hào)的。在推薦的場景,也是取得了比較好的推薦的效果。
六、CV-CUDA在微博場景的應(yīng)用

一般來說視頻處理的傳統(tǒng)做法是先把幀在 CPU 的環(huán)境里邊解碼,把原始的字節(jié)流解碼成 BGR 數(shù)據(jù),再做一些常規(guī)的操作,比如 resize 的、crop 之類的,再把數(shù)據(jù)上傳到 GPU 去做具體的模型的運(yùn)算。

而應(yīng)用 CV-CUDA 之后,處理方式是 CPU 解碼之后,在內(nèi)存里會(huì)有 JPG 的字節(jié)流,再把字節(jié)流上傳到 GPU 上做解碼。當(dāng)然這個(gè)解碼也有可能不完全在 GPU 上,這跟 CUDA 的內(nèi)部屬性有關(guān)。假定它就在 GPU 上,這個(gè)時(shí)候所有的預(yù)處理都是在 GPU 上,所以就可以跟具體的模型無縫的銜接,而不需要顯存到內(nèi)存的拷貝,或者內(nèi)存都顯存的拷貝。

從算法層面和 OpenCV 做對(duì)比。即使是使用 OpenCV,也可以調(diào)用 CUDA 的解碼函數(shù)在來解碼 JPG 數(shù)據(jù)。所以上圖 OpenCV 部分會(huì)劃兩個(gè)流程。第一個(gè)流程是解碼在 GPU 上,然后把 GPU 上解碼之后的圖像數(shù)據(jù)拷貝到 CPU,再走 OpenCV 的預(yù)處理,處理完之后傳到 GPU,再次過模型。第二種方式是 OpenCV 自己的函數(shù)在 CPU 上去解碼,再走后面的流程。CV-CUDA 的部分,圖像先傳到 GPU,然后解碼預(yù)處理再次過模型這三個(gè)步驟都是在 GPU 環(huán)境。

在算子層面是分開來對(duì)比的。OpenCV 用 CPU 的方式來解碼,CV-CUDA 用 GPU 的方式來解碼,都加上預(yù)處理。途中藍(lán)色部分是模型的消耗時(shí)間,橘黃色部分是解碼消耗的時(shí)間??梢钥吹皆谖⒉┮曨l處理的測試場景里邊,解碼是非常耗時(shí)間。因?yàn)樘幚淼氖且曨l,每一個(gè)視頻它有非常多的幀,每一幀都要去做解碼,所以它耗時(shí)相對(duì)會(huì)比較長。
綠色部分是預(yù)處理的耗時(shí)?;旧?CV-CUDA 的預(yù)處理耗時(shí)可以忽略不計(jì),可能也跟我們的預(yù)處理不是特別復(fù)雜有關(guān)系。可能在你的環(huán)境里面測,如果預(yù)處理的復(fù)雜度特別高,可能會(huì)有不太一樣。

上圖是 OpenCV 使用 GPU 去做解碼的情況下,去對(duì)比這個(gè)效果。最下面還是模型的運(yùn)算時(shí)間,中間是解碼的時(shí)間,因?yàn)槎际?GPU 解碼,所以耗時(shí)是差不多的。在預(yù)處理這一塊,CV CUDA 已經(jīng)做得非常好了,預(yù)處理時(shí)間是非常非常短的,整個(gè) pipeline 的對(duì)比也是有提升的,大概 50% 左右。

最后一塊的內(nèi)容,具體在微博線上具體的業(yè)務(wù)中,在線上去做的測試,我們的目標(biāo)是在限定的硬件場景里邊,怎么樣去充分利用硬件資源,做到單位時(shí)間處理更多的數(shù)據(jù)。上圖可以看到用 OpenCV 去做預(yù)處理的時(shí)候,整體的 CPU 的利用率基本上已經(jīng)已經(jīng)漲滿,達(dá)到 300%-350% 。但此時(shí)它 GPU 的利用率它是偏低的,低于 10% 了。整體 pipeline 的 QPS 是零點(diǎn)八六,指一秒鐘處理零點(diǎn)八六個(gè)視頻。上傳 gpu 的意思是用 OpenCV 需要 GPU 上傳的數(shù)據(jù)量。
再看 CV-CUDA 的一些性能數(shù)據(jù),相對(duì)來講,它的顯存會(huì)占比較多一些。因?yàn)樗言紨?shù)據(jù)在 GPU上做解碼,相當(dāng)于做了展開。這樣原始的圖片在 GPU 上顯存上,它肯定會(huì)占得多一些,內(nèi)存的占用會(huì)少一點(diǎn)。這個(gè)時(shí)候它的 CPU 利用率降低了,同時(shí) GPU 的利用率提升了,整體的 QPS 提升了 70%,同時(shí)上傳的數(shù)據(jù)量減少了非常多。從資源的利用來看,通過兩個(gè)方面來討論,第一個(gè)是考慮 CPU 的利用率,要把 GPU 打滿,在 GPU的利用率只有 10% 的情況下,需要十倍的 CPU 才能把 GPU 打滿利用率。而對(duì)于使用 CV-CUDA 來說,CPU 和 GPU 的總體利用率會(huì)比較均衡。能夠使用更少的 CPU 資源把 GPU 的利用率拉到最大。
七、問答環(huán)節(jié)
Q1:請(qǐng)問有總結(jié)如何排查預(yù)處理瓶頸嗎?
A1:預(yù)處理瓶頸在你的整個(gè) pipeline 里面,你先得知道你的預(yù)處理在你整個(gè) pipeline 里面占的時(shí)間占比是多少。比如你占比多,肯定預(yù)處理是有提升空間的。如果它整體占比少,那基本上的耗時(shí)都在你的模型上。預(yù)處理做得再好,也不會(huì)對(duì)整個(gè) pipeline 的提升也不大。
Q2:沒太弄明白剛才您的 10% 是怎么算出來的,可以再講一下嗎?
A2:這個(gè)會(huì)跟測試的環(huán)境有一定的關(guān)系,這個(gè)地方可以初步地去算一下,如果 GPU 利用率是 10%。能把 GPU 打滿的情況下,Open CV 需要多少個(gè) CPU 和 CUDA 需要多少個(gè) CPU 這樣子去算的。
Q3:您說訓(xùn)練框架用的是 Python 是嗎?有 demo 可以參考一下嗎?
A3:我的分享主要是 CV-CUDA 在我們推理的環(huán)節(jié)里邊去做的。訓(xùn)練框架我們都是用的PyTorch,Demo 因?yàn)樯婕暗轿覀兙唧w的業(yè)務(wù)場景,涉及到我們業(yè)線上的代碼。不是特別確定能不能分享。
Q4:您介紹的 Open CV 與 CV CUDA的效率對(duì)比,那里圖表可以看到預(yù)處理速度有很大的提升。這里對(duì)比的預(yù)處理里面包含了 resize,包含了是如何打 batch 的。表中 batch 的 128 如何對(duì)比的細(xì)節(jié)可以再介紹一下嗎?
A4:預(yù)處理是包含 resize 的,如何打 batch 的話,CV-CUDA 本身就支持 batch。如何對(duì)比,這個(gè)是在一個(gè)限定了資源的情況下,我們通過多線程或者多進(jìn)程的方式,把資源用到最大的情況之下去做的對(duì)比。對(duì)于 OpenCV,我們會(huì)采用多線程的方式,CV-CUDA 會(huì)打 batch。
Q5:業(yè)務(wù) pipeline 總共是多少個(gè)算法?是剛才講的所有算法都包括了嗎?
A5:我這里講的只是其中的四個(gè)比較有代表性的。因?yàn)闀r(shí)間有限,我沒法把所有的都介紹一遍,所以就從這里面挑選了 4 個(gè)比較有代表性,同時(shí)也是挑使用了 CV CUDA 做了測試的場景的算法進(jìn)行了介紹。
Q6:鏡頭分割時(shí),有的非常短,有的有很長,是怎么控制的?
A6:其實(shí)長短對(duì)于我們的理解來講,影響不是特別大,可能有一些極端的情況。鏡頭的切換比較頻繁,這個(gè)時(shí)候可能會(huì)產(chǎn)生一些比較短的鏡頭。但是我們鏡頭的切割它只是第一步,后面還有模型去做這種預(yù)測和融合,所以它即使切得比較短,也不會(huì)太影響最終的結(jié)果??赡芎竺娴哪P屠镞厱?huì)根據(jù)前后卷的關(guān)系以及一些語義的信息做一些融合。
Q7:推理或者訓(xùn)練的時(shí)候從遠(yuǎn)程拉圖片數(shù)據(jù)比較慢,微博是怎么解決的?可以介紹一下嗎?
A7:拉數(shù)據(jù),訓(xùn)練或者推理拉數(shù)據(jù)。我們因?yàn)槲覀児緝?nèi)部的集群都是萬兆的帶寬,目前拉數(shù)據(jù)??赡芪依斫饽闶遣皇悄惆褦?shù)據(jù)拉到本地,又要下載純實(shí)盤。通常我們的做法是我們拉取圖片數(shù)據(jù)的時(shí)候是不會(huì)落到磁盤的。如果只是作為推理或者訓(xùn)練,直接拿到內(nèi)存,直接根據(jù) jpg 字節(jié)碼去做解碼了。包含 OpenCV,它也有這個(gè)功能,不需要存磁盤的。如果你去存磁盤,因?yàn)槭艿酱疟P的性能的影響,可能會(huì)有影響速度。我們的做法是在內(nèi)存去解碼 jpg 數(shù)據(jù)。另外一點(diǎn)是,把圖片數(shù)據(jù)下載,解碼,預(yù)處理,模型計(jì)算進(jìn)行并行化,各個(gè)模塊間通過隊(duì)列進(jìn)行通信。
Q8:請(qǐng)問 embedding 向量是多久更新一次?
A8:embedding 向量的更新,更新的頻次是根據(jù)業(yè)務(wù)上的需求來定的,我們通常在確定了更新之后導(dǎo)致的效果差異,在一個(gè)可以接受的范圍之內(nèi),我們才去做更新。如果業(yè)務(wù)上認(rèn)為我們 embedding 不好的時(shí)候,我們才會(huì)去更新的。
Q9:詳細(xì)介紹一下視頻分段 embedding?

A9:其實(shí)這個(gè)圖我是畫了一個(gè)統(tǒng)一的結(jié)構(gòu)圖。在訓(xùn)練的時(shí)候,它可以用 3 個(gè) loss 來訓(xùn)練。但是具體在我們做的時(shí)候,其實(shí)是分開來訓(xùn)的,當(dāng)然你要做成統(tǒng)一的訓(xùn)練也是可以的。所以這個(gè)地方訓(xùn)練每幀的向量,它是有一個(gè)對(duì)比學(xué)習(xí)的。這個(gè)時(shí)候是通過數(shù)據(jù)增強(qiáng)的方式,包含語音也是一樣,也是通過數(shù)據(jù)增強(qiáng)的方式來做對(duì)比的訓(xùn)練。有了幀向量之后,再去訓(xùn)練段向量的時(shí)候,這個(gè)時(shí)候也是包含語音和視頻的片段,也是做一些增強(qiáng),這個(gè)地方去做了一個(gè)對(duì)比學(xué)習(xí)。
至于向量對(duì)比學(xué)習(xí),我們會(huì)做一些不僅僅是通過增強(qiáng)的方式,因?yàn)樵鰪?qiáng)的方式很難去把視頻增強(qiáng)得非常的豐富。在我們的場景里面,還是有一些比如話題,比如標(biāo)簽之類的帶有標(biāo)注性的信息,有時(shí)候會(huì)使用增強(qiáng),有時(shí)候會(huì)比如從同一個(gè)話題里邊抽取,通過一些規(guī)則去篩,基本上基于這個(gè)規(guī)則之下,我知道這兩個(gè)視頻它有一定相同的語義含義。數(shù)據(jù)擴(kuò)展這一塊,第一個(gè)方面是有正向,第二個(gè)方面是通過規(guī)則篩出來的,它是一對(duì)正樣本的數(shù)據(jù)去做對(duì)比學(xué)習(xí)。



















