Chat with Milvus #15 回顧-混合查詢功能要來了?Milvus 未來增加Scoring & 按閥值搜索功能?...

| Milvus Q&A 與文字實錄


Attendee= 參會者

 

Attendee A:我看你們以圖搜圖的基本上給的例子都是一個 general 的圖,比方說是個牛、羊、人這樣。我想問的一個場景就是說假設我們針對這個文檔圖片的這種搜索,當然OCR(Optical Character Recognition,光學字符識別)是一個方向,但我們想假設我們不用 OCR 有沒有什麼方式可以提取這個 feature,然後能更快的找到和文檔比較相似的另外一個文檔的這樣一個圖片,就從純圖片的角度去考慮這個問題?

 

顧老師 @ Milvus:你的場景能不能跟大家介紹一下?因爲文檔如果你是純用圖片來搜文檔的話,如果你用白紙黑字的那種的話,我覺得應該會比較的困難。因爲從機器視覺的角度來看,模型來說,白紙黑字的東西其實都差不多。

 

OCR 當然就可以把文字具體的提取出來,你可以把文字提取出來,你再做關鍵詞搜索也好,或者再做語義的搜索也好,我覺得都還能處理。如果你只是想從整體圖片上的話,我覺得感覺現在的這個模型應該都沒有爲這些去做。

 

Attendee A:因爲我看你們基本給的例子都是說我一個圖片出了一個向量,我想問一下有沒有什麼方法,比方說我一個圖片出了不止一個向量,然後我再去做一些搜索之類的東西?

 

顧老師 @ Milvus:也可以阿,你先做一次目標的偵測,看看這當中有一些什麼樣的目標能提取出來。 因爲是這樣,就是說當然現在也不是所有的目標都提取出來,可能人們比較關注的一些什麼動物的或者說人臉的這些這些對象能夠提取出來,相對來說你是可以針對這些對象做一些有主題的搜索,這是可以做到的。包括我們現在給的以圖搜圖的例子當中,其實它應該是可以在圖片框選一部分去進行一個特定區域的搜索,我們現在的例子當中是可以做這個的。當然那個例子比較簡單,還沒做這個事,但是我們接下來會給大家發一個開源的以圖搜圖的一個東西的話,它就會結合一個目標檢測,然後先提取這種相關的目標,然後再去進行搜索,會有這樣的元素在裏面。所以你主要是關注什麼領域的?

Attendee A:我的場景就是說,可能我這邊有一些 general 的文檔,然後可能用戶他不一定說像我們掃描儀或者怎麼着,做的特別乾淨規範了,然後 OCR 實際上像用戶比方說手機隨便照了一張圖,但是實際上 OCR 有很多時候的效果並不好,就是有些亂七八糟的東西。所以我想問一下圖搜圖這個東西是不是說可以解決相關的問題?

 

顧老師 @ Milvus:這比較困難,除非這個文檔是一模一樣的。


Attendee B:我比較感興趣的是向量檢索它索引,如果我除了檢索向量能不能複合一些其他的字段,比如說一些整型的字段?比如說我還有一些數字字段一起復合的查詢?

 

顧老師 @ Milvus:這個是我們在接下來,應該是下下一個 release,會做一個這種向量結合屬性的混合查詢。當然屬性我們一開始會相對來說規定得簡單一點,它都是一種編碼的屬性,這個屬性可能就是 12345,這 12345 什麼含義,可能就是在你自己節點創建個碼錶,就有點像阿里雲上的以圖搜圖,它電商的場景就是這樣,1 就是上衣,2 就是褲子,他會給你加一個碼錶,這相對來說會比較簡單一點,而且它會性能會好一些。因爲這些屬性它其實我沒有存的話也得和向量存一起和索引存一起的,所以屬性的部分如果佔的比例太大的話,其實對於內存什麼都會有一些的影響,所以我們會先把它做一個比較簡單一點的方式。所以您這邊主要關注的是一個什麼樣的場景?

 

Attendee B:我這邊可能還是圖片爲主,做一些比如說相似相同圖的召回。

 

顧老師 @ Milvus:你的圖片當中是有標籤的是嗎?

 

Attendee B:對,比如說像你說的這種像衣服,比如說圖片的,比如說它的質量這樣的一些東西。

 

顧老師 @ Milvus:因爲現在我們是可以做一個分區,在整個的 collection 上可以分區

。分區是根據一個屬性字符串來進行分區的,它的屬性字符串它可以是一個聯合的,比如說它也可以是一個紅色的車或者紅色的小孩這種方式,去構建這樣一個字符串,來作爲它的屬性去區別它的分區。這方式不是特別的靈活,但在一些場景下也能夠幫到大家現在。你們現在圖片大概會有多少呢?

 

Attendee B:圖片應該不多,可能五六千萬。

 

顧老師 @ Milvus:五六千萬的話,我們最近有一個做企業大數據的用戶,他是做企業的商標搜索,差不多是 5500 萬的圖片。還是比較快的,大概幾十毫秒。

 

Attendee B:幾十毫秒是那種 batch 的,還是說一張一張這麼查下來是幾十毫秒?

 

顧老師 @ Milvus:一張一張這麼查下來,因爲它的場景是一個互聯網 APP 當中的這種場景,所以他都是一張一張這樣子的。

 

Attendee B:確實還是比較快的,如果我要是有 5000 萬圖片,我們是對服務器要求大概是多少 G 的內存?

 

顧老師 @ Milvus:這個的話您可以在我們的網站上面,我們有一個 sizing tool,在上面

你可以把你的數據量,然後你所選的索引類型輸入進去,它就會告訴你大概會消耗多少內存。

 


 

Attendee C:我們現在向量實際上都是會落盤的對嗎?但是我們提供的主要功能還是去檢索的,然後這時候檢索的實際上是返回到它的向量的 ID 對吧?這個時候我其實是可以利用 ID 去檢索到它對應的向量的值的對吧?我想知道你們這邊有沒有測過讀向量的時候,這個性能是怎麼樣的?

 

顧老師 @ Milvus:通過向量 ID 拿向量這個功能之前的實現確實是有點慢。大家反映取向量本身比搜這個向量要慢的多一些,這部分我們在後續的版本當中是在不斷的優化性能的,因爲我記得好像是接下來的 6 月的版本當中應該是會對從 ID 獲取向量的性能會有一些提高的,因爲我們嘗試了一些不同的實踐的方式。通常來講您是什麼樣的向量存在裏面,需要去把這向量取出來呢?

 

因爲之前我們好像是有一個音頻類的用戶,他是做音頻類的這種 app,他們好像提到說他們很需要把向量取出來。聽下來感覺是說用的場景是類似於說是一種推薦的場景,可能是一種傳統機器學習的稀疏向量,那個向量它可能是帶了一些用戶的標籤的屬性的,所以他想把這個向量拿出來。我不知道您這邊把向量取出來的原因是什麼樣子的呢?也方便我們更多的瞭解。

  

Attendee C:我這邊的話是文本向量,拿到原始向量的話,是爲了送到排序,一個是送到打分模型裏去打分,因爲它相當於一個特徵。

顧老師 @ Milvus:對,但你打分模型是什麼樣子的呢?因爲我理解是你搜完把它最接近的都找出來,不就可以了嗎?爲什麼會要對這個向量本身去進行一個打分的計算?

它是個什麼樣的原理,你能不能給我們介紹一下?

 

Attendee C:它是一個文本分類的原理,我們所有的拿出來都是相當於是句向量,然後我們會輸入到一個文本分類模型裏面,然後把召回的這些向量輸入到文本分類模型,會拿到一個它屬於各個不同類別的分佈的概率,然後這個概率的值實際上是我拿過來做排序的一個條件。

顧老師 @ Milvus:就是說相當於說你搜索完一遍之後,其實還是需要做一些 scoring。其實這個就是我們在上一次的 Chat with Milvus 講整個整體的成長期的願景當中也提到了,我們是希望把 scoring 的功能也放在 Milvus 裏面,這樣的話你拿你的向量出去就是爲了做一次 scoring,如果我們可以在 Milvus 內部就給用戶開放這樣的 scoring 的自定的接口,相當於說你就不需要再傳輸這些向量出去,我可以內部就幫你全部都做完,搜索完再做完,scoring 再把結果返回給你,這樣的話效率會高一點。

 

Attendee C:對,我們現在的做法就是把它寫到了緩存裏,但是非常喫內存。

 

顧老師 @ Milvus:對,肯定的。所以回頭你可以跟我們分享一下您這個 scoring 的模型它的算法大概是什麼樣子的,我們也想看一下說這塊它的 scoring 的複雜度究竟有多少。因爲我們其實像支持混合查詢、多模態,然後用戶自定義的 scoring,這些其實我們都想去做,但是 scoring 這塊的話,我們還是想知道用戶究竟他 scoring function 的複雜度是什麼樣子的?能不能夠沉澱在 Milvus 引擎裏面,還是說我們會需要一個插件附着在 Milvus 的外部或者上面一層。所以很需要大家的這些反饋,然後讓我們去更好地設計未來功能怎麼去實現。

 

Attendee C:明白,我們現在這個模型是一個雙向的 LSTM 模型。

 

顧老師 @ Milvus:所以他在做最後的 scoring 的時候,就是每一條向量去進行計算,然後給向量打一個分就可以了是嗎?

 

Attendee C:對。

 

顧老師 @ Milvus:所以你比如說在您這邊的自然語言處理的場景當中,其實是先從模型到向量,然後再由向量進入一個打分的模型,就是從模型到向量再到模型,最後出現了一個我不知道你的結果一般會是一個什麼樣類型的結果?

 

Attendee C:我最終拿到這個分佈之後會綜合一些特徵,然後拿個排序,最終會返回一個文本。然後我還想問一個問題就是說,因爲我們現在存儲的這方面實際上是 LevelDB 和 RocksDB 這種類似的結構,但是他們的讀的性能都很慢,你這邊後續的優化的策略是什麼呢?

 

顧老師 @ Milvus:後續的優化策略的話,應該其實是可以做一些索引的。我不知道在你們的自然語言場景下,你們會給向量指定 ID 嗎?還是說可以接受向量系統自動生成?

 

Attendee C:這個的話一般情況下我們是自己有一個 ID 生成的工程,給他先去拿一部分 ID,然後把向量匹配上,如果新的向量來了, ID 不夠了,我再去拿 IP 是這樣的,相當於也是系統生成的 ID 但是可能生成的方式不太一樣。

 

顧老師 @ Milvus:其實相當於是你們的在應用這一層,還有一個全局的 ID, 希望在所有的系統當中都用這個 ID。這塊的話我們是在想怎麼樣去優化,今天有一些思路,之後會在羣當中給你回覆,跟大家介紹一下。

 

我們其實這個月最重要的工作,就是在給我們所有的 Milvus 做 reference,就是讓大家更能夠了解背後的一些原理,因爲現在的文檔可能更偏向於是一個簡單的使用指南,就是這個東西怎麼弄,然後參數是什麼,但是對原理的介紹目前是比較欠缺的,所以這部分我們是在這個月其實是集中精力在補充這部分的內容。

 

Attendee C:這個挺好的,我因爲這樣看源碼有一部分參考,但因爲有的時候那就是內部設計還是比較複雜的,看起來挺頭疼的。然後我還有一個問題是我們雖然現在的都是單節點的,我想做成高可用節點的這能怎麼辦?你下面的向量好像沒有這種就構建完索引沒有同步的機制。

 

顧老師 @ Milvus:是的, 我們現在分佈式的方案相對是一個支持分佈式擴展,並沒有兼顧到高可用的需求,高可用我們之前更多的是類似於這種 keep alive 的方式去做的(可產考 Milvus實戰 | 基於Keepalived的高可用方案)。然後數據的共享還是交給了這種共享存儲去做到這樣一個不同節點之間的共享。因爲這部分的話從先期來看的話,大家對於分佈式集羣的需求其實就是說問的話大家都會說需要,但是在實際的使用場景當中,從目前的角度,我們發現在這塊 AI 相關的東西的話,其實更多的可能還是受限於成本和硬件的規模,其實大家很多的都還是在這種單節點的在做部署。所以我們前期的精力都集中在把單點的性能和功能和它的穩定性都能夠先做好。我們現在單點也增加了WAL (可參考Milvus之WAL介紹)去提升整個單點的可恢復性。

 

在後續的話確實我們也在考慮怎麼去把分佈式擴展,其實我們已經有一些思路,但是怎麼去結合高可用這些的話,我們還是在研究當中,看看怎麼找到一個能夠讓大家都覺得比較合理的方式。因爲其實分佈式的問題大家都很關心,但是分佈式如果帶來了比較多的內存消耗的話,大家可能在成本上也可能不能負擔,所以這個東西我們也很糾結應該是什麼樣子的。


Attendee D:我們這邊在構建一些 embedding 的東西,但是它的量都比較大的,可能差不多在四五億這樣的一個級別。然後我們是希望有一個離線的這種 batch 的方式去把兩兩的去計算兩個 pair 之間的相似度,並不是點查的那種方式,所以我在想是直接用你們開源產品,還是說我們在基於這種 Spark 去構建一個這種分佈式的離線的這種計算這樣子,其實我這方面沒有什麼特別經驗,想和你們確認一下。規模大概是四五億的這樣一個規模,然後每一個點可能大概是在 50~100 的這樣的一個 dimension。

 

顧老師 @ Milvus:每個點在 50~100 維其實還好。

 

Attendee D:我初步的一個想法,是不是我就遍歷一遍就好了。我所有的這些 item,然後我就遍歷一遍,然後就可以算出每一個 item 對應的那個 pair 對的相似度,我不確定這樣的玩法行不行。因爲我瞭解到很多用這個 tool 的話,它都是一個點查的這種方式。

 

顧老師 @ Milvus:其實批量也是挺多的,但是你剛纔說的搜索,你是要求什麼樣的相似度?就是說比如說你的一個批量,我假定說有 100 條,每一條你是要查它的相似度是查什麼呢?是他的這四五億當中和他最像的前 1000 個嗎?還是前 100 個這樣子?top多少?

  

Attendee D:其實我們有幾種場景,其中一個場景就是說我們是需要...其實不是那種 KNN 的方式,我們是需要兩個, 就一個 pair 我們會算出一個相似度,比如說算一個 Jaccard 相似度。

 

顧老師 @ Milvus:你這一個 pair 怎麼理解呢?

 

Attendee D:比方說兩個 item 之間,我們會把它 embedding 成一個向量,然後再用比如 Jaccard 或其他一些 metrics 去計算相似度。

  

顧老師 @ Milvus:就是你計算 Item A 和 Item B 的 Jaccard 相似度。那你在做批量的時候,你的意思是說比如說我取出了一個 Item A 我需要去和這四億條都做一次相似度的比對?

 

Attendee D:我們是想找出超過一定閥值的所有 pair,比方說他超過一定閥值但它並不是超過一定數量。

 

顧老師 @ Milvus:這個向量是從深度學習的模型出來的嗎?還是一些規則生成的?

 

Attendee D:你可以理解成是模型出來的,所以說裏面應該不會有太稀疏的東西在裏面。

 

顧老師 @ Milvus:明白。所以這種情況的話,其實很多的人使用我們去都是在做批量的,但是當中有一個就是說,我們現在主要是支持的是這種取 Top 的形式去進行搜索,就你 top 1000、top 500 這樣子。Threshold 的這個方式,就是我們會在未來的版本當中進行支持,但是現在的話我們並不是按 threshold 來支持。

 

Starlord @ Milvus:我有一個小問題,像閥值的話你們在實際中是怎麼定閥值的?

 

Attendee D:閥值現在沒有一個特別好的自動定的方式,也是需要有一定探索的。

 

Starlord @ Milvus:或者說爲什麼你要定閥值,用 topK 做不會更好一些,爲什麼你那個場景一定要有閥值?

 

Attendee D:就是說你要定義它相似度的話,因爲相似度的話它肯定有一個量,比如說你是你要多相似,你是要 0.9 的相似度還是百分百相似,還是百分之六十的相似,但是其實相似的話我們並不知道,比如說我們定了個 70%,我們並不知道 70% 的相似裏面的  pair 會有多少。

Starlord @ Milvus:對,所以其實在深度學習這個領域裏面,其實沒有這個說法,說70%的相似度的,就是這個東西是無法去衡量的。或者說你發現你物品 A 去換了一類物品或者換了一個模型以後,你這個閥值都會有很大的一個變化。

 

所以其實如果你要用閥值去做一個裁剪的話,這可能是一個永遠你都不知道閥值怎麼選的一個無解的問題。之前我們也探討過這個問題,可能比較難(實現)。物品 A 跟物品 B 這個去比的話,就說他這樣的閥值的話,你會發現差異會特別大。

 

顧老師 @ Milvus:這個我覺得這個要看,因爲他剛纔講到的是 Jaccard 相似度,所以你 Jaccard 的相似度背後的實際的東西是什麼?什麼東西抽象成的向量?

 

Attendee D:我們現在一方面有可能是在 Risk 的場景去用的,所以說不是特別方便透露特別多細節,但是基本上我們之所以沒有考慮到取 topK 的那種用法的話,因爲我們現在是沒辦法知道我們跟它相似的是我們需要抓取的 k 是要定多少好。

 

Starlord @ Milvus:明白, 你剛纔說的 risk 的話,我大概會理解你的含義的。因爲就是說在金融做風控這樣一些領域的話,其實你也是不能說用 topK 的,因爲 topK 的話你有很大的一個這種 false positive 是這樣的話你是不敢要的,對不對?

 

Attendee D:是的。所以我感覺像這種場景的話,用我們這個工具的話,我就非常暴力的去遍歷一遍,我不確定這種做法可不可行。

 

顧老師 @ Milvus:暴力的去遍歷一遍當然是可以的, 還是回到這個問題,你的服務的  SLA 是什麼樣子的,如果你只是每天跑一次批量,形成一個 report 的話,其實你遍歷一遍也行,因爲他可能給你的 SLA  的時間會特別長,那其實你怎麼做空間很大。那如果你想做一個實時風控的場景,你希望在比如說出現問題的 5 分鐘之內得到提示,或者說甚至 30 秒鐘之內得到提示,你肯定就需要不能暴搜,你肯定得去用 ANN 的方式,這樣的話你纔有可能去做實時風控的事情。 

 

Attendee D:實時是另外一種策略了,我們現在只關注離線的這種。然後我現在想我是用 Spark,然後再加上實現一些 ANN 的算法去分佈式的去把這個事情搞定了,還是直接單機去部署一個我們開源工具就直接用了,還是在探索的過程當中。所以如果你們那邊有一些已經現成的一個經驗的話,我可以借鑑過來,然後我就直接用了。

 

顧老師 @ Milvus:我覺得這個可能還是要看你這個服務這個 report 它的時間限制是多少。

 

Attendee D:這時間限制基本上比如說你在五六小時以內能夠跑完其實也就 ok 了,因爲一天只需要跑一次。

 

顧老師 @ Milvus:對,那種低頻次,然後又是有五六個小時的這種窗口去跑的 report,其實你應該是有很多種選擇的,你可能就會選擇一個成本比較低的,像 Milvus 這種的單機去做,相對來說你四五億的這種 50~100 維的,單機應該是都能支撐下來去做。Spark的話,我不知道它集羣可能還是需要幾個節點去做的,但是這個東西可能你得自己實測一下,因爲五六個小時你不是很在乎時間的,你就看成本我覺得。

 

Starlord @ Milvus:如果你覺得閥值這個東西的話,是一個你們必須要做的一個東西的話,有產品的話,你也可以去 GitHub 給我們開一個 issue。我們是一個比較開放的這種社區的治理,我們的技術委員會去 review 用戶提出來的這樣的一些需求,然後我們會去定的話,下一個版本我們要把它用優先級。所以你把它提到 issue 裏面的話,也許我們下一個版本,甚至再下一個版本也可以考慮去支持你用閥值去做一個搜索。

Attendee D:我們組裏面有別人提過用那個 FAISS,這兩個平臺的話會有什麼區別?

 

顧老師 @ Milvus:是這樣,FAISS 因爲是算法庫,如果你用 FAISS 的話,你的數據文件可能得自己做好一些備份。因爲也經常有人反映說在使用的過程當中,數據文件會損壞。Milvus 這邊的,我們雖然是吸收和改進了 FAISS 的算法,但是我們底層的文件數據管理其實還是自己做一些工作,就是格式也是不太一樣的。對這部分至少目前爲止數據文件損壞的情況,在我們的用戶當中還沒有反應過。

 

Attendee D:從性能上來說會有什麼區別嗎?

 

顧老師 @ Milvus:就是說我覺得如果你的機器有 GPU 的話,那麼因爲 Milvu s在做這種  GPU 的計算的時候,其實還是爲批量場景考慮的非常多的。像 FAISS 算法庫它是把 GPU 的那些數據會常駐在 GPU 當中的。那其實顯存是非常小的,雖然你這四五億的 50~100 維的向量也不能算特別大,但是一兩塊 GPU 肯定是放不下。因爲 Milvus 的話,它其實是不是常駐 GPU 的,它就是我們 Milvus 在使用 GPU 的時候就是把它當成一個批量的處理器了,它就是會把數據不斷的複製到顯存,然後進行計算,然後再出去。所以其實單塊  GPU 卡也能夠去一定程度上加速你的過程,雖然他會有一些內存不知道顯存的時間開銷,但是因爲你是一個批量的,而且大規模批量的場景,所以這些複製的時間是比較可以忽略的。

 

Attendee D:所以說我的理解就是說我們可以在比較低成本的基礎上面去應對一些大規模的這種向量索引,相比 FAISS 的話。我再多問一句,就是說如果說我的那個數據在 Milvus 內存裏面,在 CPU內存裏面放不下的話,也可以支持嗎?

 

顧老師 @ Milvus:可以換入換出的,我不知道你們機器是私有化部署嗎?還是說是雲服務器?

 

Attendee D:是私有的,就是自己的。

 

顧老師 @ Milvus:私有部署的話,我們後續也會找英特爾的傲騰( AEP ) 來測試一下,看看在內存有限的情況下會不會提供更好的 I/O 性能。但是就是說你如果內存不足的話,其實因爲文件我們是把數據分片存了很多個文件,很多的文件我們是可以進行置換的,在內存和磁盤間進行置換,他可以 swap 進來,swap 出去,所以這個不是一個問題。

 

Attendee D:那 AEP 的話可能就得再重新購買主機了,因爲我估計他好像對 CPU 對主板有一定需求的好像是。

 

  

 

| 歡迎加入 Milvus 社區

github.com/milvus-io/milvus | 源碼

milvus.io | 官網

milvusio.slack.com | Slack 社區

zhihu.com/org/zilliz-11/columns | 知乎

zilliz.blog.csdn.net | CSDN 博客

space.bilibili.com/478166626 | Bilibili

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章