AI大模型微调(三)------Qwen3模型Lora微调(使用Llamafactory)

AI大模型微调(三)------Qwen3模型Lora微调(使用Llamafactory)

AI大模型微调(三)------Qwen3模型Lora微调(使用Llamafactory)

文章目录


一、安装LLaMA-Factory&开发环境

开源项目地址:https://github.com/hiyouga/LLaMA-Factory
文档:https://llamafactory.readthedocs.io/zh-cn/latest/

# 创建新开发环境 conda create -n llama_factory_Qwen3 python=3.11-y conda activate llama_factory_Qwen3 (llama_factory_Qwen3) C:\Users\Administrator>D:# 下载项目 & 安装 git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip install -e ".[torch,metrics]"

在git失败时,清理DNS缓存,然后继续:

ipconfig/flushdns 

二、数据集

dataset_info.json 包含了所有经过预处理的本地数据集,以及在线数据集。如果您希望使用自定义数据集,请务必在 dataset_info.json 文件中添加对数据集及其内容的定义。目前项目支持 Alpaca 格式和 ShareGPT 格式的数据集。以本实践任务关注的微调数据集为例:

1.Alpaca

指令监督微调 (Instruct Tuning) 通过让模型学习详细的指令以及对应的回答来优化模型在特定指令下的表现。instruction 列对应的内容为人类指令,input 列对应的内容为人类输入,output 列对应的内容为模型回答。下面是一个例子:

{"instruction":"计算这些物品的总费用。","input":"输入:汽车 - $3000,衣服 - $100,书 - $20。","output":"汽车、衣服和书的总费用为 $3000 + $100 + $20 = $3120。"}

在进行指令监督微调时,instruction 列对应的内容会与 input 列对应的内容拼接后作为最终的人类输入,即人类输入为 instruction\ninput。而 output 列对应的内容为模型回答。在上面的例子中,人类的最终输入是:

计算这些物品的总费用。 输入:汽车 - $3000,衣服 - $100,书 - $20。 

模型的回答是:

汽车、衣服和书的总费用为 $3000+ $100+ $20= $3120。 

如果指定 system 列对应的内容将被作为系统提示词。history 列是由多个字符串二元组构成的列表,分别代表历史消息中每轮对话的指令和回答。注意在指令监督微调时,历史消息中的回答内容也会被用于模型学习。

指令监督微调数据集的最终 格式要求 如下:

[{"instruction":"人类指令(必填)","input":"人类输入(选填)","output":"模型回答(必填)","system":"系统提示词(选填)","history":[["第一轮指令(选填)","第一轮回答(选填)"],["第二轮指令(选填)","第二轮回答(选填)"]]}]

下面提供一个Alpaca 格式多轮对话的例子,对于单轮对话只需省略history列:

[{"instruction":"今天的天气怎么样?","input":"","output":"今天的天气不错,是晴天。","history":[["今天会下雨吗?","今天不会下雨,是个好天气。"],["今天适合出去玩吗?","非常适合,空气质量很好。"]]}]

对于上述格式的数据,dataset_info.json 中的数据集描述应为:

"数据集名称":{"file_name":"data.json","columns":{"prompt":"instruction","query":"input","response":"output","system":"system","history":"history"}}

2.ShareGPT

相比 alpaca 格式的数据集,sharegpt 格式支持更多的角色种类,例如 human、gpt、observation、function 等等。它们构成一个对象列表呈现在 conversations 列中。

下面是 sharegpt 格式的一个例子:

{"conversations":[{"from":"human","value":"你好,我出生于1990年5月15日。你能告诉我今天几岁了吗?"},{"from":"function_call","value":"{\"name\": \"calculate_age\", \"arguments\": {\"birthdate\": \"1990-05-15\"}}"},{"from":"observation","value":"{\"age\": 31}"},{"from":"gpt","value":"根据我的计算,你今天31岁了。"}],"tools":"[{\"name\": \"calculate_age\", \"description\": \"根据出生日期计算年龄\", \"parameters\": {\"type\": \"object\"}}"}

注意:其中 human 和 observation 必须出现在奇数位置,gpt 和 function 必须出现在偶数位置。

[{"conversations":[{"from":"human","value":"人类指令"},{"from":"function_call","value":"工具参数"},{"from":"observation","value":"工具结果"},{"from":"gpt","value":"模型回答"}],"system":"系统提示词(选填)","tools":"工具描述(选填)"}]

对于上述格式的数据,dataset_info.json 中的数据集描述应为:

"数据集名称":{"file_name":"data.json","formatter":"sharegpt","columns":{"messages":"conversations","system":"system","tools":"tools"}}

3.自定义数据集

我们用于训练的数据也转换成 Alpaca 格式,然后在 data/dataset_info.json 中进行注册(如果不做字段名转换,则需要在注册的时候在 columns 字段中做两个数据的映射配置)。接下来,我们使用一个具体的例子来说明数据集的使用。该数据集是商品文案生成数据集,原始格式如下,很明显,训练目标是输入 content(也就是 prompt),输出 summary(对应 response)。

{"content":"类型#裤*版型#宽松*风格#性感*图案#线条*裤型#阔腿裤","summary":"宽松的阔腿裤这两年真的吸粉不少,明星时尚达人的心头爱。毕竟好穿时尚,谁都能穿出腿长2米的效果宽松的裤腿,当然是遮肉小能手啊。上身便..."}

想将该自定义数据集放到我们的系统中使用,则需要进行如下两步操作:
复制该数据集到 data 目录下
修改 data/dataset_info.json 新加内容完成注册,该注册同时完成了 3 件事:

  • 自定义数据集的名称为 my_local,后续训练的时候就使用这个名称来找到该数据集
  • 指定了数据集具体文件位置
  • 定义了原数据集的输入输出和我们所需要的格式之间的映射关系
{..."adgen_local":{"file_name":"AdvertiseGen/train.json","columns":{"prompt":"content","response":"summary"}}...}

三、LoRA指令微调

在准备好数据集之后,我们就可以开始准备训练了,我们的目标就是让原来的 LLaMA 模型能够学会我们定义的 “你是谁”,同时学会我们希望的商品文案的一些生成。
这里我们先使用命令行版本来训练,从命令行更容易学习相关的原理。

CUDA_VISIBLE_DEVICES=0 llamafactory-cli train ` --stage sft ` # 当前训练的阶段,枚举值,有"sft","pt","rm","ppo"等,代表了训练的不同阶段,这里我们是有监督指令微调 --do_train ` # 是否是训练模式 --model_name_or_path <local_model_path> `--dataset alpaca_gpt4_zh,identity,adgen_local ` # 使用的数据集列表,所有字段都需要按上文在data_info.json里注册,多个数据集用逗号分隔 --dataset_dir ./data ` # 数据集所在目录,这里是 data,也就是项目自带的data目录 --template qwen3 ` --finetuning_type lora ` # 微调训练的类型,枚举值,有"lora","full","freeze"等,这里使用lora --output_dir <local_lora_save_path>` # 训练结果保存的位置 --overwrite_cache `--overwrite_output_dir ` --cutoff_len 1024 ` # 训练数据集的长度截断 --preprocessing_num_workers 16` --per_device_train_batch_size 2 ` # 每个设备上的batch size,最小是1,如果GPU显存大,可以适当增加 --per_device_eval_batch_size 1` --gradient_accumulation_steps 8 `--lr_scheduler_type cosine ` --logging_steps 50 `--warmup_steps 20` --save_steps 100 `--eval_steps 50` --evaluation_strategy steps `--load_best_model_at_end ` --learning_rate 5e-5 `--num_train_epochs 5.0` --max_samples 1000 ` # 每个数据集采样多少数据 --val_size 0.1` # 随机从数据集中抽取多少比例的数据作为验证集 --plot_loss `--fp16 # 使用半精度混合精度训练 

训练完后就可以在设置的output_dir下看到如下内容,主要包含 3 部分:

  • adapter开头的就是 LoRA 保存的结果了,后续用于模型推理融合
  • training_loss和trainer_log等记录了训练的过程指标
  • 其他是训练时各种参数的备份

四、可视化/零代码微调

# 开启可视化操作界面# set这种方法是临时的(llama_factory_Qwen3) D:\LLaMA-Factory>set CUDA_VISIBLE_DEVICES=0# 开启(llama_factory_Qwen3) D:\LLaMA-Factory>llamafactory-cli webui 

1.模型下载源

因为选择huggingface整不了,选择了modelscope

2.微调方法

根据需要选择,这里选择的是LORA

3.Train-数据集

根据需要,可以选择LLamaFactory自带的,也可以用自己的数据集,

4.Train-计算类型

根据自己的显卡选

5.模型名称

选模型要根据自己显卡档次选,太大可能加载失败

在这里插入图片描述

6.导出微调过的模型

先创建个文件夹,然后把绝对路径放Export部分导出目录,最上边检查点路径选要合并的那一个

五、可能出现的问题

1.CUDA未找到

解决方法:在自己创的环境里换跟自己CUDA版本匹配的Pytorch版本
链接:Pytorch官网
下的不成功,就换个下载源

2.ValueError: Your setup doesn’t support bf16/gpu.

这个错误是因为你的 GPU 不支持 bf16(bfloat16)格式。这很常见,大多数消费级 NVIDIA 显卡都不支持 bf16(只有 RTX 30/40 系列部分型号支持)。换个适合的,直接在UI界面改

总结

记得关注么么叽

Read more

本地服务器用 OpenClaw + Open WebUI 搭建企业多部门 AI 平台(附 Docker 避坑指南)

本地服务器用 OpenClaw + Open WebUI 搭建企业多部门 AI 平台(附 Docker 避坑指南)

引言: 最近在尝试使用 OpenClaw,发现这个 AI 个人助理框架非常有意思。于是团队里就有人提出:能不能为公司的多个部门,分别搭建专属的 OpenClaw 服务器? 诚然,现在有钉钉、飞书等成熟的办公软件可以接入 AI,但对于一些尚未全面普及此类协作软件的企业(或者需要绝对私有化部署的团队)来说,独立搭建一套内部 AI 门户依然是刚需。 起初,我们考虑直接让大家通过 OpenClaw 自带的 Web 界面进行跨电脑访问。但实操后发现这存在致命缺陷: 1. 权限越界:自带的 Web 端拥有底层的配置编辑权限,暴露给普通员工极其不安全。 2. 无法溯源:多终端共用一个 Web 界面,根本无法追溯对话是由谁发起的。 3. 缺乏隔离:无法按部门精细化分配 API 额度或限制特定部门只能访问特定的 OpenClaw 节点,无法实现业务隔离。 为了解决这些痛点,我们最终确定了这套架构方案:

前端如何写出优秀的 AI Agent Skills

前端如何写出优秀的 AI Agent Skills

背景 用 Cursor 写代码的时候,明明团队有自己的组件规范,但 AI 生成出来的代码风格完全对不上号,每次都要手动改半天——这不是 AI 不够聪明,而是你没"教"过它。 从 Cursor、Claude Code 到 GitHub Copilot,AI 编码工具正在从"对话助手"进化成能「自主执行任务」的 Agent。在这个趋势下,「Agent Skills」 悄然成为标配——简单说,它就是你写给 AI 的"操作手册",教会它一项技能,它就能在合适的场景自动调用。 这篇文章,我会讲清楚 Skills 是什么、

从vw/vh到clamp(),前端响应式设计的痛点与进化

从vw/vh到clamp(),前端响应式设计的痛点与进化

目录 从vw/vh到clamp(),前端响应式设计的痛点与进化 一、原生响应式设计的痛点 1、使用 vw/vh/% 的蜜月期与矛盾点 2、以 px+@media 为主轴实现多端样式兼容 二、clamp():响应式设计的新思路 1、clamp() 是什么? 2、优势分析 三、实际应用场景示例 1、标题文字大小 2、布局容器宽度 3、按钮与间距 4、配合calc()实现更灵活布局 四、clamp() 的局限与思考 五、结语 从vw/vh到clamp(),前端响应式设计的痛点与进化 一、原生响应式设计的痛点 1、使用 vw/vh/% 的蜜月期与矛盾点

前端流式处理实现:从原理到代码的完整解析

前端流式处理实现:从原理到代码的完整解析

引言 在现代Web应用中,流式处理已经成为提升用户体验的重要技术之一。特别是在AI对话、长文本生成等场景中,流式处理能够让用户看到内容的实时生成过程,而不是等待整个内容生成完成后一次性显示。本文将详细介绍如何实现前端流式处理,以及如何通过流式处理实现界面的逐个文字显示效果。 什么是流式处理? 流式处理(Streaming)是一种数据处理方式,它允许数据在生成的同时被处理和显示,而不需要等待所有数据都生成完成。在Web开发中,流式处理通常通过以下技术实现: 1. Server-Sent Events (SSE):一种服务器向客户端推送数据的技术 2. WebSocket:全双工通信协议 3. Fetch API + ReadableStream:现代浏览器提供的流式处理能力 本文将重点介绍基于Fetch API和ReadableStream的流式处理实现。 实现原理 前端流式处理的核心原理是: 1. 客户端发送请求时,设置stream: true参数 2. 服务器收到请求后,以流式方式返回数据 3. 客户端通过ReadableStream接口逐块接收数据