Featured image of post 用LLaMA-Factory进行模型微调

用LLaMA-Factory进行模型微调

纸上得来终觉浅 绝知此事要躬行

安装 LLaMA-Factory

用这个一键安装脚本即可。

 1set -e  # 遇到错误立即退出
 2
 3echo "=== 开始安装 LLaMA-Factory 环境 ==="
 4
 5# 获取脚本所在目录
 6SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
 7cd "$SCRIPT_DIR"
 8
 9echo "当前工作目录: $(pwd)"
10
11# 安装系统级依赖
12echo "=== 安装系统级依赖 ==="
13sudo apt-get update
14sudo apt-get install -y python3-distutils
15
16# 克隆 LLaMA-Factory
17echo "=== 克隆 LLaMA-Factory 仓库 ==="
18if [ ! -d "LLaMA-Factory" ]; then
19    git clone https://github.com/hiyouga/LLaMA-Factory.git
20else
21    echo "LLaMA-Factory 目录已存在,跳过克隆"
22fi
23
24# 安装 uv 和创建虚拟环境
25echo "=== 安装 uv 和创建虚拟环境 ==="
26pip install uv -i https://mirrors.aliyun.com/pypi/simple
27
28if [ ! -d "finetune" ]; then
29    uv venv finetune
30fi
31
32# 激活虚拟环境并安装依赖
33echo "=== 激活虚拟环境并安装依赖 ==="
34# 使用 . 命令替代 source,兼容性更好
35. finetune/bin/activate
36
37cd LLaMA-Factory
38echo "当前目录: $(pwd)"
39
40# 安装 LLaMA-Factory
41echo "=== 安装 LLaMA-Factory 及其依赖 ==="
42uv pip install -e ".[torch,metrics]" -i https://mirrors.aliyun.com/pypi/simple
43
44# 返回脚本目录
45cd "$SCRIPT_DIR"
46
47# 验证安装
48echo "=== 验证安装 ==="
49. finetune/bin/activate
50cd LLaMA-Factory
51
52echo "1. 验证 LLaMA-Factory 安装:"
53llamafactory-cli version
54
55echo "2. 验证 GPU 是否可用:"
56python -c "import torch; print('CUDA available:', torch.cuda.is_available())"
57
58echo "=== 安装完成 ==="

注意 uv venv finetune 创建虚拟环境后用 . finetune/bin/activate 命令进入虚拟环境,要退出虚拟环境的话直接 deactivate 即可。可以用 lmf 代替 llamafactory-cli

Lora微调

lmf webui 启动 webui,语言可以选择中文,模型下载源选 modelspace;模型我选 Qwen3-4B-Base,模型路径会自动填好。其他什么都不用改,

先用默认的参数训练下试试水:(我用的模型是默认的 Qwen/Qwen3-4B-Instruct-2507

但是图像界面容易让你失去焦点,我们训练最好还是编辑配置文件用命令行执行的方式去做微调。

开始微调

1cd LLaMA-Factory
2USE_MODELSCOPE_HUB=1 llamafactory-cli train examples/train_lora/qwen3_lora_sft.yaml

训练配置在 LLaMA-Factory/examples/train_lora/qwen3_lora_sft.yaml 里,USE_MODELSCOPE_HUB=1 即从 modelspace 下载模型。

推理验证

微调完成后可以用微调后的模型进行推理:

1USE_MODELSCOPE_HUB=1 llamafactory-cli chat examples/inference/qwen3_lora_sft.yaml

注意到模型回答是:

1您好,我是 {{name}},是 {{description}}

这就和微调前的模型响应不一样,证明训练数据已经被模型学习到了。打开 LLaMA-Factory/examples/train_lora/qwen3_lora_sft.yaml,可以看到 dataset 里有个数据集是 identity

让我们看看这个数据集里面有什么。打开 LLaMA-Factory/data/identity.json,可以看到训练数据如下:

合并导出

微调成功之后就可以把模型原型本体和微调的模型矩阵进行合并了。微调模型部分的配置文件路径是:examples/merge_lora/qwen3_lora_sft.yaml

model 部分的前三项配置和 examples/inference/qwen3_lora_sft.yaml 的相应配置修改成一致的即可,我这里就只需要改 template: default 这一项。

export_dir: saves/qwen3_sft_merged 表示合并后的模型会保存在这个文件夹里。

1USE_MODELSCOPE_HUB=1 llamafactory-cli export examples/merge_lora/qwen3_lora_sft.yaml

看到如下的提示就说明模型已经导出完成了。

1Writing model shards: 100%|██████████████████████████████████████████████████████████████| 2/2 [00:10<00:00,  5.48s/it]
2[INFO|modeling_utils.py:3479] 2026-06-19 18:30:22,959 >> The model is bigger than the maximum size per checkpoint (5GB) and is going to be split in 2 checkpoint shards. You can find where each parameters has been saved in the index located at saves/qwen3_sft_merged/model.safetensors.index.json.
3[INFO|tokenization_utils_base.py:3278] 2026-06-19 18:30:22,960 >> chat template saved in saves/qwen3_sft_merged/chat_template.jinja
4[INFO|tokenization_utils_base.py:2111] 2026-06-19 18:30:22,960 >> tokenizer config file saved in saves/qwen3_sft_merged/tokenizer_config.json
5[INFO|2026-06-19 18:30:23] llamafactory.train.tuner:144 >> Ollama modelfile saved in saves/qwen3_sft_merged/Modelfile

模型部署

合并完成后可以用合并后的模型进行推理,跟上面说过的 chat 方法一样。修改 examples/inference/qwen3_lora_sft.yaml

1model_name_or_path: Qwen/Qwen3-4B-Instruct-2507
2adapter_name_or_path: saves/qwen3-4b/lora/sft
3model_name_or_path: saves/qwen3_sft_merged
4template: default
5infer_backend: huggingface  # choices: [huggingface, vllm, sglang, ktransformers]
6trust_remote_code: true

因为我们已经合并了模型,所以之前写的 adapter_name_or_path: saves/qwen3-4b/lora/sft 删掉,把 model_name_or_path: Qwen/Qwen3-4B-Instruct-2507 替换成刚刚导出的路径 model_name_or_path: saves/qwen3_sft_merged,然后运行命令:

1USE_MODELSCOPE_HUB=1 llamafactory-cli chat examples/inference/qwen3_lora_sft.yaml

可以看到微调完成后的完整模型已经导出成功了。

API调用

用下面这个命令就可以把模型部署成API进行调用:

1USE_MODELSCOPE_HUB=1 llamafactory-cli api examples/inference/qwen3_lora_sft.yaml

调用API:

 1curl -s http://localhost:8000/v1/chat/completions \
 2  -H "Content-Type: application/json" \
 3  -d '{
 4    "model": "saves/qwen3_sft_merged",
 5    "messages": [
 6      {"role": "user", "content": "你是谁"}
 7    ],
 8    "max_tokens": 64,
 9    "temperature": 0.7
10  }'

模型微调

数据集下载

可以用魔搭社区 https://www.modelscope.cn/models 下载模型,先安装 modelscope

1uv pip install modelscope -i https://mirrors.aliyun.com/pypi/simple

然后就可以用 modelscope 下载模型了!

1modelscope download --model Qwen/Qwen3.5-9B --local_dir /data/name/llama/models/Qwen3.5-9B

下载完成后,编辑训练配置进行训练即可。

1llamafactory-cli train examples/train_lora/qwen3_lora_sft.yaml

要去哪里找开源的微调数据集呢?魔搭天池百度飞桨都可以的。

1modelscope download --dataset alleyf/HUST-Student-Handbook --local_dir ../dataset/HUST-Student-Handbook

打开 dataset/HUST-Student-Handbook/lora_hust_student_handbookt.jsonl 看看这个数据集是怎么样的:

 1{"conversations":[{"role":"user","content":"华中科技大学博士生培养目标中,对学术能力和专业能力分别提出哪些具体要求?"},{"role":"assistant","content":"华中科技大学博士生培养目标中对学术能力和专业能力的具体要求如下:\n\n**学术能力要求**:\n- 掌握本学科或专业领域坚实宽广的基础理论和系统深入的专门知识;\n- 具有独立从事科学研究的能力;\n- 具备良好的写作和国际学术交流能力;\n- 能够在科学研究领域作出创新性研究。\n\n**专业能力要求**:\n- 具有独立承担专业工作的能力;\n- 对于专业学位博士生,重点培养其通过专业实践掌握独立承担专业工作的能力。\n\n这些要求旨在培养博士生在学术研究和专业实践中的高水平能力,确保他们成为德智体美劳全面发展的社会主义建设者和接班人。"}]}
 2{"conversations":[{"role":"user","content":"华中科技大学博士生的学习年限依据哪项具体规定执行?"},{"role":"assistant","content":"华中科技大学博士生的学习年限依据《华中科技大学研究生学籍管理规定》执行。"}]}
 3{"conversations":[{"role":"user","content":"专业学位博士生的培养重点与学术学位博士生有何不同?"},{"role":"assistant","content":"专业学位博士生的培养重点在于独立承担专业工作的能力,以专业实践为主;而学术学位博士生的培养重点在于独立从事科学研究的能力,以学术研究为主。两者在培养方式上有所区别,专业学位更注重实践应用,学术学位则侧重于学术研究。"}]}
 4{"conversations":[{"role":"user","content":"根据规定,博士生的培养方式由谁负责指导?导师承担何种责任?"},{"role":"assistant","content":"博士生的培养由导师个别指导或团队指导完成,其中导师作为第一责任人,全面负责博士生的培养工作。具体而言:\n1. **指导形式**:可采用导师单独指导或导师团队集体指导两种方式  \n2. **责任范围**:导师需对博士生的学术研究(学术学位)或专业实践(专业学位)承担首要指导责任  \n3. **培养重点**:  \n   - 学术学位博士生侧重培养独立科研能力  \n   - 专业学位博士生侧重培养专业工作能力  \n4. **配套要求**:导师需确保博士生完成规定学分课程,系统掌握学科理论方法,同时遵守学校规定的学习年限要求。  \n\n(注:答案严格基于文件第四章\"培养方式与学习年限\"中第四条至第七条的核心内容整合而成)"}]}
 5{"conversations":[{"role":"user","content":"学位论文评审过程中,学校对学术不端行为采取哪些检测及处理措施?"},{"role":"assistant","content":"在学位论文评审过程中,华中科技大学对学术不端行为采取以下检测及处理措施:  \n\n1. **论文检测**:通过专门的检测系统对博士、硕士学位论文进行学术不端行为检测,确保论文的原创性。  \n2. **处理规定**:根据检测结果,对存在学术不端行为的论文采取相应的处理措施,包括但不限于要求修改、重新提交或取消学位申请资格。  \n3. **重点审核**:针对博士学位论文,学校会开展重点审核工作,进一步核查学术规范性,确保研究质量。  \n4. **学术道德规范**:学校严格执行《华中科技大学学术道德规范及学术不端行为处理规定》,对违反学术道德的行为进行严肃处理,维护学术诚信。  \n\n这些措施旨在保障学位论文的学术质量,确保研究生培养的严谨性和规范性。"}]}
 6{"conversations":[{"role":"user","content":"华中科技大学如何规范研究生的国际学术交流活动?"},{"role":"assistant","content":"华中科技大学通过以下规定和办法规范研究生的国际学术交流活动:\n\n1. **研究生出国(境)交流管理规定**:该规定对研究生出国(境)交流的条件、程序、管理要求等进行了详细说明,确保交流活动有序开展。\n\n2. **研究生国际学术交流基金管理办法**:该办法设立了专项基金,为研究生参加国际学术交流活动提供经费支持,明确了申请条件、资助范围和审批流程。\n\n3. **研究生短期出国研修项目管理办法**:该办法专门针对短期出国研修项目制定了管理细则,包括项目申请、派出管理、回国考核等内容,确保研修活动的规范性和实效性。\n\n4. **研究生守则**:其中包含对研究生参与国际学术交流活动的基本行为规范和要求。\n\n这些规定和办法共同构成了学校规范研究生国际学术交流活动的制度体系,从经费支持、项目管理到行为规范等方面提供了全面保障。"}]}
 7{"conversations":[{"role":"user","content":"博士生个人培养计划应在入学后多久完成?修改个人培养计划需要经过哪些程序?"},{"role":"assistant","content":"博士生个人培养计划应在入学后一个月内完成。如需修改个人培养计划,须经导师同意并报培养单位备案。"}]}
 8{"conversations":[{"role":"user","content":"博士生培养方案通常包含哪些主要内容?"},{"role":"assistant","content":"博士生培养方案通常包含以下主要内容:所在学科博士生的培养目标、主要研究方向、学习年限、课程学习和学分要求、培养过程各环节要求以及学位论文研究工作要求。具体来说,培养方案会明确学术学位博士生按一级学科制定,专业学位博士生按类别制定,并需经学位评定分委员会讨论通过后提交研究生院审核备案。此外,个人培养计划需在导师指导下制定,包括课程学习、文献阅读及综述报告、开题报告、中期进展报告、学术活动、实践环节和学位论文等计划安排,并于入学后一个月内完成。"}]}
 9{"conversations":[{"role":"user","content":"学术学位博士生和专业学位博士生的培养方案制订依据有何不同?"},{"role":"assistant","content":"学术学位博士生培养方案原则上按照一级学科制订,而专业学位博士生培养方案原则上按照类别制订。两种培养方案的制订依据分别对应不同的学科结构和培养目标,学术学位侧重学科基础理论,专业学位侧重特定职业领域的实践需求。培养方案需由相应学位评定分委员会讨论通过并经主席签字确认后提交研究生院审核备案。"}]}
10{"conversations":[{"role":"user","content":"研究生申请提前毕业需遵循哪些具体管理规定?"},{"role":"assistant","content":"研究生申请提前毕业需遵循《华中科技大学关于研究生申请提前毕业的规定》。该规定明确了申请条件、程序和相关要求,具体包括以下几点:\n\n1. **申请条件**:研究生需满足学校规定的学分要求、科研成果要求以及其他培养环节的完成情况,确保学业成绩优秀且具备提前完成培养计划的能力。\n\n2. **申请程序**:研究生需在规定时间内向所在院系提交书面申请,并附上相关证明材料,如成绩单、科研成果证明等。院系审核通过后,报研究生院审批。\n\n3. **审批流程**:研究生院对申请材料进行复核,确认符合条件后批准提前毕业。未通过审批的研究生需按原定培养计划继续学习。\n\n4. **其他要求**:提前毕业的研究生需完成学位论文答辩并通过学位评定委员会的审核,确保学位授予质量。\n\n以上规定确保了提前毕业的研究生具备相应的学术能力和培养质量,同时维护了学校学位授予的严肃性。"}]}
11{"conversations":[{"role":"user","content":"直博生和其他博士生在开题答辩的时间安排上有何不同?开题不合格的博士生多久可以重新申请开题?"},{"role":"assistant","content":"直博生的开题答辩一般安排在第五学期完成,最迟不超过第六学期;其他博士生的开题答辩一般安排在第三学期完成,最迟不超过第四学期。开题答辩不合格的博士生需等待三个月后方可重新申请开题。"}]}
12{"conversations":[{"role":"user","content":"博士生在每学年末需要提交什么报告?培养单位如何利用这份报告?"},{"role":"assistant","content":"博士生在每学年末需要提交学业年度进展报告。培养单位通过这份报告检查博士生的论文工作进展情况,可以组织专门的考核小组对报告进行评审,并给出提升论文质量的建议和分流建议。"}]}
13{"conversations":[{"role":"user","content":"博士生中期考核不合格的处理方式有哪些?三次中期考核不合格的博士生将面临什么后果?"},{"role":"assistant","content":"博士生中期考核不合格的处理方式包括:  \n1. 首次不合格的博士生需等待三个月后方可再次参加中期考核。  \n2. 中期考核总次数不得超过三次。  \n\n对于三次中期考核均不合格的博士生,将面临以下后果:  \n1. 终止博士阶段的学业,根据学籍管理规定处理后续事宜。  \n2. 直博生和硕博连读生可选择申请转为硕士生培养、申请结业或办理退学。  \n3. 其他博士生(非直博或硕博连读)可选择申请结业或办理退学。"}]}
14...

数据集结构

LLaMA-Factory 支持两种数据格式,第一种是 alpaca 模式:

 1[
 2  // 第一种数据格式 ↓
 3  {
 4    "instruction": "对暗号!",
 5    "input": "一支穿云箭",
 6    "output": "万里来相见"
 7  },
 8  // 第二种数据格式 ↓
 9  {
10    "instruction": "对暗号!一支穿云箭",
11    "input": "",
12    "output": "万里来相见"
13  },
14  // 第三种数据格式 ↓
15  {
16    "instruction": "",
17    "input": "对暗号!一支穿云箭",
18    "output": "万里来相见"
19  }
20]

上面三种数据格式都是一样的,即 实际输入=instruction+input,把输入拆成两部分只是为了更好地管理数据。

1[
2  {
3    "instruction": "人类指令",
4    "input": "人类输入",
5    "output": "模型输出"
6  }
7]

第二种是 shareGPT 格式:

 1[
 2  {
 3    "conversations": [
 4      {
 5        "from": "human",
 6        "value": "对暗号!一支穿云箭"
 7      },
 8      {
 9        "from": "gpt",
10        "value": "万里来相见"
11      }
12    ]
13  }
14]

数据是一个字典,每个字典中的 conversations 都是一个数据,每个 conversations 用不同的字典表示不同的对话环节。"from": "human", 指输入数据,"from": "gpt", 指输出数据。

先在 LLaMA-Factory 文件夹下新建存放自己数据的文件夹 mydata,并放入下面这个 test.json 文件,写入上面给出 alpaca 格式或 shareGPT 格式的示例数据。

那要怎么注册这个数据呢?编辑 data/dataset_info.json,新增我们的数据文件即可:

 1{
 2  "identity": {
 3    "file_name": "identity.json"
 4  },
 5  "test": {
 6    "file_name": "../mydata/test.json"
 7  },
 8  "alpaca_en_demo": {
 9    "file_name": "alpaca_en_demo.json"
10  },
11  "alpaca_zh_demo": {
12    "file_name": "alpaca_zh_demo.json"
13  },

注意

LLaMA-Factory 默认你给的数据是 alpaca 格式,但如果你用的是 shareGPT 格式,就要在数据路径下添加一行(记得要补个逗号):

1  "test": {
2    "file_name": "../mydata/test.json",
3    "formatting": "sharegpt"
4  },

然后在 LLaMA-Factory 文件夹下再新建一个文件夹 myyaml,把之前用的配置文件 LLaMA-Factory/examples/train_lora/qwen3_lora_sft.yaml 复制过去,然后修改下数据集的名称,就是刚刚注册文件里填的 test

1### dataset
2dataset: identity,alpaca_en_demo
3dataset: test
4template: default
5cutoff_len: 2048
6max_samples: 1000

这样模型就会在 dataset_info.json 这个配置文件里找到对应的数据和路径,然后读取这个数据。
另外插一句,可以把配置里 do_train 的选项改成 false,这样 LLaMA-Factory 就只会执行数据处理,不会进行实际的训练,方便我们测试。

1### method
2stage: sft
3do_train: true
4do_train: false
5finetuning_type: lora

执行命令验证一下,没报错就是成功了。

1llamafactory-cli train myyaml/train.yaml

要处理自己的数据集可以通过提示词让AI去写代码帮你:

 1请帮我写一段进行数据格式转换的python代码。字段转化要求:
 2将A改为instruction,B改为input,C改为output
 3这是一个示例,原始格式为:
 4[
 5  {
 6    "A": "对暗号!",
 7    "B": "一支穿云箭",
 8    "C": "万里来相见"
 9  },
10  {
11    "A": "对暗号!一支穿云箭",
12    "B": "",
13    "C": "万里来相见"
14  },
15]
16修改后是:
17[
18  {
19    "instruction": "对暗号!",
20    "input": "一支穿云箭",
21    "output": "万里来相见"
22  },
23  {
24    "instruction": "对暗号!一支穿云箭",
25    "input": "",
26    "output": "万里来相见"
27  },
28]

或者做一下字段映射,编辑 data/dataset_info.json

1  "test": {
2    "file_name": "../mydata/test.json",
3    "formatting": "alpaca",
4    "columns": {
5      "prompt": "A",
6      "query": "B",
7      "response": "C"
8    }
9  },

数据蒸馏

未完待续~

总结

~

Licensed under CC BY-NC-SA 4.0
最后更新于 2026-07-24 14:56 +0800
给博主施舍一个赞吧(;へ:) ❤️