pull/421/head
math-zhuxy 2025-05-25 18:46:42 +08:00
parent 9e35e5348f
commit 60fa1cc635
2 changed files with 74 additions and 73 deletions

View File

@ -235,6 +235,18 @@ git clone https://github.com/jingyaogong/minimind.git
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
``` ```
因为需要的库较多,建议使用虚拟环境来安装:
```bash
python -m venv .venv
```
再下载库:
```bash
pip install -r requirements.txt
```
### 2.下载模型 ### 2.下载模型
到项目根目录 到项目根目录
```bash ```bash
@ -243,11 +255,21 @@ git clone https://huggingface.co/jingyaogong/MiniMind2
### (可选)命令行问答 ### (可选)命令行问答
如果在第1步中安装了虚拟环境,需要在使用命令行激活虚拟环境:
```bash
.venv/Scripts/activate
```
```bash ```bash
# load=0: load from pytorch model, load=1: load from transformers-hf model # load=0: load from pytorch model, load=1: load from transformers-hf model
python eval_model.py --load 1 --model_mode 2 python eval_model.py --load 1 --model_mode 2
``` ```
或者使用
```bash
python model_chat.py
```
### (可选)启动WebUI ### (可选)启动WebUI
```bash ```bash

View File

@ -1,21 +1,17 @@
print("开始加载模型")
import argparse import argparse
import random import random
import warnings
import numpy as np import numpy as np
from transformers import AutoTokenizer, AutoModelForCausalLM, TextStreamer from transformers import AutoTokenizer, TextStreamer, LlamaForCausalLM
from model.model_minimind import MiniMindConfig, MiniMindForCausalLM import torch
from model.model_lora import *
warnings.filterwarnings('ignore') def init_model():
def init_model(args):
transformers_model_path = './MiniMind2' transformers_model_path = './MiniMind2'
tokenizer = AutoTokenizer.from_pretrained(transformers_model_path) tokenizer = AutoTokenizer.from_pretrained(transformers_model_path)
model = AutoModelForCausalLM.from_pretrained(transformers_model_path, trust_remote_code=True) model = LlamaForCausalLM.from_pretrained(transformers_model_path, trust_remote_code=True)
print(f'MiniMind模型参数量: {sum(p.numel() for p in model.parameters() if p.requires_grad) / 1e6:.2f}M(illion)') print(f'模型参数量:{sum(p.numel() for p in model.parameters() if p.requires_grad) / 1e6:.2f}M(illion)')
return model.eval().to(args.device), tokenizer return model.eval().to('cuda' if torch.cuda.is_available() else 'cpu'), tokenizer
# 设置可复现的随机种子 # 设置可复现的随机种子
def setup_seed(seed): def setup_seed(seed):
@ -27,74 +23,57 @@ def setup_seed(seed):
torch.backends.cudnn.deterministic = True torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False torch.backends.cudnn.benchmark = False
parser = argparse.ArgumentParser(description="Chat with MiniMind")
parser.add_argument('--temperature', default=0.85, type=float)
parser.add_argument('--top_p', default=0.85, type=float)
def main(): parser.add_argument('--max_seq_len', default=8192, type=int)
print("开始加载模型") args = parser.parse_args()
parser = argparse.ArgumentParser(description="Chat with MiniMind") model, tokenizer = init_model()
parser.add_argument('--lora_name', default='None', type=str)
parser.add_argument('--out_dir', default='out', type=str)
parser.add_argument('--temperature', default=0.85, type=float)
parser.add_argument('--top_p', default=0.85, type=float)
parser.add_argument('--device', default='cuda' if torch.cuda.is_available() else 'cpu', type=str)
# 此处max_seq_len(最大输出长度)并不意味模型具有对应的长文本的性能,仅防止QA出现被截断的问题
# MiniMind2-moe (145M):(hidden_size=640, num_hidden_layers=8, use_moe=True)
# MiniMind2-Small (26M):(hidden_size=512, num_hidden_layers=8)
# MiniMind2 (104M):(hidden_size=768, num_hidden_layers=16)
parser.add_argument('--hidden_size', default=512, type=int)
parser.add_argument('--num_hidden_layers', default=8, type=int)
parser.add_argument('--max_seq_len', default=8192, type=int)
parser.add_argument('--use_moe', default=False, type=bool)
# 携带历史对话上下文条数
# history_cnt需要设为偶数,即【用户问题, 模型回答】为1组;设置为0时,即当前query不携带历史上文
# 模型未经过外推微调时,在更长的上下文的chat_template时难免出现性能的明显退化,因此需要注意此处设置
parser.add_argument('--history_cnt', default=0, type=int)
parser.add_argument('--load', default=0, type=int, help="0: 原生torch权重,1: transformers加载")
parser.add_argument('--model_mode', default=1, type=int,
help="0: 预训练模型,1: SFT-Chat模型,2: RLHF-Chat模型,3: Reason模型,4: RLAIF-Chat模型")
args = parser.parse_args()
model, tokenizer = init_model(args) streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True) print("模型加载完毕")
messages = [] messages = []
for prompt in iter(lambda: input('👶: '), ''): for prompt in iter(lambda: input('👶: '), ''):
if prompt == "exit": if prompt == "exit":
break break
setup_seed(random.randint(0, 2048))
messages.append({"role": "user", "content": prompt}) elif print == "clear history":
messages = []
print("成功清除对话历史")
continue
setup_seed(random.randint(0, 2048))
new_prompt = tokenizer.apply_chat_template( messages.append({"role": "user", "content": prompt})
messages,
tokenize=False,
add_generation_prompt=True
) if args.model_mode != 0 else (tokenizer.bos_token + prompt)
inputs = tokenizer( new_prompt = tokenizer.apply_chat_template(
new_prompt, messages,
return_tensors="pt", tokenize=False,
truncation=True add_generation_prompt=True
).to(args.device) )
print('🤖️: ', end='') inputs = tokenizer(
generated_ids = model.generate( new_prompt,
inputs["input_ids"], return_tensors="pt",
max_new_tokens=args.max_seq_len, truncation=True
num_return_sequences=1, ).to('cuda' if torch.cuda.is_available() else 'cpu')
do_sample=True,
attention_mask=inputs["attention_mask"],
pad_token_id=tokenizer.pad_token_id,
eos_token_id=tokenizer.eos_token_id,
streamer=streamer,
top_p=args.top_p,
temperature=args.temperature
)
response = tokenizer.decode(generated_ids[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True) print('🤖️: ', end='')
messages.append({"role": "assistant", "content": response}) generated_ids = model.generate(
print('\n') inputs["input_ids"],
max_new_tokens=args.max_seq_len,
num_return_sequences=1,
do_sample=True,
attention_mask=inputs["attention_mask"],
pad_token_id=tokenizer.pad_token_id,
eos_token_id=tokenizer.eos_token_id,
streamer=streamer,
top_p=args.top_p,
temperature=args.temperature
)
response = tokenizer.decode(generated_ids[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
if __name__ == "__main__": messages.append({"role": "assistant", "content": response})
main() print('\n')