原生安装方式参考:
从零开始:Windows系统下Qwen2.5大模型的实践教程(一)_本地部署qwen2.5-CSDN博客
LLMs之Qwen:Qwen2.5的简介、安装和使用方法、案例应用之详细攻略_ollama run qwen2.5-CSDN博客 flask 不能访问/login_the requested url was not found on the server. if -CSDN博客
ollama安装方式参考:
https://github.com/QwenLM/Qwen2.5/tree/main
魔搭社区-Qwen/Qwen2.5-0.5B-Instruct
在windows11本地部署大模型的记录(OLLAMA、AnythingLLM)_windows ollama使用gpu-CSDN博客
https://github.com/ollama/ollama/blob/main/README.md
使用ollama安装:
ollama run qwen2.5:0.5b
原生安装方式,写代码如下:
import torch
from flask import Flask
from flask import request
from transformers import (AutoTokenizer, AutoModelForCausalLM, AutoModel,
Qwen2ForCausalLM, Qwen2Tokenizer)
# from peft import PeftModel
# 参数
max_new_tokens: int = 64 # 生成响应时最大的新token数
temperature: float = 0.6 # 控制生成文本的随机性
top_p: float = 0.9 # 用于概率限制的参数,有助于控制生成文本的多样性
top_k: int = 32 # 控制生成过程中每一步考虑的最可能token的数量
repetition_penalty: float = 1.2 # 用于惩罚重复生成相同token的参数
system_template_prompt = "你是一个专门评估网购评论情感的分析模型。你的任务是判断给定评论是正面还是负面。"
system_prompt = "你是一个专门分类新闻标题的分析模型。你的任务是判断给定新闻短文本标题的分类。"
user_template_prompt = ("请评估以下评论,不要返回0或1以外的任何信息,不要返回你的思考过程。"
"如果是正面评论输出1,是反面评论输出0。输入如下:{}\n请填写你的输出:")
user_prompt = ("请将以下新闻短文本标题分类到以下类别之一:故事、文化、娱乐、体育、财经、房产、汽车、教育、"
"科技、军事、旅游、国际、股票、农业、游戏。输入如下:\n{}\n请填写你的输出:")
eos_token_id = [151645, 151643]
app = Flask(__name__)
# lora_model_path = "./output/Qwen2.5-1.5b/checkpoint-100"
model_path = "D:\Dev\models\Qwen2___5-0___5B-Instruct"
# 从指定路径加载大模型的分词器(tokenizer),用于加载预训练的文本处理模型(Tokenizer),以便将文本数据转换为模型可以接受的输入格式。
tokenizer = Qwen2Tokenizer.from_pretrained(model_path)
# AutoModelForCausalLM更适合语言大模型
model = Qwen2ForCausalLM.from_pretrained(model_path, device_map='cpu').eval()
# 非流式请求
@app.route('/chat_old', methods=["POST"])
def chat_old():
# 系统设定和prompt
req_json = request.json
content = user_template_prompt.format(req_json['message'])
messages = [
{"role": "system", "content": system_template_prompt},
{"role": "user", "content": content}
]
# 使用tokenizer将整个会话转换成模型可以理解的input_ids,并将这些input_ids输入到模型
# tokenize=False 表示不要立即分词,只是使用apply_chat_template将会话进行格式化
input_ids = tokenizer.apply_chat_template(messages,
tokenize=False,
add_generation_prompt=True)
print(f"input:{input_ids}")
inputs = tokenizer([input_ids], return_tensors="pt").to(model.device)
generated_ids = model.generate(
inputs.input_ids,
max_new_tokens=max_new_tokens,
repetition_penalty=repetition_penalty, # 解决问题后面有过多重复问答(对重复token的惩罚)
eos_token_id=eos_token_id, # 结束令牌,模型生成这个token时,停止生成
)
generated_ids = [
output_ids[len(inputs):] for inputs, output_ids in zip(inputs.input_ids, generated_ids)
]
print(f"generated_ids=\n{generated_ids}")
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
response = response.encode('utf-8', errors='ignore').decode('utf-8')
print(response)
# 使用占位符拼接字符串
return response
@app.route('/chat', methods=["POST"])
def chat():
# 系统设定和prompt
req_json = request.json
prompt = user_prompt.format(req_json['message'])
print(prompt)
# 非会话的输入方式,将单句话进行分词成token ids
inputs = tokenizer(prompt, return_tensors="pt")
input_ids = inputs.input_ids
# Generate
generate_ids = model.generate(input_ids=input_ids,
bos_token_id=151645, # 开始令牌(在生成文本时,模型会在输入序列的末尾添加这个令牌,以指示新生成的文本的开始。)
max_new_tokens=len(input_ids) + 1,
repetition_penalty=repetition_penalty)
print(generate_ids)
response = tokenizer.batch_decode(generate_ids, skip_special_tokens=True)[0]
print(response)
# # 去掉response中的包含prompt的文本
response = response[len(prompt):]
return response.strip()
@app.route('/hello')
def hello():
return 'Hello, World'
if __name__ == '__main__':
app.run(port=8181, host="0.0.0.0")
发消息访问web服务: