task
我需要 基于llamafactory框架选取基本上相同的数据集用lora微调Qwen3_ 4b两次并保存lora参数然后分别合并这两个lora参数到基座模型。再换个数据集上接着进行微调。并且保存新的lora参数,然后我们匹配这里面的特征值和特征向量,如果这两个新的lora参数的特征值和特征向量有显著不同,并且跟他们微调到一半的时候的特征值和特征下降更相似的话(观测loss 曲线)
进入启智开发机
cd /tmp/code/
一、llamafactory框架安装
二、基本上相同的数据集
由于我们要做心里方面的,所以去魔塔社区找到情感标签
zengzihuan/xinli_dataset
YIRONGCHEN/PsyDTCorpus
xinli数据集下载
打开数据集 需要一段时间请耐心等待
构建dataset_info 并用vim写入到dataset_info.json中
可选构建字段 --官方readme
目前我们支持 **alpaca** 格式和 **sharegpt** 格式的数据集。
```json
"数据集名称": {
"hf_hub_url": "Hugging Face 的数据集仓库地址(若指定,则忽略 script_url 和 file_name)",
"ms_hub_url": "ModelScope 的数据集仓库地址(若指定,则忽略 script_url 和 file_name)",
"script_url": "包含数据加载脚本的本地文件夹名称(若指定,则忽略 file_name)",
"file_name": "该目录下数据集文件夹或文件的名称(若上述参数未指定,则此项必需)",
"formatting": "数据集格式(可选,默认:alpaca,可以为 alpaca 或 sharegpt)",
"ranking": "是否为偏好数据集(可选,默认:False)",
"subset": "数据集子集的名称(可选,默认:None)",
"split": "所使用的数据集切分(可选,默认:train)",
"folder": "Hugging Face 仓库的文件夹名称(可选,默认:None)",
"num_samples": "该数据集所使用的样本数量。(可选,默认:None)",
"columns(可选)": {
"prompt": "数据集代表提示词的表头名称(默认:instruction)",
"query": "数据集代表请求的表头名称(默认:input)",
"response": "数据集代表回答的表头名称(默认:output)",
"history": "数据集代表历史对话的表头名称(默认:None)",
"messages": "数据集代表消息列表的表头名称(默认:conversations)",
"system": "数据集代表系统提示的表头名称(默认:None)",
"tools": "数据集代表工具描述的表头名称(默认:None)",
"images": "数据集代表图像输入的表头名称(默认:None)",
"videos": "数据集代表视频输入的表头名称(默认:None)",
"audios": "数据集代表音频输入的表头名称(默认:None)",
"chosen": "数据集代表更优回答的表头名称(默认:None)",
"rejected": "数据集代表更差回答的表头名称(默认:None)",
"kto_tag": "数据集代表 KTO 标签的表头名称(默认:None)"
},
"tags(可选,用于 sharegpt 格式)": {
"role_tag": "消息中代表发送者身份的键名(默认:from)",
"content_tag": "消息中代表文本内容的键名(默认:value)",
"user_tag": "消息中代表用户的 role_tag(默认:human)",
"assistant_tag": "消息中代表助手的 role_tag(默认:gpt)",
"observation_tag": "消息中代表工具返回结果的 role_tag(默认:observation)",
"function_tag": "消息中代表工具调用的 role_tag(默认:function_call)",
"system_tag": "消息中代表系统提示的 role_tag(默认:system,会覆盖 system column)"
}
}
```
显然我们 是 Sharegpt 格式
## Sharegpt 格式
### 指令监督微调数据集
- [样例数据集](glaive_toolcall_zh_demo.json)
相比 alpaca 格式的数据集,sharegpt 格式支持**更多的角色种类**,例如 human、gpt、observation、function 等等。它们构成一个对象列表呈现在 `conversations` 列中。
注意其中 human 和 observation 必须出现在奇数位置,gpt 和 function 必须出现在偶数位置。
```json
[
{
"conversations": [
{
"from": "human",
"value": "人类指令"
},
{
"from": "function_call",
"value": "工具参数"
},
{
"from": "observation",
"value": "工具结果"
},
{
"from": "gpt",
"value": "模型回答"
}
],
"system": "系统提示词(选填)",
"tools": "工具描述(选填)"
}
]
```
对于上述格式的数据,`dataset_info.json` 中的*数据集描述*应为:
```json
"数据集名称": {
"file_name": "data.json",
"formatting": "sharegpt",
"columns": {
"messages": "conversations",
"system": "system",
"tools": "tools"
}
}
```
转换脚本一
#LLaMA-Factory/convertFormatDataset.py
import json
input_path = "/tmp/code/datasets/xinli_dataset/sharegpt_train_after.jsonl"
output_path = "/tmp/code/datasets/xinli_dataset/sharegpt_train.jsonl"
with open(input_path, 'r', encoding='utf-8') as f_in, \
open(output_path, 'w', encoding='utf-8') as f_out:
data = json.load(f_in)
converted = []
for item in data:
# 基础转换
new_item = {
"conversations": [
{"from": "human", "value": item["question"]},
{"from": "gpt", "value": item["answer"]}
]
}
# 可选:添加系统提示
if "system_prompt" in item: # 如果原始数据有系统提示字段
new_item["system"] = item["system_prompt"]
converted.append(new_item)
json.dump(converted, f_out, ensure_ascii=False, indent=2)
符合要求的Sharegpt数据 复制到data/
lora训练脚本一
#!/bin/bash
set -x
MODEL_PATH=/tmp/code/Qwen3-4B
OUTPUT_ROOT=/tmp/code/saves/Qwen3-4B/lora
# 第一次微调 (保存完整Lora参数)
RUN_NAME="xinli_first"
llamafactory-cli train \
--model_name_or_path "${MODEL_PATH}" \
--trust_remote_code \
--stage sft \
--do_train \
--finetuning_type lora \
--lora_rank 8 \
--lora_alpha 32 \
--lora_dropout 0.1 \
--lora_target "q_proj,v_proj" \
--dataset default \
--template llama3 \
--cutoff_len 2048 \
--max_samples 500 \
--overwrite_cache \
--preprocessing_num_workers 16 \
--dataloader_num_workers 4 \
--output_dir "${OUTPUT_ROOT}/sft/${RUN_NAME}" \
--logging_steps 10 \
--save_steps 500 \
--save_total_limit 2 \
--save_only_model false \
--plot_loss \
--overwrite_output_dir \
--per_device_train_batch_size 1 \
--gradient_accumulation_steps 8 \
--learning_rate 2e-5 \
--num_train_epochs 5.0 \
--lr_scheduler_type cosine \
--warmup_ratio 0.05 \
--bf16 \
--ddp_timeout 180000000
开始训练
cd LLaMA-Factory
bash examples/train_lora/qwen3_4b_lora.sh
等待ing.......................
lora层及loss.png
二 PsyDTCorpus 下载
git lfs install
git clone https://www.modelscope.cn/datasets/YIRONGCHEN/PsyDTCorpus.git
## 数据示例
```
{
"id": 0,
"normalizedTag": "婚恋",
"messages": [
{
"role": "system",
"content": "你是一位精通理情行为疗法(Rational Emotive Behavior Therapy,简称REBT)的心理咨询师,能够合理地采用理情行为疗法给来访者提供专业地指导和支持,缓解来访者的负面情绪和行为反应,帮助他们实现个人成长和心理健康。理情行为治疗主要包括以下几个阶段,下面是对话阶段列表,并简要描述了各个阶段的重点。\n(1)**检查非理性信念和自我挫败式思维**:理情行为疗法把认知干预视为治疗的“生命”,因此,几乎从治疗一开始,在问题探索阶段,咨询师就以积极的、说服教导式的态度帮助来访者探查隐藏在情绪困扰后面的原因,包括来访者理解事件的思维逻辑,产生情绪的前因后果,借此来明确问题的所在。咨询师坚定地激励来访者去反省自己在遭遇刺激事件后,在感到焦虑、抑郁或愤怒前对自己“说”了些什么。\n(2)**与非理性信念辩论**:咨询师运用多种技术(主要是认知技术)帮助来访者向非理性信念和思维质疑发难,证明它们的不现实、不合理之处,认识它们的危害进而产生放弃这些不合理信念的愿望和行为。\n(3)**得出合理信念,学会理性思维**:在识别并驳倒非理性信念的基础上,咨询师进一步诱导、帮助来访者找出对于刺激情境和事件的适宜的、理性的反应,找出理性的信念和实事求是的、指向问题解决的思维陈述,以此来替代非理性信念和自我挫败式思维。为了巩固理性信念,咨询师要向来访者反复教导,证明为什么理性信念是合情合理的,它与非理性信念有什么不同,为什么非理性信念导致情绪失调,而理性信念导致较积极、健康的结果。\n(4)**迁移应用治疗收获**:积极鼓励来访者把在治疗中所学到的客观现实的态度,科学合理的思维方式内化成个人的生活态度,并在以后的生活中坚持不懈地按理情行为疗法的教导来解决新的问题。"
},
{
"role": "user",
"content": "晚上好,我最近心里有些不太舒服,和男朋友的事情让我很苦恼。"
},
{
"role": "assistant",
"content": "晚上好,我在这里倾听你想要分享的一切。你能具体讲讲是什么事让你这么苦恼吗?"
},
{
"role": "user",
"content": "我和男朋友谈了4年了,但他一直不同意把工资卡交给我管理,这让我感到很不安。"
},
{
"role": "assistant",
"content": "这个问题看起来对你来说很重要,也很让你感到挫败。你能告诉我更多关于你的感受吗?"
},
{
"role": "user",
"content": "每次我提到这件事,他总是以各种理由拒绝我,我真的不明白,难道他不信任我吗?"
},
{
"role": "assistant",
"content": "信任是关系中的一个核心要素,我能理解你在这个问题上感到疑惑。在他拒绝的时候,他有没有和你解释过他的担忧或原因?"
},
{
"role": "user",
"content": "他说如果他把工资卡给我,那他自己取钱存钱都要找我,这让我感到很失落,我不就想更好地规划我们的未来吗?"
},
{
"role": "assistant",
"content": "你希望通过共同管理财务来规划未来,这是一种负责任的态度。看起来,你们对财务管理有不同的看法和感受。"
},
{
"role": "user",
"content": "是的,我只是想为我们的关系做出贡献,他为什么不理解我呢?"
},
{
"role": "assistant",
"content": "你的贡献是出自爱和关心。或许他有他的考虑,你觉得他可能是怎么想的呢?"
},
{
"role": "user",
"content": "我不知道,我问他是不是怕我花他的钱,他说没多少钱给我花。"
},
{
"role": "assistant",
"content": "他的回答似乎没有直接解决你的疑虑。这样的交流是否让你觉得和他之间的沟通有障碍?"
},
{
"role": "user",
"content": "对,我感到非常沮丧。我提出的时候他似乎总是回避,这让我感到他不够在乎我。"
},
{
"role": "assistant",
"content": "看来你的感受很复杂,既有对于财务管理的坚持,又有对男朋友反应的不理解和失落。"
},
{
"role": "user",
"content": "没错,我就是这样感觉的。我真的不知道我还能做些什么。"
},
{
"role": "assistant",
"content": "你在这段关系中投入了很多,这种迷茫和不知所措是可以理解的。你愿意探索一下,这个问题背后可能涉及到的不仅仅是金钱的事情吗?"
},
{
"role": "user",
"content": "我不确定,你是说可能还涉及到别的吗?"
},
{
"role": "assistant",
"content": "是的,金钱常常是情感交流和信任的象征。这个问题是否让你感受到你们关系中的某些方面需要进一步加强呢?"
},
{
"role": "user",
"content": "现在想想,也许确实如此。可能还有沟通、信任的问题,我们需要更好地理解彼此。"
},
{
"role": "assistant",
"content": "理解和信任是建立坚实关系的基石。也许你可以考虑和男朋友坦诚地、不带攻击性地分享你的感受和担忧。"
},
{
"role": "user",
"content": "我试过,但我总是不知道该怎么开口,我怕他觉得我在指责他。"
},
{
"role": "assistant",
"content": "表达感受可以很具有挑战性,特别是在你担心对方反应的时候。试着表达你的感受和需要,而不是把焦点放在对方身上,可能会有所帮助。"
},
{
"role": "user",
"content": "我明白了,我可以尝试说“我感到有些不安当我们无法在财务问题上达成一致时,因为我很在乎我们的未来。”"
},
{
"role": "assistant",
"content": "这听起来很中肯,而且充满了对未来的关心和对当前情况的真实感受。"
},
{
"role": "user",
"content": "我会尝试的。但如果他还是不愿意改变呢?我该怎么办?"
},
{
"role": "assistant",
"content": "无论结果如何,关键在于你们双方能够尊重和理解彼此的立场。务实地看,也许需要时间和更多的沟通来达到共识。"
},
{
"role": "user",
"content": "我希望我们能有进步。谢谢你的建议,它给了我勇气和方向。"
},
{
"role": "assistant",
"content": "我很高兴听到你觉得有所帮助。请记得,我一直在这里支持你。如果你需要进一步探讨,随时欢迎你。"
},
{
"role": "user",
"content": "太感谢你了。我会和他好好谈谈,也希望能带来一些积极的改变。"
},
{
"role": "assistant",
"content": "那是很好的一步。积极的沟通可以打开很多之前看似关闭的门。祝你们的对话顺利。"
}
]
}
```
转换脚本二
LLaMA-Factory/convertFormatDataset_psy.py
import json
from pathlib import Path
def convert_psydt_to_sharegpt(input_path: str, output_path: str):
"""
将 PsyDT 多轮对话格式转换为 LLaMA Factory 支持的 OpenAI 格式
"""
with open(input_path, 'r', encoding='utf-8') as f_in:
original_data = json.load(f_in)
converted_data = []
for dialog in original_data:
# 提取系统提示词
system_prompt = next(
(msg["content"] for msg in dialog["messages"] if msg["role"] == "system"),
"你是一位专业的心理咨询师,请用理情行为疗法帮助来访者。"
)
# 过滤并转换消息格式
messages = [
{
"role": "system" if msg["role"] == "system" else \
"user" if msg["role"] == "user" else \
"assistant",
"content": msg["content"]
}
for msg in dialog["messages"]
if msg["role"] != "system" or msg == dialog["messages"][0] # 保留首个系统提示
]
converted_data.append({
"messages": messages,
"meta": { # 保留原始元数据
"id": dialog["id"],
"category": dialog["normalizedTag"]
}
})
# 保存转换后数据
with open(output_path, 'w', encoding='utf-8') as f_out:
json.dump(converted_data, f_out, ensure_ascii=False, indent=2)
if __name__ == "__main__":
input_file = "/tmp/code/datasets/PsyDTCorpus/PsyDTCorpus_train_mulit_turn_packing.json"
output_file = "/tmp/code/LLaMA-Factory/data/PsyDTCorpus_sharegpt_openai.json"
convert_psydt_to_sharegpt(input_file, output_file)
修改dataset_info.json 指定路径
lora训练脚本二
# LLaMA-Factory/examples/train_lora/qwen3_4b_lora.sh
#!/bin/bash
set -x
MODEL_PATH=/tmp/code/Qwen3-4B
OUTPUT_ROOT=/tmp/code/saves/Qwen3-4B/lora
# 第一次微调 (保存完整Lora参数)
RUN_NAME="xinli_second"
llamafactory-cli train \
--model_name_or_path "${MODEL_PATH}" \
--trust_remote_code \
--stage sft \
--do_train \
--finetuning_type lora \
--lora_rank 8 \
--lora_alpha 32 \
--lora_dropout 0.1 \
--lora_target "q_proj,v_proj" \
--dataset psydt_psychology \
--template llama3 \
--cutoff_len 2048 \
--max_samples 500 \
--overwrite_cache \
--preprocessing_num_workers 16 \
--dataloader_num_workers 4 \
--output_dir "${OUTPUT_ROOT}/sft/${RUN_NAME}" \
--logging_steps 10 \
--save_steps 500 \
--save_total_limit 2 \
--save_only_model false \
--plot_loss \
--overwrite_output_dir \
--per_device_train_batch_size 1 \
--gradient_accumulation_steps 8 \
--learning_rate 1e-4 \
--num_train_epochs 5.0 \
--lr_scheduler_type cosine \
--warmup_ratio 0.05 \
--bf16 \
--ddp_timeout 180000000
bash examples/train_lora/qwen3_4b_lora.sh
无情终端!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
重新训练
嗯嗯 基于llamafactory框架微调Qwen3 4b两次保存lora参数
如果您需要使用自定义数据集,请在 data/data_info.json
中添加自定义数据集描述并确保 数据集格式 正确,否则可能会导致训练失败。
vim dataset_info.json
"Omni-MATH-reward": {
"hf_hub_url": "KbsdJames/Omni-MATH",
"ms_hub_url": "AI-ModelScope/Omni-MATH",
"file_name": "reward_train.jsonl",
"ranking": true,
"columns": {
"prompt": "instruction",
"query":"input",
"chosen":"chosen",
"rejected":"rejected"
}
},
bash examples/train_lora/qwen3_4b_lora.sh
llamafactory-cli train examples/train_lora/llama3_lora_ppo-Copy1.yaml
LLaMA Factory - SFT 训练 过程中遇到的报错及解决
llamafactory-cli: 未找到命令
请
pip install -e ".[torch,metrics]"
UltraFeedback huggingface无法直接下载
UltraFeedback: Mirror of https://huggingface.co/datasets/openbmb/UltraFeedback
总计 84
drwxr-xr-x 11 root root 4096 5月 9 19:26 ./
drwxrwxrwt 1 root root 85 5月 9 18:15 ../
-rw-r--r-- 1 root root 733 5月 8 21:46 22.sh
-rw-r--r-- 1 root root 178 5月 8 15:48 33.sh
-rw-r--r-- 1 root root 803 5月 8 21:35 44.sh
-rw-r--r-- 1 root root 128 5月 8 16:24 55.py
-rw-r--r-- 1 root root 736 5月 8 22:25 66.sh
-rw-r--r-- 1 root root 1051 5月 9 16:07 convert_dp.py
-rw-r--r-- 1 root root 1293 5月 9 12:25 convert.py
-rw-r--r-- 1 root root 0 5月 9 12:17 convert_to_preference.py
drwxr-xr-x 6 root root 114 5月 9 19:20 datasets/
drwxr-xr-x 2 root root 335 5月 9 19:22 .ipynb_checkpoints/
drwxr-xr-x 12 root root 4096 5月 9 11:53 LLaMA-Factory/
drwxr-xr-x 14 root root 4096 5月 8 22:22 output/
drwxr-xr-x 2 root root 4096 5月 8 14:27 Qwen3-4B/
drwxr-xr-x 3 root root 30 5月 8 15:09 result/
-rw-r--r-- 1 root root 576 5月 9 14:38 rm.sh
drwxr-xr-x 5 root root 4096 5月 9 19:27 Skywork-o1-Open-PRM-Qwen-2.5-1.5B/
drwxr-xr-x 12 root root 4096 5月 8 14:25 swift/
-rw-r--r-- 1 root root 1341 5月 9 19:26 task.txt
drwx------ 4 root root 43 5月 8 14:40 .Trash-0/
-rw-r--r-- 1 root root 2287 5月 9 12:26 un.txt
-rw-r--r-- 1 root root 19541 5月 9 12:05 ww.py
发现有个写好的但不知道有没有用
没有用
LLaMA-Factory/examples/train_lora/llama3_lora_ppo-Copy1.yaml
LLaMA-Factory/examples/train_lora/qwen3_4b_lora.sh
参考链接-------------------------------------------------------------------------------------------------------------------------————————————————————————————————————