datawhalechina/self-llm: 《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调(全参数/Lora)、部署国内外开源大模型(LLM)/多模态大模型(MLLM)教程
大模型(LLM)狭义上指基于深度学习算法进行训练的自然语言处理(NLP)模型,主要应用于自然语言理解和生成等领域,广义上还包括机器视觉(CV)大模型、多模态大模型和科学计算大模型等。
学习实现国内外主流开源LLM的部署、使用与微调教程
Qwen1.5 模型下载 通过指令下载模型到缓存文件夹
1 2 3 4 from modelscope import snapshot_downloadmodel_dir = snapshot_download('qwen/Qwen1.5-7B-Chat' , cache_dir='/root/autodl-tmp' , revision='master' )
代码准备 在autodl-tmp路径下新建api.py文件,并输入以下内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 from fastapi import FastAPI, Requestfrom transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfigimport uvicornimport jsonimport datetimeimport torchDEVICE = "cuda" DEVICE_ID = "0" CUDA_DEVICE = f"{DEVICE} :{DEVICE_ID} " if DEVICE_ID else DEVICE def torch_gc (): if torch.cuda.is_available(): with torch.cuda.device(CUDA_DEVICE): torch.cuda.empty_cache() torch.cuda.ipc_collect() app = FastAPI() @app.post("/" ) async def create_item (request: Request ): global model, tokenizer json_post_raw = await request.json() json_post = json.dumps(json_post_raw) json_post_list = json.loads(json_post) prompt = json_post_list.get('prompt' ) messages = [ {"role" : "system" , "content" : "You are a helpful assistant." }, {"role" : "user" , "content" : prompt} ] input_ids = tokenizer.apply_chat_template(messages,tokenize=False ,add_generation_prompt=True ) model_inputs = tokenizer([input_ids], return_tensors="pt" ).to('cuda' ) generated_ids = model.generate(model_inputs.input_ids,max_new_tokens=512 ) 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 ] now = datetime.datetime.now() time = now.strftime("%Y-%m-%d %H:%M:%S" ) answer = { "response" : response, "status" : 200 , "time" : time } log = "[" + time + "] " + '", prompt:"' + prompt + '", response:"' + repr (response) + '"' print (log) torch_gc() return answer if __name__ == '__main__' : model_name_or_path = '/root/autodl-tmp/qwen/Qwen1.5-7B-Chat' tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, use_fast=False ) model = AutoModelForCausalLM.from_pretrained(model_name_or_path, device_map="auto" , torch_dtype=torch.bfloat16) uvicorn.run(app, host='0.0.0.0' , port=6006 , workers=1 )
但是很可惜,我没有gpu,所以我需要做出相应的修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 from fastapi import FastAPI, Requestfrom transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfigimport uvicornimport jsonimport datetimeimport torchDEVICE = "cpu" DEVICE_ID = "0" CUDA_DEVICE = DEVICE def torch_gc (): pass app = FastAPI() @app.post("/" ) async def create_item (request: Request ): global model, tokenizer json_post_raw = await request.json() json_post = json.dumps(json_post_raw) json_post_list = json.loads(json_post) prompt = json_post_list.get('prompt' ) messages = [ {"role" : "system" , "content" : "You are a helpful assistant." }, {"role" : "user" , "content" : prompt} ] input_ids = tokenizer.apply_chat_template(messages,tokenize=False ,add_generation_prompt=True ) model_inputs = tokenizer([input_ids], return_tensors="pt" ).to('cpu' ) generated_ids = model.generate(model_inputs.input_ids,max_new_tokens=512 ) 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 ] now = datetime.datetime.now() time = now.strftime("%Y-%m-%d %H:%M:%S" ) answer = { "response" : response, "status" : 200 , "time" : time } log = "[" + time + "] " + '", prompt:"' + prompt + '", response:"' + repr (response) + '"' print (log) torch_gc() return answer if __name__ == '__main__' : model_name_or_path = '/root/autodl-tmp/qwen/Qwen1.5-0.5B-Chat' tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, use_fast=False ) model = AutoModelForCausalLM.from_pretrained(model_name_or_path).to("cpu" ) uvicorn.run(app, host='0.0.0.0' , port=6006 , workers=1 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 # 导入所需的库 from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig import torch import streamlit as st # 在侧边栏中创建一个标题和一个链接 with st.sidebar: st.markdown("## Qwen1.5 LLM") "[开源大模型食用指南 self-llm](https://github.com/datawhalechina/self-llm.git)" # 创建一个滑块,用于选择最大长度,范围在0到1024之间,默认值为512 max_length = st.slider("max_length", 0, 1024, 512, step=1) # 创建一个标题和一个副标题 st.title("💬 Qwen1.5 Chatbot") st.caption("🚀 A streamlit chatbot powered by Self-LLM") # 定义模型路径 mode_name_or_path = '/root/autodl-tmp/qwen/Qwen1.5-0.5B-Chat' # 定义一个函数,用于获取模型和tokenizer @st.cache_resource def get_model(): # 从预训练的模型中获取tokenizer tokenizer = AutoTokenizer.from_pretrained(mode_name_or_path, use_fast=False) # 从预训练的模型中获取模型,并设置模型参数 model = AutoModelForCausalLM.from_pretrained(mode_name_or_path, torch_dtype=torch.bfloat16, device_map="auto") return tokenizer, model # 加载Qwen1.5-4B-Chat的model和tokenizer tokenizer, model = get_model() # 如果session_state中没有"messages",则创建一个包含默认消息的列表 if "messages" not in st.session_state: st.session_state["messages"] = [{"role": "assistant", "content": "有什么可以帮您的?"}] # 遍历session_state中的所有消息,并显示在聊天界面上 for msg in st.session_state.messages: st.chat_message(msg["role"]).write(msg["content"]) # 如果用户在聊天输入框中输入了内容,则执行以下操作 if prompt := st.chat_input(): # 将用户的输入添加到session_state中的messages列表中 st.session_state.messages.append({"role": "user", "content": prompt}) # 在聊天界面上显示用户的输入 st.chat_message("user").write(prompt) # 构建输入 input_ids = tokenizer.apply_chat_template(st.session_state.messages,tokenize=False,add_generation_prompt=True) model_inputs = tokenizer([input_ids], return_tensors="pt").to('cuda') generated_ids = model.generate(model_inputs.input_ids, max_new_tokens=512) 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] # 将模型的输出添加到session_state中的messages列表中 st.session_state.messages.append({"role": "assistant", "content": response}) # 在聊天界面上显示模型的输出 st.chat_message("assistant").write(response) # print(st.session_state)