?本文截取自20萬字的《PyTorch實用教程》(第二版),敬請關注:《Pytorch實用教程》(第二版)無論是零基礎入門,還是CV、NLP、LLM項目應用,或是進階工程化部署落地,在這里都有。相信在本書的幫助下,讀者將能夠輕松掌握 PyTorch 的使用,成為一名優秀的深度學習工程師。《Pytorch實用教程》(第二版)無論是零基礎入門,還是CV、NLP、LLM項目應用,或是進階工程化部署落地,在這里都有。相信在本書的幫助下,讀者將能夠輕松掌握 PyTorch 的使用,成為一名優秀的深度學習工程師。 - TingsongYu/PyTorch-Tutorial-2ndhttps://github.com/TingsongYu/PyTorch-Tutorial-2nd
LLM 入門與實踐(一)Qwen部署與分析
LLM 入門與實踐(二)ChatGLM3 部署與分析
LLM 入門與實踐(三)Baichuan2 部署與分析
LLM 入門與實踐(四) Yi 部署與分析
前言
Yi是由零一萬物開源的大語言模型,目前(2024年4月16日)包括6B和34B-chat版本,base版本有6B、9B和34B。
零一萬物是2023年7月,李開復籌組新公司,部注冊于北京,集中在大模型技術、人工智能算法、自然語言處理、系統架構、算力架構、數據安全、產品研發等領域。
更多信息:
-
公司官網:零一萬物-AI2.0大模型技術和應用的全球公司
-
HF: https://huggingface.co/01-ai
-
github: 01.AI · GitHub
-
LLM-github:GitHub - 01-ai/Yi: A series of large language models trained from scratch by developers @01-ai
-
技術報告:https://arxiv.org/abs/2403.04652
部署安裝
第一步,代碼下載
git clone https://github.com/01-ai/Yi.git
第二步,權重下載
git clone https://www.modelscope.cn/01ai/Yi-6B-Chat-4bits.git
第三步,量化環境安裝
int4和int8分別需要AWQ和GPTQ環境
pip install autoawq ? https://github.com/casper-hansen/AutoAWQ?tab=readme-ov-file#install-from-pypi https://github.com/AutoGPTQ/AutoGPTQ?tab=readme-ov-file#quick-installation
第四步,配置代碼中模型路徑
parser.add_argument("-c","--checkpoint-path",type=str,default=r"G:\04-model-weights\Yi-6B-Chat-4bits",help="Checkpoint name or path, default to %(default)r", ) ? ? ? ?default=r"G:\04-model-weights\Yi-6B-Chat-4bits", ?
第五步,運行代碼
Yi沒有提供命令行的交互demo,提供的事web ui版,運行Yi\demo\web_demo.py 即可跳出基于gradio的交互界面。
修改后的代碼可參考github
模型UML分析
Yi的github倉庫及模型權重倉庫均未找到類似Qwen、ChatGLM、Baichuan那樣的模型文件,因此無法深入探究模型結構。
為了探究Yi模型的推理步驟,debug觀察到以下信息,供流程分析所用。
-
model = AutoModelForCausalLM.from_pretrained 獲得的模型是LlamaForCausalLM類,其中的核心model是LlamaModel
LlamaForCausalLM((model): LlamaModel((embed_tokens): Embedding(64000, 4096)(layers): ModuleList((0-31): 32 x LlamaDecoderLayer((self_attn): LlamaSdpaAttention((q_proj): WQLinear_GEMM(in_features=4096, out_features=4096, bias=False, w_bit=4, group_size=128)(k_proj): WQLinear_GEMM(in_features=4096, out_features=512, bias=False, w_bit=4, group_size=128)(v_proj): WQLinear_GEMM(in_features=4096, out_features=512, bias=False, w_bit=4, group_size=128)(o_proj): WQLinear_GEMM(in_features=4096, out_features=4096, bias=False, w_bit=4, group_size=128)(rotary_emb): LlamaRotaryEmbedding())(mlp): LlamaMLP((gate_proj): WQLinear_GEMM(in_features=4096, out_features=11008, bias=False, w_bit=4, group_size=128)(up_proj): WQLinear_GEMM(in_features=4096, out_features=11008, bias=False, w_bit=4, group_size=128)(down_proj): WQLinear_GEMM(in_features=11008, out_features=4096, bias=False, w_bit=4, group_size=128)(act_fn): SiLU())(input_layernorm): LlamaRMSNorm()(post_attention_layernorm): LlamaRMSNorm()))(norm): LlamaRMSNorm())(lm_head): Linear(in_features=4096, out_features=64000, bias=False) )
-
在模型權重的config.json中,體現模型架構為LlamaForCausalLM
{"architectures": ["LlamaForCausalLM"],"attention_bias": false,"bos_token_id": 1,"eos_token_id": 2,"hidden_act": "silu","hidden_size": 4096,"initializer_range": 0.02,"intermediate_size": 11008,"max_position_embeddings": 4096,"model_type": "llama","num_attention_heads": 32,"num_hidden_layers": 32,"num_key_value_heads": 4,"pretraining_tp": 1,"quantization_config": {"bits": 4,"group_size": 128,"quant_method": "awq","version": "gemm","zero_point": true},"rms_norm_eps": 1e-05,"rope_scaling": null,"rope_theta": 5000000.0,"tie_word_embeddings": false,"torch_dtype": "float16","transformers_version": "4.35.0","use_cache": true,"vocab_size": 64000 } ?
Prompt 結構分析
web_demo.py代碼結構整體基于transformers庫的工具來實現,推理采用流處理,基于transformers的TextIteratorStreamer實現,模型單次推理由TextIteratorStreamer代理,這里不深入。
這里看看Yi源代碼中的predict函數,該函數對歷史對話進行了處理,實現多輪對話的Prompt處理。大體可分為4步:
第一步:將歷史信息轉為模型輸入的tokens_ids, 這一步調用transformers的apply_chat_template接口功能實現;
第二步:創建流處理器TextIteratorStreamer
第三步:組裝本輪對話所需信息,generate_kwargs
第四步:啟動線程執行model.generate, 從流處理器streamer中拿單次推理的結果
由于大部分是transformers庫的代碼,此處就不深入展開了
def predict(history, max_length, top_p, temperature):stop = StopOnTokens()messages = []for idx, (user_msg, model_msg) in enumerate(history):if idx == len(history) - 1 and not model_msg:messages.append({"role": "user", "content": user_msg})breakif user_msg:messages.append({"role": "user", "content": user_msg})if model_msg:messages.append({"role": "assistant", "content": model_msg}) ?print("\n\n====conversation====\n", messages)model_inputs = tokenizer.apply_chat_template(messages, add_generation_prompt=True, tokenize=True, return_tensors="pt").to(next(model.parameters()).device)streamer = TextIteratorStreamer(tokenizer, timeout=60, skip_prompt=True, skip_special_tokens=True)generate_kwargs = {"input_ids": model_inputs,"streamer": streamer,"max_new_tokens": max_length,"do_sample": True,"top_p": top_p,"temperature": temperature,"stopping_criteria": StoppingCriteriaList([stop]),"repetition_penalty": 1.2,}t = Thread(target=model.generate, kwargs=generate_kwargs)t.start() ?for new_token in streamer:if new_token != "":history[-1][1] += new_tokenyield history
小結
通過Yi的代碼,可以了解如何快速基于transformers構建一個LLM推理部署代碼。
并且可以了解GPTQ和AWQ的部署需要單獨安裝對應的python庫。