隨著人工智慧的不斷發展,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知識庫可能並不是一條平坦的道路,但正是這樣的挑戰和不斷的試錯,才使得我們能夠逐步豐富自己的技術武庫,開拓更多的可能性。希望我的文章能給你帶來啟發和幫助,我們下期再見!