本專案旨在建立一個小參數量的中文語言大模型,用於快速入門學習大模型相關知識,如果此專案對你有用,可以點一下start,謝謝!
模型架構:整體模型架構採用開源通用架構,包含:RMSNorm,RoPE,MHA等
實現細節:實現大模型兩階段訓練及後續人類對齊,即:分詞(Tokenizer) -> 預訓練(PTM) -> 指令微調(SFT) -> 人類對齊(RLHF, DPO) -> 測評-> 量化- > 部署。
專案已部署,可以在以下網站上體驗。
專案特點:
Bash
腳本啟動,支援不同大小的模型,如16m, 42m, 92m, 210m, 440m等;本計畫主要有三個分支,推薦學習主分支,具體區別如下:
main
tiny_llm
: 對齊開源社群模型,使用Transformers庫建立底層模型,也使用Transformers庫進行多卡多機訓練;tiny_llm
的基礎上,修改MLP
層為MoE模型,使用Transformers庫進行多卡多機訓練。注意:
doc
資料夾(正在整理。。) 模型已託管在Huggingface 和ModeScope 中,可運行程式碼自動下載。
建議使用Huggingface 線上載入模型,如果運行不了,在試ModeScope ;如果需要本地運行,修改model_id
中的路徑為本地目錄,即可運行。
pip install -r requirements.txt
from transformers import AutoTokenizer , AutoModelForCausalLM
from transformers . generation import GenerationConfig
model_id = "wdndev/tiny_llm_sft_92m"
tokenizer = AutoTokenizer . from_pretrained ( model_id , trust_remote_code = True )
model = AutoModelForCausalLM . from_pretrained ( model_id , device_map = "auto" , trust_remote_code = True )
generation_config = GenerationConfig . from_pretrained ( model_id , trust_remote_code = True )
sys_text = "你是由wdndev开发的个人助手。"
# user_text = "世界上最大的动物是什么?"
# user_text = "介绍一下刘德华。"
user_text = "介绍一下中国。"
input_txt = " n " . join ([ "<|system|>" , sys_text . strip (),
"<|user|>" , user_text . strip (),
"<|assistant|>" ]). strip () + " n "
generation_config . max_new_tokens = 200
model_inputs = tokenizer ( input_txt , return_tensors = "pt" ). to ( model . device )
generated_ids = model . generate ( model_inputs . input_ids , generation_config = generation_config )
generated_ids = [
output_ids [ len ( input_ids ):] for input_ids , output_ids in zip ( model_inputs . input_ids , generated_ids )
]
response = tokenizer . batch_decode ( generated_ids , skip_special_tokens = True )[ 0 ]
print ( response )
from modelscope import AutoModelForCausalLM , AutoTokenizer
model_id = "wdndev/tiny_llm_sft_92m"
tokenizer = AutoTokenizer . from_pretrained ( model_id , trust_remote_code = True )
model = AutoModelForCausalLM . from_pretrained ( model_id , device_map = "auto" , trust_remote_code = True )
sys_text = "你是由wdndev开发的个人助手。"
# user_text = "世界上最大的动物是什么?"
# user_text = "介绍一下刘德华。"
user_text = "介绍一下中国。"
input_txt = " n " . join ([ "<|system|>" , sys_text . strip (),
"<|user|>" , user_text . strip (),
"<|assistant|>" ]). strip () + " n "
model_inputs = tokenizer ( input_txt , return_tensors = "pt" ). to ( model . device )
generated_ids = model . generate ( model_inputs . input_ids , max_new_tokens = 200 )
generated_ids = [
output_ids [ len ( input_ids ):] for input_ids , output_ids in zip ( model_inputs . input_ids , generated_ids )
]
response = tokenizer . batch_decode ( generated_ids , skip_special_tokens = True )[ 0 ]
print ( response )
生成效果
问:世界上最大的动物是什么?
答:目前已知最大的动物是蓝鲸(Balaenoptera musculus),这是一个庞大的哺乳动物,属于须鲸亚目、须鲸科中的最大物种。蓝鲸的身长可达30米以上,体重可达175吨。它们在海洋中生活,主要以浮游生物为食,如甲壳类动物和小型鱼类等。由于其巨大的体型和复杂的生态群落,蓝鲸成为海洋旅游的热门景点之一。
问:介绍一下刘德华。
答:刘德华是一位香港流行歌手、演员和导演,他在音乐界的贡献非常巨大。他是华语乐坛历史上最伟大的艺人之一,代表作品包括《爱我身体》和《肥皂泡》。他也经常参演电影和电视剧,并在电视上受到好评。
问:介绍一下中国。
答:中国是位于东亚的大陆,被欧洲以及亚洲和其他大陆所包围。它是中国第二大文明和世界上最大的经济体之一。中国的历史可以追溯到公元前5000年左右,从古至今都有其独特的文化和语言传承者。
LLM分詞器的建構方式有兩種:一種是自己構造詞表,訓練一個分詞器;另一種是選擇開源模型訓練好的分詞器。
本專案為了方便,從優秀的開源專案中選擇詞表,考慮到訓練的模型較小,且詞表大小影響模型大小,故優先選擇詞表較小的開源專案;經過比較,最終選擇ChatGLM3 的詞表,該詞表大小為64798 。
自己構造詞表方式見tokenizer,擴充LLaMA2的32K詞表為50K,增加20K中文詞表,詳細擴充方式見文件或tokenizer/README.md.
注意:本項目使用的ChatGLM3的詞表。
模型結構採用類Llama2的結構,具體包括:RMSNorm,RoPE,MHA等;
具體參數細節如下圖所示:
model | hidden size | intermediate size | n_layers | n_heads | max context length | params | vocab size |
---|---|---|---|---|---|---|---|
tiny-llm-16m | 120 | 384 | 6 | 6 | 512 | 16M | 64798 |
tiny-llm-42m | 288 | 768 | 6 | 6 | 512 | 42M | 64798 |
tiny-llm-92m | 512 | 1024 | 8 | 8 | 1024 | 92M | 64798 |
tiny-llm-210m | 768 | 2048 | 16 | 12 | 1024 | 210M | 64798 |
tiny-llm-440m | 1024 | 2816 | 24 | 16 | 1024 | 440M | 64798 |
tiny-llm-1_5b | 2048 | 5504 | 24 | 16 | 1024 | 1.5B | 64798 |
因訓練資料和微調數據,大部分都是中文數據,所以在C-Eval
和CMMLU
這兩個資料集上進行模型的評估;使用OpenCompass工具,進行模型評估,評估分數如下所示:
model | Type | C-Eval | CMMLU |
---|---|---|---|
tiny-llm-92m | Base | 23.48 | 25.02 |
tiny-llm-92m | Chat | 26.79 | 26.59 |
Base模型,採用評測方式ppl 方式進行評測;Chat模型,採用gen 方式評測。具體區別如下圖所示:
資料來源:ppl和gen模式有什麼差別
注意:只對常用的兩個模型進行了評測,分數較低,其餘模型評測意義不大。
網頁Demo已部署,可在以下網站上體驗:ModeScope Tiny LLM
如果想在本機上執行網頁Demo,注意修改web_demo.py
檔案中模型的路徑model_id
,輸入如下指令即可運行:
streamlit run web_demo.py
Transfomers 框架部署,位於demo/infer_chat.py
和demo/infer_func.py
檔案中,和其他LLM運作沒有太大差別,注意輸入的拼接即可。
詳細vllm部署請見vllm
如果使用CUDA 12 以上和PyTorch 2.1 以上,可以直接使用下列指令安裝vLLM。
pip install vllm==0.4.0
否則請參考vLLM官方的安裝說明。
安裝完成後,還需要以下操作~
vllm/tinyllm.py
檔案複製到env環境對應的vllm/model_executor/models
目錄下。 " TinyllmForCausalLM " : ( " tinyllm " , " TinyllmForCausalLM " ),
由於模型結構是自己定義的,vllm官方未實現,需要自己手動加入
詳細llama.cpp 部署見llama.cpp
Tiny LLM 92M 模型已支援llama.cpp C++ 推理框架,建議在linux 環境下測試,windows效果不好;
所支援llama.cpp 為自己修改的版本,倉庫連結為: llama.cpp.tinyllm