【个人开发】macbook m1 Lora微调qwen大模型
本项目参考网上各类教程整理而成,为个人学习记录。
项目github源码地址:Lora微调大模型
项目中微调模型为:qwen/Qwen1.5-4B-Chat。
去年新发布的Qwen/Qwen2.5-3B-Instruct同样也适用。
微调步骤
step0: 环境准备
conda create --name fine-tuning python=3.10
conda activate fine-tuning
pip3 install -r requirements.txt
step1: 下载模型
本次微调使用Qwen/Qwen1.5-4B-Chat,通过modelscope下载。维护好train.py中的model_id即可,train.py运行时候,会自动下载。
其他下载方式,
# 下载到~/.cache目录。
modelscope download --model qwen/Qwen1.5-4B-Chat
step2: 准备微调语料
微调语料见./dataset/huanhuan.json文件,可根据需求调整语料。
step3: 训练模型
相应源码见github。
python3 train.py
说明:
为提升模型的微调效果,可根据需求调整train.py中训练参数:num_train_epochs(迭代次数),
training_args = TrainingArguments(output_dir=checkpoint_dir,per_device_train_batch_size=4,gradient_accumulation_steps=4,logging_steps=10,num_train_epochs=20,save_steps=100,learning_rate=1e-4,save_on_each_node=True,gradient_checkpointing=True,)
step4: 调用训练后的模型
相关代码参考train.py中的infer函数
step5: 合并模型及调用合并后的模型进行问答
分别对应merge.py中的merge函数根chat函数。
python3 merge.py
注意:因为是对话式文本生成模型,所以建议使用如下的推理方式,应包含eos_token_id,pad_token_id,attention_mask这些参数,否则容易出现回答后带上一些乱七八糟的东西。
prompt = "你好"
messages = [{"role": "user", "content": prompt}]
text = tokenizer.apply_chat_template(messages)
model_inputs = tokenizer([text], return_tensors="pt")
generated_ids = model.generate(model_inputs.input_ids,max_length=50,max_new_tokens=512,eos_token_id=tokenizer.encode('<|eot_id|>')[0],pad_token_id=tokenizer.pad_token_id,attention_mask=model_inputs.attention_mask,
)
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]
同理,这里踩了个坑,使用如下的推理方式,回答也是乱起八糟。
prompt = "你好"
inputs = tokenizer(prompt, return_tensors="pt")
# 生成文本
output_sequences = model.generate(inputs['input_ids'],max_length=50,temperature=0.7,num_return_sequences=1
)
# 解码生成的文本
generated_text = tokenizer.decode(output_sequences[0], skip_special_tokens=True)
print(generated_text)
step6: ollama集成
集成到ollama中,需要两个步骤。
step6.1 转化为gguf文件
项目同目录下,下载llama.cpp并安装
cd ..
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
pip3 install -r requirements.txt
make
转化为gguf文件
python convert_hf_to_gguf.py ../fine-tuning-by-Lora/models/output/qwen/Qwen1.5-4B-Chat --outtype f16 --outfile ../fine-tuning-by-Lora/models/
step6.2 打包模型文件
model文件夹中编辑Modelfile文件
# Modelfile文件内容
FROM Qwen1.5-4B-Chat-F16.ggufTEMPLATE """{{ if .System }}<|start_header_id|>system<|end_header_id|>{{ .System }}<|eot_id|>{{ end }}{{ if .Prompt }}<|start_header_id|>user<|end_header_id|>{{ .Prompt }}<|eot_id|>{{ end }}<|start_header_id|>assistant<|end_header_id|>{{ .Response }}<|eot_id|>"""
PARAMETER stop "<|start_header_id|>"
PARAMETER stop "<|end_header_id|>"
PARAMETER stop "<|eot_id|>"
PARAMETER stop "<|reserved_special_token>"
打包:
ollama create Qwen1.5-4B-Chat-F16 -f Modelfile
step6.3 运行
ollama run Qwen1.5-4B-Chat-F16:latest

说明:如果Modelfile中的TEMPLATE跟PARAMETER参数没写,模型推理结果也可能胡说八道。
打包到ollama之后,可以直接把模型接入到dify。

踩坑过程
经验1
一般在微调的时候,需要关注模型的loss情况,自己训练20轮的话,损失函数的值能看到在收敛,但还是还没完全收敛。
如果模型微调后效果不好,可以关注训练时损失函数下降情况。一般到50~60轮左右,loss会下降到0.01左右的水平,相应的梯度(grad_norm)跟学习率(learning_rate)也会减少。
{'loss': 3.2201, 'grad_norm': 4.969257831573486, 'learning_rate': 9.5e-05, 'epoch': 5.0}
{'loss': 1.5577, 'grad_norm': 1.9476478099822998, 'learning_rate': 9e-05, 'epoch': 10.0}
{'loss': 0.7901, 'grad_norm': 2.8456532955169678, 'learning_rate': 8.5e-05, 'epoch': 15.0}
{'loss': 0.1381, 'grad_norm': 0.3789016008377075, 'learning_rate': 8e-05, 'epoch': 20.0}
{'loss': 0.0045, 'grad_norm': 0.06659594923257828, 'learning_rate': 7.5e-05, 'epoch': 25.0}
{'loss': 0.0014, 'grad_norm': 0.034729525446891785, 'learning_rate': 7e-05, 'epoch': 30.0}
{'loss': 0.0007, 'grad_norm': 0.020955145359039307, 'learning_rate': 6.5e-05, 'epoch': 35.0}
{'loss': 0.0005, 'grad_norm': 0.01589277759194374, 'learning_rate': 6e-05, 'epoch': 40.0}
{'loss': 0.0003, 'grad_norm': 0.013618703931570053, 'learning_rate': 5.5e-05, 'epoch': 45.0}
{'loss': 0.0003, 'grad_norm': 0.01169560570269823, 'learning_rate': 5e-05, 'epoch': 50.0}
{'loss': 0.0002, 'grad_norm': 0.010867319069802761, 'learning_rate': 4.5e-05, 'epoch': 55.0}
{'loss': 0.0002, 'grad_norm': 0.010721373371779919, 'learning_rate': 4e-05, 'epoch': 60.0}
{'loss': 0.0002, 'grad_norm': 0.010178590193390846, 'learning_rate': 3.5e-05, 'epoch': 65.0}
{'loss': 0.0002, 'grad_norm': 0.009332481771707535, 'learning_rate': 3e-05, 'epoch': 70.0}
{'loss': 0.0002, 'grad_norm': 0.009383821859955788, 'learning_rate': 2.5e-05, 'epoch': 75.0}
{'loss': 0.0002, 'grad_norm': 0.008890513330698013, 'learning_rate': 2e-05, 'epoch': 80.0}
{'loss': 0.0002, 'grad_norm': 0.008669395931065083, 'learning_rate': 1.5e-05, 'epoch': 85.0}
{'loss': 0.0002, 'grad_norm': 0.00943685695528984, 'learning_rate': 1e-05, 'epoch': 90.0}
{'loss': 0.0002, 'grad_norm': 0.0088260592892766, 'learning_rate': 5e-06, 'epoch': 95.0}
{'loss': 0.0002, 'grad_norm': 0.008713439106941223, 'learning_rate': 0.0, 'epoch': 100.0}
{'train_runtime': 3008.4296, 'train_samples_per_second': 0.532, 'train_steps_per_second': 0.033, 'train_loss': 0.2857893861143384, 'epoch': 100.0}
报错1
训练时报错:NotImplementedError: Cannot copy out of meta tensor; no data! Please use torch.nn.Module.to_empty() instead of torch.nn.Module.to() when moving module from meta to a different device.
训练时在调用transformers/trainer.py的时候,会报该错。
源码如下:
model = model.to(device)
尝试了如下方式:
#修改方式
#origin: new_value=old_value.to("cpu"),下面两种写法任选其一
new_value=torch.tensor(old_value,device="cpu")
new_value=torch.empty_like(old_value,device="cpu")
不好使!
最后好使的方式是关掉电脑中高内存的应用,给程序提供足够的资源。
报错2
推理时候报错:RuntimeError: Placeholder storage has not been allocated on MPS device!
解决方案:关掉电脑高内存应用,强制设置 device = “cpu”。
报错3
合并模型出现报错,自己尝试时候只出现过一次,报错为,模型某一层的key值在某个模块中没找到
解决方案:重新微调模型,可能是模型微调出现了中断or其他原因,导致模型结构出现异常
参考文档:
Mac M2之LLaMA3-8B微调(llama3-fine-tuning)
相关文章:
【个人开发】macbook m1 Lora微调qwen大模型
本项目参考网上各类教程整理而成,为个人学习记录。 项目github源码地址:Lora微调大模型 项目中微调模型为:qwen/Qwen1.5-4B-Chat。 去年新发布的Qwen/Qwen2.5-3B-Instruct同样也适用。 微调步骤 step0: 环境准备 conda create --name fin…...
sqli-labs靶场实录(二): Advanced Injections
sqli-labs靶场实录: Advanced Injections Less21Less22Less23探测注入点 Less24Less25联合注入使用符号替代 Less25aLess26逻辑符号绕过and/or过滤双写and/or绕过 Less26aLess27Less27aLess28Less28aLess29Less30Less31Less32(宽字节注入)Less33Less34Le…...
Linux系统 环境变量
环境变量 写在前面概念查看环境变量main函数的参数argc & argvenv bash环境变量 写在前面 对于环境变量,本篇主要介绍基本概念及三四个环境变量 —— PATH、HOME、PWD。其中 PATH 作为 “ 敲门砖 ”,我们会更详细讲解;理解环境变量的全局…...
机器学习-线性回归(最大似然估计)
机器学习任务可以分为两类: 一类是样本的特征向量 𝒙 和标签 𝑦 之间存在未知的函数关系𝑦 h(𝒙),另一类是条件概率𝑝(𝑦|𝒙)服从某个未知分布。最小二乘法是属于第一类,…...
【信息系统项目管理师-案例真题】2017上半年案例分析答案和详解
更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 试题一【问题1】8 分【问题2】4 分【问题3】8 分【问题4】5 分试题二【问题1】10 分【问题2】8 分【问题3】6 分【问题4】5 分试题三【问题1】5 分【问题2】7 分【问题3】6 分【问题4】3 分试题一 阅读下列说明…...
CSP晋级组比赛生成文件夹与文件通用代码Python
快速生成文件夹与文件的脚本 import sys import osmyfiles sys.argv[1::] for f in myfiles:os.mkdir(f)os.system(f"touch {f}/{f}.in")os.system(f"touch {f}/{f}.out")os.system(f"touch {f}/{f}.cpp")with open("template.cpp",…...
正则表达式进阶(二)——零宽断言详解:\b \B \K \z \A
在正则表达式中,零宽断言是一种非常强大的工具,能够在不消费字符的情况下对匹配位置进行约束。除了环视(lookahead 和 lookbehind)以外,还有一些常用的零宽断言,它们用于处理边界、字符串的开头和结尾等特殊…...
Android 中实现 PDF 预览三种方式
目录 1. 使用第三方库 PdfRenderer(适用于 Android 5.0 及以上) 步骤:2. 使用第三方库 MuPDF步骤:3. 使用第三方库 PdfiumAndroid步骤: 1. 使用第三方库 PdfRenderer(适用于 Android 5.0 及以上)…...
尚硅谷课程【笔记】——大数据之Zookeeper【二】
课程视频:【尚硅谷Zookeeper教程】 四、Zookeeper实战 4.1分布式安装部署 1. 集群规划 在Hadoop102、Hadoop103和Hadoop104三个节点上部署Zookeeper 2. 解压安装 1)解压Zookeeper.tar.gz到指定目录 tar -zxvf zookeeper-3.7.2.tar.gz -C /opt/mod…...
CodeGPT + IDEA + DeepSeek,在IDEA中引入DeepSeek实现AI智能开发
CodeGPT IDEA DeepSeek,在IDEA中引入DeepSeek 版本说明 建议和我使用相同版本,实测2022版IDEA无法获取到CodeGPT最新版插件。(在IDEA自带插件市场中搜不到,可以去官网搜索最新版本) ToolsVersionIntelliJ IDEA202…...
postgresql 游标(cursor)的使用
概述 PostgreSQL游标可以封装查询并对其中每一行记录进行单独处理。当我们想对大量结果集进行分批处理时可以使用游标,因为一次性处理可能造成内存溢出。 另外我们可以定义函数返回游标类型变量,这是函数返回大数据集的有效方式,函数调用者…...
计算机组成原理——指令系统(六)
在时间的长河中,我们都是追梦人,脚下的每一步都在刻画未来的模样。无论世界如何变幻,心中的那团火焰都不应熄灭。它是你突破黑暗、迎接黎明的力量源泉。每一个不曾起舞的日子,都是对生命的辜负;每一次跌倒后的站起&…...
Python设计模式 - 原型模式
定义 原型模式是一种创建型设计模式,它可以通过复制现有对象来创建新对象,而不是直接实例化新的对象。 结构 抽象原型(Prototype):声明 clone() 方法,以便派生类实现克隆自身的能力。具体原型(…...
金和OA C6 DownLoadBgImage任意文件读取漏洞
金和OA C6 DownLoadBgImage任意文件读取漏洞 漏洞描述 金和C6数据库是一款针对企业信息化管理而设计的高级数据库管理系统,主要应用于企业资源规划(ERP)、客户关系管理(CRM)以及办公自动化(OA)…...
【stm32学习】STM32F103实操primary(FlyMCU)
github插入图片实在是太难用了,暂时懒得学就先用CSDN吧hh 一、在设备管理器下,找到单片机,并检查与FlyMCU-搜索端口 显示的是否一致 二、在搜索串口右面的栏里选中该Port,波特率选中115200 三、选择文件夹中的.hex文件࿰…...
如何将Excel的表格存为图片?
emmm,不知道题主具体的应用场景是什么,就分享几个我一般会用到的场景下奖excel表格保存为图片的技巧吧! 先来个总结: 方法 适用场景 画质 操作难度 截图(WinShiftS) 快速保存表格,方便粘贴…...
51单片机之使用Keil uVision5创建工程以及使用stc-isp进行程序烧录步骤
一、Keil uVision5创建工程步骤 1.点击项目,新建 2.新建目录 3.选择目标机器,直接搜索at89c52选择,然后点击OK 4.是否添加起吊文件,一般选择否 5.再新建的项目工程中添加文件 6.选择C文件 7.在C文件中右键,添加…...
AUTOSAR面试题集锦(1)
最基础概念 什么是AUTOSAR?AUTOSAR到底做了什么? AUTOSAR,即汽车开放系统架构,是一套专门用于汽车的开放性的框架和行业标准,旨在标准化汽车开发的流程。 AUTOSAR 通过标准化软件接口、交换格式和方法论等内容,主要实现以下几个目标: 1. 使软件和硬件彼此独立,让应…...
【Uniapp-Vue3】从uniCloud中获取数据
需要先获取数据库对象: let db uniCloud.database(); 获取数据库中数据的方法: db.collection("数据表名称").get(); 所以就可以得到下面的这个模板: let 函数名 async () > { let res await db.collection("数据表名称…...
AIOS: 一个大模型驱动的Multi-Agent操作系统设计与Code分析
AIOS: 一个大模型驱动的Multi-Agent操作系统设计与Code分析 随着人工智能技术的快速发展,传统操作系统逐渐暴露出难以适应AI时代多样化需求的局限性。特别是在支持多个智能体协同工作方面存在显著不足。为此,我们提出了一种名为AIOS(Artifici…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
java高级——高阶函数、如何定义一个函数式接口类似stream流的filter
java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用(Math::max) 2 函数接口…...
【记录坑点问题】IDEA运行:maven-resources-production:XX: OOM: Java heap space
问题:IDEA出现maven-resources-production:operation-service: java.lang.OutOfMemoryError: Java heap space 解决方案:将编译的堆内存增加一点 位置:设置setting-》构建菜单build-》编译器Complier...
Cursor AI 账号纯净度维护与高效注册指南
Cursor AI 账号纯净度维护与高效注册指南:解决限制问题的实战方案 风车无限免费邮箱系统网页端使用说明|快速获取邮箱|cursor|windsurf|augment 问题背景 在成功解决 Cursor 环境配置问题后,许多开发者仍面临账号纯净度不足导致的限制问题。无论使用 16…...
RFID推动新能源汽车零部件生产系统管理应用案例
RFID推动新能源汽车零部件生产系统管理应用案例 一、项目背景 新能源汽车零部件场景 在新能源汽车零部件生产领域,电子冷却水泵等关键部件的装配溯源需求日益增长。传统 RFID 溯源方案采用 “网关 RFID 读写头” 模式,存在单点位单独头溯源、网关布线…...
