安卓機(jī)上 4G 內(nèi)存跑 alpaca,歡迎試用輕量級(jí) LLM 模型推理框架 InferLLM
從 LLM 火爆以來(lái),社區(qū)已經(jīng)出現(xiàn)了非常多優(yōu)秀的模型,當(dāng)然他們最大的特點(diǎn)就是體積大,最近為了讓大模型可以在更低端的設(shè)備上運(yùn)行,社區(qū)做了非常多的工作,?gptq(https://github.com/IST-DASLab/gptq)?實(shí)現(xiàn)了將模型進(jìn)行低比特量化,因此降低了運(yùn)行大模型對(duì) CPU 內(nèi)存,GPU 顯存的要求,llama.cpp(https://github.com/ggerganov/llama.cpp)?實(shí)現(xiàn)了在本地 CPU/GPU 上就可以運(yùn)行大模型,并且步驟非常簡(jiǎn)單,replit-code-v1-3b(https://www.jianshu.com/go-wild?ac=2&url=https%3A%2F%2Fhuggingface.co%2Freplit%2Freplit-code-v1-3b)?用更小的模型實(shí)現(xiàn)了更智能的 code 生成??梢钥吹侥P偷男⌒突洼p量部署也是一個(gè)大模型的發(fā)展方向。
鑒于此,MegEngine 團(tuán)隊(duì)開發(fā)了 InferLLM 工程,主要目的有兩個(gè):
提供一個(gè)比 llama.cpp 更簡(jiǎn)單更容易上手的本地部署框架,供大家學(xué)習(xí)和討論
讓 LLM 模型在本地或者端上部署成為可能,未來(lái)可以用在一些實(shí)際的生產(chǎn)環(huán)境中
相比 llama.cpp 工程,InferLLM 結(jié)構(gòu)更簡(jiǎn)單,對(duì)一些通用組件進(jìn)行了重構(gòu),避免將所有邏輯代碼和 kernel 代碼放在一個(gè)文件中,避免在 Kernel 中引入過(guò)多的宏影響代碼閱讀和開發(fā),llama.cpp 對(duì)于學(xué)習(xí)和二次開發(fā)不是很友好,InferLLM 也是主要借鑒 llama.cpp,如:使用 llama.cpp 的模型格式,以及 copy 了一些計(jì)算的 code,同時(shí) InferLLM 對(duì)其進(jìn)行了重構(gòu),使得代碼更簡(jiǎn)單直接,非常容易上手,框架代碼和 Kernel 代碼分開,其實(shí)在大模型推理中,真正需要優(yōu)化的 kernel 是遠(yuǎn)遠(yuǎn)小于 CNN 的 kernel 的。
另外 InferLLM 也可以用在生產(chǎn)中,因?yàn)樗梢詫?LLM 量化的模型在一個(gè)性能一般的手機(jī)上流暢的運(yùn)行,可以進(jìn)行流暢的進(jìn)行人機(jī)對(duì)話,目前在手機(jī)上運(yùn)行一個(gè) llama 7b 4bit 的模型,只需要 4G 左右內(nèi)存,這個(gè)內(nèi)存是現(xiàn)在大多數(shù)手機(jī)都能滿足的。相信在不久之后會(huì)出現(xiàn)很多大模型中的輕量化模型,可以直接在端上進(jìn)行部署和推理,畢竟目前手機(jī)是大家最容易獲得的計(jì)算資源,沒(méi)有理由浪費(fèi)如此龐大的計(jì)算集群。
下面是在 xiaomi9,Qualcomm SM8150 Snapdragon 855 上使用 4 線程運(yùn)行中文 alpaca?7b (https://github.com/ymcui/Chinese-LLaMA-Alpaca)4bit 量化模型的情況:

InferLLM 主要由幾部分組成
Model:主要負(fù)責(zé)輸入的 tokenizer,詞匯表管理,存儲(chǔ)一些歷史的 token 以及 Decoder 之后的采樣等;
Graph/Op:負(fù)責(zé)創(chuàng)建整個(gè)模型,包括模型的中 Op 直接的連接關(guān)系,Op 的執(zhí)行,以及 Op 輸入輸出等內(nèi)存資源的管理;
Kernel:提供不同后端優(yōu)化的 Kernel,目前包括 x86,Arm,naive,當(dāng) x86 和 Arm 中沒(méi)有優(yōu)化的 Kernel,會(huì)直接 fallback 到 naive 中進(jìn)行運(yùn)行。
InferLLM 主要支持以下功能:
支持每個(gè) Op 執(zhí)行前準(zhǔn)備資源,每個(gè) Op 執(zhí)行前都需要調(diào)用 pre_execute,執(zhí)行之后調(diào)用 end_execute。這樣可以方便在內(nèi)存不足的設(shè)備上,在執(zhí)行前從磁盤中間權(quán)重讀取到 RAM 中,執(zhí)行完成之后將權(quán)重存回磁盤中,也可以直接使用 mmap,讓操作系統(tǒng)自動(dòng)處理這些邏輯;
支持每一個(gè) Multi-Head Attention 的 KV cache,每次計(jì)算出來(lái)的 Key 和 Value 都保存在 KVStorage 中,KVStorage 支持通過(guò) token 的 id 索引,另外如果 KV 的 cache 過(guò)大時(shí),還支持將其 swap 出去;
支持 CPU 上多線程,SIMD,量化,float16計(jì)算等加速方式,多線程是通過(guò)自己實(shí)現(xiàn)的一個(gè)類似 OpenMP 靜態(tài)調(diào)度的邏輯,使用無(wú)鎖的線程池來(lái)進(jìn)行多線程之間的同步
可以兼容多種模型格式,目前僅僅支持了 llama 類似的模型,未來(lái)將支持更多的模型結(jié)構(gòu)。
歡迎大家試用 InferLLM:https://github.com/MegEngine/InferLLM
更多 MegEngine 信息獲取,您可以:查看文檔:https://www.megengine.org.cn/doc/stable/zh/
GitHub 項(xiàng)目: https://github.com/MegEngine
加入 MegEngine 用戶交流 QQ 群:1029741705
歡迎參與 MegEngine 社區(qū)貢獻(xiàn),成為?Awesome MegEngineer:https://www.megengine.org.cn/community-AMGE,榮譽(yù)證書、定制禮品享不停。