From where I left

Salvatore Sanfilippo

從我離開的地方出發

原文由 Salvatore Sanfilippo 發布,訂閱此部落格

我不是那種會對自己的作品產生強烈依戀的人。當我決定離開 Redis 時,大約是 1620 天前(約 4.44 年),之後我就再也沒看過 Redis 的原始碼、commit 訊息,或任何與 Redis 相關的東西。偶爾需要用到 Redis 時,我就直接下載下來編譯。只要打個「make」,看到多年之後建置 Redis 依然如此簡單,就讓我很開心。

這種抽離並不是因為我討厭過去的工作。長期下來,我的創作性工作變得越來越不重要,而「處理專案」相關的事務卻越來越多——很多程式設計師能適應這種轉變,但那不是我擅長的事——不過,離開的時候,我其實還是很享受做 Redis 相關的事。然而,我並不抱持許多跟我同齡(我現在 47 歲)的人那種「自己還年輕」的想法。我想做些新的事情,尤其是寫作。我想多陪陪家人,也想多幫幫親人。我確實需要休息一下。

不過,在那幾年的「寫作時期」(順帶一提,我到現在還在寫),我也常常回頭寫程式,當作高強度寫作之間的喘息(寫作是我所經歷過,唯一比寫程式更耗費心力的腦力活動):我做了幾個嵌入式專案;更深入地玩了類神經網路;做了 Telegram 機器人:什麼都碰一點。隨意地 hack 固然很酷,但長遠來看,我總覺得缺少一個真正的目標,每天都越來越強烈地感覺到,自己想再次成為科技世界的一份子。同時,我也看到 Redis 社群正在分化,即使作為一個局外人,這也讓我有點擔心。

所以我開始想,或許我還能在 Redis 生態系中扮演某種角色。也許我能幫助重塑公司對社群的態度。甚至,也許我能幫忙讓 Redis 核心重新成為新開發的主要重心。基本上,我可以擔任某種「傳教士」(我不太喜歡這個職稱,但……你懂我的意思),一方面作為公司與社群之間的橋梁,另一方面也能製作程式示範、發明並描述新的模式、撰寫關於新舊事物的文件、影片和部落格文章。那,新東西的設計呢?我可以從外界人們的實作與他們遇到的困難中學習,將其提煉出來,再回報設計想法,讓 Redis 得以持續演進。

在紐約的時光

有個時候,我那現在 12 歲的女兒——她是我生命中至關重要的人,用她的聰明、創意與愛點亮了我的每一天——想在生日時去紐約玩。我們覺得,嗯,這主意其實不錯,畢竟最近我們度過了幾年非常艱難的時光,那又何妨呢?我的女兒現在已經比較像個少女,而不只是個孩子了。所以,在紐約時我想:也許現在正是時候,我可以找份兼職。我最近才在一次視訊通話中見了 Redis 的新執行長 Rowan Trollope。我感覺我可以和他一起合作,調整公司未來與社群的關係以及程式碼的發展方向。於是我寫了封信給他,問:你覺得我有沒有可能以某種形式回來?Rowan 對我的提議表現出興趣,很快地我們就達成了共識。

關於授權轉換

人們會問我為何*真的*要這麼做,是否除了上面寫的之外還有別的內幕,是否有什麼協議,或是一大筆錢;有什麼奇怪或不明不白的地方。但有時候事情就是很無聊:1. 是我主動聯繫公司的,不是公司來找我。2. 我回來並沒有拿到什麼天價報酬,不是要趁機敲一筆——就是一般的薪水(不過,先聲明:是的,我和以前一樣持有 Redis 的股票選擇權,不多也不少)。3. 我對 Redis 更換授權並沒有太大的意見;具體來說,我不認為與社群的分裂*真的是*因為這件事。但既然大家一定會問起這個非常重要的議題,不如馬上把實話全部告訴你們。

授權的兩難

我幾乎一輩子都在寫開放原始碼軟體。然而,就像我雖然是無神論者,但看到別人信仰上帝、如果這能幫助他們度過人生的艱難,我也會為他們感到高興一樣,我也不認為開放原始碼是寫軟體的唯一方式。當初我在自己是兩位創辦人之一的公司裡開始開發 Redis 時,我們的軟體是封閉原始碼的(Redis 之所以開源,是因為它被認為不是核心產品)。我們只是不想讓別人抄襲我們的服務,就這麼簡單。所以在這方面我不是極端派——我只在軟體設計上是極端派。

再者,我不認為開放與授權就只有 OSI 所定義的那樣。我把授權看作是一個關於你能做什麼、不能做什麼的光譜。同時,我真的很擔心大型雲端供應商已經改變了系統軟體領域的誘因結構。Redis 並不是唯一一個更換授權的專案,它其實是一大堆專案中的最後一個……。而且我感覺,近年來有許多專案甚至根本沒能啟動,就是因為缺乏清晰可行的商業模式。所以,Redis 的授權轉換並不是我的決定,或許我會選擇不同的授權?我不確定,現在事隔多年、又沒有身處商業壓力之中,要重新爭辯實在太容易了。但整體而言,我能理解這個選擇。

再者,如果你讀過新的 Redis 授權,當然,它不是 BSD,但基本上只要你不是把 Redis 當作服務來販售,你就能以和以往非常相似的方式、享有相似的自由來使用它(我的意思是,你依然可以修改 Redis、重新散布、在你的營利公司中商業使用 Redis,而且免費,諸如此類)。你*甚至*還是可以把 Redis 當作服務來賣,只要你把所有協調系統都以同樣的授權釋出(大概沒人真的會這麼做,但這顯示了該授權的 copyleft 做法)。授權條文幾乎和 AGPL 一樣,只是在 SaaS 相關的部分做了修改。所以,沒通過 OSI 認可?是的,但我不太認同把 SSPL 稱為封閉授權。

你會說(我聽得到):真正的問題是有公司在掌控開放原始碼專案的方向!所以最終利益會越來越向公司靠攏,而越來越偏離使用者。我很感謝世上有很多完全沒有公司直接介入(除了外部贊助之外)的專案,但,你知道嗎?在許多大型專案中,公司的參與其實反而減緩了這種偏離正軌的過程。在 Redis 的案例中,肯定就是如此。

軟體界的羅賓漢

讓我們回到過去,回到 Redis 最早的日子。

當 Redis 開始變得受歡迎時,我想找個辦法繼續投入其中。這是在 VMware 提出要贊助我的工作之前。我開始構思商業模式,你猜怎麼著?那是以封閉原始碼產品的形式,某種程度上幫助人們運行 Redis。(令人驚訝的是,與這個想法相關的其中一個儲存庫至今還在線上,顯示著 *15* 年前的 commit:https://github.com/antirez/redis-tools

我當時差點就要嘗試某種 open core 模式;我還記得我曾想過把新程式碼的 BSD 授權延後六個月釋出,以便為付費使用者創造某種優勢。現在回想起來,我不認為我會那麼混蛋、去跟使用者玩什麼奇怪把戲,但如果那樣做,我就不會成為後來在 VMware,以及之後更大程度上在 Redis Labs 幫助下所成為的那個角色:一個他媽的開放原始碼羅賓漢,被公司給予優渥的報酬,卻不是為了公司的利益,而是只為 Redis 社群的最佳利益著想。我確信,這比自己開一家公司還要好得多。

VMware,後來的 Redis Labs,付費支持的不只是我。如果你快速瀏覽一下儲存庫的貢獻紀錄,會看到史上貢獻第二多的是 Oran Agra(Redis),接著是 Pieter Noordhuis(VMware),依此類推。

所以基本上我認為,12 年來只專注於使用者需求、以 BSD 授權撰寫的程式碼,是一筆很划算的交易,也是值得開心的事。而對現在的我來說,最重要的是,與社群的分裂並非關於授權,至少主要不是授權的問題。事實上,新授權反而能解決其中一部分:現在已經沒有誘因只讓核心停留在維護模式、而把新開發都放到模組裡。有了新授權,雲端供應商不能再只是剪下貼上 Redis 的程式碼庫拿去販售、卻完全不分享營收(這真的要求太多嗎?如果早這麼做,或許就能避免你最近看到的所有授權轉換,不只是 Redis)。有了新授權,焦點可以重新回到 Redis 核心,讓全世界的開發者都能享受到新的、令人興奮的功能。讓數十位獲得合理報酬的人,在 GitHub 儲存庫中推送實用且文件完整的新變更。這也是我想幫公司努力的方向之一,我會盡力去做。我們必須讓這次授權轉換對使用者和功能產生正面的影響:這就是我的想法。

關於 AI、LLM 與向量索引

但還有更多:Redis 開始對發展向量能力感興趣,整體來說也想支援你能用 AI 進行的那類程式設計。現在,我每天看 Hacker News,都看到大量技術人討厭 AI 和新的發展。我也看到很多人甚至不在乎去深入嘗試最新的模型(提示:Claude AI 自成一格),就一概認為它們沒什麼用。對我來說則不同。我一直都很熱愛類神經網路。我在 2003 年就寫了我的第一個類神經網路函式庫,當時就深深震撼於這個概念有多強大、多酷。而現在,在 2024 年底,我終於看到這個領域令人難以置信的成果,幾年前看起來像科幻小說的事,現在都成為可能:最近 Claude AI 就是我的思考/編輯/程式設計夥伴。我能完成比過去多得多的事。我常常因為 AI 而做*更多的工作*,但也做出更好的成果。最近我為一家義大利出版社寫了一篇科幻短篇,多虧 Claude 對其中部分內容的批評,我重寫了結局,做出了一部好得多的作品(我沒有讓 Claude 寫故事或情節的任何一行:善用 AI 不是讓機器去做你能做得更好的事)。

昨天我需要評估把向量做 8 位元量化後,內積運算能快多少;我告訴 Claude 我需要一個以特定方式設計的基準測試,兩分鐘後我就能測試、修改,並判斷它是否值得。基本上,AI 沒有取代我,AI 是加速了我,或透過對我工作的回饋讓我變得更好。而我相信(不論 RAG 有多熱門,它不一定是主要的應用,也不一定是最能經得起未來考驗或最有用的,因為模型的上下文正變得越來越大,而且很快熱門模型的注意力機制可能就會有線性複雜度),抱歉岔題了,我想說的是,我相信學習式嵌入(learned embeddings)會留下來,而向量搜尋屬於 Redis,原因有幾個:首先是因為向量索引就是資料結構,特別是速度偏慢的資料結構,而這類資料結構在記憶體中運作得非常好。還有,因為我認為我找到了最完美的 API 來呈現它們。

在設計 Redis 的過程中,我總是表現出一些矛盾的傾向。我總是準備好對某些看起來完全適合這個專案的東西說「不」(像是具名 Lua 腳本、雜湊欄位的過期功能,順帶一提,這兩者現在都已是 Redis 的一部分),但同時我又加入了 Lua 腳本功能——當時看起來簡直瘋了,在 Redis 裡放一個直譯器?!——還有看似格格不入的 Pub/Sub 功能,然後是 streams,甚至還有電腦科學教科書裡根本不存在的合成資料結構,像是 sorted sets。因為對我來說,新功能是否適合 Redis,取決於兩件事:使用情境與內部設計的契合度。對我而言,Redis 是給程式設計師的樂高,而不是一個「產品」。

向量集合

所以最近我開始思考,sorted sets 或許能啟發一種新的資料型別,其中的分數實際上是一個向量。而在我和 Rowan 洽談的同時,我開始撰寫一份設計文件,接著開始為這個新資料結構實作概念驗證,從頭重新實作 HNSW(而不是使用現成的函式庫,因為我想微調每一個細節),用 Redis 的方式,然後,嗯,我不確定最後會如何,我還在編碼的早期階段,但或許如果這個提案被接受,我又會開始貢獻程式碼。我實作的模組(之後會合併進核心——目前為了簡單起見先做成模組)實作了能直接操作嵌入的新指令。我就先透露這一點給大家看看:

VSIM top_1000_movies_imdb ELE "The Matrix"  WITHSCORES
 1) "The Matrix"
 2) "0.9999999403953552"
 3) "Ex Machina"
 4) "0.8680362105369568"
 5) "Akira"
 6) "0.8635441958904266"
 7) "District 9"
 8) "0.8631418347358704"
 9) "The Martian"
10) "0.8608670234680176"
11) "The Bourne Ultimatum"
12) "0.8599717319011688"
13) "The Bourne Supremacy"
14) "0.8591427505016327"
15) "Blade Runner"
16) "0.8585404753684998"
17) "Metropolis"
18) "0.8572960793972015"
19) "Inception"
20) "0.8521313071250916"

所以你有了 VSIM、VADD、VCARD,所有顯而易見的指令。這完全就是 sorted sets 的概念,只是分數變成了多維度的(嵌入!)並搭配 K-NN 匹配。你覺得如何?當然,除此之外還有許多實作上的技巧來讓一切更有效率。但目前還只是概念驗證的程式碼,讓我再多琢磨一下。我正在實作多執行緒、降維、量化,以及更多東西。老實說,相當有趣。

如你所見,這裡完全沒提到混合搜尋,也就是近期關於向量儲存的流行詞彙。這又是 Redis 的風格:讓開發者保有主導權,自行決定取捨:畢竟他們最清楚自己在建模什麼。每個 key 都有一個向量索引,就像程式設計師過去用 sorted sets 所做的一樣,他們會發明有趣的分割策略、新的結構描述、Lua 腳本、模式,以及建模其使用情境所需的一切。

當然,一般來說,關聯的項目可能只是一個小字串或文件 ID,但也沒有什麼能阻止它變得更複雜,帶有之後可以過濾的中繼資料(但我會忍住不這麼做)。我只是覺得,許多使用情境其實並不需要複雜的伺服器端過濾,透過預先對資料做分區就能建模。

我非常感興趣的是,未來可能加入一個 STORE 選項,把結果存到 sorted set 中,而不是直接回傳給使用者,分數當然就是相似度。這一切對於效率、可擴展性、使用腳本的能力等等,也都有複雜而有趣的影響:我希望在接下來的幾週、幾個月內有機會再多談談這些。

好吧,好吧:回到這篇部落格文章的重點。但或許上面的那些才是*真正的*重點,能有令人興奮的新點子。

所以,我回來了 🙂

說了這麼多,就是想說,我回來了。我覺得現在正是向多年來付出良多的 Redis 社群致上深深謝意的最佳時機。期待再相見,希望這段旅程還能再添上些什麼。

P.S. 我現在活躍於 BlueSky,如果你想追蹤這一切的後續發展。https://bsky.app/profile/antirez.bsky.social

本文章由 muse-spark-1.2-contributor 進行翻譯

留言