Golang 也許是推薦系統的銀彈

語言: CN / TW / HK

一個大規模的推薦系統維護需要耗費難以想象的人力,我試著從推薦系統最初的樣子說起。

2009 年在豆瓣實習第一次聽教授和胖子在聊協同過濾,我還以為是一種比 Bloom Filter 還要牛逼的東西。

2016 年加入第四正規化,我才有了機會去參與幾個推薦系統的設計。每當我們用奇技淫巧的特徵工程把訓練 AUC 做到接近 0.8,就有種「雄關漫道真如鐵,而今邁步從頭越」的感覺。

第四正規化有一句深入人心的 Slogan:「AI for Everyone」,有多深入人心呢,當時公司的 WiFi 密碼就是 ai4every1 。我就在想這種搞完離線 Sample 再去搞線上資料,搞完資料再去復現特徵工程的日子可真是很難「For Everyone」。

難以統一的離線和線上

咱就說,也曾幻想,要當年如果 Hinton 會的不是 Python,而是 C++……算了,有點離譜,那可能他還在研究牛逼閃閃的 C++11、17、20……如果當年 Hinton 會 Golang,那是不是咱當年就不用苦逼兮兮看著 Python 翻譯成 Java 了。

打住,假設我們有了一種語言像 Python 一樣省鍵盤,像 C++ 一樣拳拳到肉。模型訓練和上線是不是就變成了:

model = train(x, y)
# y1 = model.predict(x1)
model.serv(":8080")

分分鐘訓練完成,單機 10w QPS,哇嘎嘎。看來看去,目前也就 Golang 比較接近理想

edgeRec in Golang

也不太對,資料哪來呢,哪會有現成的寬表躺在那裡等你 Train 一發

對,Spark 這玩意兒真是秒啊,但要是線上召回也用 Spark 跑個 Job?那 QPS,不,應該是 SPQ(Second Per Query?) 還不上千。

打住,假設我們有了一種語言既能描述大寬表的形成邏輯,又能描述 Predict 的特徵寬表。不用假設,這就是 SQL 啊!

大——寬——表

回頭看,為啥這麼多年了推薦系統還只是幾個豪門大廠才能玩的呢,主要還是這玩意兒是 IT 界少有的學習曲線異常陡峭,對後端技能要求又很高的領域。這麼一來不可避免的就要分工很細,只有非常少數的人能從原理、演算法和工程上完整見識過工業界推薦系統的全貌。而這少部分人要麼是英年財務自由,要麼是在為 AUC 提升 0.001 而點燈熬油。

AUC: 你基本可以理解為是推薦系統的一個核心效果指標。

一般情況下:

AUC 0.3 你把 label 整反了

AUC 0.5 代表全選“鈍角”

AUC 0.7 就是一個使用者明顯感覺到“懂我”的指標

AUC 0.8 就是一個網際網路大廠及格線的水平

AUC 1.0 代表你是上帝

其實說白了推薦系統這 10 多年主要就發生了這麼幾個重大的進步:

  1. 2009~2015 LR + 精妙的特徵工程打敗了 SVM、協同過濾這些上一代的演算法
  2. 2012~2015 NN 改變了 CV、NLP 行業之後又殺回了推薦系統,把特徵組合這個傳統藝能的重要性大大降低了
  3. 2013 Embedding 被 Google 從故紙堆裡拿出來,而後被髮揚光大產生了 Item2vec 等,激發了大家對 User Behavior 的挖掘熱潮
  4. 2015~2016 Wide & Deep 激發了NN+各種老模型的“嫁接”
  5. 2016~2017 中間經歷了 XGBoost LightGBM 等一眾樹模型多快好省的強烈反撲
  6. 2017 Transformer 大行其道,以至於 Attention Is All You Need
  7. 2018~now 主要就是對特徵,尤其是使用者特徵的深挖,代表就是大名鼎鼎的 DIEN

一來呢,既然演算法都成“科學家”了,都用 Python 做出了牛逼閃閃的新模型了,那自然是不屑於關心什麼狗屁 Numa、非同步非阻塞、shared_ptr,剩下的事情你們這些工程師還搞不定嘛??

術業有專攻啊

不是俺們無能,是這玩意兒真是術業有專攻,不搞個三五年咋能出師,沒個五年八載咋能發 Paper。

坦白來說,對於大多數系統,無論是從積累的資料量還是從必要性上看,對推薦系統的需求肯定不是 AUC 從 0.75 → 0.76。而是,我有一些後端 CRUD 邏輯、一個 MySQL 資料庫、一個 SPA 前端,那能不能在某些關鍵的影響使用者體驗,或影響收入的列表上給使用者一個千人千面的推薦?

那麼需求應該是:

  1. 能基於常見的資料庫 MySQL、PG、SQLite 作為訓練樣本的資料來源
  2. 容易 PoC(Proof of Concept),容易對接、部署、請求一下看看效果
  3. 在老子嚐到甜頭之前,別想騙老子去學習線性代數買 GPU

於是乎,在經歷了這麼多之後,我用純 Golang 寫了一個集訓練、預估於一體的服務端框架。你只需要用 SQL + Golang 完成幾個資料介面的實現,就可以跑起來一個小型推薦系統: