ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

基于win11下,使用Qwen2.5 0.5B为基模型lora微调,然后使用ollama来运行自定义的大模型并支持tools的例子

基于win11下,使用Qwen2.5 0.5B为基模型lora微调,然后使用ollama来运行自定义的大模型并支持tools的例子 近期需要做相关的一些验证工作想把相关的一些内容记录下来以供日后使用后期发现问题也会继续完善。参考文章https://blog.csdn.net/spiderwower/article/details/138755776但是我按照上述的例子只能做到一半所以又找其他一些相关的资料才完成所有任务。1、下载基模型使用魔搭社区https://modelscope.cn①首先先在魔搭社区找到需要使用的基模型比如我这里使用阿里的Qwen2.5-0.5模型完整名字Qwen/Qwen2.5-0.5B-Instruct②确保已安装合适的conda环境和python环境这里使用python3.10具体不再细说。conda create-nnlppython3.10conda activate nlp310 切换到nlp310环境 conda activate nlp310 设置镜像 pip configsetglobal.index-url https://pypi.tuna.tsinghua.edu.cn/simple③安装torch环境如果有英伟达的显卡一定要安装gpu版本我这里笔记本性能有限MX3502G显存没办法只能选择小模型当然要提前安装好cuda环境这里计划使用cuda版本为11.8。可以参考文章win114060配置CUDA11.8pytorch2.0.0好之后可以使用阿里云的镜像源来安装pip3installtorch2.6.0 torchvision torchaudio-fhttps://mirrors.aliyun.com/pytorch-wheels/cu118/#南京大学镜像站pip3installtorch2.6.0 torchvision torchaudio-fhttps://mirrors.nju.edu.cn/pytorch/whl/cu118/可以通过如下地址验证版本及cuda是否可用python-cimport torch;print(torch.cuda.is_available())当然也可以安装其他版本。安装完后再接着安装训练微调使用的pip包transformers4.49.0streamlit1.24.0sentencepiece0.1.99accelerate0.29.3datasets2.14.5peft0.10.0tiktoken0.9.0 modelscope[framework]也有可能会报错原因是transformers的版本问题。这种情况下会建议安装tf-keras。pipinstalltf-keras④基模型下载使用如下的代码当然要提前安装modelscope环境变量中提前设置modelscope的默认存储地址我把下载路径换到了d:/cuda/modelscope中。环境变量名MODELSCOPE_CACHE 环境值d:/cuda/modelscope模型下载md_download1.pyfrom modelscopeimportsnapshot_download#模型存放路径# model_path /root/autodl-tmp#模型名字nameQwen/Qwen2.5-0.5B-Instruct# model_dir snapshot_download(name, cache_dirmodel_path, revisionmaster)model_dirsnapshot_download(name)注意name为你想下载的模型全名运行即可下载python md_download1.py具体内容2、下载训练集以中文数据集弱智吧为例约1500条对话数据来进行训练,完整名称为kigner/ruozhiba-llama3-tt地址为https://huggingface.co/datasets/kigner/ruozhiba-llama3-tt/tree/main我是手工下载文件到路径d:/cuda/ruozhiba-llma3-tt。3、使用lora微调。①安装相应的python包。使用其他文章中的训练代码只调整了模型名称,train.pyimportos os.environ[TF_ENABLE_ONEDNN_OPTS]0fromdatasetsimportDatasetimportpandasaspdfromtransformersimport(AutoTokenizer,AutoModelForCausalLM,DataCollatorForSeq2Seq,TrainingArguments,Trainer,)importtorchfrompeftimportLoraConfig,TaskType,get_peft_modelimportwarnings warnings.filterwarnings(ignore,categoryUserWarning)# 忽略告警devicecudaiftorch.cuda.is_available()elsecpuprint(device:device)print(fPyTorch版本:{torch.__version__})print(f是否有可用GPU:{torch.cuda.is_available()})iftorch.cuda.is_available():print(fGPU数量:{torch.cuda.device_count()})print(f当前GPU:{torch.cuda.current_device()})print(fGPU名称:{torch.cuda.get_device_name(0)})# 模型文件路径model_pathrD:/cuda/modelscope/models/Qwen/Qwen2___5-0___5B-Instruct# 训练过程数据保存路径nameruozhibaoutput_dirf./output/qwen-0.5B-{name}#是否从上次断点处接着训练如果需要从上次断点处继续训练值应为Truetrain_with_checkpointFalse# 加载tokenizertokenizerAutoTokenizer.from_pretrained(model_path,use_fastFalse,trust_remote_codeTrue)tokenizer.pad_tokentokenizer.eos_token# 加载数据集dfpd.read_json(fD:/cuda/ruozhiba-llama3-tt/ruozhiba_qa.json)dsDataset.from_pandas(df)print(ds)# 对数据集进行处理需要将数据集的内容按大模型的对话格式进行处理# 大模型处理defprocess_func_mistral(example):MAX_LENGTH384# Llama分词器会将一个中文字切分为多个token因此需要放开一些最大长度保证数据的完整性instructiontokenizer(fs[INST] SYS\n\n/SYS\n\n{example[instruction]example[input]}[/INST],add_special_tokensFalse)# add_special_tokens 不在开头加 special_tokensresponsetokenizer(f{example[output]},add_special_tokensFalse)input_idsinstruction[input_ids]response[input_ids][tokenizer.pad_token_id]attention_maskinstruction[attention_mask]response[attention_mask][1]# 因为pad_token_id咱们也是要关注的所以 补充为1labels[-100]*len(instruction[input_ids])response[input_ids][tokenizer.pad_token_id]iflen(input_ids)MAX_LENGTH:# 做一个截断input_idsinput_ids[:MAX_LENGTH]attention_maskattention_mask[:MAX_LENGTH]labelslabels[:MAX_LENGTH]return{input_ids:input_ids,attention_mask:attention_mask,labels:labels}inputs_idds.map(process_func_mistral,remove_columnsds.column_names)#加载模型# 根据GPU能力选择合适的数据类型iftorch.cuda.is_available()andtorch.cuda.get_device_capability()[0]8:# A100、H100、RTX 40系列等支持bfloat16torch_dtypetorch.bfloat16else:# 其他GPU使用float16torch_dtypetorch.float16print(f使用的数据类型:{torch_dtype})ifnotos.path.exists(model_path):raiseValueError(f模型路径不存在:{model_path})# 列出路径下的文件检查是否包含配置文件print(f模型路径下的文件:{os.listdir(model_path)})modelAutoModelForCausalLM.from_pretrained(model_path,device_mapdevice,torch_dtypetorch.bfloat16,use_cacheFalse)model.enable_input_require_grads()# 开启梯度检查点时要执行该方法print(model)#设置lora训练参数configLoraConfig(task_typeTaskType.CAUSAL_LM,target_modules[q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj],inference_modeFalse,# 训练模式r8,# Lora 秩lora_alpha32,# Lora alaph具体作用参见 Lora 原理lora_dropout0.1# Dropout 比例)#设置训练参数modelget_peft_model(model,config)model.print_trainable_parameters()argsTrainingArguments(output_diroutput_dir,# 模型保存路径per_device_train_batch_size2,# 训练的批大小 之前为2显存2G可用实际显存最大会占到4.6G 32时显存占用到15G16时显存占用到15G8时显存占用到11.7G4时显存占用到6.7Ggradient_accumulation_steps2,# 梯度累积步数logging_steps10,# 日志打印的步数num_train_epochs2,# 训练的轮数 之前为2save_steps25,# 保存的步数save_total_limit2,# 保存的模型数量learning_rate1e-4,# 学习率save_on_each_nodeTrue,# 多节点训练时每个节点保存一次gradient_checkpointingTrue,# 开启梯度检查点label_names[labels],# 标签名称)trainerTrainer(modelmodel,argsargs,train_datasetinputs_id,data_collatorDataCollatorForSeq2Seq(tokenizertokenizer,paddingTrue),)#开始训练# 如果训练中断了还可以从上次中断保存的位置继续开始训练iftrain_with_checkpoint:checkpoint[fileforfileinos.listdir(output_dir)ifcheckpointinfile][-1]last_checkpointf{output_dir}/{checkpoint}print(last_checkpoint)trainer.train(resume_from_checkpointlast_checkpoint)else:trainer.train()执行代码python train.py会生成几个checkpoint这个过程在我的电脑上2轮批次大小2个使用了差不多50分钟精度也很差。0.5b训练截图后来找了资源又试了其他的批次8,100轮训练A4000显卡16G显存loss降到了0.005情况{loss:0.005,grad_norm:0.1689453125,learning_rate:0.0,epoch:98.94}{train_runtime:4730.9062,train_samples_per_second:31.622,train_steps_per_second:1.966,train_loss:0.09664655848256042,epoch:98.94}100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████|9300/9300[1:18:5000:00,1.97it/s]我的MX3502G显存调1.5b模型的截图②、checkpoint转为loracheckpoint_to_lora.py具体代码from transformersimportAutoModelForSequenceClassification,AutoTokenizerimportos# 需要保存的lora路径lora_pathd:/cuda/lora/qwen-0__5B-lora-ruozhiba# 模型路径model_pathD:/cuda/modelscope/models/Qwen/Qwen2___5-0___5B-Instruct# 检查点路径checkpoint_diroutput/qwen-0.5B-ruozhibacheckpoint[fileforfileinos.listdir(checkpoint_dir)ifcheckpoint-infile][-1]#选择更新日期最新的检查点modelAutoModelForSequenceClassification.from_pretrained(foutput/qwen-0.5B-ruozhiba/{checkpoint})# 保存模型model.save_pretrained(lora_path)tokenizerAutoTokenizer.from_pretrained(model_path,use_fastFalse,trust_remote_codeTrue)tokenizer.pad_tokentokenizer.eos_token# 保存tokenizertokenizer.save_pretrained(lora_path)执行代码python checkpoint_to_lora.py最终会把模型生成到d:/cuda/lora/qwen-0__5B-lora-ruozhiba中③、模型合并merge.py代码如下from transformersimportAutoModelForCausalLM, AutoTokenizerimporttorch from peftimportPeftModel from peftimportLoraConfig, TaskType, get_peft_model model_pathD:/cuda/modelscope/models/Qwen/Qwen2___5-0___5B-Instructlora_pathd:/cuda/lora/qwen-0__5B-lora-ruozhibadevicecudaiftorch.cuda.is_available()elsecpu# 合并后的模型路径output_pathrd:/cuda/merge# 等于训练时的config参数configLoraConfig(task_typeTaskType.CAUSAL_LM,target_modules[q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj],inference_modeFalse,# 训练模式r8,# Lora 秩lora_alpha32,# Lora alaph具体作用参见 Lora 原理lora_dropout0.1# Dropout 比例)baseAutoModelForCausalLM.from_pretrained(model_path,torch_dtypetorch.bfloat16,low_cpu_mem_usageTrue)base_tokenizerAutoTokenizer.from_pretrained(model_path)lora_modelPeftModel.from_pretrained(base, lora_path,torch_dtypetorch.float16,configconfig)modellora_model.merge_and_unload()model.save_pretrained(output_path)base_tokenizer.save_pretrained(output_path)执行代码python merge.py生成结果如下④模型转为gguf格式下载源码https://github.com/ggml-org/llama.cpp使用其中的转换器转换其实这里已经转为gguf格式只是是f16格式的第一种python convert_hf_to_gguf.py D:/cuda/merge--outtypef16--outfiled:/cuda/qwen-ruozhiba.bin也可以用如下指令量化为Q8的模型python convert_hf_to_gguf.py /myweb/cuda/merge--outtypeq8_0 此处处理过后会生成类似 Merge-0.5B-Q8_0.gguf 的文件4、模型量化注意如果仅用f16或者q8则如下可以不用再执行。首先下载llama.cpp的编译包https://github.com/ggml-org/llama.cpp/releases根据自己的cpu情况选择合适的包比我的使用的cpu是intel10代处理通过cpuz可以查看支持的技术我这里支持AVX和AVX2可以使用AVX2的包下载后解压会得到相关的编译包可以将路径加到path中但要注意避免冲突PS:后期升级ollama后出现了冲突去掉path即可。然后在D:/cuda中执行转换llama-quantize qwen-ruozhiba.bin q5_k_m会生成一个新文件ggml-model-Q5_K_M.gguf将文件放到新的目录D:/cuda/qwen2.5-new5、安装ollama。下载https://ollama.com/download/OllamaSetup.exe安装。然后到文件夹中新增一个文件文件名ModelFile内容如下第一种FROM D:/cuda/qwen2.5-new/ggml-model-Q5_K_M.gguf#FROM ./Merge-1.5B-F16.gguf#FROM D:/cuda/qwen2.5-new/ggml-model-Q5_K_M.gguf#FROM D:/cuda/qwen2.5-new/ggml-model-0.5_Q5_K_M.gguf# set the temperature to 0.7 [higher is more creative, lower is more coherent]PARAMETER temperature0.7PARAMETER top_p0.8PARAMETER repeat_penalty1.05TEMPLATE{{if.System}}|im_start|system{{.System}}|im_end|{{end}}{{if.Prompt}}|im_start|user{{.Prompt}}|im_end|{{end}}|im_start|assistant{{.Response}}|im_end|# set the system messageSYSTEM You are a helpful assistant.第二种FROM ./Merge-1.5B-F16.gguf# 修复1简化系统提示移除冗余条件判断SYSTEM|im_start|system You are Qwen, created by Alibaba Cloud. You are a helpful assistant.|im_end|# 修复2完全重写模板结构TEMPLATE{{if.System}}|im_start|system{{.System}}|im_end|{{else}}|im_start|system You are Qwen, created by Alibaba Cloud. You are a helpful assistant.|im_end|{{end}}{{range .Messages}}{{ifeq .Roleuser}}|im_start|user{{.Content}}|im_end|{{elseifeq .Roleassistant}}|im_start|assistant{{.Content}}|im_end|{{elseifeq .Rolesystem}}|im_start|system{{.Content}}|im_end|{{end}}{{end}}|im_start|assistant第三种如果需要支持tool可以使用如下内容#FROM qwen2.5:1.5bFROM ./Merge-1.5B-F16.gguf# set the temperature to 0.7 [higher is more creative, lower is more coherent]PARAMETER temperature0.7PARAMETER top_p0.8PARAMETER repeat_penalty1.05TEMPLATE{{-if.Messages}}{{-ifor .System .Tools}}|im_start|system{{-if.System}}{{.System}}{{- end}}{{-if.Tools}}# ToolsYou may call one ormorefunctions to assist with the user query. You are provided withfunctionsignatures withintools/toolsXML tags:tools{{- range .Tools}}{type:function,function:{{.Function}}}{{- end}}/toolsFor eachfunctioncall,returna json object withfunctionname and arguments withintool_call/tool_callXML tags:tool_call{name:function-name,arguments:args-json-object}/tool_call{{- end}}|im_end|{{end}}{{- range$i,$_:.Messages}}{{-$last:eq(len(slice $.Messages$i))1-}}{{-ifeq .Roleuser}}|im_start|user{{.Content}}|im_end|{{elseifeq .Roleassistant}}|im_start|assistant{{if.Content}}{{.Content}}{{-elseif.ToolCalls}}tool_call{{range .ToolCalls}}{name:{{ .Function.Name }},arguments:{{.Function.Arguments}}}{{end}}/tool_call{{- end}}{{ifnot$last}}|im_end|{{end}}{{-elseifeq .Roletool}}|im_start|usertool_response{{.Content}}/tool_response|im_end|{{end}}{{-ifand(ne .Roleassistant)$last}}|im_start|assistant{{end}}{{- end}}{{-else}}{{-if.System}}|im_start|system{{.System}}|im_end|{{end}}{{if.Prompt}}|im_start|user{{.Prompt}}|im_end|{{end}}|im_start|assistant{{end}}{{.Response}}{{if.Response}}|im_end|{{end}} SYSTEMYou are a helpful assistant, created by Alibaba Cloud and fine-tunedforspecific tasks. You have access to the following tools: - When appropriate, you can use tools to assist with the users query. - Tools will be provided in tools/tools XML tags. - For each function call, return a json object with function name and arguments within tool_call/tool_call XML tags. You should only use tools when necessary and beneficial to the users query.执行创建ollama create qwen2_0.5b_demo--file./ModelFile最后运行模型ollama run qwen2_0.5b_demo可以愉快的玩耍啦。可以使用ollama show qwen2_0.5b_demo类似的指令来查看部署的模型类型。一般模型我今天又调了1.5b做测试内容如下已经支持tools了但是因为大模型实在太小没什么效果后来训练的新模型还有些用有空也可以尝试比较大的模型作为基模型来进行训练。如果需要联网思路可以参考文章https://blog.csdn.net/ChinaLiaoTian/article/details/145504774如果需要知识库能力可以参考https://blog.csdn.net/sheex2012/article/details/138339166
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表