雲音樂FeatureStore建設與實踐

雲音樂技術團隊 發表於 2022-06-29

圖片來源:https://unsplash.com/photos/Z...

作者:卡妙

概述

在機器學習全流程的生命週期中,Feature Store是連線Data和Model之間的橋樑。他通過儲存和管理ML過程中的資料集和資料管道,減少特徵工程的重複工作,以實現高效率的特徵資料開發,縮短模型迭代週期。

從ML-Ops到Feature-Ops

標準的機器學習系統由”資料“、“模型”、“程式碼”三個部分組織而成,其分別對應著“特徵工程”“模型訓練”“模型部署”三個階段。他們彼此關聯和依賴,並在各自的階段承擔著重要的職責和功能,以完成整個機器學習過程的使命。

data model code

隨著AI應用的快速發展,並在人臉識別、廣告、搜尋、個性化推薦等領域有了大規模應用後,人們開始重視AI系統能力的基礎建設。各大雲平臺廠商陸續推出了一些通用的AI平臺來加速“模型訓練”“模型部署”流程,例如:AWS SageMaker、Google Vertex AI、阿里PAI等,這塊流程和系統,我們可以統一稱之為ML-Ops1

the extension of the DevOps methodology to include Machine Learning and Data Science assets as first class citizens within the DevOps ecology.

隨著AI平臺的普及和應用,“模型訓練”“模型部署”效率得到了極大的提升,而“特徵工程”作為整個機器學習流程的最初步驟,還停留在應用傳統的資料開發流程階段。為了滿足機器學習對資料開發的各種定製化要求,AI領域逐步開始探索針對機器學習場景的資料開發解決方案,於是承接ML-Ops的Feature-Ops誕生了,業內隨之也推出了一系列面向特徵工程的系統,並稱之為Feature Store,例如:Feast、Tecton、AWS SageMaker Feature Store、Databricks Feature Store。

Feature Store定義

最早提出並明確Feature Store的概念,來自2017年Uber的Michelangelo Platform2。他描述了Feature Store的主要目的是為了在機器學習過程中,促進特徵的註冊、發現以及複用,並且保證特徵資料在離線批處理和線上應用程式讀取時的一致性。其能夠提供高效能、低延遲的資料服務(面向線上的預估場景)和高吞吐、大容量的資料服務(面向離線的訓練和批預測場景)以供模型使用。

一個簡單而標準的Feature Store如下所示:

Feature Store

Music FeatureBox

FeatureBox解決的問題

在雲音樂,我們通過識別雲音樂演算法場景特有的業務問題,打造了雲音樂自研的Feature Store - Music FeatureBox。致力於解決以下問題:

  • 特徵發現/治理/複用:沒有中心化的管理,不同的演算法團隊通常無法複用特徵資料,特徵工程會佔用演算法工程師大量的時間,且還會造成計算資源和儲存資源的浪費。我們通過實現特徵後設資料的註冊與中心化管理,來幫助特徵發現/治理,以促進特徵複用,加速機器學習過程中的特徵工程效率。
  • 高效能的特徵儲存和服務:特徵資料儲存引擎在不同的場景有著完全不同的應用需求(訓練/批預估需要擴充套件性好、儲存空間大;實時預估需要低延遲、高響應),我們通過自研不同核心的儲存引擎(MDB/RDB/FDB/TDB),並封裝邏輯儲存層來路由不同的物理儲存引擎,在不同的場景使用不同的物理儲存引擎來滿足個性化的應用要求。
  • 模型訓練/預估使用的特徵資料一致性:用於訓練和預估的特徵資料往往因為不同的資料實現,而產生異構或者不一致,這會導致模型的預估產生偏差。我們在Datahub系統抽象出一層單一的資料訪問層,將模型和物理儲存隔離並解耦。通過統一資料訪問API和自動化資料同步任務,來保證訓練/預估使用的特徵資料一致性。
  • 特徵抽取&運算元複用: 因為計算的環境和資料上下文有所不同,通常模型的離線訓練和線上預估會各自實現一套特徵的抽取邏輯,這樣的做法不僅會帶來額外的開發工作量,還會造成因為跨語言、跨環境等因素所引起的計算精度不一致、質量風險和維護成本增加等問題。我們設計了一套跨語言、跨平臺的運算元庫&特徵抽取計算引擎,以達到一套運算元程式碼庫+統一的DSL語法配置能夠線上上/線下各個計算環境中生效。
  • 訓練樣本生產/管理:從特徵資料到最終餵給模型訓練的樣本資料集,往往會經過特徵篩選、特徵抽取、樣本取樣、樣本拼接等過程,FeatureBox通過標準的API規範了該過程的輸入和輸出,並支援自定義資料管道且託管了整個過程的資料管道任務,以實現特徵資料和模型訓練的無縫對接。
  • 特徵質量監控和分析:機器學習系統產生的誤差很大一部分是來自於資料的問題,FeatureBox可以通過統計儲存和服務中的一些指標,來幫助演算法工程師發現和監控這些資料的質量問題。其中包括但不限於特徵質量、特徵重要性、服務的效能等。

綜上所述,FeatureBox是一套針對機器學習場景定製的資料系統,用來解決Feature-Ops中所描述的問題,主要包括以下三個方面:

  • 儲存資料和管理後設資料。
  • 建立和管理特徵抽取管道。
  • 為模型訓練/預估提供一致性的資料服務。

FeatureBox整體架構

FeatureBox並不是單一的服務或者程式碼庫,而是一套完整的面向機器學習流程的資料系統。

FeatureBox是基於雲音樂自研的資料服務管理系統 - "Datahub" 構建起來的,整體的架構圖如下:

FeatureBox System

這裡面模組分別有什麼作用?他們之間的關係是怎麼樣的?下面我們來對其中幾個核心模組進行詳細的介紹:

Datahub

"Datahub"是FeatureBox中最核心的模組,可以說是整個FeatureBox的基石。他構造了一套抽象的特徵後設資料,並且封裝各種不同物理儲存的API,將所有對物理資料的讀寫都抽象成對特徵的操作。我們可以通過Datahub獲取特徵的Schema和Storage後設資料,並且可以在任意語言和環境中使用Datahub API訪問到你需要的特徵資料。通過Datahub,FeatureBox能夠讓演算法工程師對特徵資料的操作在離線/實時/線上等各種環境下,保持一致的體驗。

同時作為訪問Storage的Proxy,Datahub也包含了序列化、壓縮、埋點監控等切面化功能,以幫助使用者遮蔽一些技術優化項,實現更高的讀寫效率。此外,Datahub還能作為資料和物理儲存互動的攔截處理管道,新增各種自定義的處理過程(語法過濾、安全處理、快取優化等)。

datahub

Schema&序列化

​ 要想所有的儲存資料都有後設資料,首先要做的第一步就是設計一套標準的table schema,能夠表達目前所有業務資料的格式。而對於schema實現來說,最重要的就是value的序列化方案選型,我們需要考慮以下幾點目標:

  • schema要容易理解,能夠方便的擴充套件欄位
  • 支援跨語言的序列化方式
  • 擁有高效的編解碼效能和高壓縮比

​ 根據以上幾點,我們很容易想到兩個備選方案,一是json,二是protobuff,這兩個選型各有利弊,我們來分析一下。

json

​ 優點 - 很容易理解,擴充套件性也非常好,能夠相容各種語言。

​ 缺點 - 是string明文儲存,壓縮比和編解碼效能都不高。

protobuff

​ 優點 - 作為google老牌序列化方式,擁有非常好的編解碼效能和壓縮比,也有很好的跨語言支援能力。

​ 缺點 - 需要生成.proto來維護schema,不利於欄位動態擴充套件。(一個table增加欄位,可能涉及線上應用、flink應用、etl應用、spark訓練指令碼等多個地方變更schema)。

那麼有沒有辦法,即能擁有pb的高效效能,又能擁有json的擴充套件能力呢?答案是肯定的!

​ 我們調研通過PB庫中的com.google.protobuf.DynamicMessagecom.google.protobuf.Descriptors.Descriptor類來實現基於protobuff的後設資料管理和轉換,並通過開源庫protostuff來實現.proto檔案的動態編譯,從而將protobuff格式做到像json一樣可以直接通過Map<String,Object>來操作的便利性,並且不用多端同時更新發布.proto檔案。

​ 確定了value的序列化方式之後,構建table schema就容易多了。由於Datahub對於特徵服務只提供KV/KKV的資料介面,那麼我們定義的table schema只要在增加最為pk和sk的列就可以了,剩下的列就是value的pb schema。這樣我們就能即保證儲存引擎對於高效讀寫的要求,又保證了業務系統對於簡單易用的要求。

​ 例子:music_alg:fm_dsin_user_static_ftr_dpb

schema

自動生成protobuff

syntax = "proto3";
package alg.datahub.dto.proto;
message UserStaticFeature {
  repeated float userTag = 1;
  repeated float userLan = 2;
  repeated float userRedTag = 3;
  repeated float userRedLan = 4;
  SparseVector userMultiStyleSparseVector = 5;
  repeated float userRedSongTimespan = 6;
  repeated int32 userBaseFeatureStr = 7;
  float userAgeType = 8;
  float userRank = 9;
  repeated float userSong2VectorEmbedding = 10;
  repeated float userChineseTag = 11;
  repeated float userTagPlayEndRate = 12;
  repeated float userLanPlayEndRate = 13;
  repeated float userPubTimePlayEndRateAll = 14;
  SparseVector artistPlayEndRatioSparseVector = 15;
  repeated float dsUserTag = 16;
  repeated float dsUserLan = 17;
  repeated float dsUserRedTag = 18;
  repeated float dsUserRedLan = 19;
  repeated float fatiRatio = 20;
}
message SparseVector {
  int32 size = 1;
  repeated int32 indices = 2;
  repeated double values = 3;
}

Transform

"Transform"是FeatureBox除Datahub外的另一核心模組,他主要管理從特徵讀取到模型輸入的整個過程,是機器學習系統中特徵工程-模型工程銜接的紐帶。Transform是由FeatureBox中註冊的Feature後設資料、運算元後設資料等編排配置而成,他能夠跨語言、跨引擎的表達特徵抽取的執行過程。

與業內的Transform定義不同,這裡的Transform只是一個自定義DSL的配置描述,他表示的是整個特徵抽取的的計算過程,並不包括具體的任務和任務管道(相關部分在Job Generator和Web Console的任務管理功能中)。

Transform根據實際的應用場景不同,可以分為三種情況:

場景描述特徵獲取運算元語言(相容)輸出型別
離線訓練用於離線環境模型訓練的批量Transform從Hive/Hdfs獲取一個DataSetjava/scala/c++TFRecord檔案
線上預測用於線上環境模型預測的指定特徵集合的Transform從Redis/Tair通過Key查詢特徵集合java/scala/c++Vector<Tensor>物件
實時特徵(規劃)用於實時特徵生產的流式資料Transform從Kafka/Nydus獲取Streaming資料java/scala/c++動態ProtoBuf物件

我們可以通過同樣的Transform語法(MFDL)來表達不同環境和計算引擎的特徵計算執行過程,以產出最終需要特徵值:

Transform

關於我們Transform模組中的MFDL是如何實現和應用的,可以閱讀上篇文章雲音樂預估系統建設與實踐的內容,其詳細描述了MFDL線上上預估系統中的使用。

Monitor

當機器學習系統出現問題時,大部分的原因來自於資料問題。因為FeatureBox包含了所有的特徵儲存、特徵後設資料、特徵服務資訊等功能,所以他能成為一個非常好的特徵監控中心服務,來幫助整個機器學習流程定位和發現各種特徵資料問題。一般的情況下,我們主要會統計和監控以下三類指標:

  • 特徵基礎指標:“特徵基礎指標”是指基於儲存引擎的特徵資料的一些metrics統計,如特徵覆蓋度、儲存容量、新鮮度、分佈等。這些基礎指標可用幫助我們快速瞭解一個特徵的基本資訊,以方便具體的演算法工程師/資料開發工程師來使用或運維該特徵資料。
  • 特徵服務指標:“特徵服務指標”是指DataService/Storage等線上系統的實時執行資訊,如儲存指標(可用性/容量/利用率等)、服務指標(QPS/RT/錯誤率等)等相關指標。這些指標可以幫助你實時觀察和分析當前整個FeatureBox的線上系統是否穩定可用,以確保上游業務和APP提供的服務穩定可用。
  • 特徵/模型偏移指標:“特徵/模型偏移指標”是指通過特徵重要性、模型訓練/預測資料偏差等指標來表達特徵資料質量。因為隨著時間的推移或者一些突發的外部事件,可能會造成線上部署的模型的訓練資料和實際的預測資料之間產生比較大的偏差,從而造成模型效果下降,所以我們需要統計“特徵/模型偏移指標”來幫助維持生產環境中機器學習模型的效果。

關於特徵基礎指標和偏移檢測,FeatureBox的Monitor模組主要整合TFX中的Data Validation元件來實現對資料集的分析和監控。我們主要提供以下三種分析和監控功能:

  • 針對靜態資料集統計的視覺化分析。
  • 根據先驗期望Schema校驗資料集統計分析。
  • 採用雙樣本對比檢測資料偏差和漂移。

下圖詳細描述Monitor模組在整個機器學習流程中的位置和作用。

Data Validation In ML

示例:針對資料集的基礎統計資訊和分佈提供視覺化的檢視,以方便演算法同學排查資料異常問題。(原生的TFDV通過jupyter notebook執行指令碼以生成視覺化資訊,我們也可以通過採集每次統計的stats資料以展示到FeatureBox介面中)

統計檢視會將特徵分為連續值和離散值兩類,兩者都會有分佈統計(連續值採用標準直方分佈),另外連續值會有中位數、方差、標準差等統計。

TFDV_1

Storage

"Storage"是FeatureBox中的物理儲存層,負責儲存真實的特徵資料,並對上游的資料服務層提供資料的讀寫服務。根據不同的特徵應用場景,Storage模組可以分為離線儲存和線上儲存。

離線儲存:離線儲存通常應用在訓練或批預測場景,儲存近月/近年來TB級別的特徵資料,提供小時級/天級的批量讀寫能力。常見的離線儲存有HIVE/HDFS等。

線上儲存:線上儲存通用應用在實時預測場景,只儲存特徵資料的最新值,並有著高響應、低延遲的要求。常見的線上儲存有Redis/Tair/MySQL等。在雲音樂,我們為了滿足不同型別的特徵儲存要求和不同場景的響應要求,還基於Tair架構定製了儲存引擎核心,他們分別是:

  • MDB:基於記憶體Hash表的記憶體型儲存引擎,有著高響應、低延遲,儲存資源代價高的特點,通常用於儲存對響應要求非常高的小容量特徵資料的線上預測場景。
  • RDB:基於RocksDB的磁碟型儲存引擎,響應和延遲略不如MDB、但儲存資源代價更低,能夠支援資料批量更新Bulkload,通常用於儲存大容量特徵資料的線上預測場景。詳細內容可以閱讀之前的文章:自研磁碟型特徵儲存引擎RDB在雲音樂的實踐
  • FDB:基於FIFO Compaction策略的RocksDB儲存引擎,因為FIFO Compaction所以很適合儲存日誌型資料而不會帶來寫放大,通常用於儲存Snapshot特徵快照資料。
  • TDB:自研的時序儲存引擎,能夠根據不同時間粒度聚合計算資料,但響應和延遲要低於MDB/RDB,通常用於儲存帶時間欄位聚合的統計型特徵資料。

FeatureBox通過Datahub/DataService作為路由代理,將上層業務對特徵資料的讀寫路由並轉化到實際對應的Storage連線進行操作。所以使用者對底層的Storage的API和運維其實是不感知的,他們只是通過Web Console來定義Schema與選擇他們特徵資料更適用的Storage。這也促成了FeatureBox可以讓特徵儲存的管理、運維、資料遷移、快速失敗、擴縮容等工作變得更加方便。

FeatureBox Storage

結語

以上就是本篇文章的全部內容,我們簡單的介紹了FeatureOps和FeatureStore的定義和他所解決的問題,並以此展開講述了雲音樂自建Feature Store - FeatureBox的主要設計和模組功能,希望能給對特徵工程感興趣的小夥伴帶來啟發和幫助。因為篇幅問題,在整個Featur Store中還有非常多的細節沒有展開,大家可以關注後續的文章。