當前位置: 妍妍網 > 碼農

基於AntSK與LLamaSharp打造私人客製的離線AI知識庫

2024-02-28碼農

隨著人工智慧的不斷發展,AI已經逐漸成為我們日常生活中不可分割的一部份。今天,我為大家帶來的是一個我近期投入研究的開源計畫——AntSK,它結合了LLamaSharp,不僅帶來了高效便捷的本地離線AI知識庫搭建方法,更是無需借助公司帳戶,個人開發者也能輕松搭建和使用。

計畫地址請參考:

https://github.com/xuzeyu91/AntSK

AntSK:計畫概述與特點

在介紹如何整合LLamaSharp之前,我們首先要了解的是AntSK這個計畫。AntSK利用Blazor技術與Semantic Kernel相結合,配合Kernel Memory,構建了一個易於操作和擴充套件的本地知識管理系統。開源的特性使得它受到了不少朋友的關註和喜愛,並為沒有公司資源的個人開發者提供了更多可能。

外部模型依賴的困境

盡管AntSK本身嶄露頭角,我們發現,在實際套用中,尤其是想要利用國內某些Embedding模型時,往往遇到了限制個人帳號申請的壁壘,例如「百川」等AI模型服務。而星火大模型雖然對個人開放,但它缺少必要的Embedding能力,使得我們無法充分利用。

LLamaSharp:融合之道

這個問題的解決方案是引入LLamaSharp,一個可以幫助我們實作本地AI模型部署和使用的開源庫。LLamaSharp的優勢在於它允許我們在不依賴外部服務的情況下,本地執行大模型。更加詳細的資訊和程式碼,你可以在LLamaSharp on GitHub找到。

https://github.com/SciSharp/LLamaSharp/

選型模型:Hugging Face的貢獻

為了有一個測試和展示的基礎,我們需要從Hugging Face上選擇若幹AI模型。在我的試驗中,我隨機挑選了兩個模型進行了測試。不過在此過程中,需要註意的是,並非所有模型都能夠順利載入。模型載入時可能會遇到記憶體保護讀取的問題,這可能是由於所選擇的模型不支持當前的LLamaSharp版本。

處理這種情況的方法是根據LLamaSharp計畫中提供的每個版本對應的 llama.cpp 的commit id,我們可以透過複制llama倉庫,然後切換到符合我們需求的commit id來編譯我們需要的版本。

LLamaSharp介面:開啟離線AI之門

接下來的重點是如何利用LLamaSharp寫介面,這裏我們需要編寫兩個介面,一個是用於聊天的Chat介面,另一個是用於Embedding的介面。程式碼範例如下,我們將保持介面的返回格式和openai完全一致,這樣可以無縫切換到本地模型服務:

[ApiController]public class LLamaSharpController(ILLamaSharpService _lLamaSharpService) : ControllerBase {///<summary>/// 本地會話介面///</summary>///<returns></returns> [HttpPost] [Route("llama/v1/chat/completions")]publicasync Task chat(OpenAIModel model) {if (model.stream) {await _lLamaSharpService.ChatStream(model, HttpContext); }else {await _lLamaSharpService.Chat(model, HttpContext); } }///<summary>/// 本地嵌入介面///</summary>///<param name="model"></param>///<returns></returns> [HttpPost] [Route("llama/v1/embeddings")]publicasync Task embedding(OpenAIEmbeddingModel model) {await _lLamaSharpService.Embedding(model,HttpContext); } }

在配置檔中,把OpenAI的配置修改為本地服務地址,就可以愉快地呼叫原生的LLamaSharp模型了。

"OpenAIOption": {"EndPoint": "https://localhost:5001/llama/","Key": "……","Model": "……","EmbeddingModel": "……" }

效能最佳化:因地制宜

由於我的本地模型執行在CPU上,推理速度相對慢一些。為了避免在KernelMemory請求時出現超時,我對HttpClient的超時時間進行了延長,並且降低了段落分片的token數值。

var httpClient = new HttpClient(handler);httpClient.Timeout= TimeSpan.FromMinutes(5);var memory = new KernelMemoryBuilder() .WithPostgresMemoryDb(postgresConfig) .WithSimpleFileStorage(new SimpleFileStorageConfig { StorageType = FileSystemTypes.Volatile, Directory = "_files" }) .WithSearchClientConfig(searchClientConfig)//本地模型需要設定token小一點。 .WithCustomTextPartitioningOptions(new Microsoft.KernelMemory.Configuration.TextPartitioningOptions { MaxTokensPerLine=99, MaxTokensPerParagraph=99, OverlappingTokens=47 }) .WithOpenAITextGeneration(new OpenAIConfig() { APIKey = OpenAIOption.Key, TextModel = OpenAIOption.Model }, null, httpClient) .WithOpenAITextEmbeddingGeneration(new OpenAIConfig() { APIKey = OpenAIOption.Key, EmbeddingModel = OpenAIOption.EmbeddingModel }, null, false, httpClient) .Build<MemoryServerless>();

效果展示與問題排查

經過配置和部署,我們可以看到這樣的效果:知識文件已經成功切片匯入進AntSK系統。 不過當我進行檢索的時候發現效果並不理想,文件的相似度與預期有較大差距 。這是否是因為模型本身的問題,亦或是LLamaSharp的相容性問題呢?這需要更多的測試和研究才能得出結論。

我將會持續關註這個問題,並在後續的文章中為大家帶來更多進展。同時,也歡迎廣大AI技術愛好者和開發者關註我的公眾號,一起交流探討AI技術的最新趨勢和問題解決方案。

以上就是我今天想與大家分享的內容。AI的世界千變萬化,搭建一個私人客製的AI知識庫可能並不是一條平坦的道路,但正是這樣的挑戰和不斷的試錯,才使得我們能夠逐步豐富自己的技術武庫,開拓更多的可能性。希望我的文章能給你帶來啟發和幫助,我們下期再見!