1. 程式人生 > >OpenSearch演算法產品化探索與實踐

OpenSearch演算法產品化探索與實踐

        作為搜尋的使用者,我覺得最關心的是兩個方面:一是召回的結果是否符合預期,二是召回結果的排序是否符合預期。OpenSearch作為一個搜尋服務提供平臺,在這兩個方面我們提供了一定機制方便使用者定製自己的召回和排序邏輯。將搜尋這邊積累的演算法功能通過這兩個視窗開放給使用者使用,從而改善使用者的搜尋體驗。根據定製的粒度和開放的演算法功能的特點,我覺得可以分成兩個階段:自由定製時期和資料驅動時期。在自由定製階段,使用者可以組合我們提供的演算法功能,定製自己的召回和排序策略。在資料驅動階段,我們在自由定製的基礎上,廣泛使用使用者歷史資料(比如查詢日誌和行為資料)為使用者提供更加個性化的搜尋體驗,並提供一些功能方便使用者快速迭代和試錯,同時我們提供干預功能,讓使用者儘快修復badcase,最大限度的讓使用者參與進來。

自由定製時期OpenSearch演算法產品化特點

       自由定製時期對應於OpenSearch 1.0版本,在這個階段OpenSearch逐步健全了搜尋召回和排序定製體系,打通了召回和排序鏈路。使用者在OpenSearch控制檯中可以定製自己的排序公式和qp規則,並在查詢中指定失效,對於qp中產出的query資訊也會影響最終的排序結果。這一時期的演算法產品化功能可以用下圖描述,下面我們會從不同的方面進行介紹。

排序表示式定製

Ranking Formula       

      OpenSearch支援兩階段排序,粗排和精排。這兩個階段都支援使用者自定義排序表示式,只是考慮到參與粗排的文件數較多,所以我們限制了粗排表達式的長度和可以使用feature的個數。在後端實現上它們是同一套程式碼,走的是相同的邏輯,我們稱之為ranking formula。ranking formula從功能模組上講可以分成兩個部分,qrs外掛和searcher scorer外掛。qrs外掛主要用來做公式的解析和驗證,並將解析好的語法樹序列化傳給searcher。searcher scorer外掛是formula主要執行部分,它反序列化公式的語法樹,對每個命中的doc進行算分,並返回最終結果。從使用者使用過程上講ranking formula也可以分成2兩個部分,公式建立流程和查詢生效流程。使用者通過控制檯建立公式時,控制檯會實時將使用者的公式提交給後端進行驗證,如果驗證失敗會將具體的錯誤資訊返回給使用者,只有驗證成功的公式才用戶使用者儲存。公式建立成功之後,使用者可以將其設定成預設公式,這樣就會自動上線生效,使用者也可以在query中通過公式名直接引用公式(比如通過搜尋測試頁面測試公式效果)。查詢過程中也會對使用者的公式進行驗證,如果驗證失敗,此次查詢還會返回結果,只是不在使用公式進行排序。

      目前ranking formula支援的語法規則比較簡單,詳細可以參考ranking formula語法規則。在ranking formula中,使用者可以使用自己的attribute欄位,也可以使用一些數學函式或者是我們提供的一些特徵函式,通過對這些元素的組合從而定義出自己的排序表示式。

Feature Lib

        feature lib是排序表示式的重要組成部分,使用者通過我們提供的feature可以獲取doc在某個維度的分數,比如文字匹配分,距離分數等。目前feature lib支援的feature主要有3類:一是文字類feature,通過它可以獲取doc的文字匹配方面的分數,比如查詢詞和doc的匹配度,查詢詞在doc上的緊密度等;二是具有一定特殊功能的feature,比distance可以獲取2點之間的距離,tag_match可以用來做query和doc中kv的匹配;三是數學函式,比如normalize函式,decay函式等。我們通過不斷豐富我們的feature lib,可以為使用者提供很多強大的功能。

查詢分析定製

       查詢分析主要用於query改寫,query意圖識別等方面,通過查詢分析使用者可以擴大召回,獲取想要的結果。OpenSearch將查詢分析中常用的功能通過封裝開放給使用者,使用者在OpenSearch控制檯上通過勾選需要的供能即可定製自己的查詢分析策略。使用者可以通過控制檯上線查詢分析策略,也可以在查詢中指定使用哪個策略。查詢分析的用法和支援的功能可以參考查詢分析使用手冊

       查詢分析是DII進行實現的,DII支援鏈式處理而且支援在查詢中指定策略,但是策略要在配置檔案中提前定義。對於OpenSearch來說,每個使用者定義的策略是各不相同的,但是後端系統配置不可能隨時變化。為了能夠支援不同的使用者使用不同的策略,我們再系統配置上定義了一個完整的chain,並且在查詢的過程中動態組鏈。從上圖也可以看到,整個查詢分析處理過程不僅僅是我們提供出去的那些功能,還有一些內建的處理邏輯,比如normalize和分詞等,這些處理邏輯在DII上都實現為獨立的processor。當查詢執行時,我們會根據使用者選擇的功能和內建的處理邏輯重新組鏈,這樣就可以支援不同使用者使用不同策略。

       對於OpenSearch來說,我們的使用者是B類使用者,我們接收到的query是使用者加工過的query,是帶有AND OR等運算子的query。查詢分析要處理的只是最終端使用者輸入的查詢詞,如何識別出這些查詢詞是OpenSearch查詢分析需要考慮的。我們發現,使用者最常用的加工query的邏輯為將終端使用者輸入的查詢拼上一些條件比如AND status:'1',而且這些條件的索引和終端使用者的索引往往不是同一個。所以,我們規定使用者的查詢詞前面必須指定要查詢的索引,在查詢分析時只分析特定索引下面的查詢詞。因此,我們在查詢分析前會將使用者的查詢parse為語法樹,在遍歷這顆樹的過程中只對特定索引下面的查詢詞做處理。

多種型別分詞器支援

       分詞在離線索引構建和線上查詢,查詢分析中起著非常重要的作用,分詞結果的好壞會直接影響檢索結果和相關性排序。OpenSearch目前支援多種型別的分詞器,比如中文基礎分詞、全拼分詞和簡拼分詞等,詳細資訊請參考OpenSearch分詞器介紹。在產品上,OpenSearch分詞器經歷了從欄位型別與分詞器繫結,到索引與分詞器繫結兩個階段。在欄位型別與分詞繫結階段,我們每新增一個分詞器就要新增一種欄位型別,而且使用者在使用時對於同一個欄位如果要使用不同的分詞器那麼就要將一個欄位複製成另一個不同型別的欄位。這大大增加了系統的複雜性和使用者的使用成本。舉個例子,之前我們會有TEXT、SWS_TEXT、NWS_TEXT、MWS_TEXT、ENG_TEXT、SHORT_TEXT,每種欄位型別就對應一種分詞,使用者title欄位要使用通用分詞和單子分詞,那麼title要設定成TEXT型別,title_copy要設定成NWS_TEXT型別。為了減少系統的複雜性和使用者的使用成本,我們通過優化schema編碼結構,將欄位型別和分詞器解綁,分詞器只和索引相關。這樣如果使用者title要使用通用分詞和單字分詞時,只需要在設定索引時建立一個title索引,使用title欄位分詞器為通用分詞,建一個title_single索引,使用title欄位分詞器為單字分詞。在不同場景下使用不同的分詞器,極大豐富了使用者搜尋形式和搜尋結果的多樣性。

資料驅動時期OpenSearch演算法產品化的探索

       OpenSearch上的使用者來自各行各業,每個行業的資料都有其特殊的地方。OpenSearch第一階段提供的演算法和模型是基於全網資料訓練出來的,在適配到各個使用者時不可避免的會出現一些badcase。面對這些badcase,使用者最自然的需求就是希望能對其進行干預。針對我們提供的分詞和查詢分析,使用者希望能夠干預分詞結果,干預停用詞、詞權重、同義詞、糾錯等處理結果。另一方面,隨著淘寶千人千面的巨大成功,搜尋結果個性化的需求越來越多,使用者希望我們能夠提供更豐富的feature,幫助他們獲取更好的排序效果。同時使用者還希望我們能夠提供快速試錯,快速驗證的功能,方便使用者快速迭代。從OpenSearch自身來講,我們返回給使用者搜尋結果之後獲取不到使用者的反饋,不知道返回的結果是否滿足使用者的需求,我們和使用者之間缺少反饋機制,不能利用反饋來迭代我們的演算法。

       根據使用者反饋的問題和OpenSearch自身發展計劃,我們開始了新一輪的演算法產品化探索。首先我們提供了針對badcase的快速干預機制,提供了使用者行為資料收集機制,提供AB test和資料報表功能方便使用者進行快速迭代和效果評估。同時,我們升級ranking formula為指令碼語言,讓使用者可以定製更加複雜的排序邏輯。利用使用者的查詢日誌和行為資料,結合使用者的原始文件為使用者提供更加高效的演算法功能,豐富我們的feature lib。在訓練使用者資料的過程中,我們總結了通用的機器學習流程,並沉澱到演算法服務平臺,可以讓高階使用者干預模型訓練過程。這些功能有的已經支援,有的正在進行中,下面我們詳細介紹。

自定義分詞

       為了方便使用者干預分詞結果,OpenSearch在產品上支援了自定義分詞器。使用者的自定義分詞器由系統分詞器和使用者自定義詞典組成,分詞時會同時載入系統詞典和使用者詞典,從而實現干預分詞的目的。在實現上,我們使用alinlp替換了aliws,並基於DII構建了分詞服務。在使用者索引重建時,如果使用者使用了自定義分詞(資訊儲存在使用者schema中),對於使用者的doc,processor分詞時會訪問分詞服務獲取分詞結果。在查詢過程中,agg會根據應用是否配置了自定義分詞來決定是否訪問分詞服務,對於訪問了分詞服務的查詢會設定對應的index為不分詞,這樣qrs就不會做二次分詞了。自定義分詞的實現邏輯可以參考OpenSearch自定義分詞服務

干預服務

       隨著我們提供的演算法功能越來越多,出現badcase之後使用者需要干預的地方也會越來越多。干預服務制定了統一的標準和流程,方便的對接各個演算法模組,快速實現對某個功能的干預。干預服務本身不涉及都具體的業務邏輯,它只是接收使用者的干預詞條,並將其推送給對應演算法模組實時生效。目前依託干預服務,我們實現了對停用詞、詞權重、同義詞和糾錯等功能的干預。干預服務的實現細節可以參考OpenSearch線上干預服務

多版本的支援

       使用者在日常使用和功能升級過程中,不可避免的會有索引重建的需求。在OpenSearch之前的實現中,應用在OpenSearch內部只有一個例項,索引重建都是在這個例項上進行的。如果使用者的修改有問題(比如schema修改錯誤)或者資料來源用問題,索引重建會直接影響線上的服務。而且索引重建週期比較長,從發現問題到恢復的週期很長,對線上服務的影響會很大。為了減少使用者變更對線上服務的影響,方便使用者快速的回滾,我們引入了多版本概念,即一個應用在OpenSearch內部可能會對應多個例項。多個例項之間資料隔離,例項之間可以自由切換,所以當發現問題後可以秒級切換到老的例項繼續提供服務,系統健壯性大大提高。目前OpenSearch對一個應用最多隻支援兩個版本,OpenSearch多版本可以描述如下圖所示。

 

AB test功能

       為了方便使用者快速迭代和試錯,OpenSearch提供了AB test和實驗指標統計功能。藉助內網成熟的AB test實驗平臺hyperspace,OpenSearch搭建了自己的AB test系統,並且為了方便使用者的使用做了一些概念的抽象和功能的封裝。得益於OpenSearch以前的設計,查詢時可以根據公式名或者qp規則名直接引用相關的公式或qp規則。在設計AB test實驗時,我們支援使用者將粗排和精排公式,查詢分析規則甚至是演算法模型名稱做為獨立的實驗引數。查詢時根據流量分配因子,決定查詢是否命中實驗,命中實驗時用實驗的引數替換查詢中的引數,這樣即可對不同的排序公式和查詢規則進行實驗對比。OpenSearch AB test功能的架構如下圖所示,具體的使用和實現細節請參考ABtest在OpenSearch上的設計與實現

AB_test_flow

行為資料收集

        OpenSearch將搜尋結果返回給使用者之後,我們並沒有提供一種機制來回收使用者的反饋,整個搜尋鏈路還未完全打通。我們不知道我們返回的結果使用者是否滿意,我們也拿不到終端使用者的反饋幫助使用者改進其搜尋體驗。同時,我們希望將主搜這邊沉澱多年的演算法輸出給外網使用者使用,這些演算法模型的訓練都需要使用者的行為資料。因此,收集做為演算法模型訓練基礎的行為資料就變的異常重要。目前OpenSearch支援server端行為資料收集,即使用者可以將收集到行為資料通過API推送給OpenSearch,至於web端和移動端採集目前還未支援。為了方便內網使用者使用,OpenSearch行為資料採集所支援的行為資料格式和內網UT的格式一致。這樣內網使用者如果需要對接OpenSearch只需要將UT採集的資料轉發一份給OpenSearch即可。關於行為資料收集的實現細節請參考OpenSearch資料採集介紹

排序表示式語言化

       ranking formula在實際應用中存在一些問題,首先為了控制粗排和精排開銷我們限制了formula的長度,比如粗排限制只能使用4個元素,而且僅限線性運算,二是formula中不支援變數定義,三是不支援迴圈操作,四是無法直接引用引擎中的資料比如match doc。所以說ranking formula只能基於我們提供的feature使用者做簡單的定製。我們希望能夠將formula發展成一種語言,可以解決上面4個問題。使用者使用這個語言可以線上開發自己的算分外掛,實時開發、實時測試、實時上線。目前引擎同學已經做了一些工作,OpenSearch需要在此基礎上做一些包裝提供給使用者使用。關於排序表示式語言化的底層實現細節可以參考cava

演算法服務平臺建設

第一次試水--類目預測功能

       在構建類目預測和行為資料收集等演算法產品化基礎設施的同時,我們也在考慮將集團內成熟的演算法功能開放給使用者使用。我們以類目預測為原型開始了第一次試水。類目預測是電商領域一個非常重要的特徵,對搜尋結果排序有著非常大的影響。我們抽象了類目預測模型訓練與生效流程,架構圖如下所示:

        使用者在前端控制檯建立其類目預測模型,設定模型訓練所需的引數,比如title欄位與類目欄位,並將其儲存下來。離線訓練任務可以手動觸發,也可以定時觸發,整個訓練流程由rainbow控制。rainbow首先呼叫sync service將使用者的訓練資料匯入到odps中,然後呼叫aflow執行預先定義好的模板進行類目預測模型訓練,最後rainbow呼叫autoumars(qp ops)將訓練好的資料切換上線。訓練資料除了使用者的原始doc外,還需要使用者的查詢日誌和點選日誌。Agg會記錄使用者的查詢請求,通過sls將日誌同步到odps,通過日誌解析job可以得到每天每個應用的查詢日誌。至於點選資料,我們支援使用者通過odps上傳自己的點選日誌(query:click_count格式),也支援使用通過我們行為資料收集得到的點選日誌。

演算法服務

       在支援類目預測過程中,我們發現類目預測模型訓練對使用者來說就是個黑盒子。首先使用者不知道自己訓練資料的質量情況,其使用者不知道自己訓練資料經過了哪些處理,再次使用者無法干預模型的執行,無法調整模型的引數,最後模型訓練的效果只能通過AB test進行測試,反饋週期過長,對於一些明顯的錯誤發現的較晚。同時,我們調研了下期要開發的演算法功能,比如人氣模型和CTR預估等。我們發現這些模型訓練(機器學習)其實是有些固定的流程的,比如資料處理,特徵工程,模型訓練,模型評估等。我們希望能夠提供一個演算法服務平臺,在平臺中抽象出機器學習流程,在每個流程中提供多個選項供使用者選擇。這樣對於初級使用者可以直接使用我們提供的演算法功能,對於高階一些的使用者可以通過我們的平臺進行特徵工程,調整模型訓練引數從而對我們提供的演算法模型進行定製。演算法服務在OpenSearch體系中的位置如上圖所示,底層依託於集團強大的演算法訓練平臺,為OpenSearch查詢理解、排序和其他搜尋外圍功能提供模型訓練能力。關於演算法服務的其他內容請參考OpenSearch演算法服務

小結

       OpenSearch從立項之初到現在從未停止過對演算法產品化的探索,在機器學習深入人心大行其道的今天,我們才剛剛起步。我們希望通過OpenSearch將淘寶演算法多年的積累,以更低的門檻開放給更多的人使用。作為一個平臺型的產品,在提供低門檻的演算法功能的同時,可定製化是不可或缺的。只有可以定製化,讓使用者參與進來我們的平臺才會更有活力,才能解決不同使用者的問題。